Skip to content

Instantly share code, notes, and snippets.

@karans4
Last active May 11, 2025 22:08
Show Gist options
  • Save karans4/054cac5771dfa206888af8876d192fa0 to your computer and use it in GitHub Desktop.
Save karans4/054cac5771dfa206888af8876d192fa0 to your computer and use it in GitHub Desktop.
Anubis PoW Form Solver (userscript)
// ==UserScript==
// @name Anubis PoW Form Solver (Dual-Compatible)
// @namespace http://tampermonkey.net/
// @version 1.1.1
// @description Compute Anubis PoW and present a manual submission form (works on both old and new Anubis versions)
// @match *://*/*
// @grant none
// ==/UserScript==
(async () => {
if (!document.getElementById("anubis_version")){
return;
}
function toHex(buffer) {
return Array.from(new Uint8Array(buffer))
.map(b => b.toString(16).padStart(2, "0"))
.join("");
}
async function computePoW(challenge, difficulty) {
const encoder = new TextEncoder();
const prefix = "0".repeat(difficulty);
let nonce = 0;
while (true) {
const input = encoder.encode(challenge + nonce);
const hashBuffer = await crypto.subtle.digest("SHA-256", input);
const hashHex = toHex(hashBuffer);
if (hashHex.startsWith(prefix)) return { hash: hashHex, nonce };
nonce++;
}
}
async function getChallengeAndPrefix() {
try {
// Try newer version: embedded challenge
const challengeEl = document.getElementById("anubis_challenge");
const prefixEl = document.getElementById("anubis_base_prefix");
if (challengeEl && prefixEl) {
const challengeData = JSON.parse(challengeEl.textContent);
const basePrefix = JSON.parse(prefixEl.textContent);
return {
challenge: challengeData.challenge,
difficulty: challengeData.rules.difficulty,
basePrefix
};
}
// Fallback to older version: API fetch
const versionEl = document.getElementById("anubis_version");
const versionInfo = versionEl ? JSON.parse(versionEl.textContent) : "fallback";
const apiUrl = `${window.location.origin}/.within.website/x/cmd/anubis/api/make-challenge`;
const response = await fetch(apiUrl, {
method: "POST"
});
if (!response.ok) throw new Error("Failed to fetch challenge");
const data = await response.json();
return {
challenge: data.challenge,
difficulty: data.rules.difficulty,
basePrefix: "" // older version hardcodes path
};
} catch (err) {
console.error("PoW script failed to initialize:", err);
return null;
}
}
const challengeInfo = await getChallengeAndPrefix();
if (!challengeInfo) return;
const { challenge, difficulty, basePrefix } = challengeInfo;
console.log("Solving Anubis challenge:", challenge, "(difficulty:", difficulty, ")");
let newDiv = document.createElement("div");
newDiv.id = "status";
const oldP = document.querySelector("p#status");
if (oldP) {
oldP.replaceWith(newDiv);
} else {
document.body.prepend(newDiv);
}
const msg = document.createElement("h2");
msg.innerText = "Browser Plugin: Computing proof of work...";
msg.style.color = "red";
newDiv.appendChild(msg);
const t0 = performance.now();
const { hash, nonce } = await computePoW(challenge, difficulty);
const elapsedTime = Math.round(performance.now() - t0);
console.log("✅ PoW solved", { hash, nonce, elapsedTime });
const form = document.createElement("form");
form.action = `${basePrefix}/.within.website/x/cmd/anubis/api/pass-challenge`;
form.method = "GET";
const addField = (name, value) => {
const input = document.createElement("input");
input.type = "hidden";
input.name = name;
input.value = value;
form.appendChild(input);
};
addField("response", hash);
addField("nonce", nonce.toString());
addField("redir", window.location.href);
addField("elapsedTime", elapsedTime.toString());
const label = document.createElement("p");
label.textContent = `✅ PoW complete (nonce=${nonce}, hash=${hash.slice(0, 12)}...). Click to submit.`;
form.appendChild(label);
const button = document.createElement("button");
button.type = "submit";
button.textContent = "Submit Proof of Work →";
button.style = "padding: 0.5em 1em; font-size: 1em;";
form.appendChild(button);
newDiv.replaceChildren(form);
})();
@SergioFLS
Copy link

seems to have no effect on the FFmpeg wiki (https://trac.ffmpeg.org/)

@karans4
Copy link
Author

karans4 commented May 11, 2025

Hmm... That page seems to dynamically load in the challenge, so I'll have to add a work around for pages like that

@karans4
Copy link
Author

karans4 commented May 11, 2025

I was only testing it on version 1.18, but this should work for Anubis 1.16 too. I probably won't come up with any other workarounds unless I turn it into a real thing, but the FFmpeg wiki should work too now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment