From 00eeaa6c119b0ae569c3376b2dcde234e42a58c5 Mon Sep 17 00:00:00 2001 From: abdibekbolot Date: Tue, 11 Aug 2026 09:46:04 +0900 Subject: [PATCH 01/10] feat: add ADA detection challenge and update related documentation --- .gitmodules | 3 + docs/challenges/.nav.yml | 2 +- docs/challenges/README.md | 2 +- docs/challenges/ada_detection/README.md | 104 ++++------ .../ada_detection/testing_manuals.md | 183 ++++++++++++++---- docs/challenges/ada_detection/v3.md | 116 +++++++++++ requirements.txt | 1 + src/challenges/ada_detection | 1 + src/challenges/flowprint | 1 + .../challenge_pool/active_challenges.yaml | 61 +++++- 10 files changed, 369 insertions(+), 105 deletions(-) create mode 100644 docs/challenges/ada_detection/v3.md create mode 160000 src/challenges/ada_detection create mode 160000 src/challenges/flowprint diff --git a/.gitmodules b/.gitmodules index 2cc00bb9..9c0db0e4 100644 --- a/.gitmodules +++ b/.gitmodules @@ -4,3 +4,6 @@ [submodule "src/challenges/bot_virus"] path = src/challenges/bot_virus url = https://github.com/RedTeamSubnet/bot-virus-challenge.git +[submodule "src/challenges/ada_detection"] + path = src/challenges/ada_detection + url = https://github.com/RedTeamSubnet/ada-detection-challenge.git diff --git a/docs/challenges/.nav.yml b/docs/challenges/.nav.yml index 53ae4096..04153525 100644 --- a/docs/challenges/.nav.yml +++ b/docs/challenges/.nav.yml @@ -3,10 +3,10 @@ nav: - Active Challenges: - ab_sniffer: ./ab_sniffer - bot_virus: ./bot_virus + - ada_detection: ./ada_detection - Inactive Challenges: - flowradar: ./flowradar - flowprint: ./flowprint - historical_fingerprinter: ./historical_fingerprinter - dev_fingerprinter: ./dev_fingerprinter - - ada_detection: ./ada_detection - humanize_behaviour: ./humanize_behaviour diff --git a/docs/challenges/README.md b/docs/challenges/README.md index bf1efd6b..d991e7f6 100644 --- a/docs/challenges/README.md +++ b/docs/challenges/README.md @@ -69,5 +69,5 @@ Follow these steps to successfully submit your challenge solution: - **[FlowRadar v2](flowradar/README.md)** Train and run a two-stage model pipeline for VPN detection from network flow data. - **[FlowPrint v1](flowprint/README.md) — Inactive** Former OS-classification challenge; submissions are rejected. - **[Humanize Behaviour](humanize_behaviour/README.md)** Develop bot scripts that mimic natural human interaction with web forms. -- **[Anti-Detect Automation Detection (AAD)](ada_detection/README.md)** Detect browser automation inside anti-detect environments where fingerprints are masked. +- **[Anti-Detect Browser Detection (ADA)](ada_detection/README.md)** Identify which commercial anti-detect browser is driving a session, without firing on human traffic. - **[Device Fingerprinter](dev_fingerprinter/README.md) Inactive** Create browser SDKs that accurately fingerprint and identify devices. diff --git a/docs/challenges/ada_detection/README.md b/docs/challenges/ada_detection/README.md index 5b97bec6..7a47401e 100644 --- a/docs/challenges/ada_detection/README.md +++ b/docs/challenges/ada_detection/README.md @@ -1,89 +1,69 @@ -# Anti-Detect Automation Detection (AAD) Challenge +# Anti-Detect Browser Detection (ADA) Challenge ## Overview -The **Anti-Detect Automation Detection (AAD)** challenge evaluates a participant's ability to reliably detect browser automation frameworks operating inside anti-detect browsers, while preserving human safety. +The **Anti-Detect Browser Detection (ADA)** challenge tests miners' ability to identify which +**commercial anti-detect browser** is driving a session, while leaving genuine human traffic +untouched. -Evaluation runs simulate real-world anti-detect usage where static signals are masked and fingerprints are fresh. Detection must rely on runtime behavior and orchestration patterns. +Each target is a paid desktop application that launches a managed profile and is driven over +its own loopback API. There is no WebDriver or CDP automation flag to key on, so detection +must rely on the product artifacts the anti-detect browser itself leaves behind in the page +environment. -## Anti-Detect Environment +## General Technical Requirements -Each evaluation run involves: +- **Development Language**: JavaScript (ES6+), one self-contained detector per target +- **Environment**: Docker container environment +- **Architecture**: amd64 (ARM64 at your own risk) +- **State**: Stateless execution with no persistence between runs -- A **fresh NST-Browser profile**. -- An **isolated Docker container per framework**. -- Masks for browser fingerprints and no shared state between runs. +## General Guidelines -!!! Info "NST-Browser Dependency" - Participants need an API key from the [NSTBrowser](https://www.nstbrowser.io/en/pricing) dashboard (Professional plan recommended) for local testing. +- **Detection Method**: Analyze product-specific artifacts, patched APIs, injected objects, + and behavioral patterns. +- **Execution Modes**: Detectors are tested in both headed and headless modes. +- **Human Safety**: A normal headed browser must not trigger a browser or headless detector. + Any false positive on a human task drives the score to zero. +- **Prohibited Method**: Browser fingerprinting is not allowed. -## Features of ADA Detection v2 +## Plagiarism Check -- **Hardened NSTBrowser Environment**: Advanced obfuscation including dynamic fingerprinting and hardware simulation (8GB RAM, 16 Cores). -- **Engine-Level Stealth**: `AutomationControlled` flags are disabled at the browser engine level to eliminate static detection signals. -- **Fail-Fast Scoring**: High-stakes evaluation where missing critical targets (Selenium) or exceeding miss limits results in an immediate 0.0 score. -- **Protocol-Level Verification**: Mandatory detection of low-level communication patterns (Webdriver and WebSocket). -- **Selenium Safety Gate**: Mandatory detection of `seleniumbase` and `selenium_driverless` is required for incentive eligibility. -- **Similarity/time decay**: Similarity penalties apply to lookalike submissions; scores decay over 15 days to encourage refreshed heuristics. - -## Evaluation Flow +We maintain strict originality standards: -1. **Submission Received**: Detection scripts are submitted via the `/score` endpoint. -2. **Task Generation**: A randomized sequence of multiple automation framework runs and human interactions is generated. -3. **NST-Browser Launch**: A clean instance is started for each task. -4. **Execution**: Automation frameworks connect via WebSocket or WebDriver, while humans interact manually. -5. **Detection Phase**: Scripts may emit detection payloads to `/_payload`. -6. **Scoring**: Results are aggregated and normalized using the Fail-Fast pillars. +- All submissions are compared against other miners' detectors. +- 100% similarity = zero score. +- Similarity above 60% will result in rejection of the submission. -## Technical Constraints +## Submission Path -- **Language**: JavaScript (ES6+) -- **Environment**: NST-Browser only -- **Architecture**: Docker (amd64 recommended) -- **State**: Stateless execution with no persistence between runs. +**Dedicated Path:** [`examples/miner_commit/src/commit/`](https://github.com/RedTeamSubnet/ada-detection-challenge/tree/main/examples/miner_commit/src/commit/) -## Plagiarism Policy +Place your detection module files in this directory before building your commit: -We maintain strict originality standards: +- `ads_power.js` +- `dolphin_anty.js` +- `gologin.js` +- `headless.js` +- `multilogin.js` +- `octo.js` -- All submissions are compared against other participants' SDKs. -- 100% similarity = zero score. -- Similarity above 60% results in proportional score penalties based on the **detected similarity percentage**. +## Challenge Versions -## Submission Path +**Current:** -**Dedicated Path:** [templates/commit/src/detections/](https://github.com/RedTeamSubnet/ada-detection-challenge/tree/main/templates/commit/src/detections/) - -Submit your detection scripts as a JSON payload with the following structure: - -```json -{ - "detection_files": [ - { "file_name": "nodriver.js", "content": "..." }, - { "file_name": "playwright.js", "content": "..." }, - { "file_name": "patchright.js", "content": "..." }, - { "file_name": "puppeteer.js", "content": "..." }, - { "file_name": "puppeteer_extra.js", "content": "..." }, - { "file_name": "zendriver.js", "content": "..." }, - { "file_name": "selenium_driverless.js", "content": "..." }, - { "file_name": "seleniumbase.js", "content": "..." }, - { "file_name": "webdriver.js", "content": "..." }, - { "file_name": "websocket.js", "content": "..." } - ] -} -``` - -Each file must be named exactly as shown and contain self-contained JavaScript (ES6+) detection logic. +- [**v3**](./v3.md) - Commercial anti-detect browser identification, independent headless + classification, and human verification -## Challenge Versions +**Deprecated:** -- [**v2** (Active after Feb 14, 2026 14:00 UTC)](depricated/v2.md) - Hardened detection with Fail-Fast scoring -- [**v1** (Deprecated)](./depricated/v1.md) +- [v2](./depricated/v2.md) - NSTBrowser-hardened automation detection with fail-fast scoring +- [v1](./depricated/v1.md) ## Resources & Guides - [Building a Submission Commit](../../miner/workflow/3.build-and-publish.md) - General submission instructions -- [NSTBrowser Official](https://www.nstbrowser.io/en/pricing) - Professional plan required for local testing +- [ADA-3 Testing Manual](./testing_manuals.md) - Local validation and environment guidance - [Challenge Repository](https://github.com/RedTeamSubnet/ada-detection-challenge/) - [Miner Repository](https://github.com/RedTeamSubnet/miner/) diff --git a/docs/challenges/ada_detection/testing_manuals.md b/docs/challenges/ada_detection/testing_manuals.md index e1b59f32..5b828728 100644 --- a/docs/challenges/ada_detection/testing_manuals.md +++ b/docs/challenges/ada_detection/testing_manuals.md @@ -1,72 +1,179 @@ --- title: Testing Manual --- +# ADA-3 Testing Manual -# Anti-Detect Automation Detection Testing Manual +This manual covers local miner testing for ADA-3. Testing is primarily semi-automated: miners +run each supported anti-detect browser against the challenge page and inspect whether the page +classifies the browser, the browser mode, and human sessions correctly. Local results help +improve a submission, but the official score is produced by the production scoring +environment. -This manual provides instructions for testing the Anti-Detect Automation Detection challenge using Docker and Docker Compose. +## Prerequisites -## Overview +- Docker with the Docker Compose plugin +- A normal browser for human checks +- Miner-controlled installations of the configured anti-detect browsers, each with a valid + licence and a local profile +- Test hosts or virtual machines for Linux, macOS, and Windows +- Network access from each test host to the challenge API -- Tests all detection scripts' ability to detect automation frameworks -- Uses Docker for easy submission and testing +Miners are responsible for licensing, configuring, and running their own anti-detect browser +installations. The challenge repository does not provide them, and each is a paid product. -## Quick Start Guide +!!! warning "Runner differences" + Miner installations may differ from the private runners used by the challenge because of + product versions, operating systems, profile settings, launch arguments, and patches. Do + not rely on one runner configuration or one observed signal. Test multiple + implementations, launch modes, browser versions, and operating systems to make detection + logic robust. -### Prerequisites +The active target list lives in +[`challenge.yml`](https://github.com/RedTeamSubnet/ada-detection-challenge/blob/main/src/aad_challenge/challenge/api/configs/challenge.yml). +Current targets: `ads_power`, `dolphin_anty`, `gologin`, `multilogin`, `octo`. -- Docker -- Docker Compose +## 1. Add Detection Scripts -### Step 0: Clone the Repository [skip if you cloned already] +Place all six JavaScript files in: -```bash -git clone git@github.com:RedTeamSubnet/ada-detection-challenge.git ada_detection -cd ada_detection +```text +src/aad_challenge/challenge/templates/static/detections/ ``` -### Step 1: Provide Your all Scripts +Keep the expected filenames and exported function names. Validate before testing: -- Paste all of your scripts for detection into **detections** folder with matching names. +```bash +python3 skills/validate-submission/scripts/validate_submission.py +``` -### Step 2: Update Configuration Files +## 2. Configure The Challenge ```bash cp .env.example .env -cp ./templates/compose/compose.override.dev.yml ./compose.override.yml ``` -### Step 3: Setting up environmental variables +Set a private challenge API key in `.env`: + +```dotenv +AAD_CHALLENGE_API_KEY=replace_with_your_private_api_key +AAD_CHALLENGE_API_PORT=10001 +``` + +The API key must be longer than eight characters and contain only letters, numbers, +underscores, and hyphens. Protected endpoints require it in the `X-API-Key` header. If port +`10001` is unavailable, change both port variables to the same available port. + +## 3. Start The Challenge Container + +```bash +docker compose up -d +``` + +or: -- You need to set `AAD_CHALLENGE_NSTBROWSER_API_KEY` with real api key of [nstbrowser](https://www.nstbrowser.io/en/pricing), and you need to buy **professional** plan for testing this challenge. **Without `AAD_CHALLENGE_NSTBROWSER_API_KEY` challenge will not work.** +```bash +./compose.sh start -l +``` -### Step 4: Start the Challenge Server +Confirm the service is running: ```bash -docker compose up -d +docker compose ps +curl http://localhost:${AAD_CHALLENGE_API_PORT:-10001}/health ``` -### Step 4: Test Your Bot +## 4. Choose A Reachable Test URL + +The detection page is served at `http://:/_web`. + +- Runner on the same machine: `http://localhost:10001/_web` +- Runner in another container: use a reachable Compose service name or host address +- Runner on another machine: use the challenge host's LAN IP or DNS name, for example + `http://192.168.1.20:10001/_web` + +`0.0.0.0` is a bind address. Do not use it as a destination from another machine. Ensure the +port is reachable through host firewalls and container port mapping. + +## 5. Test Every Anti-Detect Browser + +Run every configured browser against the `/_web` URL in both headed and headless mode where +the product supports both, and repeat on Linux, macOS, and Windows. If a browser or mode is +unsupported on an operating system, record that limitation rather than silently skipping it. -- Visit -- Authenticate using provided authentication method. You can find Api-Key from `.env` [By default it set to `challenge_api_key_here`] - ![alt text](https://github.com/RedTeamSubnet/ada-detection-challenge/blob/08e3deea03d551a5d97b9f93c41b7b31a5c2ee01/docs/images/image.png?raw=true) -- Test your detection files by running the `/score` endpoint -- if you see the warning log(like `Please visit endpoint to complete human verification for the task.`) then open given uri in log in your browser to complete human verification in your side. +For each browser and mode: -## Important Notes +1. Start a clean browser session. +2. Navigate to the `/_web` URL. +3. Wait for the page to show `Done`, or select **Run detections**. +4. Capture the displayed results. +5. Close the session and repeat enough times to detect unstable behavior. -- The server runs on port 10001 by default -- Make sure port 10001 is available on your system -- Make sure your `nstbrowser` api key works and have **professional plan**. -- All interactions are logged for analysis. Miners can check logs by running `docker compose logs -f` -- All commands must be executed from challenge's root directory. +## 6. Interpret The Results + +A correct anti-detect browser run has the active browser set to `true`, every other browser +set to `false`, **Human** set to `false`, and **Headless** matching the actual browser mode. + +```text +ads_power: true +all other browsers: false +Human: false +Headless: false # true for a headless run +``` + +A collision occurs when more than one browser detector returns `true`. Remove collisions +before submission — they reduce browser accuracy and can create human false positives. + +## 7. Test Human Sessions + +Open `/_web` manually in a normal headed browser without an anti-detect browser. A correct +human result has all browsers `false`, **Human** `true`, and **Headless** `false`. + +Human testing is mandatory. Any browser or headless detector firing during a human task can +reduce the complete challenge score to zero. Test multiple fresh human sessions across +operating systems, including normal interaction such as navigation, pointer movement, typing, +and scrolling. + +## 8. Check Headless Results + +Headless testing is semi-automated. Two possible approaches: + +- **Screenshot approach**: run the browser headless, wait for detection to complete, take a + screenshot of the page, and inspect the browser cards and the **Headless** result. +- **Miner-implemented result capture**: place detection results in `localStorage` and retrieve + them through your anti-detect browser. This is a suggestion only — it is not implemented or + supported by the challenge, and RedTeam is not responsible for its accuracy. + +Do not include testing-only storage or extraction logic in the final submission. + +## 9. Record A Test Matrix + +Record at least the following, including repeated runs and human sessions: + +| OS | Anti-detect browser | Engine version | Mode | Expected | Actual true | Headless | Collision | Pass | +| ----- | ------------------- | ---------------- | ------ | --------- | ----------- | -------- | --------- | ---- | +| Linux | ads_power | Chromium version | Headed | ads_power | ads_power | false | No | Yes | + +A submission is ready only when results are stable, browser-specific, collision-free, and +correct for headed and headless modes. ## Troubleshooting -If you encounter issues: +- **Page is unreachable**: verify `docker compose ps`, port mapping, firewall rules, and the + host address used by the runner. +- **Remote runner uses `localhost`**: replace it with the challenge host's reachable IP or DNS + name. +- **Changes do not appear**: rebuild or recreate the challenge container, then start a fresh + browser session without cache. +- **No detector runs**: inspect the browser console and challenge logs for JavaScript errors. +- **Multiple detectors are true**: isolate shared signals and tighten browser-specific + conditions. +- **Human is false in a manual browser**: at least one browser detector or the headless + detector produced a false positive. +- **Headless result is unstable**: repeat clean sessions across browser versions and inspect + screenshots before changing the detector. + +Stop the environment when testing is complete: -1. Check if Docker is running -2. Verify port 10001 is not in use -3. Check Docker logs using `docker compose logs` -4. Ensure you have proper permissions to run Docker commands +```bash +docker compose down --remove-orphans +``` diff --git a/docs/challenges/ada_detection/v3.md b/docs/challenges/ada_detection/v3.md new file mode 100644 index 00000000..5e6cabaa --- /dev/null +++ b/docs/challenges/ada_detection/v3.md @@ -0,0 +1,116 @@ +--- +title: Anti-Detect Browser Detection v3 +--- +# Anti-Detect Browser Detection (ADA-3) + +## Overview + +ADA-3 replaces the NSTBrowser-based ADA v2 challenge. Miners submit browser-side JavaScript +detectors that identify which **commercial anti-detect browser** is driving a session, while +staying silent on genuine human traffic. + +Unlike AB Sniffer, the targets are not Python automation frameworks. Each target is a paid +desktop application that launches a managed profile and is driven over its own loopback API, +so detection must key on artifacts the product itself leaves in the page environment rather +than on a WebDriver or CDP automation flag. + +A submission contains six JavaScript files: one detector for each of the five target browsers +and one independent headless detector. The challenge also runs human verification sessions to +ensure normal browser users are never classified as an anti-detect browser or as headless. + +## Target Browsers + +- `ads_power` — AdsPower +- `dolphin_anty` — Dolphin Anty +- `gologin` — GoLogin +- `multilogin` — Multilogin +- `octo` — Octo Browser + +NSTBrowser, the sole target of ADA v2, is **not** part of the ADA-3 roster. Its prior +integration is kept for reference only and is never scheduled. + +## Submission Contract + +Use the templates in the +[`examples/miner_commit/src/commit/`](https://github.com/RedTeamSubnet/ada-detection-challenge/tree/main/examples/miner_commit/src/commit/) +directory. The submission must contain exactly: + +| File | Required browser function | +| --- | --- | +| `ads_power.js` | `window.detect_ads_power` | +| `dolphin_anty.js` | `window.detect_dolphin_anty` | +| `gologin.js` | `window.detect_gologin` | +| `headless.js` | `window.detect_headless_non_ua` | +| `multilogin.js` | `window.detect_multilogin` | +| `octo.js` | `window.detect_octo` | + +Each function must return, or resolve to, a value interpreted as a boolean. Do not rename the +files or the exported functions. Each file must contain no more than 500 lines and pass the +repository ESLint configuration +([`examples/miner_commit/eslint.config.mjs`](https://github.com/RedTeamSubnet/ada-detection-challenge/tree/main/examples/miner_commit/eslint.config.mjs)). + +Browser fingerprinting is prohibited. Detection must rely on product-specific artifacts left +in the page environment by the anti-detect browser — patched APIs, injected objects, profile +or automation glue, protocol behavior, serialization, execution timing, or stack traces. Do +not construct persistent browser identities or aggregate canvas, audio, font, WebGL, hardware, +or device fingerprints. + +## Headless And Human + +**Headless** describes a browser execution mode without a normal visible browser window. +`headless.js` classifies the execution mode independently from the browser detectors, and must +use non-user-agent evidence — inspecting or comparing only the user-agent string is not +sufficient. + +**Human** is not a sixth detector or a separate submission file. A run is treated as human +when all five browser detectors return `false` and the headless detector also returns `false`. + +Expected classifications: + +| Session | Browser result | Headless result | Human result | +| --- | --- | --- | --- | +| Headed AdsPower | `ads_power` only | `false` | `false` | +| Headless AdsPower | `ads_power` only | `true` | `false` | +| Normal headed browser | all `false` | `false` | `true` | + +A **collision** occurs when more than one browser detector returns `true` for the same run. +Collisions receive heavily reduced credit and can create human false positives, so they must +be removed before submission. + +## Scoring + +The final score combines two weighted components: + +| Component | Weight | +| --- | --- | +| Anti-detect browser detection | 90% | +| Headless detection | 10% | + +- Browser accuracy is a weighted average across the configured targets; all five currently + carry equal weight. +- A colliding detection is credited at 10% of a clean detection. +- Headless credit is reduced per headless failure. +- If browser detection scores `0.0`, the final score is `0.0`. +- **Any** browser or headless detector firing during a human task drives the final score to + `0.0`. Human safety is the hard gate. + +## Technical Constraints + +- **Language**: JavaScript (ES6+), one self-contained file per target +- **File limit**: 500 lines per file, ESLint-clean +- **Architecture**: Docker, amd64 +- **State**: Stateless execution, no persistence between runs +- **Prohibited**: browser fingerprinting; testing-only storage or result-extraction logic + +## Plagiarism Policy + +- All submissions are compared against other miners' detectors. +- 100% similarity = zero score. +- Similarity above 60% will result in rejection of the submission. + +## Resources & Guides + +- [ADA-3 Testing Manual](./testing_manuals.md) — local validation and environment guidance +- [Building a Submission Commit](../../miner/workflow/3.build-and-publish.md) +- [Challenge Repository](https://github.com/RedTeamSubnet/ada-detection-challenge/) +- [Miner Repository](https://github.com/RedTeamSubnet/miner/) diff --git a/requirements.txt b/requirements.txt index 3ecbc209..752a04fb 100644 --- a/requirements.txt +++ b/requirements.txt @@ -8,3 +8,4 @@ pydantic[email,timezone]>=2.0.3,<3.0.0 pydantic-settings>=2.8.1,<3.0.0 abs_challenge @ git+https://github.com/RedTeamSubnet/ab-sniffer-challenge.git@v6.0.3 bv_challenge @ git+https://github.com/RedTeamSubnet/bot-virus-challenge.git@v1.0.2 +aad_challenge @ git+https://github.com/RedTeamSubnet/ada-detection-challenge.git@v3.0.0 diff --git a/src/challenges/ada_detection b/src/challenges/ada_detection new file mode 160000 index 00000000..172ce0e3 --- /dev/null +++ b/src/challenges/ada_detection @@ -0,0 +1 @@ +Subproject commit 172ce0e390fc823c21eb9ef4cd7cf3e1b7fb7c4f diff --git a/src/challenges/flowprint b/src/challenges/flowprint new file mode 160000 index 00000000..e36a96f7 --- /dev/null +++ b/src/challenges/flowprint @@ -0,0 +1 @@ +Subproject commit e36a96f76c0f0dec9c080bc0c8154877f1a8e892 diff --git a/src/redteam_core/challenge_pool/active_challenges.yaml b/src/redteam_core/challenge_pool/active_challenges.yaml index eeaf2e3d..fef8f2de 100644 --- a/src/redteam_core/challenge_pool/active_challenges.yaml +++ b/src/redteam_core/challenge_pool/active_challenges.yaml @@ -1,7 +1,7 @@ ab_sniffer_v6: name: "ab_sniffer_v6" description: "Detect automation frameworks" - challenge_incentive_weight: 0.4 + challenge_incentive_weight: 0.3 challenge_image: "redteamsubnet61/rest-abs-challenge:6.0.2" target: abs_challenge.controller.ABSController challenge_manager: abs_challenge.challenge_manager.ABSChallengeManager @@ -56,8 +56,8 @@ ab_sniffer_v6: bot_virus_v1: name: "bot_virus_v1" description: "Building a bot virus to infect the internet" - challenge_incentive_weight: 0.6 - challenge_image: "redteamsubnet61/rest-bv-challenge:1.0.3" + challenge_incentive_weight: 0.4 + challenge_image: "redteamsubnet61/rest-bv-challenge:1.0.2" target: bv_challenge.controller.BVController challenge_manager: bv_challenge.challenge_manager.BVChallengeManager script_path_identifier: "commit_files" @@ -102,3 +102,58 @@ bot_virus_v1: resource_limits: num_cpus: 4 mem_limit: "12g" + +ada_detection_v3: + name: "ada_detection_v3" + description: "Detect commercial anti-detect browsers" + challenge_incentive_weight: 0.3 + challenge_image: "redteamsubnet61/rest-aad-challenge:3.0.0" + target: aad_challenge.controller.AADController + challenge_manager: aad_challenge.challenge_manager.AADChallengeManager + script_path_identifier: "commit_files" + challenge_type: "aad" + challenge_solve_timeout: 60 + challenge_min_acceptable_score: 0.4 + docker_run_timeout: 900 + num_tasks: 1 + scoring_headers: + X-API-KEY: "${RT_CHALLENGE_API_KEY}" + comparison_config: + max_unique_commits: 15 + max_self_comparison_score: 0.8 + min_acceptable_score: 0.6 + challenge_container_run_kwargs: + name: "ada_detection_v3" + platform: "linux/amd64" + ulimits: + - Name: "nofile" + Soft: 65536 + Hard: 65536 + privileged: true + environment: + ENV: "PRODUCTION" + AAD_CHALLENGE_API_KEY: "${RT_CHALLENGE_API_KEY}" + AAD_CHALLENGE_VERIFICATION_API_KEY: "${AAD_CHALLENGE_VERIFICATION_API_KEY}" + AAD_CHALLENGE_VERIFICATION_ENDPOINT: "${AAD_CHALLENGE_VERIFICATION_ENDPOINT}" + AAD_CHALLENGE_VERIFICATION_STARTUP_URL: "${AAD_CHALLENGE_VERIFICATION_STARTUP_URL}" + AAD_CHALLENGE_BOT_RUNNER__SERVERS: "${AAD_CHALLENGE_BOT_RUNNER__SERVERS}" + AAD_CHALLENGE_BOT_RUNNER__API_KEY: "${AAD_CHALLENGE_BOT_RUNNER__API_KEY}" + AAD_CHALLENGE_BOT_RUNNER__PUBLIC_BASE_URL: "${AAD_CHALLENGE_BOT_RUNNER__PUBLIC_BASE_URL}" + AAD_CHALLENGE_BOT_RUNNER__BOT: "${AAD_CHALLENGE_BOT_RUNNER__BOT}" + AAD_API_LOGS_DIR: "/var/log/rest-aad-challenge" + volumes: + - "${RT_CHALLENGE_LOGS_DIR}:/var/log/rest-aad-challenge" + miner_container_run_kwargs: + cpu_count: 4 + mem_limit: "12g" + network: "redteam_local" + environment: + CHALLENGE_NAME: "ada_detection_v3" + protocols: + challenger: "http" + challenger_ssl_verify: false + miner: "http" + miner_ssl_verify: false + resource_limits: + num_cpus: 4 + mem_limit: "12g" From 77f7f50e909b3517aaf2f12849b6fee1d0d42e0a Mon Sep 17 00:00:00 2001 From: abdibekbolot Date: Thu, 20 Aug 2026 15:35:36 +0900 Subject: [PATCH 02/10] fix: update environment variable names for ada_detection_v3 challenge --- src/redteam_core/challenge_pool/active_challenges.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/redteam_core/challenge_pool/active_challenges.yaml b/src/redteam_core/challenge_pool/active_challenges.yaml index fef8f2de..0d3dbfe0 100644 --- a/src/redteam_core/challenge_pool/active_challenges.yaml +++ b/src/redteam_core/challenge_pool/active_challenges.yaml @@ -136,10 +136,10 @@ ada_detection_v3: AAD_CHALLENGE_VERIFICATION_API_KEY: "${AAD_CHALLENGE_VERIFICATION_API_KEY}" AAD_CHALLENGE_VERIFICATION_ENDPOINT: "${AAD_CHALLENGE_VERIFICATION_ENDPOINT}" AAD_CHALLENGE_VERIFICATION_STARTUP_URL: "${AAD_CHALLENGE_VERIFICATION_STARTUP_URL}" - AAD_CHALLENGE_BOT_RUNNER__SERVERS: "${AAD_CHALLENGE_BOT_RUNNER__SERVERS}" - AAD_CHALLENGE_BOT_RUNNER__API_KEY: "${AAD_CHALLENGE_BOT_RUNNER__API_KEY}" - AAD_CHALLENGE_BOT_RUNNER__PUBLIC_BASE_URL: "${AAD_CHALLENGE_BOT_RUNNER__PUBLIC_BASE_URL}" - AAD_CHALLENGE_BOT_RUNNER__BOT: "${AAD_CHALLENGE_BOT_RUNNER__BOT}" + AAD_CHALLENGE_BOT_RUNNER_SERVERS: "${AAD_CHALLENGE_BOT_RUNNER_SERVERS}" + AAD_CHALLENGE_BOT_RUNNER_API_KEY: "${AAD_CHALLENGE_BOT_RUNNER_API_KEY}" + AAD_CHALLENGE_BOT_RUNNER_PUBLIC_BASE_URL: "${AAD_CHALLENGE_BOT_RUNNER_PUBLIC_BASE_URL}" + AAD_CHALLENGE_BOT_RUNNER_BOT: "${AAD_CHALLENGE_BOT_RUNNER_BOT}" AAD_API_LOGS_DIR: "/var/log/rest-aad-challenge" volumes: - "${RT_CHALLENGE_LOGS_DIR}:/var/log/rest-aad-challenge" From e2bd969243558758ebd7235fcdd6eb7574d416a5 Mon Sep 17 00:00:00 2001 From: abdibekbolot Date: Sat, 22 Aug 2026 14:45:01 +0900 Subject: [PATCH 03/10] fix: remove orphan flowprint gitlink and repin aad_challenge The flowprint gitlink was committed without a corresponding .gitmodules entry, so `git submodule update --init --recursive` aborted with "No url found for submodule path 'src/challenges/flowprint'". pip runs that step for git+ installs, which broke every image build depending on redteam_core. flowprint is not in active_challenges.yaml and is not referenced by any code, so the gitlink is simply dropped. Also repin aad_challenge from the nonexistent v3.0.0 tag to the ada-detection-challenge commit that actually carries VERSION 3.0.0, and align the submodule pointer with it. Co-Authored-By: Claude Opus 5 Claude-Session: https://claude.ai/code/session_016mzHJxSS2iLLRNJ52RbciF --- requirements.txt | 2 +- src/challenges/ada_detection | 2 +- src/challenges/flowprint | 1 - 3 files changed, 2 insertions(+), 3 deletions(-) delete mode 160000 src/challenges/flowprint diff --git a/requirements.txt b/requirements.txt index 752a04fb..fb6f1edf 100644 --- a/requirements.txt +++ b/requirements.txt @@ -8,4 +8,4 @@ pydantic[email,timezone]>=2.0.3,<3.0.0 pydantic-settings>=2.8.1,<3.0.0 abs_challenge @ git+https://github.com/RedTeamSubnet/ab-sniffer-challenge.git@v6.0.3 bv_challenge @ git+https://github.com/RedTeamSubnet/bot-virus-challenge.git@v1.0.2 -aad_challenge @ git+https://github.com/RedTeamSubnet/ada-detection-challenge.git@v3.0.0 +aad_challenge @ git+https://github.com/RedTeamSubnet/ada-detection-challenge.git@48cdde01b84782b61751992a18f150a504be2a6d diff --git a/src/challenges/ada_detection b/src/challenges/ada_detection index 172ce0e3..48cdde01 160000 --- a/src/challenges/ada_detection +++ b/src/challenges/ada_detection @@ -1 +1 @@ -Subproject commit 172ce0e390fc823c21eb9ef4cd7cf3e1b7fb7c4f +Subproject commit 48cdde01b84782b61751992a18f150a504be2a6d diff --git a/src/challenges/flowprint b/src/challenges/flowprint deleted file mode 160000 index e36a96f7..00000000 --- a/src/challenges/flowprint +++ /dev/null @@ -1 +0,0 @@ -Subproject commit e36a96f76c0f0dec9c080bc0c8154877f1a8e892 From 2f8e4774d51a8af520e1fdd151b43ca385f84526 Mon Sep 17 00:00:00 2001 From: aliyuldashev Date: Tue, 25 Aug 2026 09:48:36 +0900 Subject: [PATCH 04/10] refactor: remove ab_sniffer challenge and update ada_detection references --- .gitmodules | 3 - .../challenges/ada_detection/depricated/v1.md | 4 +- .../challenges/ada_detection/depricated/v2.md | 2 +- .../ada_detection/testing_manuals.md | 10 +-- requirements.txt | 2 +- src/challenges/ab_sniffer | 1 - src/challenges/ada_detection | 2 +- .../challenge_pool/active_challenges.yaml | 87 ++++--------------- 8 files changed, 26 insertions(+), 85 deletions(-) delete mode 160000 src/challenges/ab_sniffer diff --git a/.gitmodules b/.gitmodules index 9c0db0e4..c4bf27a8 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,3 @@ -[submodule "src/challenges/ab_sniffer"] - path = src/challenges/ab_sniffer - url = https://github.com/RedTeamSubnet/ab-sniffer-challenge.git [submodule "src/challenges/bot_virus"] path = src/challenges/bot_virus url = https://github.com/RedTeamSubnet/bot-virus-challenge.git diff --git a/docs/challenges/ada_detection/depricated/v1.md b/docs/challenges/ada_detection/depricated/v1.md index 5424cc29..98b5d954 100644 --- a/docs/challenges/ada_detection/depricated/v1.md +++ b/docs/challenges/ada_detection/depricated/v1.md @@ -8,7 +8,7 @@ title: Anti-Detect Automation Detection **ADA Detection v1** focuses on behavioral detection inside NST-Browser where traditional static signals are masked. This version uses a payload-based flow with strict human safety requirements. -For general challenge information, environment details, and plagiarism policies, please refer to the [AAD README](../README.md). +For general challenge information, environment details, and plagiarism policies, please refer to the [ADA README](../README.md). --- @@ -58,7 +58,7 @@ Submissions must follow this structure: ## Scoring System -AAD scoring is continuous, normalized, and strict, combining three main components before being normalized into a final score. +ADA scoring is continuous, normalized, and strict, combining three main components before being normalized into a final score. * **Human Accuracy:** This is the most critical component. Your submission must not flag real human users as bots or automation. You are allowed a maximum of 2 mistakes; exceeding this limit results in an immediate **final score of 0.0** (human safety kill switch). For scoring, you start with 1.0 point, and each mistake reduces this component by 0.1. diff --git a/docs/challenges/ada_detection/depricated/v2.md b/docs/challenges/ada_detection/depricated/v2.md index 7a386f2a..546ba341 100644 --- a/docs/challenges/ada_detection/depricated/v2.md +++ b/docs/challenges/ada_detection/depricated/v2.md @@ -16,7 +16,7 @@ title: Anti-Detect Automation Detection v2 Scoring has transitioned to a **Fail-Fast** model, emphasizing accuracy across three critical pillars: Human Detection, Framework Detection (with a Selenium Safety Gate), and Protocol Accuracy. -For general challenge information, environment details, and plagiarism policies, please refer to the [AAD README](../README.md). +For general challenge information, environment details, and plagiarism policies, please refer to the [ADA README](../README.md). --- diff --git a/docs/challenges/ada_detection/testing_manuals.md b/docs/challenges/ada_detection/testing_manuals.md index 5b828728..f9b66a64 100644 --- a/docs/challenges/ada_detection/testing_manuals.md +++ b/docs/challenges/ada_detection/testing_manuals.md @@ -29,7 +29,7 @@ installations. The challenge repository does not provide them, and each is a pai logic robust. The active target list lives in -[`challenge.yml`](https://github.com/RedTeamSubnet/ada-detection-challenge/blob/main/src/aad_challenge/challenge/api/configs/challenge.yml). +[`challenge.yml`](https://github.com/RedTeamSubnet/ada-detection-challenge/blob/main/src/ada_challenge/challenge/api/configs/challenge.yml). Current targets: `ads_power`, `dolphin_anty`, `gologin`, `multilogin`, `octo`. ## 1. Add Detection Scripts @@ -37,7 +37,7 @@ Current targets: `ads_power`, `dolphin_anty`, `gologin`, `multilogin`, `octo`. Place all six JavaScript files in: ```text -src/aad_challenge/challenge/templates/static/detections/ +src/ada_challenge/challenge/templates/static/detections/ ``` Keep the expected filenames and exported function names. Validate before testing: @@ -55,8 +55,8 @@ cp .env.example .env Set a private challenge API key in `.env`: ```dotenv -AAD_CHALLENGE_API_KEY=replace_with_your_private_api_key -AAD_CHALLENGE_API_PORT=10001 +ADA_CHALLENGE_API_KEY=replace_with_your_private_api_key +ADA_CHALLENGE_API_PORT=10001 ``` The API key must be longer than eight characters and contain only letters, numbers, @@ -79,7 +79,7 @@ Confirm the service is running: ```bash docker compose ps -curl http://localhost:${AAD_CHALLENGE_API_PORT:-10001}/health +curl http://localhost:${ADA_CHALLENGE_API_PORT:-10001}/health ``` ## 4. Choose A Reachable Test URL diff --git a/requirements.txt b/requirements.txt index fb6f1edf..9840aefd 100644 --- a/requirements.txt +++ b/requirements.txt @@ -8,4 +8,4 @@ pydantic[email,timezone]>=2.0.3,<3.0.0 pydantic-settings>=2.8.1,<3.0.0 abs_challenge @ git+https://github.com/RedTeamSubnet/ab-sniffer-challenge.git@v6.0.3 bv_challenge @ git+https://github.com/RedTeamSubnet/bot-virus-challenge.git@v1.0.2 -aad_challenge @ git+https://github.com/RedTeamSubnet/ada-detection-challenge.git@48cdde01b84782b61751992a18f150a504be2a6d +ada_challenge @ git+https://github.com/RedTeamSubnet/ada-detection-challenge.git@48cdde01b84782b61751992a18f150a504be2a6d diff --git a/src/challenges/ab_sniffer b/src/challenges/ab_sniffer deleted file mode 160000 index 5e1a456f..00000000 --- a/src/challenges/ab_sniffer +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 5e1a456fc1ec305bcebf6c68e96bdeb16951d534 diff --git a/src/challenges/ada_detection b/src/challenges/ada_detection index 48cdde01..3c914c38 160000 --- a/src/challenges/ada_detection +++ b/src/challenges/ada_detection @@ -1 +1 @@ -Subproject commit 48cdde01b84782b61751992a18f150a504be2a6d +Subproject commit 3c914c3866070882da10af7bdfeefc51e8228333 diff --git a/src/redteam_core/challenge_pool/active_challenges.yaml b/src/redteam_core/challenge_pool/active_challenges.yaml index 0d3dbfe0..16304923 100644 --- a/src/redteam_core/challenge_pool/active_challenges.yaml +++ b/src/redteam_core/challenge_pool/active_challenges.yaml @@ -1,58 +1,3 @@ -ab_sniffer_v6: - name: "ab_sniffer_v6" - description: "Detect automation frameworks" - challenge_incentive_weight: 0.3 - challenge_image: "redteamsubnet61/rest-abs-challenge:6.0.2" - target: abs_challenge.controller.ABSController - challenge_manager: abs_challenge.challenge_manager.ABSChallengeManager - script_path_identifier: "commit_files" - challenge_type: "abs" - challenge_solve_timeout: 60 - challenge_min_acceptable_score: 0.4 - docker_run_timeout: 900 - num_tasks: 1 - scoring_headers: - X-API-KEY: "${RT_CHALLENGE_API_KEY}" - comparison_config: - max_unique_commits: 15 - max_self_comparison_score: 0.8 - min_acceptable_score: 0.6 - challenge_container_run_kwargs: - name: "ab_sniffer_v6" - platform: "linux/amd64" - ulimits: - - Name: "nofile" - Soft: 65536 - Hard: 65536 - privileged: true - environment: - ENV: "PRODUCTION" - ABS_CHALLENGE_API_KEY: "${RT_CHALLENGE_API_KEY}" - ABS_CHALLENGE_VERIFICATION_API_KEY: "${ABS_CHALLENGE_VERIFICATION_API_KEY}" - ABS_CHALLENGE_VERIFICATION_ENDPOINT: "${ABS_CHALLENGE_VERIFICATION_ENDPOINT}" - ABS_CHALLENGE_VERIFICATION_STARTUP_URL: "${ABS_CHALLENGE_VERIFICATION_STARTUP_URL}" - ABS_CHALLENGE_BOT_RUNNER_SERVERS: "${ABS_CHALLENGE_BOT_RUNNER_SERVERS}" - ABS_CHALLENGE_BOT_RUNNER_API_KEY: "${ABS_CHALLENGE_BOT_RUNNER_API_KEY}" - ABS_CHALLENGE_BOT_RUNNER_PUBLIC_BASE_URL: "${ABS_CHALLENGE_BOT_RUNNER_PUBLIC_BASE_URL}" - ABS_CHALLENGE_BOT_RUNNER_BOT: "${ABS_CHALLENGE_BOT_RUNNER_BOT}" - ABS_API_LOGS_DIR: "/var/log/rest-abs-challenge" - volumes: - - "${RT_CHALLENGE_LOGS_DIR}:/var/log/rest-abs-challenge" - miner_container_run_kwargs: - cpu_count: 4 - mem_limit: "12g" - network: "redteam_local" - environment: - CHALLENGE_NAME: "ab_sniffer_v6" - protocols: - challenger: "http" - challenger_ssl_verify: false - miner: "http" - miner_ssl_verify: false - resource_limits: - num_cpus: 4 - mem_limit: "12g" - bot_virus_v1: name: "bot_virus_v1" description: "Building a bot virus to infect the internet" @@ -106,14 +51,14 @@ bot_virus_v1: ada_detection_v3: name: "ada_detection_v3" description: "Detect commercial anti-detect browsers" - challenge_incentive_weight: 0.3 - challenge_image: "redteamsubnet61/rest-aad-challenge:3.0.0" - target: aad_challenge.controller.AADController - challenge_manager: aad_challenge.challenge_manager.AADChallengeManager + challenge_incentive_weight: 0.6 + challenge_image: "redteamsubnet61/ada_detection:2.0.4" + target: ada_challenge.controller.ADAController + challenge_manager: ada_challenge.challenge_manager.ADAChallengeManager script_path_identifier: "commit_files" - challenge_type: "aad" + challenge_type: "ada" challenge_solve_timeout: 60 - challenge_min_acceptable_score: 0.4 + challenge_min_acceptable_score: 0.6 docker_run_timeout: 900 num_tasks: 1 scoring_headers: @@ -132,17 +77,17 @@ ada_detection_v3: privileged: true environment: ENV: "PRODUCTION" - AAD_CHALLENGE_API_KEY: "${RT_CHALLENGE_API_KEY}" - AAD_CHALLENGE_VERIFICATION_API_KEY: "${AAD_CHALLENGE_VERIFICATION_API_KEY}" - AAD_CHALLENGE_VERIFICATION_ENDPOINT: "${AAD_CHALLENGE_VERIFICATION_ENDPOINT}" - AAD_CHALLENGE_VERIFICATION_STARTUP_URL: "${AAD_CHALLENGE_VERIFICATION_STARTUP_URL}" - AAD_CHALLENGE_BOT_RUNNER_SERVERS: "${AAD_CHALLENGE_BOT_RUNNER_SERVERS}" - AAD_CHALLENGE_BOT_RUNNER_API_KEY: "${AAD_CHALLENGE_BOT_RUNNER_API_KEY}" - AAD_CHALLENGE_BOT_RUNNER_PUBLIC_BASE_URL: "${AAD_CHALLENGE_BOT_RUNNER_PUBLIC_BASE_URL}" - AAD_CHALLENGE_BOT_RUNNER_BOT: "${AAD_CHALLENGE_BOT_RUNNER_BOT}" - AAD_API_LOGS_DIR: "/var/log/rest-aad-challenge" + ADA_CHALLENGE_API_KEY: "${RT_CHALLENGE_API_KEY}" + ADA_CHALLENGE_VERIFICATION_API_KEY: "${ADA_CHALLENGE_VERIFICATION_API_KEY}" + ADA_CHALLENGE_VERIFICATION_ENDPOINT: "${ADA_CHALLENGE_VERIFICATION_ENDPOINT}" + ADA_CHALLENGE_VERIFICATION_STARTUP_URL: "${ADA_CHALLENGE_VERIFICATION_STARTUP_URL}" + ADA_CHALLENGE_BOT_RUNNER_SERVERS: "${ADA_CHALLENGE_BOT_RUNNER_SERVERS}" + ADA_CHALLENGE_BOT_RUNNER_API_KEY: "${ADA_CHALLENGE_BOT_RUNNER_API_KEY}" + ADA_CHALLENGE_BOT_RUNNER_PUBLIC_BASE_URL: "${ADA_CHALLENGE_BOT_RUNNER_PUBLIC_BASE_URL}" + ADA_CHALLENGE_BOT_RUNNER_BOT: "${ADA_CHALLENGE_BOT_RUNNER_BOT}" + ADA_API_LOGS_DIR: "/var/log/ada_detection" volumes: - - "${RT_CHALLENGE_LOGS_DIR}:/var/log/rest-aad-challenge" + - "${RT_CHALLENGE_LOGS_DIR}:/var/log/ada_detection" miner_container_run_kwargs: cpu_count: 4 mem_limit: "12g" From d0def6d287ce8b137f33b7c40d32b0501033378d Mon Sep 17 00:00:00 2001 From: aliyuldashev Date: Tue, 25 Aug 2026 17:09:26 +0900 Subject: [PATCH 05/10] fix: update ADA detection challenge image version and enhance development workflow documentation --- docs/challenges/ada_detection/v3.md | 22 +++++++++++++++++-- requirements.txt | 3 +-- src/challenges/ada_detection | 2 +- .../challenge_pool/active_challenges.yaml | 2 +- 4 files changed, 23 insertions(+), 6 deletions(-) diff --git a/docs/challenges/ada_detection/v3.md b/docs/challenges/ada_detection/v3.md index 5e6cabaa..d516ab32 100644 --- a/docs/challenges/ada_detection/v3.md +++ b/docs/challenges/ada_detection/v3.md @@ -102,15 +102,33 @@ The final score combines two weighted components: - **State**: Stateless execution, no persistence between runs - **Prohibited**: browser fingerprinting; testing-only storage or result-extraction logic +## Development Workflow + +1. Start from the six supplied commit templates; retain their file names and `window` exports. +2. Use the repository validator before each scoring attempt. It checks the submission + contract and lint requirements before the more expensive challenge run. +3. Follow the testing manual to start the local challenge, submit the detector payload, and + inspect results. Complete every requested human-verification run: a human false positive + is a hard scoring failure. +4. Use the output to isolate missed targets, collisions, headless failures, and human + failures. Re-test after every change. +5. Build a submission image only after the score is satisfactory. The image must target + `linux/amd64`; follow the standard miner commit workflow to publish it. + +The local helper is useful for development, but miners should use the challenge scoring +workflow for the authoritative result. Do not add an `nstbrowser.js` detector: NSTBrowser is +not scheduled in ADA-3. + ## Plagiarism Policy - All submissions are compared against other miners' detectors. - 100% similarity = zero score. -- Similarity above 60% will result in rejection of the submission. +- Similarity score above 0.6 will result in rejection of the submission. ## Resources & Guides -- [ADA-3 Testing Manual](./testing_manuals.md) — local validation and environment guidance +- [ADA-3 Testing Manual](https://github.com/RedTeamSubnet/ada-detection-challenge/blob/main/docs/Testing_manuals.md) — local validation and environment guidance +- [Submission template and image instructions](https://github.com/RedTeamSubnet/ada-detection-challenge/tree/main/examples/miner_commit) - [Building a Submission Commit](../../miner/workflow/3.build-and-publish.md) - [Challenge Repository](https://github.com/RedTeamSubnet/ada-detection-challenge/) - [Miner Repository](https://github.com/RedTeamSubnet/miner/) diff --git a/requirements.txt b/requirements.txt index 9840aefd..50a2b364 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,6 +6,5 @@ substrate-interface>=1.7.11,<2.0.0 python-dotenv>=1.0.1,<2.0.0 pydantic[email,timezone]>=2.0.3,<3.0.0 pydantic-settings>=2.8.1,<3.0.0 -abs_challenge @ git+https://github.com/RedTeamSubnet/ab-sniffer-challenge.git@v6.0.3 bv_challenge @ git+https://github.com/RedTeamSubnet/bot-virus-challenge.git@v1.0.2 -ada_challenge @ git+https://github.com/RedTeamSubnet/ada-detection-challenge.git@48cdde01b84782b61751992a18f150a504be2a6d +ada_challenge @ git+https://github.com/RedTeamSubnet/ada-detection-challenge.git@v2.0.5 diff --git a/src/challenges/ada_detection b/src/challenges/ada_detection index 3c914c38..f0fb631d 160000 --- a/src/challenges/ada_detection +++ b/src/challenges/ada_detection @@ -1 +1 @@ -Subproject commit 3c914c3866070882da10af7bdfeefc51e8228333 +Subproject commit f0fb631d6b17114374a7b947c22c400efab0fee7 diff --git a/src/redteam_core/challenge_pool/active_challenges.yaml b/src/redteam_core/challenge_pool/active_challenges.yaml index 16304923..8e568093 100644 --- a/src/redteam_core/challenge_pool/active_challenges.yaml +++ b/src/redteam_core/challenge_pool/active_challenges.yaml @@ -52,7 +52,7 @@ ada_detection_v3: name: "ada_detection_v3" description: "Detect commercial anti-detect browsers" challenge_incentive_weight: 0.6 - challenge_image: "redteamsubnet61/ada_detection:2.0.4" + challenge_image: "redteamsubnet61/ada_detection:2.0.5" target: ada_challenge.controller.ADAController challenge_manager: ada_challenge.challenge_manager.ADAChallengeManager script_path_identifier: "commit_files" From 0210501ba6e483626acbb478dffadbcdac7c9010 Mon Sep 17 00:00:00 2001 From: aliyuldashev Date: Wed, 26 Aug 2026 14:36:52 +0900 Subject: [PATCH 06/10] refactor: simplify challenge input handling in Controller and update subproject commits --- src/challenges/ada_detection | 2 +- src/challenges/bot_virus | 2 +- src/redteam_core/challenge_pool/controller.py | 98 ++++++------------- 3 files changed, 34 insertions(+), 68 deletions(-) diff --git a/src/challenges/ada_detection b/src/challenges/ada_detection index f0fb631d..87428ce5 160000 --- a/src/challenges/ada_detection +++ b/src/challenges/ada_detection @@ -1 +1 @@ -Subproject commit f0fb631d6b17114374a7b947c22c400efab0fee7 +Subproject commit 87428ce5f609f4845a8edb80a8f57d9881ff28e1 diff --git a/src/challenges/bot_virus b/src/challenges/bot_virus index d3286fa5..518dd4b8 160000 --- a/src/challenges/bot_virus +++ b/src/challenges/bot_virus @@ -1 +1 @@ -Subproject commit d3286fa51816e57190acc575f83dbb0edf546ef0 +Subproject commit 518dd4b8172093b6b50d82fc1787e9f619800e1c diff --git a/src/redteam_core/challenge_pool/controller.py b/src/redteam_core/challenge_pool/controller.py index e03adc42..cd526481 100644 --- a/src/redteam_core/challenge_pool/controller.py +++ b/src/redteam_core/challenge_pool/controller.py @@ -1,5 +1,4 @@ from abc import abstractmethod -import copy import time import traceback @@ -28,7 +27,6 @@ def __init__( miner_commits: list[MinerChallengeCommit], reference_comparison_commits: list[MinerChallengeCommit], miners_docker_info: dict[str, dict], - seed_inputs: list[dict] = [], ): """ Initializes the Controller with the name of the challenge and the list of miner Docker images. @@ -43,7 +41,6 @@ def __init__( self.challenge_info = challenge_info self.miner_commits = miner_commits self.reference_comparison_commits = reference_comparison_commits - self.seed_inputs = seed_inputs self.miners_docker_info = miners_docker_info self.docker_client = docker_utils.create_docker_client() @@ -118,28 +115,13 @@ def start_challenge(self): """ self._setup_challenge() - num_task = self.challenge_info.get( - "num_tasks", constants.N_CHALLENGES_PER_EPOCH - ) - # Start with seed inputs and generate more if needed to reach num_task - challenge_inputs = self.seed_inputs.copy() - remaining_tasks = max(0, num_task - len(challenge_inputs)) - if remaining_tasks > 0: - challenge_inputs.extend( - [self._get_challenge_from_container() for _ in range(remaining_tasks)] - ) - - bt.logging.debug( - f"[CONTROLLER] Generated {len(challenge_inputs)} challenge inputs" - ) - for miner_commit in self.miner_commits: uid, hotkey = miner_commit.miner_uid, miner_commit.miner_hotkey try: self._setup_miner_container(miner_commit) - self._generate_scoring_logs(miner_commit, challenge_inputs) + self._generate_scoring_logs(miner_commit) _max_comparison_score = self._check_comparison_score(miner_commit) if _max_comparison_score >= 0.6: bt.logging.info( @@ -157,7 +139,7 @@ def start_challenge(self): else: self._run_reference_comparison_inputs(miner_commit) - self._score_miner_with_new_inputs(miner_commit, challenge_inputs) + self._score_miner_with_new_inputs(miner_commit) self.same_score_comparison(miner_commit) except Exception as e: @@ -415,39 +397,34 @@ def _validate_miner_submission(self, miner_commit: MinerChallengeCommit) -> bool bt.logging.error(f"Error in validation request: {str(e)}") return False - def _generate_scoring_logs( - self, miner_commit: MinerChallengeCommit, challenge_inputs - ): + def _generate_scoring_logs(self, miner_commit: MinerChallengeCommit): """Run and score miner with new challenge inputs.""" - for miner_input in challenge_inputs: - miner_output, error_message = self._submit_challenge_to_miner(miner_input) + miner_output, error_message = self._submit_challenge_to_miner() - if miner_output is None or error_message: - bt.logging.warning( - f"[CONTROLLER - ABSController] Miner {miner_commit.miner_hotkey} \ - failed to produce output for reference comparison: {error_message}" - ) - miner_commit.scoring_logs.insert( - 0, - ScoringLog( - miner_input=miner_input, - miner_output=None, - error=( - f"[Not Accepted] {error_message}" - if error_message - else "[Not Accepted] No output from miner" - ), - ), - ) - continue + if miner_output is None or error_message: + bt.logging.warning( + f"[CONTROLLER - ABSController] Miner {miner_commit.miner_hotkey} \ + failed to produce output for reference comparison: {error_message}" + ) miner_commit.scoring_logs.insert( 0, ScoringLog( - miner_input=miner_input, - miner_output=miner_output, - error=error_message, + miner_output=None, + error=( + f"[Not Accepted] {error_message}" + if error_message + else "[Not Accepted] No output from miner" + ), ), ) + return + miner_commit.scoring_logs.insert( + 0, + ScoringLog( + miner_output=miner_output, + error=error_message, + ), + ) def _compare_outputs( self, miner_output: dict, reference_output: dict, user_id: str | None = None @@ -520,7 +497,10 @@ def same_score_comparison(self, miner_commit: MinerChallengeCommit) -> None: return _scoring_log = miner_commit.scoring_logs[0] _commit_score = _scoring_log.score - if _commit_score is None or _commit_score <= 0.4: + if ( + _commit_score is None + or _commit_score <= self.challenge_min_acceptable_score + ): return reference_commits_in_range = [] for ref_commit in self.reference_comparison_commits: @@ -766,7 +746,7 @@ def _compare_with_baseline(self, miner_commit: MinerChallengeCommit): bt.logging.error(f"Error in baseline comparison request: {str(e)}") return - def _submit_challenge_to_miner(self, challenge_input) -> tuple[dict, str]: + def _submit_challenge_to_miner(self) -> tuple[dict, str]: """ Sends the challenge input to a miner by making an HTTP POST request to a local endpoint. The request submits the input, and the miner returns the generated output. @@ -779,17 +759,13 @@ def _submit_challenge_to_miner(self, challenge_input) -> tuple[dict, str]: """ error_message = "" - miner_input = copy.deepcopy(challenge_input) - exclude_miner_input_key = self.challenge_info.get("exclude_miner_input_key", []) - for key in exclude_miner_input_key: - miner_input[key] = None try: _protocol, _ssl_verify = self._check_protocol(is_challenger=False) response = requests.post( f"{_protocol}://{self.miner_ip}:{constants.MINER_DOCKER_PORT}/solve", timeout=self.challenge_info.get("challenge_solve_timeout", 60), verify=_ssl_verify, - json=miner_input, + json={}, ) if not response.ok: @@ -834,15 +810,13 @@ def _get_challenge_from_container(self) -> dict: f"Failed to get challenge after {max_retries} attempts: {str(e)}" ) - def _score_challenge(self, miner_input, miner_output, task_id: int = 0) -> float: + def _score_challenge(self, miner_output) -> float: """ Submits the miner's input and output for scoring by making an HTTP POST request to the challenge container. The challenge container computes a score based on the miner's performance. Args: - miner_input: The input provided to the miner. miner_output: The output generated by the miner. - task_id: The task ID for the challenge. Defaults to 0. Returns: A float representing the score for the miner's solution. @@ -851,17 +825,11 @@ def _score_challenge(self, miner_input, miner_output, task_id: int = 0) -> float _protocol, _ssl_verify = self._check_protocol(is_challenger=True) try: - payload = { - "miner_input": miner_input, - "miner_output": miner_output, - } - - bt.logging.debug(f"[CONTROLLER] Scoring payload: {str(payload)[:100]}...") response = requests.post( f"{_protocol}://localhost:{constants.CHALLENGE_DOCKER_PORT}/score", verify=_ssl_verify, - json=payload, + json=miner_output, headers=self.challenge_info.get("scoring_headers", {}), ) @@ -936,8 +904,6 @@ def _exclude_output_keys(self, miner_output: dict, reference_output: dict): pass @abstractmethod - def _score_miner_with_new_inputs( - self, miner_commit: MinerChallengeCommit, challenge_inputs - ): + def _score_miner_with_new_inputs(self, miner_commit: MinerChallengeCommit): """Run and score miner with new challenge inputs.""" pass From ae64c3ce32073ff6365087fd514b2b0e8bf1c6be Mon Sep 17 00:00:00 2001 From: aliyuldashev Date: Wed, 26 Aug 2026 16:38:17 +0900 Subject: [PATCH 07/10] chore: update ada_detection challenge image version and adjust minimum acceptable score --- requirements.txt | 2 +- src/challenges/ada_detection | 2 +- src/challenges/bot_virus | 2 +- src/redteam_core/challenge_pool/active_challenges.yaml | 4 ++-- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/requirements.txt b/requirements.txt index 50a2b364..214a2c2c 100644 --- a/requirements.txt +++ b/requirements.txt @@ -7,4 +7,4 @@ python-dotenv>=1.0.1,<2.0.0 pydantic[email,timezone]>=2.0.3,<3.0.0 pydantic-settings>=2.8.1,<3.0.0 bv_challenge @ git+https://github.com/RedTeamSubnet/bot-virus-challenge.git@v1.0.2 -ada_challenge @ git+https://github.com/RedTeamSubnet/ada-detection-challenge.git@v2.0.5 +ada_challenge @ git+https://github.com/RedTeamSubnet/ada-detection-challenge.git@v3.0.0 diff --git a/src/challenges/ada_detection b/src/challenges/ada_detection index 87428ce5..68c0a328 160000 --- a/src/challenges/ada_detection +++ b/src/challenges/ada_detection @@ -1 +1 @@ -Subproject commit 87428ce5f609f4845a8edb80a8f57d9881ff28e1 +Subproject commit 68c0a328fdb43ed4c5e9206f7b7de48a38ee57e0 diff --git a/src/challenges/bot_virus b/src/challenges/bot_virus index 518dd4b8..a3fd1e9a 160000 --- a/src/challenges/bot_virus +++ b/src/challenges/bot_virus @@ -1 +1 @@ -Subproject commit 518dd4b8172093b6b50d82fc1787e9f619800e1c +Subproject commit a3fd1e9a4144a2df3d85f01735165433722962a9 diff --git a/src/redteam_core/challenge_pool/active_challenges.yaml b/src/redteam_core/challenge_pool/active_challenges.yaml index efd27a6d..2ceca9fe 100644 --- a/src/redteam_core/challenge_pool/active_challenges.yaml +++ b/src/redteam_core/challenge_pool/active_challenges.yaml @@ -52,13 +52,13 @@ ada_detection_v3: name: "ada_detection_v3" description: "Detect commercial anti-detect browsers" challenge_incentive_weight: 0.6 - challenge_image: "redteamsubnet61/ada_detection:2.0.5" + challenge_image: "redteamsubnet61/ada_detection:3.0.0" target: ada_challenge.controller.ADAController challenge_manager: ada_challenge.challenge_manager.ADAChallengeManager script_path_identifier: "commit_files" challenge_type: "ada" challenge_solve_timeout: 60 - challenge_min_acceptable_score: 0.6 + challenge_min_acceptable_score: 0.5 docker_run_timeout: 900 num_tasks: 1 scoring_headers: From de11d2cbab11e5c80b4ad6e7f8baebe62ab01b32 Mon Sep 17 00:00:00 2001 From: aliyuldashev Date: Wed, 26 Aug 2026 16:43:36 +0900 Subject: [PATCH 08/10] chore: update volume path for ada_detection challenge logs --- src/redteam_core/challenge_pool/active_challenges.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/redteam_core/challenge_pool/active_challenges.yaml b/src/redteam_core/challenge_pool/active_challenges.yaml index 2ceca9fe..1956a104 100644 --- a/src/redteam_core/challenge_pool/active_challenges.yaml +++ b/src/redteam_core/challenge_pool/active_challenges.yaml @@ -87,7 +87,7 @@ ada_detection_v3: ADA_CHALLENGE_BOT_RUNNER_BOT: "${ADA_CHALLENGE_BOT_RUNNER_BOT}" ADA_API_LOGS_DIR: "/var/log/ada_detection" volumes: - - "${RT_CHALLENGE_LOGS_DIR}:/var/log/ada_detection" + - "${RT_CHALLENGE_LOGS_DIR}/ada_detection:/var/log/ada_detection" miner_container_run_kwargs: cpu_count: 4 mem_limit: "12g" From 255476fae5e067c8bbaa214e45fded042ed190d9 Mon Sep 17 00:00:00 2001 From: aliyuldashev Date: Wed, 26 Aug 2026 16:54:42 +0900 Subject: [PATCH 09/10] chore: update max_unique_commits to 7 for bot_virus_v1 and ada_detection_v3 challenges --- src/redteam_core/challenge_pool/active_challenges.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/redteam_core/challenge_pool/active_challenges.yaml b/src/redteam_core/challenge_pool/active_challenges.yaml index 1956a104..73fc3361 100644 --- a/src/redteam_core/challenge_pool/active_challenges.yaml +++ b/src/redteam_core/challenge_pool/active_challenges.yaml @@ -14,7 +14,7 @@ bot_virus_v1: scoring_headers: X-API-KEY: "${RT_CHALLENGE_API_KEY}" comparison_config: - max_unique_commits: 15 + max_unique_commits: 7 max_self_comparison_score: 0.8 min_acceptable_score: 0.6 challenge_container_run_kwargs: @@ -64,7 +64,7 @@ ada_detection_v3: scoring_headers: X-API-KEY: "${RT_CHALLENGE_API_KEY}" comparison_config: - max_unique_commits: 15 + max_unique_commits: 7 max_self_comparison_score: 0.8 min_acceptable_score: 0.6 challenge_container_run_kwargs: From 02fe8a5f44cbe39b7f28414cec6cd22166e35fae Mon Sep 17 00:00:00 2001 From: aliyuldashev Date: Wed, 26 Aug 2026 16:57:37 +0900 Subject: [PATCH 10/10] deps: update bot virus challenge image version to 1.0.4 --- requirements.txt | 2 +- src/redteam_core/challenge_pool/active_challenges.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/requirements.txt b/requirements.txt index 214a2c2c..47e1a357 100644 --- a/requirements.txt +++ b/requirements.txt @@ -6,5 +6,5 @@ substrate-interface>=1.7.11,<2.0.0 python-dotenv>=1.0.1,<2.0.0 pydantic[email,timezone]>=2.0.3,<3.0.0 pydantic-settings>=2.8.1,<3.0.0 -bv_challenge @ git+https://github.com/RedTeamSubnet/bot-virus-challenge.git@v1.0.2 +bv_challenge @ git+https://github.com/RedTeamSubnet/bot-virus-challenge.git@v1.0.4 ada_challenge @ git+https://github.com/RedTeamSubnet/ada-detection-challenge.git@v3.0.0 diff --git a/src/redteam_core/challenge_pool/active_challenges.yaml b/src/redteam_core/challenge_pool/active_challenges.yaml index 73fc3361..762c8aeb 100644 --- a/src/redteam_core/challenge_pool/active_challenges.yaml +++ b/src/redteam_core/challenge_pool/active_challenges.yaml @@ -2,7 +2,7 @@ bot_virus_v1: name: "bot_virus_v1" description: "Building a bot virus to infect the internet" challenge_incentive_weight: 0.4 - challenge_image: "redteamsubnet61/rest-bv-challenge:1.0.2" + challenge_image: "redteamsubnet61/rest-bv-challenge:1.0.4" target: bv_challenge.controller.BVController challenge_manager: bv_challenge.challenge_manager.BVChallengeManager script_path_identifier: "commit_files"