When abandoned apps and watering holes land on the same abuse feed
Security teams spent recent cycles reacting to reports that abandoned Popcorn Time builds left millions of devices open to remote code execution, that watering-hole campaigns pushed ScanBox keyloggers into browser sessions, and that PHP2Shell-style webshell exposure put shared hosting prefixes back on every abuse list overnight. In each case, the operational problem for defenders is familiar: fresh IP blocklist entries arrive mixed with routine internet scanning, and autodrop at the edge can hide the one signal that matters most, an internal host already talking out to that destination.
Threat hunting with IP blocklists works when you treat destination hits as endpoint leads, score them against session shape and process context, and only then decide whether to widen from a single address to a prefix or ASN. This article walks that path with concrete telemetry joins and controls you can run the same day a feed updates.
Start from the client that reached out, not the packet that died at the firewall
Inbound blocklist drops answer one question: did unsolicited traffic from a known-bad address touch your edge. Outbound destination matches answer a different one: did something inside your network choose that address. Popcorn Time-style RCE on unmanaged endpoints, ScanBox payloads delivered through compromised legitimate sites, and PHP webshell follow-on staging all produce the second pattern. Your hunt queue should open on egress and name resolution before it opens on the deny counter.
A practical morning ritual looks like this. Pull overnight deltas from your primary abuse and C2 feeds. Join those IPs and /24s to outbound firewall accepts and denies, forward proxy CONNECT and HTTPS SNI records, recursive DNS answers, and VPN or remote-support egress. Rank rows where an internal source made the request. Park pure inbound SYN floods from the same prefixes in a separate scanner bucket so they never starve the client hunt.
Telemetry that separates beacons from noise
Scanner noise and compromised-client traffic often share hosting cities and even the same /24. Use session attributes that scanners rarely fake well at once:
- Direction and initiator: internal RFC1918 or corp VPN address as the client of a TCP session to the listed IP.
- DNS preceding connect: a recursive query from the same host for a domain that resolves to the listed IP within a short window before the connect.
- User-agent or JA3/JA4 consistency: browser-like TLS on a workstation after a watering-hole visit versus repetitive tool fingerprints from a build server.
- Process tree: EDR parent/child for the socket owner, especially media players, browser helpers, scripting hosts, or unexpected PHP/runtime children on servers.
- Cadence: short periodic connects with small payloads versus one-shot banner grabs across many ports.
When LLM gateways and AI coding agents sit on the same egress paths as user browsers, add a service inventory join. LiteLLM-style gateway misconfigurations and AGENTS.md-style agent hijacks change which process owns the socket. Label those paths so a blocklist hit on an AI runner does not get triaged as a random laptop infection, and the reverse.
Build a two-lane hunt from every fresh blocklist row
Give each new indicator two tickets in your queue, not one. Lane A is compromised client candidate. Lane B is internet scout. Promotion rules keep the lanes honest.
- Match the IP or prefix to outbound proxy, DNS, and firewall logs for the prior 7–30 days, not only after the list publish time. Pre-list traffic is often your earliest infection evidence.
- If any internal host shows initiator traffic, open Lane A immediately. Collect hostname, user, last interactive logon, installed software inventory for abandoned or EOL apps, and browser history around the first DNS hit.
- If only inbound edge hits exist, keep Lane B. Sample for exploit path strings (Winbox, PHP admin paths, VPN portals) and compare ASN tenure. Escalate Lane B to prefix rate caps only after you confirm no silent outbound partners share that space.
- When both lanes fire on the same prefix, assume dual use. Contain the named clients first, then apply temporary destination blocks that log and alert rather than silent drop until host replay finishes.
Concrete example: ScanBox-style watering hole into outbound blocklist hit
An analyst sees a new C2 IP on an industry feed. Proxy logs show three finance workstations completed TLS sessions to that IP two days earlier. DNS shows the IP answered for a domain that also appears in a watering-hole advisory. EDR shows chrome.exe spawning a short-lived script host on one of the three machines. That single join set promotes the case from “new deny rule” to “credential and keylogger hunt on three endpoints,” with mailbox rules and browser extension inventory in scope the same hour.
Concrete example: abandoned media app and PHP hosting overlap
A Popcorn Time-related advisory lists callback infrastructure on a cheap VPS prefix. The same /24 appears in PHP2Shell scanner chatter against your public sites. Your edge already drops inbound probes. Outbound logs still show two contractor laptops resolving and connecting to one address on that prefix over the weekend. Hunt those laptops for the abandoned binary, quarantine their VPN profiles, and keep the inbound scanner volume in the scout lane so you do not burn the shift retuning WAF rules that already fire correctly.
Map findings to controls you can ship without waiting for perfect attribution
Once Lane A hosts are named, move in a fixed order so autodrop does not erase forensic value.
- Preserve: snapshot proxy, DNS, and EDR timelines for the destination IP before you push a silent deny. Export PCAPs or SSL keys only where policy allows.
- Contain the client: isolate the endpoint or cut its VPN, rotate tokens on the user, and kill the offending process tree. Destination blocks alone leave the implant free to rotate IPs.
- Block with memory: add the IP to egress deny with hit logging and a 72-hour review date. Mirror the same object into DNS RPZ or secure web gateway categories so AAAA and alternate names fail closed together.
- Widen carefully: if multiple distinct C2 hostnames resolve into the same /24 and your clients hit more than one, raise a temporary prefix destination control on user egress only. Leave partner API corridors and AI gateway allow objects out of that object group until tenancy is proven.
- Feed upstream: ship the internal-source count, first-seen time, and process owner back to your ISAC or vendor. Partial notes with client-side confirmation help peers who still only see scanner noise.
Implementation details that keep the hunt repeatable
Store blocklist rows with category, first-seen, confidence, and source feed ID. Require a mandatory log join per category before autodrop expands: C2 and malware categories join DNS plus EDR; scanner and exploit categories join edge IDS plus WAF; phishing hosting joins mail gateway clicks plus proxy. Schedule a daily job that diffs feed membership and writes “new,” “removed,” and “relisted” states into your SIEM so analysts hunt deltas instead of full list volume.
For shared cloud prefixes, bind every widen decision to a tenancy check: reverse DNS, certificate SANs, known-good neighbor IPs from your own allow history, and whether Microsoft Teams or other SaaS callbacks already occupy adjacent space. Context-aware phishing detection on collaboration suites reduces user-borne clicks; it does not replace outbound destination hunting when an implant is already present.
What to rehearse before the next advisory dump
Run a short tabletop that starts with a published RCE or watering-hole advisory, injects a blocklist delta containing both a true client beacon IP and a noisy scanner twin on the same ASN, and scores whether your team names the infected host inside one hour. Success criteria are simple: Lane A ticket exists, three log sources joined, destination block logs rather than silent-drops until host evidence is bagged, and inbound scout volume stays out of the critical queue.
Threat hunting with IP blocklists pays off when every fresh destination is a question about your own assets. Abandoned apps, ScanBox-style keyloggers, and exposed PHP shells all leave outbound footprints that perimeter counters alone will not explain. Rank those footprints by initiator, DNS, and process tree, contain the client, then let prefix and ASN controls follow the evidence you already proved.