Skip to content

Takedowns

SuckerPot follows what happens to the targets in your reports. Is the malware file still served? Is the attacking address still active? How long did the takedown take, and which providers act?

Takedown tracking is optional and off by default. It needs TAKEDOWN_ENABLED=true. Re-checks of payload URLs also need COLLECTOR_ENABLED=true.

This page covers:

  • what is re-checked, and what is never contacted;
  • the states a target can have;
  • the statistics, including the 48-hour rule;
  • the abuse.ch submissions (off by default).

Related pages: Replies to reports (the answers from providers), Configuration, and the design in docs/design/m27.md.

SuckerPot is a honeypot. It does not hunt back. Takedown tracking follows the same rule:

TargetContacted?
A malware URL that served a sample to the collectorYes, one bounded GET (see below).
Other paths on the same host, such as a directory listingNever.
A command-and-control (C2) serverNever. No connection, no ping, no banner grab.
An attacking IP addressNever. No connection, no ping, no traceroute.
A URL hosted on an address that attacked you in the last 30 daysNever. Passive signals only.
Any host for port scans, DNS brute force or reverse lookupsNever.
An abuse report to AbuseIPDBNever. SuckerPot only reads AbuseIPDB.

The fixed intel services are asked about a value. These are URLhaus, ThreatFox and AbuseIPDB. They are not the target. Their answers come from their own databases.

Why:

  • A connection to a C2 server or an attacker is a probe of their infrastructure. That is a counter-scan.
  • A payload host is public by nature: it serves a file to anyone who asks. Asking once, the same way the collector asked the first time, is the same request.
  • An address that attacks you is not a host that serves you. SuckerPot keeps out of it.

The collector re-checks a URL only when all of these are true:

  1. The collector fetched the URL before and stored a sample from it.
  2. The URL is not on a C2 address, and not on an address that attacked you in the last 30 days.
  3. The target is still being tracked.

The re-check is one GET with the same identity and limits as the original fetch:

  • the same user agent, headers and timeouts;
  • redirects followed by hand, at most COLLECTOR_MAX_REDIRECTS, and each hop is checked against the same URL rules;
  • the body is capped at COLLECTOR_MAX_BYTES;
  • every request goes through the VPN. With the tunnel down, nothing is sent and no quota is used.

SuckerPot stores nothing unless the file changed. The body is hashed while it streams. If the hash matches the last one, the bytes are thrown away. If the file is different, it is kept as a new sample, if there is room in quarantine. A file that is never stored is never run.

The schedule of re-checks per URL:

When after the reportCheck
0 h, 1 h, 6 h, 24 h, 48 hEach once.
Every 24 h after thatUntil tracking stops (TAKEDOWN_TRACK_DAYS, 30 by default).
Every 72 h while the URL is downTo catch a host that comes back.

That is about 35 requests per URL in 30 days. The daily cap is TAKEDOWN_HTTP_DAILY_QUOTA (200 by default).

Some signals need no request at all:

CheckLooks atUsed for
SightingsYour own sensors. Did an attacking address connect again after the report?Attack sources: Active or Quiet.
SamplesDid a new sample that you collected point to a reported C2 address?C2 servers: Active or Unknown.
ListingsURLhaus, ThreatFox and AbuseIPDB answers, asked at 0 h, 24 h, 7 days and 30 days.Extra evidence for every kind.

Listing lookups have their own daily caps, TAKEDOWN_INTEL_DAILY_QUOTA (100) and TAKEDOWN_ABUSEIPDB_DAILY_QUOTA (50). Each one also uses the provider’s normal quota, so tracking can never take the whole intel budget. When a cap is used up, no more lookups run until the next day. A closed tunnel means no lookup and no quota used.

A target is one thing you reported. SuckerPot creates targets from:

SourceTarget kindRole
The subject of an attack-source reportIP addressAttack source
The subject of a payload-host reportIP address or domainPayload host
A URL that served a sample from that hostURLPayload URL (a child of its host)
The subject of a C2 reportIP address or domainC2
A URL or C2 you submitted to abuse.chURL or IP:portPayload URL or C2

