port_scanner.py
Async TCP port scanner with banner grabbing and service detection. Bounded concurrency, conservative rate-limiting, and an explicit authorization flag.
asyncio · bounded · --acknowledge
➜ ~ $ ./qaq_cli.py --menu
A defensive network toolkit in a single folder: a fast async port scanner, a WAF and firewall fingerprint detector, and a proxy validator, wired together by one CLI. Conservative defaults, explicit authorization guards, no destructive exploits. Download the zip, preview every source file below, and push it to GitHub in a minute.
Tools
3 + launcher
Files
7
Status
READY
License
MIT
./tools
Four self-contained scripts with clean module boundaries. Each one stands alone, validates its own scope, and errs on the conservative side by default.
Async TCP port scanner with banner grabbing and service detection. Bounded concurrency, conservative rate-limiting, and an explicit authorization flag.
asyncio · bounded · --acknowledge
Heuristic WAF and packet-filter fingerprinting from RST/drop patterns, TCP flags, TTL variance, and HTTP header anomalies. Degrades gracefully without raw sockets.
non-destructive · heuristic · degrades
SOCKS4/5 and HTTP(S) proxy validator with latency and anonymity reporting. Only touches proxies you supply, rate-limited with hard timeouts.
socks4/5 · http(s) · user lists only
Unified launcher with a branded interactive menu and subcommands. Drives every tool with help, validation, and a single entry point.
menu · subcommands · --help
./src
The full source, un-truncated, exactly as it is packed into the download. Select a file to inspect it - line numbers, syntax highlighting, and a copy button included.
| 1 | #!/usr/bin/env python3 |
| 2 | # -*- coding: utf-8 -*- |
| 3 | |
| 4 | |
| 5 | |
| 6 | |
| 7 | |
| 8 | |
| 9 | |
| 10 | |
| 11 | |
| 12 | |
| 13 | |
| 14 | |
| 15 | |
| 16 | |
| 17 | |
| 18 | |
| 19 | """QAQ Network Suite - qaq_cli.py ============================== Unified command-line launcher for the QAQ toolkit. It provides a branded, interactive terminal menu plus proper subcommands and help, so you can either browse the tools interactively or drive them script-friendly from shell automation. Usage ----- python qaq_cli.py --menu # interactive guided menu python qaq_cli.py scan 10.0.0.5 # run a scan via the port scanner python qaq_cli.py detect example.com python qaq_cli.py proxies -f list.txt python qaq_cli.py --help """ |
| 20 | |
| 21 | import argparse |
| 22 | import os |
| 23 | import shutil |
| 24 | import subprocess |
| 25 | import sys |
| 26 | from typing import List, Optional |
| 27 | |
| 28 | TOOLS = { |
| 29 | "port_scanner": { |
| 30 | "path": "port_scanner.py", |
| 31 | "help": "TCP port scanner with banner grabbing and service detection", |
| 32 | "cmd": [], |
| 33 | }, |
| 34 | "firewall_detector": { |
| 35 | "path": "firewall_detector.py", |
| 36 | "help": "WAF / firewall fingerprint heuristic detector", |
| 37 | "cmd": [], |
| 38 | }, |
| 39 | "proxy_scanner": { |
| 40 | "path": "proxy_scanner.py", |
| 41 | "help": "SOCKS/HTTP proxy validator for user-supplied lists", |
| 42 | "cmd": [], |
| 43 | }, |
| 44 | } |
| 45 | |
| 46 | |
| 47 | def banner() -> str: |
| 48 | """The branded ASCII banner shown on menu start.""" |
| 49 | b = [ |
| 50 | " ____ ____ _ __", |
| 51 | " / __ \\ / __ \\ (_) / /_ ___ _____", |
| 52 | " / / / / / / / / / / / __ \\/ _ \\/ ___/", |
| 53 | "/ /_/ / / /_/ / / / / /_/ / __/ /", |
| 54 | "\\___\\_\\ \\____/ /_/ /_.___/\\___/_/", |
| 55 | "", |
| 56 | " Network Suite - defensive recon toolkit", |
| 57 | ] |
| 58 | return "\n".join(b) |
| 59 | |
| 60 | |
| 61 | def _edge() -> str: |
| 62 | return "-" * 58 |
| 63 | |
| 64 | |
| 65 | def menu_prompt() -> None: |
| 66 | """Render the interactive pick menu and dispatch on the user's choice.""" |
| 67 | print(banner()) |
| 68 | print() |
| 69 | names = list(TOOLS.keys()) |
| 70 | for i, name in enumerate(names, 1): |
| 71 | print(f" {i}. {name:<20} {TOOLS[name]['help']}") |
| 72 | print(f" {len(names) + 1}. exit") |
| 73 | print(_edge()) |
| 74 | try: |
| 75 | choice = input(" > select: ").strip() |
| 76 | except (EOFError, KeyboardInterrupt): |
| 77 | print("\n bye") |
| 78 | sys.exit(0) |
| 79 | if choice == str(len(names) + 1) or choice.lower() in ("q", "quit", "exit"): |
| 80 | print(" bye") |
| 81 | return |
| 82 | if not choice.isdigit() or not (1 <= int(choice) <= len(names)): |
| 83 | print(" [!] invalid selection") |
| 84 | return menu_prompt() |
| 85 | name = names[int(choice) - 1] |
| 86 | run_tool(name, interactively=True) |
| 87 | |
| 88 | |
| 89 | def run_tool(name: str, interactively: bool = False) -> None: |
| 90 | """Locate and exec a bundled tool script, passing through args.""" |
| 91 | script_dir = os.path.dirname(os.path.abspath(__file__)) |
| 92 | path = os.path.join(script_dir, TOOLS[name]["path"]) |
| 93 | if not os.path.exists(path): |
| 94 | print(f"[!] Tool not found: {path}") |
| 95 | sys.exit(1) |
| 96 | cmd = [sys.executable, path] |
| 97 | if interactively: |
| 98 | print() |
| 99 | print(f"[*] Running {name} ...") |
| 100 | print(_edge()) |
| 101 | os.environ.setdefault("QAQ_INTERACTIVE", "1" if interactively else "0") |
| 102 | try: |
| 103 | raise SystemExit(subprocess.call(cmd)) |
| 104 | except KeyboardInterrupt: |
| 105 | print("\n[!] cancelled") |
| 106 | sys.exit(130) |
| 107 | |
| 108 | |
| 109 | def build_parser() -> argparse.ArgumentParser: |
| 110 | parser = argparse.ArgumentParser( |
| 111 | prog="qaq_cli.py", |
| 112 | description="QAQ Network Suite - unified CLI launcher for the defensive toolkit.", |
| 113 | formatter_class=argparse.RawDescriptionHelpFormatter, |
| 114 | epilog="Run \`python qaq_cli.py <subcommand> --help\` for tool-specific options.", |
| 115 | ) |
| 116 | parser.add_argument("--menu", action="store_true", |
| 117 | help="launch the interactive menu (default if no subcommand)") |
| 118 | sub = parser.add_subparsers(dest="tool", metavar="tool") |
| 119 | |
| 120 | p_scan = sub.add_parser("scan", help="TCP port scan a host (port_scanner.py)") |
| 121 | p_scan.add_argument("hosts", nargs="*", help="host names / IPs to scan") |
| 122 | |
| 123 | p_detect = sub.add_parser("detect", help="fingerprint a WAF/firewall") |
| 124 | p_detect.add_argument("host", help="host name / IP to examine") |
| 125 | |
| 126 | p_proxy = sub.add_parser("proxies", help="validate a proxy list (proxy_scanner.py)") |
| 127 | p_proxy.add_argument("-f", "--file", help="file of proxy entries") |
| 128 | p_proxy.add_argument("proxies", nargs="*", help="host:port[:type] entries") |
| 129 | |
| 130 | p_about = sub.add_parser("about", help="show toolkit overview and responsibility notice") |
| 131 | return parser |
| 132 | |
| 133 | |
| 134 | def cmd_about() -> None: |
| 135 | print(banner()) |
| 136 | print(_edge()) |
| 137 | print( |
| 138 | " About\n" |
| 139 | " QAQ is a small, defensive network toolkit: a port scanner, a\n" |
| 140 | " WAF/firewall detector, and a proxy validator. Every tool ships\n" |
| 141 | " with conservative defaults and explicit 'authorized use only'\n" |
| 142 | " guards. Run them only against systems you own or are permitted\n" |
| 143 | " to test. Unauthorized scanning is intrusive and often illegal.\n" |
| 144 | ) |
| 145 | print(_edge()) |
| 146 | |
| 147 | |
| 148 | def main(argv: Optional[List[str]] = None) -> int: |
| 149 | parser = build_parser() |
| 150 | args = parser.parse_args(argv) |
| 151 | |
| 152 | if args.tool == "scan": |
| 153 | if not args.hosts: |
| 154 | parser.error("scan requires at least one host") |
| 155 | run_tool("port_scanner") |
| 156 | elif args.tool == "detect": |
| 157 | run_tool("firewall_detector") |
| 158 | elif args.tool == "proxies": |
| 159 | if not args.file and not args.proxies: |
| 160 | parser.error("proxies requires a list via --file or inline entries") |
| 161 | run_tool("proxy_scanner") |
| 162 | elif args.tool == "about": |
| 163 | cmd_about() |
| 164 | return 0 |
| 165 | else: |
| 166 | menu_prompt() |
| 167 | return 0 |
| 168 | |
| 169 | |
| 170 | if __name__ == "__main__": |
| 171 | raise SystemExit(main()) |
| 172 |
./build
The download is generated in your browser with JSZip. Every file above is written under a root QAQ/ folder - real, runnable Python, not placeholders - then zipped and saved as QAQ.zip.
QAQ.zip
7 files · root folder QAQ/ · generated client-side
./deploy
Create an empty repository, then run these commands from inside the unzipped QAQ folder. Replace the placeholder with your repository URL.
Placeholder: replace https://github.com/USERNAME/qaq.git with your own repository URL.
01Create a repository first
gh repo create qaq --public
02Initialize and connect
git init && git remote add origin https://github.com/USERNAME/qaq.git git branch -M main
03Stage, commit, push
git add . && git commit -m "QAQ Network Suite: defensive network toolkit" git push -u origin main
./start
From unzip to the interactive menu in three steps. Python 3.10 or newer is all you need for the core tools.
$ unzip QAQ.zip && cd QAQ
$ python -m venv venv && source venv/bin/activate$ pip install -r requirements.txt
$ python qaq_cli.py --menu
Authorized targets only
Every tool is built for defensive work on systems you own or have explicit written permission to test. Unauthorized scanning is intrusive and often illegal. The scanners require an explicit authorization flag before they will run.
Conservative by default
Concurrency is bounded, probes are rate-limited and timeout-bound, and nothing scans an unowned network. No credential theft, no evasion of access controls, no destructive exploitation - and results are heuristics, not proof.