Improve evidence classification and compact CLI reporting
This commit is contained in:
1 parent
9dc7289652
commit
dda4f8563f
28 files changed
+945
-87
No files matched your search
@@ -86,7 +86,9 @@ rpcscope scan 10.10.10.0/24 --checks recommended --deep --authorised -o deep-new
|
||||
|
||||
Omitting `--checks` still runs enumeration only. Presets `exposure` and `info` can be combined with explicit checks. Inventory results never cause `NOT VULNERABLE` by themselves. Each check attempt retains its backend and evidence; contradictory results appear as `CONFLICT` in minimal output.
|
||||
|
||||
The current SMBGhost module tests dialect/compression support, PrintNightmare uses a driver-permission probe, and noPac uses ticket-size behavior. Positive results from these adapters are labelled `SUSPECTED` pending validation. The old NTLM reflection adapter is disabled because NetExec removed that module; it is listed as unsupported instead of silently appearing to run. These adapter assumptions follow the primary upstream [SMBGhost](https://github.com/Pennyw0rth/NetExec/blob/main/nxc/modules/smbghost.py), [PrintNightmare](https://github.com/Pennyw0rth/NetExec/blob/main/nxc/modules/printnightmare.py), [noPac](https://github.com/Pennyw0rth/NetExec/blob/main/nxc/modules/nopac.py), and [NTLM reflection](https://github.com/Pennyw0rth/NetExec/blob/main/nxc/modules/ntlm_reflection.py) implementations. Silence, access denial, and an unknown message format are inconclusive.
|
||||
The `smbghost` selector now performs one native, unauthenticated SMB2 negotiation instead of invoking NetExec's login-dependent heuristic. It parses the actual compression context, including frame bounds, response identity, dialect and algorithm array. The result is `EXPOSED[SMB3-COMPRESSION]` or `NOT-EXPOSED[SMB3-COMPRESSION]`, never a CVE or patch verdict. Patched servers may support compression. No compressed transform, exploit, login or remote write is sent. The wire format follows Microsoft's [negotiate request](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/e14db7ff-763a-4263-8b10-0c3944f52fc5) and [response](https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-smb2/63abf97c-0d09-47e2-88d6-6bfa552949a5) specifications. Its absolute deadline is at most five seconds, including fragmented reads; malformed replies/timeouts are unknown.
|
||||
|
||||
PrintNightmare's driver-permission probe and noPac's ticket-size heuristic remain `SUSPECTED` in saved reports (`REVIEW` in the compact CLI). They do not prove code execution. An explicit RPC bind denial is `skipped-access-denied`, not vulnerable or patched. NetExec's explicit exhausted-attempts Zerologon result is now recognized as a scoped, probabilistic negative; generic connection errors are not evidence that a host is not a DC. Several NetExec adapters use `on_login`, so credentialless means no supplied credentials, not guaranteed anonymous access. An attributed failed SMB login is shown as an authentication skip. There are no automatic credential guesses, payloads or unsafe retries. The removed NTLM reflection module remains disabled. See the upstream [PrintNightmare](https://github.com/Pennyw0rth/NetExec/blob/main/nxc/modules/printnightmare.py), [Zerologon](https://github.com/Pennyw0rth/NetExec/blob/main/nxc/modules/zerologon.py), and [noPac](https://github.com/Pennyw0rth/NetExec/blob/main/nxc/modules/nopac.py) implementations.
|
||||
|
||||
LongLogon is included in `--checks recommended` (12 checks total). It remains a precondition-only check and can also run separately:
|
||||
|
||||
@@ -119,24 +121,26 @@ Outputs include a one-line-per-reachable-host `report.txt`, detailed `report.jso
|
||||
Execution coverage and evidence certainty are separate. A completed heuristic check is `SUSPECTED`; an executed check without a reliable verdict is `UNKNOWN`. Both count as completed. Skips appear separately, for example `CHECKS: 9/9 SKIPPED: 2` for eleven selected checks. Only real failures, unfinished work, or interruption produce partial coverage. A skipped or uncertain check still prevents an all-selected-checks clean claim: `NOT VULNERABLE (SELECTED CHECKS)` requires explicit negative vulnerability results and successful collection, with no unresolved selected checks. RPC tags describe endpoint-mapper registrations; bindings have not been independently tested for reachability. Conflicting evidence is preserved in the detailed report.
|
||||
|
||||
```text
|
||||
192.0.2.10 (LAB) SUSPECTED: [CVE-2020-0796/SMBGHOST] EXPOSURE: [SMB-SIGNING-NOT-REQUIRED] PORTS: 135/open,445/open CHECKS: 9/9 SKIPPED: 2
|
||||
192.0.2.10 (LAB) CHECKED EXPOSURE: [SMB3-COMPRESSION] [SMB-SIGNING-NOT-REQUIRED] PORTS: 135/open,445/open CHECKS: 9/9 SKIPPED: 2
|
||||
192.0.2.20 CHECKED UNKNOWN: [MS17-010] PORTS: 135/open,445/open CHECKS: 1/1
|
||||
```
|
||||
|
||||
## Progress and performance
|
||||
|
||||
The default progress display goes to stderr and shows the active stage/reachable host, completed task count, and elapsed time. Dead addresses advance discovery totals silently and never enter a host-check pipeline. Completed checks keep a compact result line. A heartbeat updates the display during slow collectors. Redirected output uses stable lines without terminal escape codes; stdout contains only the final minimal host report. A completed scan with no reachable SMB/RPC hosts prints a summary without per-IP lines; that is not itself an error.
|
||||
The default CLI uses one updating progress bar on stderr and a compact final report on stdout. It does not print every start/finish event. Color is automatic on terminals; `--color never` or `NO_COLOR` disables it, and `--color always` forces it. Redirected compact progress emits only phase/final lines, never animation escapes. Discovery and audit have separately labelled phase percentages: finishing hundreds of dead targets does not imply the checks are almost finished. The audit denominator is established after live-host discovery; the bar is not an ETA. Dead addresses advance counts silently and never enter a host-check pipeline.
|
||||
|
||||
```text
|
||||
[0/3] START discovery (elapsed 0s)
|
||||
[1/3] DONE discovery success (0.3s) | 2 target(s)
|
||||
[1/3] START batch:ms17-010 (elapsed 0s)
|
||||
[2/3] DONE ms17-010 192.0.2.10 vulnerable (0.5s)
|
||||
[3/3] DONE ms17-010 192.0.2.20 not-vulnerable (0.4s)
|
||||
[3/3] SUMMARY check-batch complete (elapsed 1s) | ms17-010; 2 alive host(s)
|
||||
[3/3] SUMMARY scan complete (elapsed 1s) | 2 target(s); 0 collection note(s)
|
||||
[########--------] 50% audit [25/50] batch:ms17-010 | 12s
|
||||
192.0.2.10 (LAB-DC) VULN[MS17-010] EXPOSED[SMB3-COMPRESSION]
|
||||
192.0.2.20 (WS01) NOT-VULN[MS17-010] SKIP[access-denied:1] ERROR[rpcdump]
|
||||
```
|
||||
|
||||
`VULN` means a dedicated checker signature, not proof of remote code execution. `NOT-VULN` is negative for the named probe and identity only. `REVIEW` needs validation. `UNKNOWN` includes a short reason/count instead of repeating every CVE; `SKIP` shows unmet prerequisites; `ERROR` names the failing collection stage. A failed RPC dump no longer hides a separately successful check behind an unexplained per-host `PARTIAL` tag. Full coverage and all check evidence remain in `report.json`, `report.md`, and the uncolored `report.txt`. `--verbose` includes per-check evidence/collection notes; `--format full` restores the longer terminal host lines. `--progress auto` or `--progress plain` restores per-task progress.
|
||||
|
||||
Each external invocation and native check records duration in JSON; Markdown groups summed task time by stage (parallel task time is not wall-clock duration). Errors now retain a bounded diagnostic excerpt. A recognized local RPC-dump dependency/argument failure disables further queued copies of that collector; already running tasks finish and the stage remains explicitly skipped/failed. It does not disable checks or hide remote failures. This is not a general circuit breaker for access denial.
|
||||
|
||||
RPC dump must return parsed endpoints or an explicit empty inventory without a protocol error; a zero exit code alone is insufficient. A missing requested collector makes coverage partial. Conflicting check attempts remain in JSON, but show `CONFLICT` instead of a positive/clean verdict in reports and are excluded from the compact confirmed count. Optional signing is labelled `SIGNING-OPTIONAL`, not disabled signing.
|
||||
|
||||
Use `--progress plain` for log files or `--no-progress` for quiet operation. Lightweight TCP and NetExec inventory discovery use `--discovery-workers 256`, matching the reviewed NetExec thread default. `--jobs 8` limits heavier checks and host collectors separately. Each NetExec check batch contains at most `--jobs` live hosts (capped at 128 targets), with the same NetExec thread limit. Only one check batch runs at a time, avoiding multiplied/nested concurrency. Dedicated checks precede optional broad enumeration; native checks, optional MSF, RPC dump and finally `--deep` enum4linux run in bounded host pipelines.
|
||||
|
||||
`--timeout 120` bounds each collector or single-check batch. The five combined bind checks receive five check budgets in total; this is an invocation ceiling, not an independently enforced per-method deadline. `--discovery-timeout 600` bounds discovery separately. Output is spooled to disk; the runner actively stops a noisy collector at its next poll once output exceeds 16 MiB, retains bounded output, and marks the invocation partial.
|
||||
@@ -145,9 +149,9 @@ Use `--progress plain` for log files or `--no-progress` for quiet operation. Lig
|
||||
|
||||
The installed NetExec SMB help is inspected once and cached. Supported versions use `--no-admin-check` to avoid unnecessary Service Control Manager checks; none of our adapters needs an admin-only callback. Share enumeration uses legacy `--no-write-check` where supported, or current ACL-only defaults where `--file-write-check` is an explicit opt-in. RPCScope never enables file-write testing; unknown share semantics cause an explicit skip/error rather than a guessed flag. Existing filenames supplied as literal credentials are rejected because NetExec would treat them as credential lists.
|
||||
|
||||
Accuracy safeguards include host/module/port-indexed output, explicit negative signatures, caught-host-exception detection even on exit zero, and IPv4-only gating for the reviewed upstream MS17-010/SMBGhost adapters. Missing output never implies patched. Failed batches are retained as unknown/partial without replaying probes. Local socket-resource exhaustion is a scan failure, not thousands of supposedly dead hosts.
|
||||
Accuracy safeguards include host/module/port-indexed output, explicit negative signatures, caught-host-exception detection even on exit zero, and IPv4-only gating for the upstream MS17-010 adapter. The native SMB negotiation supports IPv4 and IPv6. Missing output never implies patched. Failed batches are retained as unknown/partial without replaying probes. Local socket-resource exhaustion is a scan failure, not thousands of supposedly dead hosts.
|
||||
|
||||
The offline 32-host `recommended` test reduces NetExec **check** process invocations from 352 to 28 while retaining twelve per-host check records. This measures orchestration work, not live throughput or CVE-detection accuracy. NetExec and the other external collectors are not installed in the development environment, so live version interoperability and network timing still require an authorized lab. A twelve-check audit plus RPC/optional deep inventory cannot be expected to take the same time as a bare `nxc smb` banner scan. See [the source review](docs/NETEXEC_REVIEW.md).
|
||||
The offline 32-host `recommended` test uses 24 NetExec **check** processes (six module groups, four batches each), plus native SMB negotiation and LongLogon checks, retaining twelve per-host check records. The prior all-NetExec orchestrator needed 352 check processes; the first batching version needed 28. This measures orchestration work, not live throughput or CVE-detection accuracy. NetExec and the other external collectors are not installed in the development environment, so live version interoperability and network timing still require an authorized lab. A twelve-check audit plus RPC/optional deep inventory cannot be expected to take the same time as a bare `nxc smb` banner scan. See [the source review](docs/NETEXEC_REVIEW.md).
|
||||
|
||||
Default discovery expands explicit IPs, CIDRs, DNS names, and UTF-8 target files, deduplicates them, and checks TCP/135 and TCP/445 independently. A host enters collection only if either port is open, retaining RPC-only systems. Closed and timed-out connections are completed reachability outcomes, not blanket partial coverage. For a reachable host, unavailable ports skip only dependent adapters; hosts with neither service reachable receive no collectors/checks. JSON retains all expanded addresses and discovery results. Files allow one IP/CIDR/hostname per line and `#` comments. Use `--connect-timeout 1` to tune connection probing and `--max-hosts 4096` to control the expansion cap. Discovery time is bounded by `--discovery-timeout`, including per-connection timeout clamping; unfinished probes remain distinguishable from completed timeouts. `--discovery smb` keeps an SMB-only workflow for environments where direct TCP probing is inappropriate. The Python `ScanConfig` API retains SMB-only discovery and isolated checks by default for compatibility; set `tcp_discovery=True, batch_checks=True, use_enum4linux=False` for the CLI's normal execution strategy.
|
||||
|
||||
|
||||
Reference in new issue
Block a user