SAMPLE DELIVERABLE · illustrative data only. Organisation names, IP addresses, subscription/tenant IDs and all other identifiers are fictional placeholders (Contoso & RFC 5737 documentation ranges) and refer to no real client or infrastructure.
Fig. 01 · External exposure · v2 (post-active assessment) thinsky.com

Client exposure brief · Contoso Payments

External exposure, confirmed by direct testing.

v2 supersedes the passive-only v1 by adding active probing of the client's nine public Azure IPs. Two findings escalated to Critical, four servers confirmed correctly hardened, every “ambiguous” v1 result resolved.

Assessment date
2026-05-14
Method
Passive + active
Scope
9 public IPs · Azure estate
Active scan source
198.51.100.50
Scan window
14:07–14:13 UTC−4
Toolchain
nmap 7.99 · dig 9.10 · openssl 3 · curl

This report is an exposure assessment — it shows the client what is currently visible and reachable from the public internet. It does not estimate effort, schedule remediation work, or commit to dates. Sequencing, owners, and timeline will be defined in a separate Statement of Work.

§ 0 · Change notes vs v1

From ambiguous to confirmed.

v1 was built entirely on third-party intelligence sources (Shodan, RDAP, Mnemonic PassiveDNS, crt.sh) and shipped with caveats about what passive sources could not verify. v2 supersedes v1 by adding active probing — packets sent directly from the assessor's source IP to the client's nine in-scope IPs — resolving every “ambiguous” v1 finding into either confirmed-bad or confirmed-good.

v1 ID v1 severity v2 severity Why
INFRA-PORT-01-A
DCs port 53
High Critical dig google.com @<DC> returned qr rd ra flags + 6 valid Google A records on both DCs. They are not just “exposed on port 53” — they are actively answering recursive DNS queries from anywhere on the public internet. Textbook abuse pattern for DNS amplification DDoS reflectors.
INFRA-PORT-01-B
VPN GW diag ports
Medium Critical Active scan revealed PIP1 (203.0.113.21) exposes six ports — 7999, 8081, 8443, 10001, 10002, 20000 — not the single port 8081 that Shodan saw. All six respond with a Windows Communication Foundation (WCF) default page served by kernel-mode http.sys. PIP2 (203.0.113.22) exposes only 8083. The active-active pair is not equivalent.
INFRA-SHADOW-01
4 “no info” IPs
Low (ambiguous) Resolved — clean Active TCP-connect scan of all 1000 top ports against ACC-001, ADM-001, DBSvr-001, LANSvr-001 returned 999 filtered + 0 open. NSGs are correctly drop-by-default on all four. Moved to § 4 What's working.
INFRA-CLOUD-02
Bastion present
Info Confirmed Active TLS handshake confirmed Bastion serving on port 443 with 2-instance Standard SKU deployment. Moved to § 4 What's working.
SOC notice
for the client

Nine IPs scanned in parallel from a single source IP at nmap -T4 timing (~300 packets/sec aggregate). If the client runs Microsoft Defender for Cloud, Sentinel, or Azure Network Watcher with traffic analytics, alerts should have fired in the 2026-05-14 14:07–14:13 UTC−4 window with source 198.51.100.50. No exploit-class scripts. No vuln-category NSE scripts. No service should have been disrupted.

§ 1 · Executive summary — for the CEO

Two things at the highest severity. One significant piece of good news.

Two issues at Critical. Four servers the passive sweep could not characterise have been confirmed by direct testing as correctly hardened — the firewall is doing its job on all four.

Critical · #1

Your domain controllers are functioning as open DNS servers for the entire internet.

This is no longer a suspicion — confirmed by direct test. We asked DCSvr-001 and DCSvr-002 to look up google.com for us. Both did, and returned the correct answers. This is the single behaviour that DNS-abuse mitigation projects (Spamhaus, Open Resolver Project, Shadowserver) scan for daily — your IPs will end up on those public lists shortly if they aren't already. Once listed, attackers will use your servers as a free amplifier to attack other people from your IP address. Your bandwidth bill goes up, your IP reputation collapses, and your own outbound email starts bouncing.

