Zero-dependency Anubis PoW solver — bypasses fast / metarefresh / preact challenge modes
Project description
gan-anubis 幹 Anubis
A minimal, zero-dependency Python PoC that bypasses all three Anubis challenge modes.
零依賴 Python 概念驗證,繞過 Anubis 全部三種挑戰模式。
What is Anubis? / Anubis 是什麼?
Anubis is a proof-of-work reverse proxy designed to block AI scrapers. It claims to force bots to run a full Chrome browser (~500MB RAM) just to solve its challenges.
Anubis 是一個工作量證明反向代理,設計用來阻擋 AI 爬蟲。官方宣稱爬蟲必須跑完整的 Chrome 瀏覽器(~500MB RAM)才能解題。
This PoC proves otherwise. / 本專案證明並非如此。
Results / 結果
| Headless Chrome | gan-anubis | |
|---|---|---|
| RAM | ~500MB | ~20MB |
| Solve time (difficulty=2) | ~1.35s | <10ms |
| Solve time (difficulty=5) | ~7s+ | ~200ms |
| Dependencies | Chrome + Playwright | None (stdlib only) |
Verified targets / 實測目標
| Site | Difficulty | Mode | Result |
|---|---|---|---|
| anubis.techaro.lol | 1 | preact | ✅ |
| cgit.freebsd.org | 2 | fast | ✅ |
| bugs.freebsd.org | 2 | fast | ✅ |
| git.kernel.org | 5 | fast | ✅ 202ms |
Install / 安裝
pip install gan-anubis
Or clone and install locally / 或本地安裝:
git clone https://github.com/your-username/gan-anubis
cd gan-anubis
pip install .
Usage / 使用方式
CLI
# Basic / 基本用法
gan-anubis "https://git.kernel.org/"
# Save cookie for reuse (valid 7 days) / 儲存 cookie 重複使用(有效 7 天)
gan-anubis "https://git.kernel.org/" --cookie-file cookies.txt
# Custom output filename / 自訂輸出檔名
gan-anubis "https://git.kernel.org/" --output result.html
# Don't save HTML / 不儲存 HTML
gan-anubis "https://git.kernel.org/" --no-save
# Quiet mode / 靜默模式
gan-anubis "https://git.kernel.org/" --quiet --output result.html
Library / 作為套件使用
import http.cookiejar
from gan_anubis import bypass
jar = http.cookiejar.MozillaCookieJar()
html = bypass("https://git.kernel.org/", cookie_jar=jar)
print(html[:500])
# Reuse cookie next time / 下次重用 cookie
jar.save("cookies.txt", ignore_discard=True)
Example output / 範例輸出
[*] Target: https://git.kernel.org/
[*] Fetching challenge...
[*] Algorithm: fast, Difficulty: 5
[*] Solving PoW...
[+] Solved! nonce=194413, hash=00000aba01b40da4..., elapsed=202ms
[*] Submitting solution...
[+] Got JWT cookie! (techaro.lol-anubis-auth-auth)
[*] Fetching real content...
[+] Success! title: Kernel.org git repositories
Supported Modes / 支援模式
| Mode | Logic |
|---|---|
fast |
Brute-force SHA-256(randomData + nonce) until leading difficulty nibbles are 0 |
metarefresh |
Wait difficulty × 0.8s, return randomData as-is |
preact |
Wait difficulty × 0.08s, return SHA-256(randomData) |
Cookie valid for 7 days — solve once, scrape freely.
Cookie 有效期 7 天,解一次就能爬一週。
Why existing Python solvers are wrong / 為什麼現有 Python solver 是錯的
The only other Python solver on PyPI (anubis-solver) has two critical bugs:
PyPI 上唯一的 Python solver 有兩個關鍵 bug:
Bug 1: Wrong nibble check / nibble 檢查錯誤
# ❌ Wrong: checks leading bytes (256x harder than needed)
if all(b == 0 for b in h[:difficulty]):
# ✅ Correct: checks leading nibbles (hex characters)
if h[:difficulty] == '0' * difficulty:
Bug 2: Missing id parameter / 缺少 id 參數
# ❌ Wrong: always returns HTTP 500
"pass-challenge?response={hash}&nonce={nonce}&redir=/"
# ✅ Correct
"pass-challenge?id={id}&response={hash}&nonce={nonce}&redir=/"
This PoC was reverse-engineered directly from Anubis source code (main.mjs, pow_native.go, preact.go).
本專案直接從 Anubis 原始碼逆向工程而來。
How it works / 原理
1. GET target URL (with cookie jar)
→ Server returns challenge page with JSON embedded in <script> tag
2. Parse challenge JSON:
{ "rules": { "algorithm": "fast", "difficulty": 5 },
"challenge": { "id": "...", "randomData": "..." } }
3. Solve based on algorithm:
fast → SHA-256(randomData + nonce) with N leading zero nibbles
metarefresh → return randomData after waiting difficulty × 0.8s
preact → return SHA-256(randomData) after waiting difficulty × 0.08s
4. GET /.within.website/x/cmd/anubis/api/pass-challenge?id=...&response=...&nonce=...
→ Server verifies, issues EdDSA-signed JWT cookie (valid 7 days)
5. Use cookie for subsequent requests — no re-solving needed
Tested on / 測試環境
- Anubis
v1.25.1(latest as of June 2026) - Android (Termux) and Linux x86_64
- All three challenge modes verified
Security note / 安全說明
This is a proof of concept for educational and research purposes.
The goal is to demonstrate that PoW-based bot protection has fundamental limitations against determined scrapers.
本專案僅供教育與研究目的的概念驗證。
目的是說明基於工作量證明的機器人防護對有心的爬蟲存在根本性的局限。
As Tavis Ormandy noted: "I don't think we reach a single cent per month in compute costs until several million sites have deployed Anubis."
License / 授權
MIT
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file gan_anubis-1.0.0.tar.gz.
File metadata
- Download URL: gan_anubis-1.0.0.tar.gz
- Upload date:
- Size: 6.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f35b44f9bc6fa8aa0195a9e361c3f2c91f9c9469392c81893bcf7cfb641a666a
|
|
| MD5 |
8b087b22da4e58e7c88ad2ce7bdf063b
|
|
| BLAKE2b-256 |
12ff13e4ebb43af9cbea3e2093d652cefdf6e11da9e88f8d3be588604cc68288
|
File details
Details for the file gan_anubis-1.0.0-py3-none-any.whl.
File metadata
- Download URL: gan_anubis-1.0.0-py3-none-any.whl
- Upload date:
- Size: 7.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.5
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e2ece8b585a4d3516d5c8724da4a45375aa2b2f8bf753a45a7106afa6978ec77
|
|
| MD5 |
b736fd6a88355396754fe90dd1c5a3a2
|
|
| BLAKE2b-256 |
c7467c25244848d5c99f726f7bdcb1faa686c60a8df7579b5d17d2a35cacce15
|