An Anti-AI CAPTCHA system for CS7NS1 at Trinity College Dublin. This repository contains a configurable CAPTCHA generator, a FastAPI backend that enforces several anti-automation signals (mouse/keystroke analysis, honeypots, navigator fingerprints, PoW), an OCR microservice, and several attack suites to evaluate the robustness of the system.
It follows the colour blending principle to generate a CAPTCHA image based on the colour theory:
- Backend web app:
captcha-system/main.py(servesindex.html) — default port 5174 - OCR / model microservice:
captcha-system/model_service.py— default port 8001 - CAPTCHA generator:
captcha-system/generate.pyandgenerate_dataset.py - Behavioral model training:
captcha-system/captcha_mouse_movement_prediction/train_model.py - Attack suite:
attackers/(attacker_1..4.py, utils)
- CS7NS1 – Anti-AI CAPTCHA
- Quick Links
- Table of Contents
- Project overview
- Prerequisites
- Helper scripts (convenience)
- Local Development Setup
- Running the Services
- Endpoints (Quick Reference)
- Generate sample CAPTCHAs & Datasets
- Train the Movement & Recognition Models
- Attack Suite: How to Run Attackers
- Notes for Developers (Important details / files to inspect)
- Raspberry Pi / Low-power Deployment
- Port Forwarding from Raspberry Pi to Local Machine
- Acknowledgements & Resources
This project attempts to produce CAPTCHAs that resist AI-based solving by combining multiple defenses:
- Camouflage-style visual CAPTCHAs (text blended into backgrounds; see
generate.py). - Behavioral detection using keystroke/mouse dynamics and an ML model (
captcha_mouse_movement_prediction). - Browser fingerprinting and navigator signal validation.
- Rate limiting and server-side PoW challenge (proof-of-work) to slow automated solvers.
- Optional OCR-based API (
model_service.py) that provides a microservice for canvas OCR and movement model evaluation.
This repo includes attacker scripts under attackers/ to validate and benchmark how easily these CAPTCHAs can be bypassed.
- Python 3.8 (recommended) — some dependencies like EasyOCR may need newer Python versions or specific wheels.
- pip
- Virtualenv (recommended to isolate dependencies)
- Git
- For Playwright-based attackers: Playwright CLI and browser binaries
Windows users: this repo has been tested on Windows with Python 3.8 and a standard PowerShell environment.
CS7NS1-Anti-AI-CAPTCHA/
├── captcha-system/ # Main CAPTCHA service
│ ├── main.py # Backend API (FastAPI) - 1900 lines
│ ├── generate.py # CAPTCHA image generation - 475 lines
│ ├── model_service.py # ML microservice - 222 lines
│ ├── index.html # Frontend SPA - 987 lines
│ ├── config/
│ │ └── constants.py # System constants
│ ├── captcha_mouse_movement_prediction/
│ │ ├── utils.py # Feature extraction utilities
│ │ ├── train_model.py # ML model training
│ │ └── models/
│ │ └── mouse_movement_model.pkl # Trained classifier
│ ├── fonts/ # TrueType fonts for CAPTCHA text
│ ├── background_images/ # Background textures for camouflage
│ ├── overlay_images/ # Overlay textures for blending
│ ├── captcha_images/ # Generated CAPTCHA storage
│ │ └── drawings/ # User canvas submissions
│ └── logs/ # Persistent audit logs
│
└── attackers/ # Attack validation suite
├── attacker_1.py # EasyOCR + Multi-channel attack
├── attacker_2.py # CNN/CTC model attack
├── attacker_3.py # LLM (Gemini) attack
├── attacker_4.py # YOLO object detection attack
├── utils.py # Shared attack utilities
├── symbol_mouse_data.json # Pre-recorded human strokes
├── train.py # CNN training script
├── train_yolo.py # YOLO training script
└── attack_results.csv # Attack outcome tracking
Two convenience Bash helper scripts are included to make local development easier. Both scripts live at the repository root and are intended to be run from a Bash environment (Linux/macOS/WSL/Git Bash). On Windows PowerShell you can run them via bash run-backend.sh / bash run-attackers.sh if you have WSL or Git Bash installed.
-
run-backend.sh— boots only the services (backend and OCR/model microservice) and performs setup checks:- Creates a
venv(if missing) and uses it for run-time commands - Installs backend and model microservice dependencies from
captcha-system/backend-service-requirements.txtandcaptcha-system/model-service-requirements.txt - Verifies Python and pip are available
- Checks the default ports (Model=8001, Backend=5174) and warns if in use
- Launches the model microservice (
captcha-system/model_service.py) and backend (captcha-system/main.py) in the background - Writes logs to
logs/model_service.logandlogs/backend.log - Can be stopped gracefully with Ctrl+C (SIGINT) and traps signals to stop processes
Usage examples:
- Creates a
# From repo root (Unix / Git Bash / WSL)
chmod +x run-backend.sh
./run-backend.sh
# On Windows PowerShell (if WSL/Git Bash is installed)
bash run-backend.sh-
run-attackers.sh— helper script that runs the backend/model services (as above) and then launches the attacker scripts sequentially:- Performs the same venv & dependency installation as
run-backend.sh(installsattackers/requirements.txtif present) - Verifies
API_KEYandLLM_MODELenvironment variables are set (required for attacker scripts that call external LLMs or APIs) - Warns about missing
GEMINI_API_KEYif present;attacker_1.pycontains a hard-coded key in its__main__block by default - Starts the model service and backend microservices in the background
- Runs the attacker scripts in
attackers/sequentially (default:attacker_1.py..attacker_4.py) - Stores attacker logs under
logs/attackers/*.log - Helpful if you want to run a full test harness or run simulated attacks against a locally running server
Usage examples:
- Performs the same venv & dependency installation as
# From repo root (Unix / Git Bash / WSL)
chmod +x run-attackers.sh
./run-attackers.sh
# On Windows PowerShell (if WSL/Git Bash is installed)
bash run-attackers.shNotes & security:
- Both scripts are Bash scripts and call
pip install -r <requirements>automatically — they will install packages into thevenv. Be aware that running them performs network downloads and package installation. - The attacker script requires environment variables
API_KEYandLLM_MODELto be set; if they are missing the script warns and exits. You can set them in the current shell or createattackers/.envwith the variables. run-attackers.shwill call into Playwright if attackers are enabled; if you need Playwright browsers installed, runpython -m playwright install chromium.- Logs are written to
logs/by default — checklogs/backend.log,logs/model_service.logandlogs/attackers/*.logfor diagnostics.
- Clone the repo
git clone https://github.com/AjinkyaTaranekar/CS7NS1-Anti-AI-CAPTCHA.git
cd CS7NS1-Anti-AI-CAPTCHA- Create & activate virtual environment
python -m venv venv
venv\Scripts\Activate.ps1 # Windows PowerShell
# or for cmd: venv\Scripts\activate
# or linux / macOS: source venv/bin/activate- Install backend dependencies
pip install -r captcha-system/backend-service-requirements.txtInstall the OCR/model microservice dependencies (separate environment if preferred):
pip install -r captcha-system/model-service-requirements.txtFor the attacker suite, install:
pip install -r attackers/requirements.txt
# Playwright requires an extra setup step to install browsers
python -m playwright install chromiumNOTE: If you are deploying on resource-constrained Pi hardware, use captcha-system/backend-service-rasp-requirements.txt for a trimmed set of compatible versions.
- Start the OCR/Model Microservice (optional but recommended if you want to use the OCR endpoint):
cd captcha-system
python model_service.py1.1 Optionally, connect the microservice with NGROK for external access:
ngrok http 80011.2 Add the public URL in MODEL_SERVICE_URL environment variable before starting the backend:
$env:MODEL_SERVICE_URL="https://<random-id>.ngrok-free.dev" #Windows PowerShell
export MODEL_SERVICE_URL="https://<random-id>.ngrok-free.dev" #Linux / macOS- Start the main backend service (serves
index.htmland REST APIs):
# From captcha-system folder
python main.py- Visit the frontend at
http://localhost:5174. The web page (index.html) calls the backend endpoints:/api/captcha/challengeand/api/signup.
- GET / — Serves
index.html(main SPA) - POST /api/captcha/challenge — Generates a new CAPTCHA + PoW challenge (response model:
CaptchaResponse) - POST /api/signup — Signup endpoint that validates PoW, behavioral signals, fingerprint, and the CAPTCHA solution (request model:
SignupRequest)
Microservice endpoints: Additional microservice endpoints:
- POST /ocr — OCR the provided base64 PNG payload using EasyOCR (model service)
- POST /human_evaluate — Query the human/bot classifier with kinematic vectors (returns probability list)
The frontend also sends navigator signals for additional server-side scoring. The server uses rate limiting and returns helpful codes (e.g. 428 for refresh/challenge-required).
- Generate a handful of sample CAPTCHAs with
generate.py:
cd captcha-system
python generate.py --count 10 --output-dir sample_data --bg-dir background_images --ov-dir overlay_images --fonts-dir fonts- Generate widespread synthetic dataset using
generate_dataset.py(multi-process):
cd captcha-system
python generate_dataset.pygenerate.py has CLI options for width/height, blur, font-size, difficulty, and more.
Training uses the captcha_mouse_movement_prediction scripts and dataset files.
Steps:
- Place the behavioral dataset in
captcha-system/captcha_mouse_movement_prediction/data/(e.g., download from the provided dataset/Zenodo output). - Run training:
cd captcha-system/captcha_mouse_movement_prediction
python train_model.pyThis script trains a human vs bot XGBoost classifier and a character recognition classifier (if training data is present) — outputted model files are saved under captcha_mouse_movement_prediction/models/.
IMPORTANT: Generated models are referenced by the microservice and backend, so ensure the produced files are correctly placed. config/constants.py contains: SYMBOLS, MOUSE_MOVEMENT_MODEL, and CHAR_RECOGNITION_MODEL.
The attackers folder holds multiple attacker scripts that attempt to automate solving / bypassing CAPTCHAs. They rely on Playwright and EasyOCR and include example workflows.
Install attacker dependencies:
pip install -r attackers/requirements.txt
python -m playwright install chromiumThen run an attacker script to simulate an attack against the running backend (defaults: http://localhost:5174):
cd attackers
python attacker_1.py
python attacker_2.py
python attacker_3.py
python attacker_4.pyPolicy notes:
attack-recordings/will contain optional Playwright video recordings whenrecord_video=Truein attacker scripts.attack_results.csvwill contain a summary of attack attempts and results.
captcha-system/main.py— FastAPI backend implementing PoW, scoring, fingerprinting, rate-limiting and serving the SPA.captcha-system/model_service.py— standalone EasyOCR and human movement model microservice (port 8001 by default).captcha-system/generate.py— image generator with color/palette and prompt-injection techniques to confuse LLMs.captcha-system/generate_dataset.py— multiprocess wrapper to generate thousands of CAPTCHAs.captcha-system/config/constants.py— shared constants for model file names and symbols.captcha-system/captcha_mouse_movement_prediction— feature extraction, scripts and models for human vs bot detection.attackers— attacker scripts and helpers (Playwright / EasyOCR-based tactics).
Log files are in captcha-system/logs/ (e.g., signup_attempts.log). Generated CAPTCHAs are placed in captcha_images by default and sample outputs from generate.py live in sample_data when you use that command.
To deploy the CAPTCHA system on a Raspberry Pi, follow these additional steps:
To access the CAPTCHA system running on your Raspberry Pi from your local machine, you can set up port forwarding using SSH. Here’s how to do it:
-
Ensure you have SSH access to both the Jump Server (
macneill.scss.tcd.ie) and your Raspberry Pi (rasp-015.berry.scss.tcd.ie). -
Open a terminal on your local machine.
-
Run the model service on your machine since the Raspberry Pi won't have enough resources and doesn't support GPU acceleration:
cd captcha-system python model_service.py -
In another terminal, set up the ngrok tunnel to expose the model service:
ngrok http 8001
Note the public URL provided by ngrok (e.g.,
https://<random-id>.ngrok-free.dev). -
Now in another terminal, create an SSH tunnel from your local machine to the Jump Server:
ssh -L 5174:localhost:5174 <username>@macneill.scss.tcd.ie
-
After entering your password, the tunnel will be established. Now, create another SSH tunnel from the Jump Server to your Raspberry Pi:
ssh -L 5174:0.0.0.0:5174 <username>@rasp-015.berry.scss.tcd.ie
-
After entering your password, the second tunnel will be established.
-
Git clone the repository on your Raspberry Pi if you haven't already:
git clone https://github.com/AjinkyaTaranekar/CS7NS1-Anti-AI-CAPTCHA.git cd CS7NS1-Anti-AI-CAPTCHA -
Create and activate a virtual environment on your Raspberry Pi:
python3 -m venv venv source venv/bin/activate -
Install the backend dependencies using the Raspberry Pi specific requirements file:
pip install -r captcha-system/backend-service-rasp-requirements.txt- Update the
MODEL_SERVICE_URLin env to point to the ngrok URL you obtained earlier:
export MODEL_SERVICE_URL="https://<random-id>.ngrok-free.dev"- Start the backend service on your Raspberry Pi:
cd captcha-system
python main.py- Now you can access the CAPTCHA system from your local machine by navigating to
http://localhost:5174in your web browser.
- Some datasets and ideas used for training and evaluation are external (e.g. mouse-stroke datasets like those on Zenodo). See
captcha_mouse_movement_prediction/for details and dataset links.