Critical · #2

Your Azure VPN Gateway is leaking a Microsoft-internal management interface to the public internet.

The active scan found six unusual ports on one of the gateway's two public IPs — all six respond with a Microsoft .NET service framework page. The other public IP shows only one port. This is highly atypical: the two public IPs of a VPN Gateway pair are supposed to be functionally identical. Microsoft owns and operates this software (you cannot directly close the ports), but you can — and should — open a support ticket with Microsoft presenting the evidence and asking why the management plane is internet-reachable.

Risk dashboard

Critical 2 Specific, exploitable weaknesses confirmed by direct testing.
High 0
Medium 1 Significant weakness that warrants follow-up.

Plus three positive findings (correctly hardened posture confirmed) — see § 4 What's working.

Reading list

  1. Critical   INFRA-PORT-01-A — Open recursive DNS resolver on both domain controllers. § 3.1
  2. Critical   INFRA-PORT-01-B — Six ports of WCF / .NET surface on VPN Gateway PIP1. § 3.2
  3. Medium   INFRA-IP-01 — Two of your IPs were used by other Microsoft customers in the recent past. § 3.3
  4. What's working — § 4

§ 2 · Findings summary

Three findings — verified against nine assets.

ID Severity Title Asset
INFRA-PORT-01-A Critical Open recursive DNS resolver — both domain controllers respond to internet DNS queries 203.0.113.11 (DCSvr-001)
203.0.113.12 (DCSvr-002)
INFRA-PORT-01-B Critical Windows Communication Foundation service stack reachable on six ports of VPN Gateway PIP1; asymmetric to PIP2 203.0.113.21 (AzureVPN-PIP1)
INFRA-IP-01 Medium IP recycling — two client public IPs were previously used by other Microsoft customers 203.0.113.31 (ACC-001)
203.0.113.22 (AzureVPN-PIP2)

§ 3 · Findings — detail

Three weaknesses, each reproducible from the cited evidence.

§ 3.1 · INFRA-PORT-01-A Critical

Open recursive DNS resolver on both domain controllers.

Status. Escalated from v1 High (passive evidence of port 53 open) to Critical (active confirmation of recursive resolution behaviour).

Active evidence — DCSvr-001 (203.0.113.11)

$ dig +time=5 +tries=1 google.com A @203.0.113.11
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 16318
;; flags: qr rd ra; QUERY: 1, ANSWER: 6, AUTHORITY: 0, ADDITIONAL: 1
;; ANSWER SECTION:
google.com.   86  IN  A  172.253.122.101
google.com.   86  IN  A  172.253.122.113
google.com.   86  IN  A  172.253.122.100
google.com.   86  IN  A  172.253.122.139
google.com.   86  IN  A  172.253.122.102
google.com.   86  IN  A  172.253.122.138
;; Query time: 23 msec

Active evidence — DCSvr-002 (203.0.113.12)

$ dig +time=5 +tries=1 google.com A @203.0.113.12
;; flags: qr rd ra; QUERY: 1, ANSWER: 6, AUTHORITY: 0, ADDITIONAL: 1
;; ANSWER SECTION:
google.com.   120  IN  A  172.253.62.138    ... (5 more rows)
;; Query time: 28 msec

Recursion proof — random subdomain

Proves the DC is recursing, not just returning a cached entry.

$ dig +time=5 +tries=1 a3f9b1c2d0e4f5a8.example.com A @203.0.113.11
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 5635
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 1, ADDITIONAL: 1
;; Query time: 35 msec

A non-recursive server would have returned REFUSED. This server returned NOERROR with an AUTHORITY section pointing at the parent zone — proving it walked the DNS hierarchy on our behalf.

Why critical

