# BruteForceAI: an LLM front end for login form brute forcing

> BruteForceAI uses an LLM to find the login form selectors on a page, then runs a multi-threaded credential attack against them. It is a two-stage Python tool for authorised penetration testing, with a non-commercial licence and a thin record of maintenance.

**MorDavid/BruteForceAI** — Advanced LLM-powered brute-force tool combining AI intelligence with automated login attacks

- Repository: https://github.com/MorDavid/BruteForceAI
- Website: https://www.MORDAVID.com
- Stars: 1,721 · Forks: 343
- Language: Python
- License: NOASSERTION
- Published: 2026-09-10 · Updated: 2026-09-10 · Language: en
- Canonical page: https://hysenlabs.com/projects/mordavid-bruteforceai

## The selector problem BruteForceAI tries to remove

Most brute force tooling assumes you already know the field names. You inspect the login page, find that the username input is called user_login and the password input is called pass, and you feed those into a tool. On a single target that is a five minute job. Across a list of targets it is the slow part, because every application names its fields differently and half of them wrap the form in JavaScript that rewrites the DOM after load.

BruteForceAI targets that specific step. The README describes it as a penetration testing tool that integrates Large Language Models for intelligent form analysis, and the two-stage split is the whole design: an analyze command that hands page HTML to a model and asks it to return the login form elements and selectors, and an attack command that consumes those selectors and runs the credential attempts. The intended user is a penetration tester or bug bounty hunter working from a file of URLs, not someone attacking a single known form.

The claim worth scrutinising is the word intelligent. The model is not deciding whether an attack is appropriate or whether a target is in scope. It is doing pattern recognition over HTML, which is a task a well written CSS selector heuristic can also do. What the LLM buys you is tolerance for markup that does not follow conventions. What it costs you is a dependency on a model endpoint, and a failure mode where the model confidently returns a selector that matches nothing.

## How the two stages pass data between each other

The repository has two Python files at the top level, BruteForceAI.py and BruteForceCore.py, plus requirements.txt, version.txt and a logo. BruteForceAI.py is the command line entry point, since every documented invocation is python BruteForceAI.py followed by a subcommand. The README lists four subcommands: analyze, attack, clean-db and check-updates. The split between the two files is not spelled out in the README, but the naming and the command structure point to the CLI wrapper in one and the shared attack and analysis logic in the other.

The analyze stage takes a URLs file and an LLM provider. It fetches the page, extracts HTML content, and sends it to the model. The README mentions automatic retry with feedback learning, which implies that when a returned selector does not work the tool feeds that result back and asks again. The selectors it finds have to be stored somewhere for the attack stage to use, and the README points at SQLite for logging, so the same database is the natural place. The clean-db subcommand exists to clear those tables, and the attack stage has a skip existing attempts behaviour, which only makes sense if previous attempts are persisted.

The attack stage is a Playwright browser session, not a raw HTTP client. Playwright appears in requirements.txt as playwright>=1.49 and the install step pulls the Chromium build. That choice matters: it means the tool can drive forms that depend on JavaScript, and it also means each thread carries a browser context, which is a much heavier unit than a requests session. The README advertises thread counts from 1 to 100+, and that range is worth treating with suspicion on a single machine, because the bottleneck will be browser contexts and target response time rather than Python threads.

## Installing BruteForceAI and running a first analysis

The README asks for Python 3.8 or higher and recommends a virtual environment. The dependency list is short: playwright, requests pinned at 2.31.0, and PyYAML pinned at 6.0.1. Playwright's browser binaries are a separate install step, which is the part people forget.

```bash
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
playwright install chromium
```

On Windows the activation line differs. The README gives .venv\Scripts\Activate.ps1 for PowerShell and .venv\Scripts\activate.bat for cmd. The venv creation step is once per checkout; activation is once per terminal session.

