Back to Articles

Inside gwen001's pentest-tools: A Bug Bounty Hunter's Arsenal of Single-Purpose Security Scripts

[ View on GitHub ]

Inside gwen001's pentest-tools: A Bug Bounty Hunter's Arsenal of Single-Purpose Security Scripts

Hook

While the security industry obsesses over comprehensive frameworks, one of the most-starred penetration testing repositories on GitHub is just a folder of disconnected Python scripts—and that's exactly why it works.

Context

The penetration testing landscape has long been dominated by monolithic frameworks like Metasploit and commercial suites like Burp. These tools promise comprehensive coverage but come with steep learning curves, heavy dependencies, and the overhead of features you'll never use. Bug bounty hunters face a different reality: they need to scan hundreds of domains quickly, test specific vulnerability patterns, and chain together workflows that change with each target.

Gwen Rimet (gwen001) built this collection from the trenches of active bug bounty hunting, where speed and adaptability matter more than polish. Rather than creating yet another framework, she published the actual scripts she uses daily—tools born from the "I need to check 500 subdomains for this specific CORS misconfiguration right now" moments that define modern reconnaissance work. The collection has accumulated 3,296 stars not through marketing but through practitioners recognizing tools that solve their immediate problems.

Technical Insight

Tool Composition

Script Ecosystem

Sequential

Parallel

Pipe/Chain

Input Source

CLI args/files

Standalone Script

Python/Bash/PHP

Processing Layer

HTTP Requests

DNS Lookups

Multiprocessing Pool

Concurrent Tasks

External Tools

nmap/netcat/msf

Result Aggregation

Output

stdout/files

System architecture — auto-generated

The architecture of pentest-tools embodies the Unix philosophy: each script does one thing, accepts standard inputs, and produces parseable outputs. This isn't an accident—it's a design decision that enables the tool chaining workflows essential to reconnaissance.

Consider cloudflare-origin-ip.php, a 50-line script that attempts to discover the real IP address behind Cloudflare's CDN. Instead of building a complex framework, it simply makes HTTP requests with different Host headers and compares responses:

$domain = $argv[1];
$subdomains = file('subdomains.txt', FILE_IGNORE_NEW_LINES);

foreach($subdomains as $subdomain) {
    $ip = gethostbyname($subdomain);
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, 'http://'.$ip);
    curl_setopt($ch, CURLOPT_HTTPHEADER, array('Host: '.$domain));
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    $response = curl_exec($ch);
    // Compare response to known Cloudflare page
}

This simplicity enables command-line composition: subfinder -d example.com | cloudflare-origin-ip.php becomes a complete workflow. The script doesn't manage its own subdomain discovery—it assumes you'll pipe in data from whatever tool you prefer.

The Python tools follow similar patterns but leverage concurrency for performance. subdomains-from-csp.py demonstrates the parallel processing approach common throughout the collection:

import requests
from multiprocessing.dummy import Pool as ThreadPool
import re

def check_csp(url):
    try:
        r = requests.get(url, timeout=5, verify=False)
        csp = r.headers.get('Content-Security-Policy', '')
        # Extract domains from CSP header
        domains = re.findall(r'https?://([^\s;]+)', csp)
        return domains
    except:
        return []

if __name__ == '__main__':
    urls = open('urls.txt').read().splitlines()
    pool = ThreadPool(20)  # 20 concurrent threads
    results = pool.map(check_csp, urls)
    pool.close()
    pool.join()

This uses Python's ThreadPool to check 20 URLs simultaneously—critical when processing thousands of targets. The error handling is deliberately minimal: failed requests return empty lists and the script continues. In bug bounty work, you want to process 10,000 domains even if 500 time out, rather than halting on the first error.

Several tools in the collection act as "convenience wrappers" around existing security tools, adding parallelization or format conversion. mass-nmap.sh exemplifies this pattern:

#!/bin/bash
while IFS= read -r ip; do
    nmap -sV -T4 -p- "$ip" -oX "results/$ip.xml" &
    # Limit concurrent nmap processes
    while [ $(jobs -r | wc -l) -ge 10 ]; do
        sleep 1
    done
done < "$1"
wait

Rather than reimplementing port scanning, it manages parallel nmap invocations with job control—a 15-line script that solves the "I need to scan 200 IPs but nmap doesn't parallelize across targets" problem.

The collection also includes vulnerability-specific checkers like cors-misconfig.py, which tests for dangerous CORS policies by making requests with attacker-controlled Origins and checking if credentials are reflected. These scripts encode specific attack patterns, making them immediately useful for testing particular vulnerability classes without configuring complex scanner rules.

What makes this architecture powerful for reconnaissance is composability. A typical workflow might look like: subfinderhttpx (check which respond) → subdomains-from-csp.py (find more subdomains) → waybackurlsextract-endpoints.py (custom script) → ffuf. Each tool transforms data for the next. Because pentest-tools scripts follow standard input/output conventions, they slot into these chains seamlessly.

Gotcha

The biggest limitation is exactly what makes the collection useful: these are personal tools made public, not products. Documentation ranges from comprehensive to "read the source." github-subdomains.py has a detailed help menu, while email-extractor.php has three comment lines. You'll spend time reading code to understand parameters, output formats, and dependencies. Several scripts assume you have API keys configured (Shodan, SecurityTrails) without clear documentation on where to put them—you'll grep for "API_KEY" to figure it out.

Dependency management is entirely manual. Some Python scripts need requests, others need BeautifulSoup, a few need selenium. There's no requirements.txt, no virtual environment setup, no version pinning. You'll encounter import errors and need to pip install packages one by one. The PHP scripts assume php-curl is available. Bash scripts might call jq, parallel, or other utilities without checking if they're installed. This works fine if you maintain a dedicated penetration testing VM with everything pre-installed, but it's friction for newcomers.

Several tools depend on services that have evolved or disappeared. Scripts using PhantomJS (deprecated since 2018) won't work without modification. API-based tools may hit rate limits quickly when processing large target lists—there's no built-in rate limiting or retry logic. Some scripts output to hardcoded filenames, creating race conditions if you run multiple instances. These aren't bugs; they're artifacts of tools built for immediate personal use rather than general distribution.

Verdict

Use if: You're doing active reconnaissance or bug bounty hunting and need quick, specific automation for tasks like subdomain enumeration, vulnerability pattern checking, or mass scanning. You're comfortable reading source code to understand tool behavior, managing dependencies manually, and adapting scripts to your workflow. You value having 50+ specialized tools you can combine in novel ways over having one comprehensive framework. You maintain a dedicated security testing environment where you can pre-install dependencies once. Skip if: You need enterprise-grade reliability, comprehensive documentation, or unified dependency management. You're new to penetration testing and want guided workflows rather than building blocks. You require robust error handling and logging for compliance documentation. You prefer modern, actively maintained tools—consider the ProjectDiscovery suite (subfinder, httpx, nuclei) which offers similar functionality with better performance, comprehensive documentation, and active development.

// ADD TO YOUR README
[![Featured on Starlog](https://starlog.is/api/badge/cybersecurity/gwen001-pentest-tools.svg)](https://starlog.is/api/badge-click/cybersecurity/gwen001-pentest-tools)