This is the textbook “open recursive resolver” pattern. The IPs will be picked up by:

  • Open Resolver Project (openresolverproject.org) — public list, scraped by attackers.
  • Shadowserver — distributed daily reports to network owners and CSIRTs.
  • Spamhaus DROP / EDROP — if the IPs get used in amplification, they land here, and any mail server using Spamhaus will reject your outbound email.
  • DNS-amplification botnets — once on the lists, attackers point UDP-spoofed queries with large ANY responses at your IP. Your IP is the source of the attack from the victim's perspective; you eat the bandwidth.

Remediation guidance

  1. Snapshot first.
    az snapshot create --resource-group <rg> --name DCSvr-001-pre-fix-$(date +%Y%m%d) --source <osdisk-id>
    az snapshot create --resource-group <rg> --name DCSvr-002-pre-fix-$(date +%Y%m%d) --source <osdisk-id>
  2. Identify and replace the offending NSG rules.

    In Azure Portal: each DC VM → Networking → Inbound port rules → look for any rule with destination port 53 and source * / Internet / 0.0.0.0/0. Replace with a rule allowing only your trusted CIDRs (on-prem office, VPN client pool, internal VNet), then add an explicit Deny on Internet→53 below it.

    $nsg = Get-AzNetworkSecurityGroup -ResourceGroupName <rg> -Name <nsg-of-DCSvr-001>
    $nsg | Set-AzNetworkSecurityRuleConfig -Name "Allow-DNS-Internal" -Access Allow `
      -Protocol "*" -Direction Inbound -Priority 100 `
      -SourceAddressPrefix @("10.0.0.0/8","172.16.0.0/12","<on-prem-CIDR>","<VPN-pool>") `
      -SourcePortRange "*" -DestinationAddressPrefix "*" -DestinationPortRange "53"
    $nsg | Set-AzNetworkSecurityRuleConfig -Name "Deny-DNS-Internet" -Access Deny `
      -Protocol "*" -Direction Inbound -Priority 110 `
      -SourceAddressPrefix "Internet" -SourcePortRange "*" `
      -DestinationAddressPrefix "*" -DestinationPortRange "53"
    $nsg | Set-AzNetworkSecurityGroup
    # Repeat for DCSvr-002
  3. Disable recursion for non-trusted clients on the DC itself (via Bastion).
    # Hard option — disables recursion entirely (use if no internet-bound clients need it)
    Set-DnsServerRecursion -Enable $false
    
    # Soft option — keep recursion but only for trusted scope
    Set-DnsServerRecursionScope -Name "." -EnableRecursion $false
    Add-DnsServerRecursionScope -Name "InternalOnly" -EnableRecursion $true
    Set-DnsServerQueryResolutionPolicy -Name "InternalRecursion" `
      -Action ALLOW -ServerInterfaceIP "EQ,<DC-internal-IP>" `
      -ApplyOnRecursion -RecursionScope "InternalOnly"
    
    # Always enable the global query block list
    Set-DnsServerGlobalQueryBlockList -Enable $true -List "wpad","isatap"
  4. Patch verification.
    Get-HotFix | Where-Object { $_.HotFixID -eq 'KB4569509' }   # SIGRed
    Get-HotFix | Sort-Object InstalledOn -Descending | Select -First 5
  5. Verify externally.

    Re-run from any internet-connected host (or ask the assessor):

    dig +time=5 +tries=1 google.com A @203.0.113.11
    dig +time=5 +tries=1 google.com A @203.0.113.12

    Expected new behaviour: connection timed out or REFUSED. If qr rd ra flag still appears with answer rows, the change did not take effect.

Long-term
architectural option

Migrate internal DNS to Azure DNS Private Resolver. The DCs lose their need for public IPs entirely, closing this finding class permanently.

§ 3.2 · INFRA-PORT-01-B Critical

VPN Gateway PIP1 exposes a Windows Communication Foundation service stack on six ports.

Status. Escalated from v1 Medium (one diagnostic port observed via Shodan) to Critical (six ports of WCF / .NET service surface confirmed via active probing).

Active evidence — AzureVPN-PIP1 (203.0.113.21)

