pivoting-phishing-infrastructure-with-scanmalware27.7 KB
View saved version →
---
name: pivoting-phishing-infrastructure-with-scanmalware
description: >-
Expands one phishing or fake-download URL into its wider campaign using the ScanMalware
public scan archive (no API key needed): redirect-aware domain history (matched_on),
SMQL searches on each kit artifact (script SHA-256 including inline scripts, favicon
MMH3, screenshot hash, page title) and on the operator's own account keys (analytics
IDs, chat-widget licenses, CAPTCHA site keys), plus JARM, IP and CT-derived subdomains,
then judges which pivots are selective enough to hunt or block on. Use when a reported
phishing URL needs its sibling hosts found, when checking how an already scanned page
was judged, or when a verdict must be attributed to the right host after a redirect.
Keywords: ScanMalware, SMQL, matched_on, final_url, js_sha256, tracking_id,
favicon_hash, dhash, jarm, CONFIRMED_SCAM, phishing kit, scanner cloaking.
license: Apache-2.0
---
# Pivoting Phishing Infrastructure with ScanMalware
## Overview
A single phishing URL is rarely the whole campaign. Kits are redeployed across dozens of
disposable hosts, and the pages share artifacts that survive the move: the same bundled
JavaScript, the same favicon, the same rendered screenshot, the same page title. Many also
carry the operator's own accounts, such as an analytics ID or a live-chat license, which
follow the operator even when the kit is rebuilt or moved to another hosting platform. A
public archive of rendered scans lets an analyst search for those artifacts and find the
sibling hosts that were already scanned by someone else.
ScanMalware (scanmalware.com, operated by Triop AB) runs submitted URLs through isolated
analysis environments, records what each page loads and runs, and keeps the public scans
searchable through a REST API and the SMQL query language. The read endpoints and
anonymous scan submission need no account or API key.
This skill covers the pivot procedure and two traps that produce wrong conclusions if
ignored: verdicts attributed to a redirect destination, and pivot values that describe a
hosting platform rather than an actor.
## When to Use
- A user reported a phishing URL and you need the other hosts running the same kit.
- You want to know whether a URL or domain was already scanned, and what it did, before
submitting it again.
- A domain appears in scan results with a malicious verdict and you must decide whether
the verdict belongs to that domain or to a page that redirected to it.
- You have a kit artifact (script SHA-256, favicon hash, page title) or an account key
(analytics ID, chat-widget license, CAPTCHA site key) and want every archived page that
carries it, newest first.
- You need to decide which indicators from a phishing page are safe to block on without
blocking a shared hosting platform.
## Prerequisites
- `curl` and `jq` 1.6 or later, or the ScanMalware MCP server that comes with this plugin
(see Tools & Systems for the tool behind each step).
- Outbound HTTPS to `scanmalware.com`. No account or API key is needed for anything in
this workflow except private scans.
- Rate limits are per source IP: 600 requests per minute anonymously (60 per minute for
the hash-search pages); a ScanMalware account raises them. A 429 response carries
`Retry-After`; wait that many seconds.
- OPSEC: `public` scans (the default) are visible to anyone. If the URL carries a victim's
email address, a per-victim link code or a tracking ID, submit it as `unlisted`
(reachable only by scan ID, absent from search) or `private` (requires a ScanMalware
account; anonymous requests get HTTP 401). Submitting also makes the scanner fetch the
URL, which a kit operator can observe.
## Workflow
### Step 1: Check the archive, and read `matched_on`
```bash
DOMAIN=facebook.com
curl -s "https://scanmalware.com/api/v1/domains/$DOMAIN/scans?limit=100" -o history.json
jq -r '.[] | [(.matched_on | join("+")), .scan_id, .url, .final_url] | @Preview of the first 4,000 characters. Read full instructions →
Referenced files: 5 — file references are metadata, not package contents.