Next you need an LLM. There are two documented providers. Ollama runs locally and needs no API key, which is the cleaner choice for testing against a lab target because no page content leaves the machine. Groq is a cloud provider and needs a key from the Groq console.

```bash
curl -fsSL https://ollama.ai/install.sh | sh
ollama pull llama3.2:3b
```

The README lists llama3.2:3b as the default Ollama model, with llama3.2:1b as the fastest option and qwen2.5:3b as an alternative. Now create a file with one target URL per line and run the analysis stage.

```bash
python BruteForceAI.py analyze --urls targets.txt --llm-provider ollama --llm-model llama3.2:3b
```

What you should see is per-URL output identifying the login form elements the model selected, written with timestamps. If the model returns a selector that does not exist on the page, the retry-with-feedback behaviour described in the README is what you are watching for. The attack stage is a separate command and needs username and password files.

```bash
python BruteForceAI.py attack --urls targets.txt --usernames users.txt --passwords passwords.txt --threads 10 --delay 5 --jitter 2
```

Do not run that second command against anything you do not have written permission to test. The tool has no scope checking of its own.

## Attack modes, timing controls and what the evasion options actually do

The README documents two attack modes. Bruteforce mode tries all username and password combinations. Password spray mode tests each password against all usernames, which is the mode that avoids locking accounts out, because a spray sends one attempt per account rather than a burst against one account. If account lockout is a concern on the target, password spray is the mode to pick, and the mode flag is --mode passwordspray.

The timing controls are --delay and --jitter, and the README describes them as synchronized delays between attempts for the same user. That detail is more interesting than it looks. A shared delay across threads would slow the whole run to the speed of the slowest target. A per-user delay means the tool tracks timing per account, which is what a spray needs to stay under a lockout threshold, and what a bruteforce run needs to avoid a pattern that a rate limiter can spot.

Evasion options include random User-Agent rotation, with a --user-agents file argument, proxy support, and browser visibility control. There is also --success-exit, which stops the run after the first valid credential pair, and DOM change detection for success validation. The DOM change approach is a trade-off worth naming: it works when a successful login visibly alters the page, and it fails on single page applications where the login response is a JSON payload and the DOM barely moves. The README does not describe a fallback for that case.

Notifications go out over webhooks to Discord, Slack, Teams and Telegram. The command example in the README shows a truncated --discord-webhoo flag, so treat the exact flag spelling as something to confirm with the tool's own help output rather than copying from the README.

## Where BruteForceAI is the wrong tool

The first limitation is the licence. The repository carries a NOASSERTION licence identifier and the README badge says Non-Commercial. That is a real constraint for anyone in a commercial penetration testing firm, and the LICENSE.md file is the document that governs, not the badge. A tool you cannot use on client engagements is a tool with a much smaller audience than the feature list suggests.

The second is maintenance. The last push to the repository was on 2026-07-17, which is roughly two months before the date of writing. That is recent enough that the project is not abandoned, but there are no retrieved releases, so there is no versioned artifact to pin against and no changelog to read. The README documents a check-updates subcommand that checks mordavid.com, which means update discovery depends on an external site rather than on tagged releases in the repository.

The third is dependency drift. requirements.txt pins requests at 2.31.0 and PyYAML at 6.0.1, while playwright is left as a floor of >=1.49. Pinned transitive dependencies go stale, and a floor-only pin on the browser automation layer means the behaviour of the tool can change when you install it on a new machine months later. For a tool that drives a browser, that is the dependency most likely to break a working setup.

The fourth is the wrong-tool case. If you have a single target with a well documented login form and you already know the selectors, the analyze stage is overhead. A scripted requests loop with a known field name will be faster and easier to reason about. The LLM stage only pays for itself when you are working across many unfamiliar forms.

## How BruteForceAI differs from general purpose AI pentest assistants