A target reported in several places keeps the earliest report date. Demo reports never create tracked targets unless ABUSE_REPORTS_INCLUDE_DEMO=true (for screenshots).

Each target is tracked for TAKEDOWN_TRACK_DAYS days after it was reported. You can stop tracking early: a target page has a Stop tracking button for administrators.

Each host with URLs keeps at most 20 child URLs, the latest first.

Each target has one state. The dashboard shows the state as an icon and a word. Red is used only for a payload that is still served or replaced, never for an address or a C2.

TargetState in the dataShown asMeaning
Payload URLupStill servingThe last check found the same file, or a file that could not be compared.
Payload URLchangedServing a new fileThe URL answers with a different file. It may be a new sample.
Payload URLdownDownTwo checks in a row found it gone (see below).
Payload URLunknownUnknownNot checked yet.
Payload hostup, changed, down, unknownSame wordsTaken from its URLs: up while any URL is up, down when every URL is down.
Attack source (IP)upActiveOur sensors saw it attack in the last 72 hours, or a listing reported it again.
Attack source (IP)downQuietNot seen for 7 days (TAKEDOWN_QUIET_DAYS) after the report.
C2 serverupActiveNew malware points to it, or a listing was refreshed after the report.
C2 serverunknownUnknownNo passive signal yet.

A single failed check never means down. A URL is down when its last two checks are down answers, and they are far enough apart:

Kind of answerExamplesGap between the two checks
StrongNot found (404), Gone (410), other client error, suspended-account page, empty answerAt least 1 hour
WeakNot reachable, no answer in time, server error (5xx)At least 6 hours

The dashboard shows “Not answering since” for a URL that has failed once and is not yet confirmed down.

For a C2 server the state is never down. SuckerPot does not contact C2 servers, so it cannot see them go away. The page says so: it shows whether new malware still points to the address.

Time to takedown is the first confirmed down time minus the report time. It is an upper bound. The takedown happened between the last check that was up and the first check that was down. The target page shows that window, for example “down between 14:00 and 20:00, 19 hours after the report”.

A target that was already down at its first check (down_before_report) has no time to takedown. It is left out of the statistics.

The Results page counts takedowns from the targets. It leaves out demo targets and targets that were already down at the first check.

Attack sources and C2 servers are not takedowns. They have their own “quiet” and “active” counts. Only payload URLs and payload hosts count as takedowns.

“Taken down within 48 hours” is counted over the targets that can be judged. A target can be judged only when it was observed for the whole 48 hours, or when it went down within them.

Example. You reported 31 malware URLs. Nine of them were reported less than 48 hours ago and have not gone down yet. Those nine are not judged yet, so they are left out of the count. The other 22 can be judged. Twelve of the 22 went down within 48 hours. The Results page reads: “12 of 22 reported malware URLs went down within 48 hours.”

The same rule applies to 7 days and 30 days. This is called right-censoring. It stops young reports from making the numbers look worse than they are.

Other rules:

  • Median time to takedown needs at least five values. Below that the page says “not enough data yet”.
  • Still up after 30 days counts the targets that were tracked to the end and never went down.
  • Channels are shown as mail only, URLhaus only, or both. URLhaus notifies hosting providers itself. The page does not claim that your report caused a takedown that URLhaus also reported.

Each provider gets a row with its targets, the share down within 48 hours and 30 days, its median time to takedown, the number still up, and, from Replies to reports, the reports sent, the share answered and the median first reply.

A provider is:

  • the network (AS number) of the address, when it is known;
  • otherwise the abuse mailbox of the registrar you wrote to, for domains.

The Results page can group by provider, mailbox, country or report kind. Filters live in the URL, so a view can be shared.

A monthly roll-up keeps the counts per provider, kind and channel. It holds numbers only: no values, no URLs, no addresses. It is kept after the reports are deleted by retention, so the history stays on the Results page.

SuckerPot can send captured malware URLs to URLhaus, and command-and-control addresses to ThreatFox. abuse.ch then shares them with other defenders.

Submission is off by default, twice:

  1. The server switch ABUSECH_SUBMIT_ENABLED=false. With it off, the card says “Disabled on this server” and nothing is computed or sent.
  2. The mode in Settings > Reporting > abuse.ch, which starts at Off.

