asqli
Async, parallel SQL injection scanner. Built on asyncio + aiohttp,
designed to extract data orders of magnitude faster than serial scanners by
running blind-inference probes concurrently across cells, retries, and
proxies.
pip install asqli
asqli -u 'http://target/vuln.php?id=1' --batch --dump
Why not just use sqlmap?
sqlmap is the canonical SQL-injection tool and a brilliant piece of
engineering — but it's a 19-year-old synchronous codebase. asqli is a
ground-up rewrite focused on three things sqlmap can't easily do:
| asqli | sqlmap | |
|---|---|---|
| Concurrency model | asyncio + aiohttp, bounded semaphores |
Threading (--threads 1–10) |
| Dump throughput (200 cells) | All cells fire in parallel, rows stream as they finish | One cell at a time per thread |
| Request rotation | UAForge realistic UA + Sec-CH-UA Client Hints per request, weighted by market share | Static UA list, no Client Hints |
| Proxy support | HTTP + HTTPS + SOCKS4 + SOCKS5 out of the box (aiohttp-socks), rotating proxy pool via --proxies FILE |
Single --proxy |
| Retry semantics | Honors Retry-After on 429/503, exponential backoff with jitter cap |
Generic retry loop |
| Output | Colored terminal logs + boxed CSV dumps streamed as rows arrive | Boxed table, batched at end |
| Install footprint | 4 wheels (aiohttp, aiohttp-socks, uaforger, asqli) |
Bundled monolith with legacy dependencies |
| Lines of Python | ~4 000 | ~40 000 |
| File-write / OS-shell | MSSQL planner shipped; orchestration stub for stacked execution | All DBMSes, mature |
Use asqli when: speed matters (large dumps, CI scanners, recon piping), you're running at scale through proxy pools, or you want a small, auditable codebase you can read in an afternoon.
Stick with sqlmap when: you need OS-shell pivoting, deep takeover features (registry edits, Metasploit handoff), or DBMSes outside MySQL/PostgreSQL/MSSQL/Oracle/SQLite.
Install
pip install asqli
That's it. aiohttp, aiohttp-socks, and uaforger come along
automatically — no extra steps for SOCKS proxies or realistic UAs.
Usage
Detect
asqli -u 'http://target/list?id=1' # GET, all techniques
asqli -u 'http://target/login' --data 'u=admin&p=x' # POST
asqli -r request.txt # raw Burp/ZAP export
Enumerate
asqli -u '...' --banner --current-user --current-db --hostname --privileges
asqli -u '...' --dbs
asqli -u '...' --tables -D security
asqli -u '...' --columns -T users -D security
asqli -u '...' --passwords # mysql.user / pg_shadow / sys.sql_logins
Dump
asqli -u '...' --dump -D security -T users # boxed table + CSV
asqli -u '...' --dump-all # every table in every db
asqli -u '...' --file-read 'C:\inetpub\wwwroot\web.config' --file-read-out web.config
Tuning
asqli -u '...' --level 3 --risk 3 --technique=BEUSTQ
asqli -u '...' -c 0 --max 200 --per-host 64 # unlimited workers, 200 probes per query
asqli -u '...' --tamper space2comment,between --no-random-agent
Flags
| Flag | Default | Meaning |
|---|---|---|
-u URL |
— | Target URL |
-r FILE |
— | Raw HTTP request file (Burp/ZAP) |
--data BODY |
— | POST body (switches method to POST) |
--method M |
GET/POST | HTTP method override |
-H "K: V" |
— | Extra header (repeatable) |
--cookie STR |
— | Cookie header |
--user-agent UA |
— | Force a fixed UA |
--random-agent / --no-random-agent |
on | Fresh UAForge identity per request |
--proxy URL |
— | Single HTTP/HTTPS/SOCKS proxy |
--proxies FILE |
— | Rotating proxy pool — random pick per request |
--force-ssl |
off | Upgrade scheme to HTTPS |
--timeout SECS |
30 | Per-request timeout |
--retries N |
3 | Retries on 429/502/503/504 and network errors |
-c N --concurrency N |
0 (∞) | Total concurrent workers |
--max N |
100 | Concurrent probes per query / per parameter |
--per-host N |
32 | Concurrent connections per host |
-p NAMES |
— | Restrict testing to these parameter names |
--skip NAMES |
— | Skip these parameter names |
--level N |
1 | Test breadth (1–5) |
--risk N |
1 | Test aggressiveness (1–3) |
--technique BEUSTQ |
BEUSTQ | Subset of B/E/U/S/T/Q techniques to try |
--tamper SCRIPT[,…] |
— | Tamper script chain |
--dbms NAME |
auto | Force a back-end DBMS hint |
--banner --current-user --current-db --hostname --privileges --passwords |
— | Single-fact / sys-user table extraction |
--dbs --tables --columns --dump --dump-all |
— | Enumeration / dumping |
-D NAME -T NAME |
— | Restrict to a database / table |
--file-read REMOTE --file-read-out LOCAL |
— | Read file off target via DBMS |
--output-dir PATH |
./output |
Root for CSV dumps |
-v |
INFO | -vv debug, -vvv payloads, -vvvv traffic-out, -vvvvv traffic-in |
--batch |
off | Non-interactive |
Rotating proxies for high-volume scans
A blind SQLi --dump against a 13-row × 3-column table runs ~270 inference
probes per cell × 39 cells ≈ 10 500 requests. From one IP, most
production targets will rate-limit, IP-block, or trip a WAF long before
asqli's binary search completes.
The fix is request distribution. --proxies FILE takes a newline-separated
list of proxy URLs (HTTP, HTTPS, SOCKS4, SOCKS5 are all native — no extra
install) and dispatches every request through a uniformly-random pick:
proxies.txt:
http://proxy1.example.com:3128
http://user:pass@proxy2.example.com:3128
socks5://10.0.0.1:1080
socks5h://user:pass@10.0.0.2:1080
$ asqli -u 'http://target?id=1' --dump --proxies proxies.txt -c 64
Internally asqli opens one pooled aiohttp session per proxy URL,
preserving the per-host connection cap on each. A 200-proxy pool can
parallelise an entire dump to the point where the bottleneck is the
target's DBMS round-trip, not the network or rate-limit.
If you also pass --random-agent (default on), the combination of
fresh UAForge identity + rotating egress IP per request makes most
naive rate-limiters useless against you. Source-side fingerprinting
(TLS JA3, request-cadence behaviour) is a separate problem — see
ROADMAP.
Architecture
asqli.py → CLI bootstrap → asqli_engine.run.detect()
asqli_engine/scan.py → Scan, Target, Parameter, InjectionPoint
asqli_engine/http/client.py → aiohttp + aiohttp-socks pooled sessions
asqli_engine/http/useragents.py → UAForge wrapper
asqli_engine/detect/ → boolean / error / time / stacked / union
asqli_engine/extract/ → DBMS-aware blind inference + streaming dump
asqli_engine/extract/dbms_queries → MySQL / PostgreSQL / MSSQL / Oracle / SQLite
asqli_engine/upload/file_ops.py → --file-read
asqli_engine/upload/mssql.py → --file-write planner (MSSQL/Windows)
asqli_engine/scheduler.py → bounded-concurrency runner
Parallelism map for extraction:
- Databases: sequential count, parallel name fetch
- Tables / columns: sequential count, parallel name fetch
- Cells: every
(row, col)fires concurrently; rows stream out as each one's character bisection completes viaasyncio.as_completed - Bisection within one char: sequential (~7 requests/char printable ASCII)
DBMS-specific catalogs cover MySQL, PostgreSQL, MSSQL, Oracle, SQLite.
Byte-value comparison (ASCII / ORD / UNICODE) is used instead of
collation-sensitive >=, which on MySQL's default collation case-folds
and yields garbage at the byte level.
Legal
For authorised security testing only.
Metadata
Release files for asqli 0.2.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| asqli-0.2.2.tar.gz | 42.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| asqli-0.2.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 98.5 kB
Release files / asqli-0.2.2.tar.gz
| Download URL | asqli-0.2.2.tar.gz |
|---|---|
| Size | 42.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
46a1e74dd8ee6125ff462672021b643c2394fbbc649a799daac4b2b56e85c8bb
|
|
BLAKE2b-256 checksum How to use checksums |
8d3b497f2a27226aaaecde83f1685e5bd3e8da13bf67fba84e55dcfc21552204
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.0.1 CPython/3.10.12
|
Release files / asqli-0.2.2-py3-none-any.whl
| Download URL | asqli-0.2.2-py3-none-any.whl |
|---|---|
| Size | 55.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
ca8b2cabbf73185b0765b74f12bdd1ae89c4f5370f2f085b4a50e016359d4324
|
|
BLAKE2b-256 checksum How to use checksums |
b81ad20180c0288640ba30d6c3f46cb527fcdb7efa4d7a55ef403f3147d6b079
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.0.1 CPython/3.10.12
|