Every tool runs with its full power. ReconFrame is an orchestration layer — it coordinates them intelligently, not a watered-down wrapper.
Every feature exists because running 12 tools manually wastes time. ReconFrame handles the coordination so you can focus on analysis.
A single Python file with 10 distinct components. Each one has a clear responsibility. Nothing bleeds into anything else.
$ git clone https://github.com/Jishnuec/reconframe.git $ cd reconframe $ chmod +x reconframe.py $ ./reconframe.py
| Command | Description |
|---|---|
| ./reconframe.py | Interactive mode — full TUI menu |
| ./reconframe.py -t example.com | Quick scan of a domain |
| ./reconframe.py -t 192.168.1.1 | Scan an IP address |
| ./reconframe.py -t example.com -v | Verbose mode — shows full tool output |
| ./reconframe.py -t example.com -o report.txt | Save results to file |
| ./reconframe.py -t 10.0.0.1 --tools nmap,whois | Run specific tools only |
| ./reconframe.py --list-tools | List all available tools |
| ./reconframe.py --no-banner | Skip startup animation |
# IP given, DNS tools selected — prompts for domain $ ./reconframe.py -t 192.168.1.100 [?] IP detected. Enter domain for DNS tools (or Enter to skip): example.com # No web ports — web tools automatically skipped [!] No web ports detected (80/443/8080 closed) [-] Skipping: gobuster, nikto, sqlmap, wafw00f # Port 443 closed — sslyze automatically skipped [!] SSL scan only works on HTTPS ports [-] Skipping: sslyze
8 phases from initial concept to GitHub publication. Every phase solved a specific problem.
These weren't obvious issues — each one required understanding the underlying system before the fix made sense.
The header above the progress bar was redrawn inside the tool loop, causing it to print fresh 12 times instead of updating in-place.
Moved the header outside the loop. Used ANSI cursor movement sequences (\033[A) to move the cursor up and overwrite only the progress content — not the header.
"version" appeared as "versio..." in the results table. Column widths were hardcoded too narrow, cutting off content in the UI boxes.
Calculated column widths dynamically based on terminal size using shutil.get_terminal_size(). Content now wraps cleanly at any width.
When an IP address was given as the target, DNS tools like subfinder and amass would fail — they require a domain name, not an IP.
Added IP detection with socket.inet_aton(). If IP detected and DNS tools selected, prompt for a domain. If no domain entered, skip all DNS tools with a clear message.
gobuster, nikto, and sqlmap were running against targets with no web server — consuming time and producing useless output.
Added port probing with socket.connect_ex() before any web tool execution. If ports 80, 443, and 8080 are all closed, all web tools are skipped with a clear explanation.
Slow or unresponsive targets caused individual tool processes to hang indefinitely, blocking progress on the entire scan.
Added timeout= parameter to subprocess.run() for every tool runner. Timeout exceeded produces a friendly "tool timed out" message and the scan continues with the next tool.