In my post on active defense versus hacking back, Coreflood got one paragraph. In April 2011 the US Justice Department took over the botnet’s command servers and told the infected computers to stop. That paragraph is accurate, but it skips the part I find most interesting as an engineer.
The takeover was possible because of design decisions the authors made years earlier. Coreflood trusted whatever server answered at its addresses, and it obeyed commands without checking who sent them. In other words, it forgot to lock its front door.
This post is the technical story behind that paragraph. It is also Part 1 of a series, A Short History of Botnets. Each part follows one botnet through the same lens: lineage, spread, command and control, money, takedown and legacy.
A note on the exhibits. Real Coreflood traffic captures from 2008 to 2011 are not public. The network indicators below come from the 2008 SecureWorks analysis and the 2011 US-CERT notice. The Windows event logs are reconstructions of how the documented behaviour would look on a network today. Each exhibit says which kind it is. Nothing here is working malware or command-and-control code.
Lineage: from AFcore to Coreflood (2002 to 2008)
Coreflood was not one program but a decade of incremental engineering by a single, small crew. Joe Stewart of SecureWorks reconstructed its family tree in his 2008 report:
| Year | Milestone |
|---|---|
| 2008 | New samples add worm-like spread inside Windows domains |
| 2005 | Controller domains mcupdate.org and mcupdate.net run continuously |
| 2004 | First documented theft: a $90,348 wire to Parex Bank in Riga, Latvia |
| 2004 | Autoproxy merges into Coreflood; command channel moves from IRC to HTTP |
| 2003 | Autoproxy, a proxy-botnet trojan, is analysed |
| 2002 | Coreflood, also called AFcore, runs as an IRC trojan used for DDoS |
The move from IRC to HTTP in 2004 is the detail that matters for defenders. An IRC connection from a workstation on port 6667 stands out on any corporate network. An HTTP POST to a web server blends into thousands of normal requests and passes through proxies and firewalls that allow web traffic. Coreflood was early to that trade-off, and most of the botnets that followed it made the same one.
The second shift was in business model. From 2004 onward Coreflood stopped being a tool for knocking websites offline and became a tool for stealing money. That shift explains every design choice that follows: stealth over speed, corporate networks over home users, and a server-side pipeline for sorting stolen data.
Patient lateral movement: waiting for the domain admin
Coreflood’s most modern feature was its patience. According to the 2011 US-CERT notice, an infected machine stayed quiet until a user with administrative rights logged in. Then it used those credentials to copy itself to other machines in the Windows domain.
Early versions did this with Sysinternals PsExec, the legitimate remote-administration tool. Later versions used a custom tool that imitated PsExec. SecureWorks reported cases where thousands of machines on a single corporate or government network were infected this way.
Today we call this lateral movement with valid accounts, or living off the land. Coreflood was doing it in 2008, years before it became the standard playbook of ransomware crews. The weak point it exploited is still common: a domain admin account used for everyday support on ordinary workstations.
US-CERT listed three traces worth hunting for:
- log files named
mng1.logandmng2.login the user’s Local Settings folder, which recorded successful and failed spread attempts; - unusual use of the
ADMIN$administrative share; - HTTP POST activity from workstations to the command servers (next sections).
Exhibit 1 (reconstruction). The documented PsExec technique as it would appear in Windows Security and System logs on a target server today. Host names, accounts and addresses are placeholders.
# Target: FILESRV-01 | Source: WS-FIN-042 (10.20.30.42), already infected
[Security 4624] An account was successfully logged on
Logon Type: 3 (Network)
Account Name: adm.jsmith <- domain admin, logged on at WS-FIN-042
Account Domain: CORP
Source Address: 10.20.30.42
Authentication: NTLM
[Security 5140] A network share object was accessed
Share Name: \\*\ADMIN$
Account Name: adm.jsmith
Source Address: 10.20.30.42
[Security 5145] Network share object checked for access
Share Name: \\*\ADMIN$
Relative Target: PSEXESVC.exe <- service binary copied over SMB
Accesses: WriteData (or AddFile)
[System 7045] A service was installed in the system
Service Name: PSEXESVC
Image Path: %SystemRoot%\PSEXESVC.exe
Service Type: user mode service
Start Type: demand start
Account: LocalSystem
[Sysmon 1] Process Create
ParentImage: C:\Windows\PSEXESVC.exe
Image: C:\Windows\<dropped-binary>.exe <- placeholder
User: NT AUTHORITY\SYSTEM
Two things in this chain matter for detection. First, the sequence happens within seconds: network logon, ADMIN$ write, service install, child process. Second, the service name is the weakest indicator in it. Coreflood’s later custom tool imitated PsExec, so a rule that only looks for the name PSEXESVC would have missed it. The hunting section returns to this.
What it stole, and how
Coreflood worked from inside the victim’s browser session. It recorded what users submitted to websites and the pages they saw, including intranet pages and webmail. It also took client certificates and cookie files. Because it captured the live session rather than just a password, a hardware token did not stop it: the token code was used once, legitimately, and the attacker rode the authenticated session.
We would now call this a man-in-the-browser attack. Its lesson still holds: a second factor protects the login, not the session that follows it.
The scale became visible when SecureWorks gained access to a Coreflood server in 2008. It held about 50 GB of mostly compressed stolen data covering six months, and server scripts suggested up to four times as much had already been processed and deleted. On a busy day the botnet collected a gigabyte or more of uncompressed data. The report broke down the 463,582 stolen credentials, covering more than 35,000 domains:
| Credential type | Count |
|---|---|
| Email accounts | about 151,000 |
| Social networking | 58,391 |
| Bank and credit union logins (29 institutions) | 8,485 |
| Online retailers | 4,237 |
| Credit cards | 3,233 |
| Online payment processors | 869 |
| Payroll processors | 553 |
| Finance companies | 422 |
| Stock trading | 416 |
| Mortgage lenders | 413 |
The server also held an account-testing directory with 740 stolen bank accounts. In the 79 the crew had checked, the average balance was $4,553.74 in savings and $2,096.31 in checking. Stewart’s rough extrapolation put the whole set at more than $2.5 million, while noting that moving that much would be impractical.
The 2011 court case showed the operation was still running at full scale. Between March 2009 and January 2010 the operators collected about 190 GB of data from 413,710 infected computers, according to The Register’s account of the case. Named victims included a Tennessee defense contractor that lost about $242,000 and a North Carolina investment firm that lost more than $151,000.
Command and control: the fatal flaw
Coreflood’s command channel was simple, and simplicity is what made the takeover possible. Infected machines checked in at regular intervals with a small set of controllers: five command servers, all hosted in the United States, reached through a fixed list of domain names. The botnet used no domain generation algorithm, no peer-to-peer fallback and no fast-flux hosting.
The check-in was an HTTP POST. SecureWorks documented its shape in the removal guide it published for network administrators:
- the request went to the path
/c/a; - it was sent as HTTP/1.0 with a
Hostheader; - the POST body carried a variable
vwith the build number (the guide was tested up to build 3118, labelled AF-3.1/test18); - the server’s reply was the command, as plain text.
Exhibit 2 (illustrative). A check-in built from those documented fields. The path, protocol version, Host header and v variable are documented; the domain is one of the 2008 controller domains; the other body fields are omitted because they were not published.
POST /c/a HTTP/1.0
Host: mcupdate.org
Content-Type: application/x-www-form-urlencoded
Content-Length: 6
v=3118
HTTP/1.1 200 OK
Content-Type: text/plain
<command>
Two details in this exchange stand out to a defender. Browsers of the time already spoke HTTP/1.1, so an HTTP/1.0 POST from a workstation was a useful signal on its own. And the reply carries no proof of who sent it: no signature, no shared secret, no certificate check.
That second detail is the fatal flaw. Coreflood understood commands such as uninstall and dropself, and any server that answered at a controller address could send them. Whoever controlled the address controlled the botnet.
Exhibit 3. Why the substitute servers could talk to the bots.

