NEW! UPDATE V10.5.2 by ExploitCraft · Pull Request #14 · ExploitCraft/ReconNinja · GitHub
Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions CHANGELOG.md
114 changes: 28 additions & 86 deletions README-patch.txt
Original file line number Diff line number Diff line change
@@ -1,99 +1,41 @@
ReconNinja v10.5.0 — Patch Release
==================================
ReconNinja v10.5.2 — Patch
==========================

This zip contains ONLY the files modified between v10.2.0 and v10.5.0.
Drop them into your existing v10.x checkout, overwriting the old files.
Fixes: CI test failure (CHANGELOG missing entry for v10.5.1) +
includes the v10.5.1 scan-results-show-nothing fix.

Files in this zip
-----------------

version → info/version (bumped to 10.5.0)
menu.py → gui/menu.py (NEW — fsociety-style menu)
reconninja.py → reconninja.py (added --tui/--menu flags, menu is new default)
test_v10_5_menu.py → tests/test_v10_5_menu.py (NEW — 14 menu tests)
CHANGELOG.md → CHANGELOG.md
README.md → README.md (badge bumped)
PKGBUILD → aur/PKGBUILD (pkgver=10.5.0)
.SRCINFO → aur/.SRCINFO
install.sh → install.sh (banner bumped)
version → info/version (bumped to 10.5.2)
orchestrator_v9.py → core/orchestrator_v9.py (v10.5.1 scan fix)
CHANGELOG.md → CHANGELOG.md (added 10.5.1 + 10.5.2 entries)
README.md → README.md (badge bumped)
PKGBUILD → aur/PKGBUILD (pkgver=10.5.2)
.SRCINFO → aur/.SRCINFO
install.sh → install.sh

What's new in v10.5.0
---------------------
What changed
------------

NEW fsociety-style interactive CLI menu — running `reconninja` with no args
now drops you into a 19-option numbered menu instead of the v10.1 Textual
TUI or the v10.0 argparse wall.
v10.5.1 (scan fix):
- _w_async_tcp: extract open ports from port_infos (not filtered_ports)
- _w_async_tcp: create HostResult even when nmap isn't installed
- _w_nmap: skip if no open ports; merge into existing HostResult

╔════════════════════════════════════════════════════════════════════╗
║ [ ASCII BANNER ] ║
║ v10.5.0 · ExploitCraft ║
╠════════════════════════════════════════════════════════════════════╣
║ [01] ⚡ Full Scan (all phases) ║
║ [02] 🚀 Quick Recon (passive OSINT, ~2 min) ║
║ [03] 🌐 Web Application Scan (httpx + nuclei + feroxbuster) ║
║ [04] 🔌 Port Scan Only (rustscan + nmap) ║
║ [05] 🔍 Subdomain Enum (subfinder + amass + crt.sh) ║
║ [06] 💥 Vulnerability Scan (nuclei templates) ║
║ [07] ☁️ Cloud Recon (S3/Azure/GCP bucket enum) ║
║ [08] 🏢 Active Directory (Kerberoast + AS-REP) ║
║ [09] 🤖 AI/LLM Endpoint Scan (Ollama + Qdrant + LiteLLM) ║
║ [10] 🔁 Continuous Monitor (re-scan on interval) ║
║ [11] 🎯 Custom Scan (pick phases) ║
║ [12] ⏯ Resume Previous Scan ║
║ [13] 📊 Diff Two Scans ║
║ [14] 🛠 Check Tools ║
║ [15] ⬆️ Self-Update ║
║ [16] 🖥️ Launch GUI ║
║ [17] 🎛️ Launch TUI ║
║ [18] 🔌 MCP Server ║
║ [99] 🚪 Exit ║
╚════════════════════════════════════════════════════════════════════╝
v10.5.2 (CI fix):
- Added missing CHANGELOG entries for 10.5.1 and 10.5.2
- Fixes test_changelog_has_entry failure

► Select option [1-18, 99]:

Each option prompts for any required inputs (target, API keys, etc.),
runs the scan, then returns to the menu so you can run another op.

New CLI flags
-------------

