MSF RCP study materials
MSF RCP study resources

Covering a /22 in Twenty Hostile Hours

MSF RCP · Put your knowledge to work in context.

All case studies

Covering a /22 in Twenty Hostile Hours

The scope is the client's internal server range 172.16.8.0/22 - 1,022 addresses - reachable only from a jump host inside the data centre. The network team confirms ICMP echo is blocked across the server VLAN and that the core firewall rate-limits new TCP connections from any single source to 20 per second. The tester runs db_nmap -sS -p- 172.16.8.0/22; after six hours it is still running, 780 hosts remain unresolved, and the engagement window is three nights of six hours each. A follow-up services lists only 14 records, all from a hand-built targeted scan of three hosts run earlier. In parallel, a Nessus export flags "MS17-010: SMBv1 remote code execution" on 40 hosts, and the client wants a definitive list before dispatching patch crews on Saturday, because patching is change-controlled and a false positive costs a maintenance window.

1. Redesign the scanning approach to fit the window. Show the arithmetic that justifies the change.

Read the worked answer

Start with feasibility, because the arithmetic alone rejects the current plan. A full 65,535-port sweep of 1,022 hosts is roughly 67 million probes. At the 20-connection-per-second cap that is over 900 hours of wall clock even at perfect efficiency; the six-hour run had not covered a meaningful fraction. The scan was never going to finish - the error was choosing -p- for discovery rather than for confirmation.

The redesign is phased:

  1. Liveness without ICMP. ICMP echo is filtered, so use TCP-based discovery on ports likely to be open in a server VLAN (-PS22,80,443,445,3389), with -Pn retained only for sub-ranges where discovery returns nothing but a service is known to exist.
  2. Top-ports first. --top-ports 1000 against the full /22, with --max-rate 18 to stay under the firewall limit, --max-retries 1, and a per-host timeout. Tune --min-hostgroup upward so parallelism stays inside the rate cap.
  3. Depth on survivors. Only hosts with at least one open port get -p-, and only for the ports not already probed (-p- --exclude-ports from the first pass), again rate-limited.
  4. Persist as you go. db_nmap every phase into a named workspace so a window overrun does not lose the night's work.

Two adjustments worth flagging: if raw sockets are unavailable on the jump host, -sS silently degrades to a connect scan that burns full connections - check for the fallback. And NSE scripts on 1,000 hosts are what actually blow the time budget; run version detection with --version-intensity 2 during discovery and reserve heavy scripts for the confirmed shortlist.

2. Why do only 14 services persist in the database, and how do you make results durable and verifiable?

Read the worked answer

Nothing in the symptom implies the database is broken. Three other causes fit better, and they should be eliminated in this order.

The scan never completed. db_nmap commits results as they are discovered, so an aborted or still-running sweep leaves a partial record. The 780 unresolved hosts are consistent with a scan that had not reached most of the range; 14 services is what a real, if thin, partial result looks like.

Workspace mismatch. The 14 records came from the three-host manual scan, which was presumably run in a different workspace from the /22 sweep. workspace and hosts -a quickly confirm whether the sweep is writing somewhere else.

Backend not connected - less likely here, since records do exist, but db_status is a two-second check that rules it out.

Durability plan: run each phase into an explicitly named workspace, and keep nmap's -oX XML for every phase. XML is the audit artifact; the database is the working index. If a console or database is lost, db_import restores state and merges by address, so re-importing does not create duplicate hosts. Before each night ends, verify with hosts | wc -l and services -R that the record matches what was observed, and spool the console. The rule of thumb: if a finding cannot be reproduced from an artifact the client can be shown, it is not yet a finding.

3. The client wants a definitive MS17-010 list for 40 hosts before Saturday. What is a defensible validation plan?

Read the worked answer

A Nessus plugin hit is a candidate, not a confirmation, and the cost asymmetry matters here: a false positive wastes a change-controlled maintenance window, while a false negative leaves an exploitable host on the network. The plan must therefore produce a confidence statement, not just a yes/no list.

Step 1 - non-intrusive check across all 40. Run auxiliary/scanner/smb/smb_ms17_010 against the candidate list. It performs the specific protocol exchange used by the exploit's check logic and is far safer than running the exploit module. Any host for which the check is inconclusive (filtered, patched-but-SMBv1-enabled, hardened honeypot behaviour) goes on a separate list rather than being silently binned.

Step 2 - enrich with patch level. Where credentials exist, post/windows/gather/enum_patches on one reachable host gives build and hotfix data that confirms or contradicts the plugin. Build number alone is not proof - backported patches change the answer - but it separates the obviously-current hosts from the doubtful ones.

Step 3 - single-host exploitation, only with written approval. If the client needs proof of exploitability, choose one non-critical host, schedule a window, get written confirmation, and confirm monitoring coverage. Never fire an exploit that yields SYSTEM against 40 production servers to answer a patching question.

Step 4 - report in tiers. Confirmed vulnerable, likely vulnerable (check inconclusive), and not vulnerable, each with the probe used, the timestamp, and the residual uncertainty. Patch crews can act on tier one immediately and the client can accept the risk on the rest.