PORT      STATE SERVICE                          NOTES
7999/tcp  open  http (Microsoft-HTTPAPI/2.0)     WCF default page, "Endpoint not found"
8081/tcp  open  https (XML response, 1565 bytes) WCF service template (HTTP 200)
8443/tcp  open  https (Microsoft-HTTPAPI/2.0)    Valid TLS cert, ALPN h2/http1.1
                                                 Subject: 3a4b5c6d-4444-4d55-af66-3007b882cd10.gwt.cloudapp.net
                                                 Issuer:  CN=CCME G1 TLS RSA 2048 SHA256 2049 CUS CA 01
                                                 Valid:   2026-02-27 → 2027-02-23
                                                 Body:    "Windows® Communication Foundation service.
                                                          Metadata publishing for this service is currently disabled."
10001/tcp open  https (HTTP 200, 6437 bytes)     Same WCF body
10002/tcp open  https (HTTP 200, 6437 bytes)     Same WCF body
20000/tcp open  https (HTTP 200, 6437 bytes)     Same WCF body

For comparison — PIP2 (203.0.113.22) shows one port

PORT     STATE SERVICE
8083/tcp open  us-srv (closes connection on direct request, no banner)

The asymmetry is the smoking gun

Both PIPs are bound to the same Azure VPN Gateway resource (3a4b5c6d-4444-4d55-af66-3007b882cd10). In an active-active VPN Gateway deployment, both PIPs should be functionally equivalent — same service surface, same NSG, same gateway image. The fact that PIP1 exposes six management/.NET ports and PIP2 exposes one means either:

  1. Microsoft's gateway image is configured asymmetrically — one PIP is the “primary management” PIP and the other is the “client traffic” PIP, contrary to Azure documentation that says active-active means equivalent.
  2. An NSG (yours or Microsoft's) is filtering PIP2 but not PIP1.
  3. A failover event has left PIP1 in a different state than PIP2 — possibly stuck mid-reconfiguration.

Any of these is a Microsoft support case.

Why critical

Six ports of WCF service surface on a customer-facing public IP with the kernel-mode Microsoft-HTTPAPI/2.0 (http.sys) underneath:

  • http.sys CVE class. MS15-034 (CVE-2015-1635) is a remote pre-auth RCE in http.sys that affected every Windows server with a kernel-mode HTTP listener. Subsequent CVEs have appeared in the same code path (CVE-2021-31166, CVE-2022-21907). Six exposed http.sys listeners is six attack surfaces.
  • WCF deserialisation CVEs. WCF has a long history of unsafe deserialisation (CVE-2020-0646 NetDataContractSerializer, multiple others). The “Metadata publishing is currently disabled” body is the WCF default — it does not mean the underlying SOAP/REST endpoints are absent; it means metadata exchange (the WSDL) is hidden. The service is still listening.
  • You cannot patch this from your side. This is the gateway appliance OS image. Microsoft owns the patch cadence.
  • Spectre of customer-managed misconfiguration. Even if Microsoft's intent is to expose only documented IKE / IPsec ports, the asymmetry between PIP1 and PIP2 suggests something on your side or theirs is different between the two — and the difference is in your favour to investigate.

Remediation guidance

  1. Document the asymmetry in an Azure support case.

    Suggested title:

    Azure VPN Gateway PIPs 203.0.113.21 and 203.0.113.22 show asymmetric port exposure — PIP1 exposes ports 7999, 8081, 8443, 10001, 10002, 20000 (Microsoft-HTTPAPI/2.0 + WCF “Endpoint not found”); PIP2 exposes only 8083. Both are bound to the same gateway resource 3a4b5c6d-4444-4d55-af66-3007b882cd10. Please confirm: (a) is this asymmetry intended? (b) is the WCF management plane on PIP1 reachable from public internet by design or by misconfiguration? (c) confirm patch level of http.sys against MS15-034 / CVE-2021-31166 / CVE-2022-21907; (d) if not intended, how do we suppress?

    Attach: nmap output, TLS cert details for 8443, the HTML body returned by 7999 / 8081 / 10001 / 10002 / 20000, and this report ID.

    Severity in Microsoft's case-grading scheme: B (Moderate) at minimum; bump to A (Critical) if Microsoft pushes back or does not substantively reply — the active-active misalignment can also affect VPN failover, which is a production risk.

  2. Confirm Gateway SKU and image vintage.
    az network vnet-gateway show --resource-group <rg> --name <vpn-gw-name> \
      --query "{sku:sku, generation:vpnGatewayGeneration, type:gatewayType, vpnType:vpnType, activeActive:activeActive, enableBgp:enableBgp}"

    Acceptable: VpnGw1 and above, vpnGatewayGeneration: Generation2.
    Not acceptable: Basic, Generation1. If on Basic, plan a migration to VpnGw1AZ or higher (zone-redundant) — the migration will cause a brief gateway re-image which may also clear the asymmetric state.

  3. Confirm the cert.

    The TLS cert on 8443 is dated 2026-02-27 → 2027-02-23 and chained to CCME G1 TLS RSA 2048 SHA256 2049 CUS CA 01 (Microsoft Cloud-Managed Endpoint). Consistent with a recently re-keyed gateway. If the cert pre-dates a known Microsoft VPN Gateway maintenance event, that event may have re-introduced the asymmetric exposure — note the date in the support ticket.

  4. Compensating control.

    Your customer NSG cannot directly close gateway-side listeners, but you can document the exposure and watch the NSG flow logs on the gateway subnet for any actual connection attempts to those ports. If anything other than known Microsoft IPs hits 7999 / 8081 / 8443 / 10001 / 10002 / 20000, escalate.

§ 3.3 · INFRA-IP-01 Medium

IP recycling — two client IPs were previously used by other Microsoft customers.

Two of the client's public IPs were previously used by other Microsoft Azure customers per Mnemonic PassiveDNS:

  • 203.0.113.31 (currently labelled ACC-001) — historically pgflexserver0748291630551207.postgres.database.azure.com (last seen 2023-08-20) and azuregateway-1a2b3c4d-0a0a-4bcc-85dd-966d1ee82d76-b7788c99d0e1.vpn.azure.com (last seen 2020-10-15).
  • 203.0.113.22 (currently labelled AzureVPN-PIP2) — historically ext.quietmeadow-2b7c1d09.eastus.azurecontainerapps.io, scm.quietmeadow-2b7c1d09…, internal.quietmeadow-2b7c1d09… (last seen 2024-10-25).

Why this matters

Azure recycles public IPs across tenants. Any allowlists, OAuth redirect URIs, monitoring probes, callback URLs, or HSTS-pinned client apps that the previous tenants configured to point at these IPs are now sending traffic to your servers. The risk is bidirectional: stale inbound traffic from the previous tenants' partners may show up as false positives in your monitoring, and when you eventually release these IPs, the next tenant will receive the traffic that was destined for you.

Active scan partial confirmation

The historic Postgres surface on 203.0.113.31 is closed (port 5432 returned filtered); the historic ACA HTTP surface on 203.0.113.22 is also no longer responding on 80 / 443. So the recycled-tenant services are not currently reachable through the client's IPs — but DNS / firewall-allowlist references at third parties may still be active.

Remediation guidance

  1. Audit current behaviour on the recycled IPs.

    From a VM inside the same VNet (does not touch the public IP):

    Test-NetConnection -ComputerName <internal-ip-of-ACC-001> -Port 5432
    Test-NetConnection -ComputerName <internal-ip-of-AzureVPN-PIP2-VM> -Port 80
    Test-NetConnection -ComputerName <internal-ip-of-AzureVPN-PIP2-VM> -Port 443

    Each should TimedOut or report Blocked unless those services are intentionally part of your environment.

  2. Use Azure Public IP Prefix for IPs that need stability.

    Where an IP genuinely needs to outlive a single VM (e.g. for partner allowlists), allocate from a Microsoft.Network/publicIPPrefixes resource so the prefix is reserved to your subscription and rotating the VM behind it does not change the IP.

    az network public-ip prefix create \
      --resource-group <rg> --name contoso-stable-ips \
      --length 28 --location <region>
    az network public-ip create --resource-group <rg> --name contoso-app-pip1 \
      --public-ip-prefix contoso-stable-ips
  3. Document the recycling pattern in the DR runbook.

    When investigating any unusual traffic on these IPs, the on-call engineer should know to check historic Mnemonic PassiveDNS data first to rule out “stale traffic from a previous tenant.”

§ 4 · What's working — positive findings

What we didn't find is as important as what we did.

These items were either confirmed correct by active testing, or confirmed not to constitute external exposure. They are listed so the client has a complete picture of their posture.

§ 4.1 · was INFRA-SHADOW-01 Resolved

Four customer VMs are correctly hardened.

Active TCP-connect scan of the top-1000 ports against all four “no info” IPs returned 999 filtered + 0 open:

ACC-001    203.0.113.31  : Not shown: 999 filtered tcp ports (no-response)
ADM-001    203.0.113.32  : Not shown: 999 filtered tcp ports (no-response)
DBSvr-001  203.0.113.33 : Not shown: 999 filtered tcp ports (no-response)
LANSvr-001 203.0.113.34 : Not shown: 999 filtered tcp ports (no-response)

filtered (not closed) means the NSG silently dropped the SYN packet — no TCP RST returned. This is the textbook signature of a deny-by-default firewall rule. Your team has done the right thing routing administrative access through Azure Bastion and not punching individual VM holes.

Caveats. nmap top-1000 covers the most common 1000 ports; a service bound to an unusual port (e.g. 33893, 18080) would not have been probed. UDP services were not scanned.

§ 4.2 · was INFRA-CLOUD-02 Confirmed

Azure Bastion is in place and serving correctly.

Active evidence (203.0.113.41 = vNet-001-IPv4 = Azure Bastion):

PORT    STATE SERVICE  VERSION
443/tcp open  ssl/http Apache Tomcat (language: en)
| ssl-cert: Subject: commonName=bst-5e6f7a8b-5555-4e66-b077-4118c993de21.bastion.azure.com
|           organizationName=Microsoft Corporation, stateOrProvinceName=WA, countryName=US
| Subject Alternative Name:
|   DNS:bst-5e6f7a8b-5555-4e66-b077-4118c993de21.bastion.azure.com
|   DNS:bst-5e6f7a8b-5555-4e66-b077-4118c993de21-0.bastion.azure.com
|   DNS:bst-5e6f7a8b-5555-4e66-b077-4118c993de21-1.bastion.azure.com
| Not valid before: 2026-04-24T22:58:24
| Not valid after:  2026-11-08T22:58:24

Single port exposed (443). No 80, no 22, no 3389. Microsoft-issued cert. Two-instance deployment confirmed by SAN entries -0 and -1 (Standard SKU minimum). TLS handshake succeeded.

Recommended verification (internal)

Confirm via Resource Graph that no VM NSG allows * / Internet / 0.0.0.0/0 to RDP / SSH / WinRM ports — Bastion should be the only path:

resources
| where type =~ 'microsoft.network/networksecuritygroups'
| mv-expand sg=properties.securityRules
| where sg.properties.destinationPortRange in ('22','3389','5985','5986')
| where sg.properties.sourceAddressPrefix in ('*','Internet','0.0.0.0/0')
| where sg.properties.access =~ 'Allow'
| project nsg=name, rule=sg.name, ports=sg.properties.destinationPortRange,
          source=sg.properties.sourceAddressPrefix

Expected result: zero rows.

§ 4.3

No shadow IT outside Microsoft Azure.

All nine in-scope IPs confirmed in Microsoft AS8075 via RDAP and RIPEstat. No third-party hosting providers, no surprise CDN endpoints, no infrastructure outside the Azure tenancy (within the supplied IP list).

§ 4.4

No client-owned domain leakage via Certificate Transparency.

crt.sh by-IP search returned HTTP 404 for all nine IPs. No public certificates have these IPs in their Subject Alternative Names. External reverse DNS reveals only Microsoft-managed hostnames, not customer role labels — so internal naming conventions (acc-001, dcsvr-001, etc.) do not leak externally.

§ 5 · What active testing could still not verify

Honest gaps. Surfaced rather than implied.

  1. Whether the WCF endpoints on VPN GW PIP1 accept anonymous SOAP / REST calls. We confirmed they listen and return the WCF “Endpoint not found” template. We did not submit SOAP envelopes or attempt to enumerate endpoints — that crosses from reconnaissance into active exploitation, which was not authorised in this engagement scope. Recommend Microsoft confirm.
  2. UDP services on all nine IPs. UDP scanning from a residential source IP is slow and unreliable; not run. Especially relevant for IKE (UDP 500 / 4500) on the VPN GWs and DNS (UDP 53) on the DCs.
  3. Patch level of the DCs and the VPN Gateway image. Banner-grabbing did not reveal Windows version or patch level. Internal verification only.
  4. The four hardened VMs on ports 1001-65535. Could have services on ports 33893 or similar. nmap top-1000 only covers the most common 1000.
  5. AD topology disclosure. dig _ldap._tcp.dc._msdcs SRV @<DC> returned NXDOMAIN because we don't have the AD domain name. With the domain name supplied, this query class would reveal forest topology.
  6. Email / domain posture (SPF / DKIM / DMARC / MTA-STS / HSTS / CSP / CT). Out of scope — no domains supplied. Requires apex domain(s) for a follow-up assessment.
  7. Credential leaks (HIBP, GitHub code search, paste sites). Not run — would have required the client's email domain(s).

§ 6 · Verification after remediation

One re-test, three proof points.

External re-test (assessor or client) to confirm the Critical findings are closed.

# Should time out or REFUSED:
dig google.com @203.0.113.11
dig google.com @203.0.113.12

# Should show all closed/filtered, OR Microsoft's response should be filed in
# the runbook explaining why they remain open:
nmap -Pn -sT -p7999,8081,8443,10001,10002,20000,8083 203.0.113.21 203.0.113.22

# Shodan re-scan of all 9 IPs:
for ip in 203.0.113.31 203.0.113.32 203.0.113.21 203.0.113.22 \
         203.0.113.33 203.0.113.11 203.0.113.12 \
         203.0.113.34 203.0.113.41; do
  curl -s "https://internetdb.shodan.io/$ip"
  echo
done

Schedule the same external sweep as part of routine operations to catch regressions.

§ 7 · Sources & evidence provenance

Every finding is reproducible from the cited evidence.

Passive sources · v1
  • Shodan InternetDB (internetdb.shodan.io) — 2026-05-14 13:37 UTC
  • RDAP via rdap.org and rdap.arin.net — 2026-05-14 13:37–13:38 UTC
  • RIPEstat (stat.ripe.net) — 2026-05-14 13:38 UTC
  • Mnemonic PassiveDNS v3 (api.mnemonic.no/pdns/v3/) — 2026-05-14 13:37 UTC
  • crt.sh (crt.sh/?q=<ip>) — 2026-05-14 13:38 UTC
Active sources · v2 (new)
  • nmap 7.99 — TCP top-1000 + version detection + safe NSE scripts, source 198.51.100.50, target = 9 client IPs, window 2026-05-14 14:07–14:13 UTC−4
  • dig 9.10.6 — DNS recursion / version / AD-SRV probes against 203.0.113.11 and 203.0.113.12, same window
  • openssl 3 (s_client) — TLS handshake against 203.0.113.21:8443 and 203.0.113.41:443
  • curl — HTTP/1.1 + HTTP/2 GET against 203.0.113.21 ports 7999, 8081, 8443, 10001, 10002, 20000

Two Critical findings, verified. Ready to remediate?

Snapshot, NSG-replace, re-test — the §3 playbooks walk every step. Bring us in for the verification sweep once the patches land, and the Shodan / Spamhaus / Open Resolver Project listings unwind on their next crawl.

Talk to a security engineer →

§ 8 · CISO sign-off checklist

Eight items. Each one a verifiable proof point.