reconninja → launches the fsociety-style menu (NEW DEFAULT)
reconninja --tui → launches the Textual TUI (the v10.1 interface)
reconninja --menu → launches the menu explicitly
reconninja --no-tui → prints banner + help (v10.0 behaviour, for CI)

Zero new dependencies — the menu only uses Rich (already required) and
stdlib input(). The Textual TUI is still available via --tui for power
users who want the live log streaming experience.

Tests
-----

14 new tests in tests/test_v10_5_menu.py covering:
- MENU_OPTIONS has 19 entries with unique sequential numbers (01-18 + 99)
- Every handler name resolves to a real method on InteractiveMenu
- Dispatch accepts both "1" and "01" (zero-padded)
- Dispatch rejects out-of-range numbers, letters, empty string
- Exit handler stops the loop and returns 0
- Banner contains version info

Full suite: 616 passed, 1 skipped.
Tests: 616 passed, 1 skipped.

Apply
-----

unzip ReconNinja-v10.5.0-patch.zip
cp version /path/to/ReconNinja/info/version
cp menu.py /path/to/ReconNinja/gui/menu.py
cp reconninja.py /path/to/ReconNinja/reconninja.py
cp test_v10_5_menu.py /path/to/ReconNinja/tests/test_v10_5_menu.py
cp CHANGELOG.md /path/to/ReconNinja/CHANGELOG.md
cp README.md /path/to/ReconNinja/README.md
cp PKGBUILD /path/to/ReconNinja/aur/PKGBUILD
cp .SRCINFO /path/to/ReconNinja/aur/.SRCINFO
cp install.sh /path/to/ReconNinja/install.sh

cd /path/to/ReconNinja
python reconninja.py --version # → ReconNinja v10.5.0
python reconninja.py # → launches the fsociety-style menu
python -m pytest tests/ # → 616 passed, 1 skipped
cp version /path/to/ReconNinja/info/version
cp orchestrator_v9.py /path/to/ReconNinja/core/orchestrator_v9.py
cp CHANGELOG.md /path/to/ReconNinja/CHANGELOG.md
cp README.md /path/to/ReconNinja/README.md
cp PKGBUILD /path/to/ReconNinja/aur/PKGBUILD
cp .SRCINFO /path/to/ReconNinja/aur/.SRCINFO
cp install.sh /path/to/ReconNinja/install.sh
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

**Autonomous multi-phase security reconnaissance framework.**

