Post

Fast Scripting for Hackers: Asynchronous Recon Tools in Python

Fast Scripting for Hackers: Asynchronous Recon Tools in Python

When auditing APIs or verifying candidate vulnerabilities across thousands of endpoints, standard synchronous scripts (requests or urllib) are bottlenecked by blocking network I/O. Multiprocessing and threads add CPU context-switching overhead and can be cumbersome to manage cleanly.

Python’s native asyncio and aiohttp libraries provide an exceptionally fast, lightweight foundation for custom security tooling.

1. The Power of Single-Threaded Concurrency

With an asynchronous event loop, thousands of HTTP requests or TCP probes can be in-flight concurrently without spawning thousands of OS threads. The loop merely registers socket activity and yields execution until the remote server replies.

2. A Clean Async HTTP Fingerprinter

Here is a concise, robust template for scanning target endpoints with strict rate limiting and graceful exception handling:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
import asyncio
import aiohttp
import sys

TARGETS = [f"https://api{i}.example.com/health" for i in range(1, 100)]
SEMAPHORE_LIMIT = 20  # Limit concurrent connections

async def probe_endpoint(session, url, sem):
    async with sem:
        try:
            async with session.get(url, timeout=5, ssl=False) as response:
                status = response.status
                server = response.headers.get("Server", "Unknown")
                print(f"[{status}] {url} -> Server: {server}")
                return url, status
        except Exception:
            return url, None

async def main():
    sem = asyncio.Semaphore(SEMAPHORE_LIMIT)
    timeout = aiohttp.ClientTimeout(total=10)
    
    async with aiohttp.ClientSession(timeout=timeout) as session:
        tasks = [probe_endpoint(session, target, sem) for target in TARGETS]
        results = await asyncio.gather(*tasks)
        
    valid = [r for r in results if r[1] is not None]
    print(f"\n[+] Successfully audited {len(valid)}/{len(TARGETS)} targets.")

if __name__ == "__main__":
    asyncio.run(main())

3. Best Practices for Hacker Scripts

  • Always apply a Semaphore: Unbounded concurrency (asyncio.gather(*tasks) without a semaphore) will exhaust file descriptors (ulimit -n) or trip local network rate limits.
  • Disable SSL Verification with Caution: For target triage where self-signed certificates are common, ssl=False prevents connection abortion, but should never be used in code handling sensitive secrets.
  • Stream Responses: When downloading or checking large files, use chunked reading rather than loading entire response bodies into memory.
This post is licensed under CC BY 4.0 by the author.