Both must be on before anything is sent.

  1. Create a free abuse.ch account, or use one that you already have. Choose an account whose public name does not identify you. Submissions show that name unless you ask for anonymity.
  2. Copy its Auth-Key from the abuse.ch account page.
  3. Open Settings > Reporting > abuse.ch. Paste the key in the Auth-Key field and save. Saving asks for your dashboard password again. The key is encrypted and never shown again. Only its last four characters are shown.
  4. Choose a mode:
ModeWhat happens
OffCandidates are not even computed.
Review eachCandidates appear on the Submissions tab. You select one or more (up to 20), confirm, and they are sent.
AutomaticEach new candidate is scheduled. It is sent after the hold time (60 minutes by default, 10 to 1440). Each one shows “Submitting at hh:mm” with a Cancel button.

Automatic mode needs the key and ABUSECH_SUBMIT_ENABLED=true. The card explains if either is missing.

Other switches on the card:

  • Also submit command server addresses to ThreatFox. Off by default.
  • Anonymous. On by default. It asks abuse.ch to hide your name.
  • Daily cap. At most 20 submissions per UTC day by default (1 to 200).

The Auth-Key for submissions is separate from the Auth-Key for lookups. The lookup key is ABUSECH_AUTH_KEY in .env, or the abuse.ch key on Settings > Enrichment. It is used to ask whether a value is already known. Without it, no lookups run.

URLhaus: a URL is a candidate only when all of these are true:

  • the collector stored a sample from it in the last 48 hours, and the sample is a binary or a script (not a web page);
  • it is an http or https URL of at most 1,024 characters;
  • its host is not on the never-share list (large public services, resolvers and your own addresses);
  • it was not already submitted.

ThreatFox: only with the ThreatFox switch on. A candidate is a command-and-control ip:port read with high confidence from a sample seen in the last 7 days, whose family has a Malpedia name in ingest/rules/abusech/malpedia.yaml. Domains are not submitted.

Demo data is never submitted.

The body is built from a fixed list of fields:

FieldContent
The valueThe URL, or the ip:port.
Threatmalware_download for URLhaus, botnet_cc for ThreatFox.
TagsUp to five, from a fixed list: the family, the architecture (for example arm, mips, x86-64), and sh for shell scripts.
Anonymous1 or 0, from the switch.

The body has no free text, no comment, no reference link, no date and no session data. Before it leaves, it goes through the same identity check as the abuse reports. If the check fails, nothing is sent. A URL that contains your monitored address is blocked and never submitted.

Before a candidate can be submitted, SuckerPot asks abuse.ch whether it already knows the value:

Lookup resultStatus shown
Already listedAlready on URLhaus (skipped, and never sent again)
Not listedCan be submitted
Lookup could not run (no key, or the quota is used up)Waits. You cannot submit it until the lookup has finished.

A submission is sent at most once. SuckerPot records “Sending” in the database before it makes the request. If the outcome is unknown, for example after a crash, the row becomes Failed and is never retried. A tunnel that is down before the request returns the row to the queue, unsent.

TabStatusesWords in the dashboard
To reviewcandidateTo review
Scheduledpending, submittingScheduled, Sending
Submittedsubmitted, duplicateSubmitted, Already listed
Skippedskipped_known, skipped_never_list, cancelledAlready on URLhaus, Not shared (safe list), Cancelled
Failedfailed, rejected, guard_failedFailed, Rejected by abuse.ch, Blocked by the identity check

Demo rows stay in To review and cannot be submitted.

Each submitted row links to the abuse.ch page for the value. The link is built by the server from a fixed prefix.

The abuse.ch documentation describes the submission request, but it does not describe every answer. SuckerPot maps answers to short codes, such as inserted, already_known or auth_failed. Unknown answers become unknown_outcome or a generic code. Check the first result on the Submissions tab after you turn on automatic mode, before you rely on it.

DataKept for
Individual checksTAKEDOWN_CHECK_RETENTION_DAYS (400 by default).
Targets400 days after tracking stops.
abuse.ch submissions730 days.
Monthly roll-upForever.