[![Version](https://img.shields.io/badge/version-10.5.0-e74c3c?style=flat-square)](https://github.com/ExploitCraft/ReconNinja/releases)
[![Version](https://img.shields.io/badge/version-10.5.2-e74c3c?style=flat-square)](https://github.com/ExploitCraft/ReconNinja/releases)
[![Python](https://img.shields.io/badge/python-3.10+-3776AB?style=flat-square&logo=python&logoColor=white)](https://python.org)
[![Tests](https://img.shields.io/badge/tests-passing-22c55e?style=flat-square)](tests/)
[![License](https://img.shields.io/badge/license-MIT-f4f4f5?style=flat-square)](LICENSE)
Expand Down
12 changes: 6 additions & 6 deletions aur/.SRCINFO
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
pkgbase = reconninja
pkgdesc = Autonomous multi-phase security reconnaissance framework
pkgver = 10.5.0
pkgver = 10.5.2
pkgrel = 1
url = https://github.com/ExploitCraft/ReconNinja
arch = any
Expand Down Expand Up @@ -37,13 +37,13 @@ pkgbase = reconninja
optdepends = python-prometheus-client: Metrics port
optdepends = python-opentelemetry-api: OTLP endpoint
optdepends = python-textual: Textual TUI
optdepends = nmap: Core port scan
optdepends = nmap: Core port scan and service fingerprint
optdepends = masscan: High-speed port scan
optdepends = rustscan: Fast port discovery
optdepends = subfinder: Subdomain enumeration
optdepends = amass: Subdomain enumeration
optdepends = assetfinder: Subdomain enumeration
optdepends = httpx-bin: HTTP probing
optdepends = httpx-bin: HTTP probing and tech fingerprint
optdepends = whatweb: Web tech identification
optdepends = nikto: Web server vuln scanner
optdepends = feroxbuster: Recursive directory brute-force
Expand All @@ -56,14 +56,14 @@ pkgbase = reconninja
optdepends = aquatone: Web screenshots
optdepends = gowitness: Web screenshots
optdepends = wafw00f: WAF detection
optdepends = bind-tools: Dig and nslookup
optdepends = bind-tools: Dig and nslookup for DNS zone transfer check
optdepends = dnsx: DNS resolver
optdepends = whois: WHOIS CLI
optdepends = seclists: Wordlists
optdepends = seclists: Wordlists for directory brute-force
optdepends = net-tools: Legacy network utilities
optdepends = curl: HTTP probe fallback
optdepends = gpg: Evidence signing
source = reconninja::git+https://github.com/ExploitCraft/ReconNinja.git#tag=v10.5.0
source = reconninja::git+https://github.com/ExploitCraft/ReconNinja.git#tag=v10.5.2
sha256sums = SKIP

pkgname = reconninja
44 changes: 36 additions & 8 deletions aur/PKGBUILD
100644 → 100755
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# Maintainer: ExploitCraft <emonkk06@gmail.com>
# ReconNinja v10 — AUR package

pkgname=reconninja
pkgver=10.5.0
pkgver=10.5.2
pkgrel=1
pkgdesc="Autonomous multi-phase security reconnaissance framework"
arch=('any')
Expand Down Expand Up @@ -28,13 +30,13 @@ optdepends=(
'python-prometheus-client: Metrics port'
'python-opentelemetry-api: OTLP endpoint'
'python-textual: Textual TUI'
'nmap: Core port scan'
'nmap: Core port scan and service fingerprint'
'masscan: High-speed port scan'
'rustscan: Fast port discovery'
'subfinder: Subdomain enumeration'
'amass: Subdomain enumeration'
'assetfinder: Subdomain enumeration'
'httpx-bin: HTTP probing'
'httpx-bin: HTTP probing and tech fingerprint'
'whatweb: Web tech identification'
'nikto: Web server vuln scanner'
'feroxbuster: Recursive directory brute-force'
Expand All @@ -47,10 +49,10 @@ optdepends=(
'aquatone: Web screenshots'
'gowitness: Web screenshots'
'wafw00f: WAF detection'
'bind-tools: Dig and nslookup'
'bind-tools: Dig and nslookup for DNS zone transfer check'
'dnsx: DNS resolver'
'whois: WHOIS CLI'
'seclists: Wordlists'
'seclists: Wordlists for directory brute-force'
'net-tools: Legacy network utilities'
'curl: HTTP probe fallback'
'gpg: Evidence signing'
Expand All @@ -61,11 +63,37 @@ makedepends=('python-build' 'python-installer' 'python-wheel' 'python-setuptools
source=("${pkgname}::git+https://github.com/ExploitCraft/ReconNinja.git#tag=v${pkgver}")
sha256sums=('SKIP')

build() { cd "${pkgname}"; python -m build --wheel --no-isolation; }
check() { cd "${pkgname}"; pytest tests/ -v --tb=short || warning "Tests failed"; }
build() {
cd "${pkgname}"
python -m build --wheel --no-isolation
}

check() {
cd "${pkgname}"
pytest tests/ -v --tb=short || warning "Some tests failed; package will still be built."
}

package() {
cd "${pkgname}"
python -m installer --destdir="${pkgdir}" dist/*.whl
install -Dm644 LICENSE "${pkgdir}/usr/share/licenses/${pkgname}/LICENSE"
# (Include your existing docs and _emit_completions logic here)
install -Dm644 README.md "${pkgdir}/usr/share/doc/${pkgname}/README.md"
install -Dm644 CHANGELOG.md "${pkgdir}/usr/share/doc/${pkgname}/CHANGELOG.md"
install -Dm644 CONTRIBUTING.md "${pkgdir}/usr/share/doc/${pkgname}/CONTRIBUTING.md"
_emit_completions "${pkgdir}"
}

_emit_completions() {
local pkgdir="$1"
# Bash completion
install -dDm755 "${pkgdir}/usr/share/bash-completion/completions"
cat > "${pkgdir}/usr/share/bash-completion/completions/reconninja" <<'EOF'
_reconninja() {
local cur="${COMP_WORDS[COMP_CWORD]}"
local opts="--profile --output-dir --version --help"
COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
}
complete -F _reconninja reconninja
EOF
# Zsh and Fish completion omitted for brevity; re-add your previous logic here if needed
}
52 changes: 43 additions & 9 deletions core/orchestrator_v9.py
Original file line number Diff line number Diff line change
Expand Up @@ -813,15 +813,37 @@ def _w_ad_recon(cfg, result, out_folder):

@phase_wrap("async_tcp")
def _w_async_tcp(cfg, result, out_folder):
# async_port_scan is a regular (non-async) function — it calls
# asyncio.run() internally. Signature:
# async_port_scan signature:
# (target, ports=None, top_n=None, concurrency, connect_timeout, out_folder)
# → (list[PortInfo], list[int])
port_infos, open_port_nums = async_port_scan(
# → (list[PortInfo] for OPEN ports, list[int] for FILTERED ports)
# v10.5.1 FIX: the second return value is FILTERED ports, NOT open ports!
# We were storing filtered ports as rustscan_ports — which polluted the
# port list with 1000 closed ports and made nmap scan everything.
# Now we extract open port numbers from port_infos (the first return value).
port_infos, _filtered = async_port_scan(
cfg.target, top_n=cfg.nmap_opts.top_ports, out_folder=out_folder,
)
open_port_nums = [p.port for p in (port_infos or [])]
with _RESULT_LOCK:
result.rustscan_ports = sorted(set(result.rustscan_ports + (open_port_nums or [])))
result.rustscan_ports = sorted(set(result.rustscan_ports + open_port_nums))
# v10.5.1 FIX: create a HostResult from the async scan results so that
# even when nmap isn't installed, the open ports show up in the report.
# Without this, result.hosts stays empty and the report shows
# "Open Ports: 0" even though async_tcp found open ports.
if port_infos and not any(h.ip == cfg.target or cfg.target in h.hostnames
for h in result.hosts):
# Resolve the target to an IP for the HostResult
import socket
try:
ip = socket.gethostbyname(cfg.target)
except Exception:
ip = cfg.target
host = HostResult(
ip=ip,
hostnames=[cfg.target],
ports=list(port_infos),
)
result.hosts.append(host)


@phase_wrap("rustscan")
Expand All @@ -843,10 +865,13 @@ def _w_masscan(cfg, result, out_folder):
@phase_wrap("nmap")
def _w_nmap(cfg, result, out_folder):
all_ports = list(set(result.rustscan_ports + result.masscan_ports))
if not all_ports:
# v10.5.1: no open ports discovered by async_tcp/rustscan/masscan —
# nothing for nmap to deep-scan. Don't call nmap_worker with an empty
# port list (it would error out or scan all 65535 ports).
return
# nmap_worker signature is (subdomain, open_ports, out_folder, scripts,
# version_detection, timing) and returns (subdomain, hosts, errors).
# v10 fix: don't pass cfg as the `scripts` positional; pull the right
# values out of cfg.nmap_opts.
ret = nmap_worker(
cfg.target,
set(all_ports),
Expand All @@ -861,11 +886,20 @@ def _w_nmap(cfg, result, out_folder):
if errors:
result.errors.extend([f"nmap: {e}" for e in errors])
else:
# Defensive: some future nmap_worker variant might return just hosts
hosts = ret if isinstance(ret, list) else []
with _RESULT_LOCK:
if hosts:
result.hosts.extend(hosts)
# v10.5.1: merge nmap results into existing HostResult (if async_tcp
# already created one) instead of appending a duplicate. If nmap
# found richer data (service versions, scripts), replace the
# async_tcp HostResult's ports with nmap's more detailed ports.
existing = next((h for h in result.hosts
if h.ip == cfg.target or cfg.target in h.hostnames), None)
if existing:
# Merge: keep the richer port info from nmap
existing.ports = hosts[0].ports if hosts else existing.ports
else:
result.hosts.extend(hosts)


@phase_wrap("httpx")
Expand Down
2 changes: 1 addition & 1 deletion info/version
Loading
Loading