We built NoxScan as a side product to solve our own problem.
Backstory: we're SOC 2 compliant, which means we have to run continuous vulnerability scanning on our own infrastructure. We were paying €700/mo to a well known scanner for 50+ IPs. For that money we got full port coverage, but scans ran once a month on top of basic Nmap. No service enrichment, no smart filtering. Just raw output that we had to triage by hand. Their cheaper tiers were worse: capped at the top 1,000 ports.
What we actually wanted was three things: full 65,535 port coverage, daily scans instead of monthly, and output that a human didn't have to hand filter. That combination didn't seem to exist at a price that made sense for our size, so we started building it ourselves. After running it internally for a while we realized other small SOC 2 and ISO 27001 shops almost certainly have the same pain, so here we are.
We started with masscan. It's the obvious choice for sweeping 65K ports across a lot of hosts. It's fast, but under load it drops open ports, and context switching eats into throughput when you're trying to push line rate on cheap hardware.
Then we read c3l3si4n's Phrack article on high performance scanning with AF_XDP (Phrack #72, article 5) and it was pretty much exactly what we needed. The short version: attach an eBPF program to the NIC's XDP hook, set up a shared UMEM region with a four ring mailbox (RX, TX, FILL, COMPLETION), and you get zero copy packet I/O between userspace and the driver with almost no syscall overhead. The eBPF side handles SYN/ACK matching at the XDP hook, so we never push every response up to userspace. Rate limiting is done per destination ASN instead of globally, otherwise a few large targets will starve everything else. For now we run masscan and our AF_XDP scanner in parallel. Masscan is still the battle tested workhorse doing the bulk of production scans, and we cross check its findings against our AF_XDP path on every run. The Phrack benchmarks line up with what we see on our own infra: AF_XDP is faster and more accurate in dense scans against a single host (c3l3si4n measured ~1.3s vs masscan's ~2s on a full 65,535 port scan, and masscan dropped ports at that rate while AF_XDP didn't). Once we're confident our AF_XDP path is stable across the mix of NICs and kernels our customers actually run, we'll switch to it fully. Right now the redundancy is worth the extra compute.
Port open/closed on its own is almost useless. What you actually want to know is "what's running on that port and which version is it." For that we use ZGrab2 with a set of custom probes we wrote for the services we care about: HTTP and TLS of course, but also etcd, Consul, Prometheus, unauthenticated Redis, exposed Docker daemons, and similar. ZGrab2 is underrated. It's pretty much what you'd build yourself if you had to fingerprint thousands of services per second, and the output format is cleaner than Nmap's NSE.
Once we know what's running, we enrich it with known CVEs and assign severity. Web services also go through Nuclei. Nuclei is the best thing that happened to vuln scanning in years. Compared to OpenVAS or ZAP, which will happily flag every missing X-Content-Type-Options header as a vulnerability, Nuclei's templates are version aware and the signal to noise ratio is much better.
Even Nuclei produces noise in aggregate. We route anonymized findings through an LLM that cross references against the NVD CVE database, deduplicates related findings, and assigns severity based on actual exploitability in context (exposed to the internet vs. behind auth vs. requires specific config to trigger).
Last piece: because we're SOC 2 compliant ourselves, the PDF reports are in the exact format our auditor asked for. CC7.1 mapping, timestamps, scope definitions, remediation tracking. Basically the report we wish our old scanner had been producing.
HN folks can use LAUNCH30 code during checkout.