Coreflood ran any reply from its controller address, so a court-ordered server could command it. A bot that checks a signature against a public key built into its binary would have ignored that server.
SecureWorks turned this flaw into a defensive tool before the FBI did. Its signature for spotting infected hosts matched the check-in itself. Rewritten here from the published description:
alert tcp $HOME_NET any -> $EXTERNAL_NET $HTTP_PORTS (
msg:"Coreflood/AFcore trojan infection";
flow:established,to_server;
content:"POST|20|/c/a"; depth:9;
content:"HTTP/1.0"; content:"Host:";
classtype:trojan-activity; sid:99999999; )
Anatomy of the takeover: from one network to the Internet
The 2011 operation did on the Internet what SecureWorks had already shown administrators how to do on a single network. Both rest on the same idea: make the bots’ controller address lead to a server you run, then answer their check-ins yourself.
The in-house version
SecureWorks’ removal guide described it in four steps:
- Give a Linux or BSD host on your network the controller’s IP address as a /32 alias.
- Add a static route on the gateway that sends traffic for that IP to the host.
- Run a small Perl daemon on port 80 that answers every POST to
/c/awithuninstalland every request for/cgi-bin/*.phpwithdropself. Everything else gets a 403. - Log each client’s IP, method and path. That log is your list of infected machines.
The guide added two warnings that any incident responder will recognise. Test on one host first, because a new build could break the method. And tell the affected users that their data may be compromised, then have them change every password.
The Internet-scale version (April to June 2011)
Scaling this up needed a court, not a router. On 11 April 2011 the US Attorney’s Office in Connecticut obtained a temporary restraining order against 13 unidentified operators, named as John Does. It covered 29 domains and the controllers’ IP addresses. Traffic to them was redirected to substitute servers run by the non-profit Internet Systems Consortium, with help from Microsoft (FBI, The Register).
The substitute servers did less than the 2008 guide. They sent only a stop command, not uninstall, because investigators worried that deletion could crash machines they knew nothing about (Dark Reading). Coreflood restarted with Windows, so the stop had to be repeated at every check-in. The court also allowed the servers to log the IP addresses of connecting machines. The FBI used that log to notify victims directly, to brief about 25 large US ISPs and to share data with foreign law enforcement.
Exhibit 4 (illustrative). The same bot before and after the redirection. The domain is a documented controller domain; the IP addresses come from the reserved documentation ranges; the stop command’s exact wording was not published.
# BEFORE: bot resolves its controller and checks in
$ dig +short mcupdate.org
198.51.100.23 <- operators' C2 server
POST /c/a HTTP/1.0 (v=3118) -> 198.51.100.23
<- 200 OK <operator command> <- e.g. upload stolen data
# AFTER: same domain, same request, different owner
$ dig +short mcupdate.org
203.0.113.80 <- substitute server (court order)
POST /c/a HTTP/1.0 (v=3118) -> 203.0.113.80
<- 200 OK <stop command> <- bot stops until next reboot
# Substitute server log, used for victim notification
2011-04-14T09:12:44Z src=192.0.2.41 POST /c/a v=3118 reply=stop
The last phase came in June. With written consent from 24 identifiable victims, the FBI sent about 19,000 uninstall commands to their machines. None of them reported problems (Krebs on Security). Machines whose owners could not be reached stayed infected, and the FBI noted that Coreflood would resume once the substitute servers were switched off.
The numbers say what the operation was: about 2.3 million infected machines over the botnet’s life, and 19,000 actually cleaned. The stop command broke the crew’s control. The cleaning still depended on owners, antivirus vendors and Microsoft’s Malicious Software Removal Tool, which added Coreflood detection.
Hunting the same pattern today
Coreflood’s network signature died with the botnet, but its spreading technique did not. Remote service creation through an admin share is still one of the most common lateral-movement steps in public incident reports. The rules below target the technique, not the name, because Coreflood itself switched from PsExec to a look-alike.
Exhibit 5a: Sigma, technique-level. An executable written to ADMIN$ over the network. This catches PsExec, its clones and many custom tools. Expect noise from software deployment and patching systems, so tune with an allow-list of their source hosts.
title: Executable Written to ADMIN$ Share Over the Network
id: 6c1f0a52-8d3e-4b7a-9f21-2c4e5d6a7b80
status: experimental
description: >
Detects an executable copied to the ADMIN$ share, the first step of
PsExec-style remote service execution (used by Coreflood from 2008).
references:
- https://www.cisa.gov/uscert/sites/default/files/publications/TIP-11-103-01_Coreflood.pdf
tags:
- attack.lateral-movement
- attack.t1021.002
- attack.t1569.002
logsource:
product: windows
service: security
definition: Requires 'Audit Detailed File Share' (event 5145)
detection:
selection:
EventID: 5145
ShareName|endswith: '\ADMIN$'
RelativeTargetName|endswith: '.exe'
filter_deploy_tools:
IpAddress|cidr: '10.0.5.0/28' # your SCCM/patching hosts
condition: selection and not filter_deploy_tools
fields:
- SubjectUserName
- IpAddress
- RelativeTargetName
falsepositives:
- Software distribution and remote administration tools
level: medium
Exhibit 5b: Sigma, Coreflood-specific (historical). The documented check-in from proxy logs. It will not fire today; I include it to show how a family-level rule ages compared with a technique-level one.
title: Coreflood/AFcore C2 Check-in
id: 0b7e3d19-4a6c-4f2e-8d15-7a9c3e1f6b24
status: deprecated
description: HTTP POST to /c/a, the Coreflood check-in documented by SecureWorks
references:
- https://www.sophos.com/research/coreflood-removal
logsource:
category: proxy
detection:
selection:
cs-method: 'POST'
c-uri: '/c/a'
condition: selection
level: high
Exhibit 5c: Splunk. The full chain on one host: an executable lands in ADMIN$, then a service is installed within two minutes. Field names follow the Splunk Add-on for Microsoft Windows.
index=wineventlog
((EventCode=5145 Share_Name="*\\ADMIN$" Relative_Target_Name="*.exe")
OR EventCode=7045)
| eval stage=if(EventCode=5145, "admin_share_write", "service_install")
| bin _time span=2m
| stats values(stage) AS stages
values(Relative_Target_Name) AS written_file
values(Service_Name) AS service
values(Service_File_Name) AS image_path
values(Source_Address) AS source_ip
BY _time, host
| where mvcount(stages) = 2
| table _time host source_ip written_file service image_path
Exhibit 5d: KQL (Microsoft Sentinel). The same correlation with SecurityEvent for the share write and the Event table for the service install. Adjust the XML parsing if your connector stores event 7045 differently.
let window = 2m;
let adminWrites = SecurityEvent
| where EventID == 5145
| where ShareName endswith "ADMIN$" and RelativeTargetName endswith ".exe"
| project WriteTime = TimeGenerated, Computer, Account,
SourceIp = IpAddress, WrittenFile = RelativeTargetName;
let serviceInstalls = Event
| where Source == "Service Control Manager" and EventID == 7045
| extend Data = parse_xml(EventData).DataItem.EventData.Data
| mv-apply Item = Data on (
summarize ServiceName = take_anyif(tostring(Item["#text"]), tostring(Item["@Name"]) == "ServiceName"),
ImagePath = take_anyif(tostring(Item["#text"]), tostring(Item["@Name"]) == "ImagePath"))
| project InstallTime = TimeGenerated, Computer, ServiceName, ImagePath;
adminWrites
| join kind=inner serviceInstalls on Computer
| where InstallTime between (WriteTime .. WriteTime + window)
| project WriteTime, Computer, Account, SourceIp, WrittenFile, ServiceName, ImagePath
Two smaller hunts complete the picture. Look for HTTP/1.0 POSTs from workstations in proxy logs, grouped by source and destination; a steady, regular rhythm points to beaconing. And search endpoint telemetry for small text files that a process writes after each remote connection attempt, the modern equivalent of Coreflood’s mng1.log and mng2.log.
What I take away
Keep domain admin credentials off workstations. Coreflood waited for exactly one mistake: an administrator logging on to an ordinary PC. A tiered admin model, privileged access workstations and unique local admin passwords (LAPS) remove the credential it was waiting for.
Detect techniques, not families. The /c/a rule had a shelf life of a few years. The ADMIN$-plus-service rule still works, because attackers change their tools far more often than the Windows features those tools abuse.
Authenticate every command channel, including your own. Coreflood’s authors lost their botnet because the bots never checked who was talking to them. The same rule applies to any fleet we build: update servers, robot and vehicle back ends, device management. If a command is not signed, whoever controls the DNS name or IP address controls the fleet. In my post on service robots I argued that fleet learning is a software release; the channel that delivers it needs the same protection.
A takedown is not a cleanup. About 2.3 million machines were infected over Coreflood’s life; about 19,000 were cleaned with their owners’ consent. Breaking the operators’ control was fast. Getting the malware off every machine still depended on owners, ISPs and antivirus vendors.
The botnet authors learned the third lesson faster than many defenders did. Within a few years, botnets signed their commands, generated thousands of domain names a day and fell back to peer-to-peer networks. That is where Part 2 of this series picks up.
Sources
- Joe Stewart, SecureWorks: Coreflood report (August 2008)
- SecureWorks: Coreflood removal for the network administrator
- US-CERT: Technical Information Paper TIP-11-103-01, Coreflood (April 2011)
- FBI New Haven: Department of Justice takes action to disable international botnet (April 2011)
- US Department of Justice: government’s supplemental memorandum in the Coreflood case (archived)
- The Register: coverage of the Coreflood takedown (April 2011)
- Dark Reading: Coreflood botnet an attractive target for takedown (April 2011)
- CSO Online: Botnet takedown sets legal, not technical, precedent (April 2011)
- Krebs on Security: FBI scrubbed 19,000 PCs snared by Coreflood botnet (June 2011)
- Computerworld: Users must sign consent form before FBI tells malware to delete itself (2011)