Anubis PoW Form Solver

Compute Anubis PoW and fill in a manual submission form

As of 2025-05-11. See the latest version.

// ==UserScript==
// @name        Anubis PoW Form Solver
// @namespace   Anubis PoW Form Solver
// @version     1.0
// @description Compute Anubis PoW and fill in a manual submission form
// @match        *://*/*
// @license MIT
// ==/UserScript==



(async () => {
    if (!document.getElementById("anubis_challenge")) return;

    const challengeData = JSON.parse(document.getElementById("anubis_challenge").textContent);
    const basePrefix = JSON.parse(document.getElementById("anubis_base_prefix").textContent);
    const { challenge, rules } = challengeData;
    const difficulty = rules.difficulty;
  	const newDiv = document.createElement('div');
  	
  
		

    console.log("Solving Anubis challenge:", challenge, "(difficulty:", difficulty, ")");
    
	  function replaceStatusWithPlugInIndicator(newDiv) {

			const oldP = document.querySelector('p#status');
    	newDiv.id = 'status';
            
    	if (oldP) {
          oldP.replaceWith(newDiv);        
      }
      else {
      	// this is so that if they change the format of the page, it should still work:
      	document.body.append(newDiv);
      }
      
      
      const plugInIndicator = document.createElement('h2');
      plugInIndicator.innerText = 'Browser Plugin: Computing proof of work...';
			plugInIndicator.style = "color: red";
     
      newDiv.appendChild(plugInIndicator);
      
	}
  
  
 	function showDone(newDiv, done_form) {
    newDiv.replaceChildren(done_form)

      
	}
  
  
    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++;
        }
    }

  
  
  	replaceStatusWithPlugInIndicator(newDiv);
    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 });

    // Build form
    const form = document.createElement("form");
    form.action = `${basePrefix}/.within.website/x/cmd/anubis/api/pass-challenge`;
    form.method = "GET";

    // Helper to make inputs
    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 = `✅ Proof-of-Work complete (nonce=${nonce}, hash=${hash.slice(0, 12)}...). Click below to continue.`;
    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);


  
  
  	showDone(newDiv, form);
  
})();