The related searches around this project surface HexStrike AI and PentestGPT AI, and the comparison is worth drawing because the three occupy different positions. PentestGPT-style tools are conversational: you describe a target, the model suggests an approach, and you execute it. The output is guidance that a human acts on. HexStrike-style tooling wraps a collection of offensive utilities behind an AI interface, so the model chooses which existing tool to invoke.

BruteForceAI does neither. It is a single-purpose tool with an LLM embedded in one step of its own pipeline. The model does not choose the attack, does not decide the scope, and does not call other tools. It reads HTML and returns selectors. Everything after that is deterministic code with thread counts, delays and a SQLite log. That narrowness is the honest description of the project, and it is also its main advantage over the assistant pattern: there is no prompt-injection surface from the target page steering the model into running a different command, because the model has no commands to run.

The cost of that narrowness is that BruteForceAI is not a workflow tool. It does not do reconnaissance, it does not enumerate users, and it does not tell you whether the target is in scope. You bring the URL list. If your engagement needs the model to reason about the whole attack path, this is not that tool.

## Logging, the database and what to check before trusting a run

The README describes comprehensive logging with a SQLite database, verbose timestamped output, output capture to files via --output, and skip existing attempts for duplicate prevention. Those four features together define the operational model: a run is resumable, because completed attempts are recorded and skipped on the next invocation, and auditable, because the record persists in a file you can query.

The clean-db subcommand clears database tables. The README does not document which tables, whether it prompts for confirmation, or whether there is a way to clear one target's records rather than all of them. That is a gap worth knowing about before you run it on a database you care about, because the safe assumption is that it clears everything the tool has recorded.

The force retry existing attempts option is the counterpart to skip existing attempts, and the two together mean you control whether a rerun re-tests pairs already tried. For a long spray against many targets, that is the difference between a run that finishes and one that repeats work.

What to verify first, concretely: run analyze on one target you control and read the returned selectors against the page source. If the model returns a selector for a field that does not exist, the attack stage will produce failures that look like wrong credentials rather than a bad selector, and the SQLite log will record them as attempts. Confirming the selector is correct before the attack stage is the cheapest way to avoid a misleading result set.

## Conclusion

BruteForceAI fits authorised penetration testers who already have a target list and want the selector-hunting step automated through Ollama or Groq. It does not fit anyone without written authorisation, anyone who needs a maintained dependency set, or teams that cannot accept a non-commercial licence. Before adopting it, run the analyze stage against one target you control and confirm the selectors the model returns match the actual form, since the README documents no rollback or validation step for a wrong guess.

## FAQ

### What is BruteForceAI in simple terms?

It is a Python penetration testing tool that uses an LLM to find the login form selectors on a page, then runs a multi-threaded brute force or password spray attack against those selectors. The README splits it into an analyze stage and an attack stage.

### Is a brute force attack illegal?

The README does not address legality, but it frames BruteForceAI as a penetration testing tool, and it has no scope checking of its own. Running credential attacks against systems you do not have written authorisation to test is a legal matter outside what the documentation covers.

### Which LLM providers does BruteForceAI support?

The README documents two: Ollama, which runs locally and needs no API key, and Groq, which is a cloud provider and needs a key from the Groq console. The provider is selected with the --llm-provider flag.

### What is the difference between bruteforce and password spray mode in BruteForceAI?

Bruteforce mode tries all username and password combinations, while password spray mode tests each password against all usernames. The README selects spray with --mode passwordspray.

### What licence does BruteForceAI use?

The repository carries a NOASSERTION licence identifier and the README badge says Non-Commercial. The LICENSE.md file in the repository is the document that governs use.

## Sources

- [Issues](https://github.com/MorDavid/BruteForceAI/issues)
- [MorDavid/BruteForceAI on GitHub](https://github.com/MorDavid/BruteForceAI)
- [Project website](https://www.MORDAVID.com)
- [README](https://github.com/MorDavid/BruteForceAI/blob/main/README.md)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/mordavid-bruteforceai
