DarKnight: Retrieval-Guided Agentic Framework for Breaking Dark Web CAPTCHA Gates
Organizations: National University of Singapore Singapore · A*STAR Institute of Advanced Intelligence and Compute Singapore
Abstract
Cyber Threat Intelligence (CTI) investigators who monitor dark web marketplaces for leaked credentials and breach listings must pass the diverse CAPTCHAs that operators deploy to block automated collection. Existing solvers either need unscalable per-site fine-tuning or rely on commercial Vision-Language Model (VLM) APIs, which surrender operational sovereignty: provider policies, Tor-exit blocking, government regulation, or model updates outside the investigator's control can halt or alter the solver overnight, and per-call costs recur with every session and retry. We present DarKnight, a self-improving agentic framework designed to run on a single workstation GPU inside an investigator's Tor crawler and solve CAPTCHAs with small, locally hosted open-weight VLMs that no provider decision can withdraw, without per-market training or third-party services. For each CAPTCHA, DarKnight retrieves successful and failed past attempts on similar images (dual-signal RAG), composes an image-specific preprocessing pipeline, and learns from the site's pass/fail verdict. In a case study on four real-world dark web marketplaces, agentic tool selection outperformed parameter scaling. A deployable open-weight VLM with DarKnight reached 83.2% on the most heavily defended market, 37.2 percentage points above its base model, outperforming even the frontier Claude Opus~5 (44%). DarKnight recovered 48.2% of baseline failures at a 7.6% degeneration cost, indicating that selective tool use can avoid much of the degradation caused by uniform preprocessing.
Figures & tables
| Features | Values |
| captcha_type | alphanumeric math chinese |
| char_count | Integer count of CAPTCHA characters |
| noise | none color_lines : multiple coloured wavy/diagonal lines of a different hue from the text strikethrough : one thin dark line crossing all characters arc : dark curved or arc-shaped bands vertical_lines : thin dark vertical strokes through characters dots : scattered isolated dot clusters salt_pepper : fine pixel-level random grain |
| background | clean gradient noisy patterned |
| distortion | none wave blur perspective |
| char_quality | normal hollow faded thin broken thick |
| Slot | Content | Capacity | Eviction Policy |
| correct | Successful predictions | 100 records | Least-retrieved first |
| failed | Failed predictions | 100 records | Least-retrieved first |
| Slot | Similarity | Action |
| Correct | Adopt pipeline if features match | |
| – | Verify each feature before copying | |
| Ignore entirely | ||
| Failed | Avoid same tools | |
| – | Still a negative signal | |
| Repeated | Treat that tool as banned |
| Tool | Description and Usage Condition |
| color_extract | Removes colored interference lines by isolating non-color pixels. Use when wavy or diagonal lines of a distinct color cross the text region. |
| sharpen | Restores character edge crispness via unsharp masking. Use when blur distortion has softened character boundaries. |
| denoise | Removes small connected components below an area threshold. Use to clean residual noise dots or on patterned backgrounds. |
| remove_line | Detects and removes a single thin dark diagonal or near-horizontal line via the Hough transform. Use when such a line crosses all characters. |
| binarize | Converts a faded-grayscale image to black-and-white using Otsu’s global threshold. Use only when background = "clean" . |
| Dataset | Type | Sample size | Background | Noise | Distortion | Char Quality | Difficulty | Dark web site |
| Alpha / Math / Chinese | 500 | Mixed | colored lines | Wave | Mixed | High | ChangAn | |
| Alphanumeric | 500 | Clean | Strikethrough line | None | Normal | Low | Freecity | |
| Alphanumeric | 500 | Gradient | Dots/specks | Wave | Normal | Medium | Russian market | |
| Alphanumeric | 500 | Patterned | None (mesh texture) | None | Thick | Medium | Mobilestore |
| Model Name | Size | Mode | Domain | Date | Source |
| HunyuanOCR | 1B | Inst | OCR | Nov 2025 | Tencent |
| Gemma4-E4B-it | 8B | Inst | General | Apr 2026 | |
| Qwen3-vl-4B | 4B | Inst | General | Oct 2025 | Alibaba |
| Qwen3-vl-8B | 8B | Inst | General | Oct 2025 | Alibaba |
| Qwen3.5-9B | 9B | Think | General | Mar 2026 | Alibaba |
| Step3-VL-10B | 10B | Think | General | Jan 2026 | Stepfun |
| Tool | N | % | C C | C W | W C | W W | Degen% | Recov% | Net |
| (no tool) | 4406 | 72.8 | 2357 | 159 | 733 | 1157 | 6.3 | 38.8 | 32.5 |
| color_extract | 1216 | 20.1 | 371 | 58 | 508 | 279 | 13.5 | 64.5 | 51.0 |
| sharpen | 197 | 3.3 | 66 | 3 | 90 | 38 | 4.3 | 70.3 | 66.0 |
| remove_straight_line | 184 | 3.0 | 111 | 9 | 53 | 11 | 7.5 | 82.8 | 75.3 |
| denoise | 43 | 0.7 | 17 | 12 | 6 | 8 | 41.4 | 42.9 | 1.5 |
| binarize | 3 | 0.0 | 0 | 0 | 0 | 3 | — | 0.0 | — |
| No-preproc rate | 26.6% | 86.9% | 97.0% | 56.7% |
| Avg baseline acc | 35.7% | 67.7% | 50.5% | 70.6% |
| Avg with DarKnight | +34.2 | +21.5 | +6.5 | +9.5 |
| Model | Baseline | DarKnight | |
| Qwen3-VL-8B | 65.0 | 75.0 | +10.0 |
| Gemma4-E4B | 50.8 | 60.8 | +10.0 |
| Qwen3.5-9B | 16.5 | 80.4 | +63.9 |
| Qwen3.6-27B | 65.0 | 78.0 | +13.0 |
| Model | Params | B | DK | B | DK | B | DK | B | DK |
| HunyuanOCR | 1B | 1.82 | – | 0.10 | – | 0.07 | – | 0.13 | – |
| Gemma4-E4B-IT | 8B | 0.156 | 3.81 | 0.154 | 3.25 | 0.137 | 3.12 | 0.157 | 2.97 |
| Qwen3-VL-4B-Instruct | 4B | 0.122 | 2.72 | 0.102 | 2.21 | 0.120 | 2.57 | 0.108 | 2.34 |
| Qwen3-VL-8B-Instruct | 8B | 0.170 | 4.26 | 0.164 | 3.72 | 0.273 | 3.89 | 0.165 | 3.67 |
| Qwen3.5-9B | 9B | 0.168 | 5.38 | 0.162 | 4.70 | 0.163 | 5.17 | 0.166 | 4.43 |
| Model | Params | Avg B | Avg DK | Avg | (s) |
| Qwen3-VL-4B-Instruct | 4B | 29.9 | 54.8 | 24.9 | 2.46 |
| Qwen3-VL-8B-Instruct | 8B | 36.3 | 48.3 | 12.0 | 3.89 |
| Gemma4-E4B-IT | 8B | 50.8 | 59.9 | 9.1 | 3.29 |
| Qwen3.5-9B | 9B | 64.6 | 80.9 | 16.3 | 4.92 |
| Step3-VL-10B | 10B | 74.2 | 78.8 | 4.6 | 52.75 |
| Gemma4-12B-IT | 12B | 54.9 | 67.4 | 12.6 | 4.43 |
| Dataset | Samples | ESA (%) | CER (%) | Resolution |
| 500 | 90.4 | 2.90 | Consensus | |
| 500 | 99.4 | 0.16 | Consensus | |
| 500 | 96.4 | 0.70 | Consensus | |
| 500 | 94.4 | 1.29 | Consensus |
| Model | Params | B | DK | B | DK | B | DK | B | DK | ||||
| HunyuanOCR | 1B | 12.4 | – | – | 61.4 | – | – | 45.7 | – | – | 90.0 | – | – |
| Gemma4-E4B-IT | 8B | 5.8 | 46.8 | +41.0 | 71.4 | 65.8 | 5.6 | 51.5 | 56.5 | +5.0 | 74.4 | 70.4 | 4.0 |
| Qwen3-VL-4B-Instruct | 4B | 28.0 | 55.6 | +27.6 | 30.8 | 73.4 | +42.6 | 26.8 | 35.3 | +8.5 | 33.8 | 54.8 | +21.0 |
| Qwen3-VL-8B-Instruct | 8B | 39.6 | 66.6 | +27.0 | 43.4 | 49.0 | +5.6 | 33.4 | 38.3 | +4.9 | 28.8 | 39.4 | +10.6 |
| Qwen3.5-9B | 9B | 36.6 | 73.4 | +36.8 | 78.2 | 94.2 | +16.0 | 58.1 | 63.4 | +5.3 | 85.4 | 92.4 | +7.0 |
| RAG Size | ||
| No RAG | 52.8 | 51.0 |
| 10 | 57.2 | 53.0 |
| 20 | 56.8 | 73.2 |
| 50 | 56.0 | 73.2 |
| 80 | 57.2 | 64.8 |
| 100 | 57.8 | 73.4 |
| Parameter | visual_analysis & plan | run_ocr |
| max_tokens | 2048 | 1024 |
| temperature | 0.0 | 0.1 |
| Input | image+text+RAG | processed image+text |