Worms, and the Ones That Made History
Chapter Eighty-Nine
Syllabus topic Module 2, "Malicious Software: Viruses and Related Threats"
Pages 596 to 602 of 678
In one line
A worm is a program that copies itself to other machines by itself, so its speed is limited by the network rather than by people, and the fastest of them infected most of the vulnerable machines on the Internet in about ten minutes.
In the words an answer should use: a worm is, in NIST's definition, "a self-replicating, self-contained program that usually executes itself without user intervention". It uses network connections to spread from system to system: network service worms exploit a flaw in a service to propagate, and mass mailing worms send themselves as email. A worm performs the same four phases as a virus, dormant, propagation, triggering and execution, but its propagation phase is different: it searches for other systems to infect, establishes a connection to a chosen system, and copies itself there, where the copy begins again.
How a worm spreads
A worm's propagation phase has three steps, repeated for every target. It searches for other systems, using whatever lists the infected machine holds, host tables, address books, lists of trusted machines, or simply by generating addresses at random. It connects to one it has found. And it copies itself across and starts the copy running.
Each step is a place to stop it. The search shows up as an unusual number of connection attempts; the connection can be refused by a firewall; and the copy has to exploit something, which a patch can close.
The five that are worth knowing
Morris, 2 November 1988
The first worm to reach the whole Internet. RFC 1135 records it as unleashed "the evening of 2 November 1988", attacking Sun workstations and VAXes running Berkeley Unix. It used four ways in: a non-standard debug command in sendmail; an overflow in fingerd, where too many characters were sent for the gets library routine to hold, so that the worm "was able to execute a small arbitrary program"; the trusted host features of local networks, through rexec and rsh, following /etc/hosts.equiv and .rhosts files; and password guessing, "attempting to access accounts with obvious passwords".
What it taught. Four lessons, all still current. Input that is longer than the buffer holding it is a way in. Trust between machines spreads a compromise along with it. Weak passwords open accounts. And, as the chapters on incident response reflect, somebody has to coordinate the answer: the lessons RFC 1135 lists include that "Connectivity was important" and that late-night authentication of the person on the telephone is a real problem. CERT/CC was created in the aftermath.
Code Red, 19 July 2001
A network service worm against Microsoft's IIS web server. CAIDA measured it: "more than 359,000 computers connected to the Internet were infected with the Code-Red (CRv2) worm in less than 14 hours", and its infection rate "peaked at over 2,000 hosts per minute".
Worms, and the Ones That Made History
What it taught. Two things. The first version chose the addresses it probed with "a static seed in its random number generator and thus generates identical lists of IP addresses on each infected machine", so every copy scanned the same machines in the same order and it spread slowly; the version that seeded properly spread explosively. And CAIDA's conclusion, which is the lesson for a defender: the episode "demonstrates that wide-spread vulnerabilities in Internet hosts can be exploited quickly and dramatically, and that techniques other than host patching are required to mitigate Internet worms".
Nimda, 18 September 2001
CERT/CC's advisory CA-2001-26 lists five ways it spread, which is why it is remembered:
- from client to client by email;
- from client to client over open network shares;
- from a web server to a client, when someone browsed a compromised site;
- from a client to a web server, by scanning for directory traversal flaws in IIS;
- from a client to a web server, by scanning for the back doors left behind by the earlier Code Red II and sadmind worms.
Its email arrived as a message that "appears to have no content", carrying an attachment named readme.exe declared as audio, which a vulnerable mail program ran automatically on being opened or previewed.
What it taught. A worm with several ways in cannot be stopped by closing one of them: mail filtering, patching the web server and closing the shares all had to happen. It also showed that one worm's leftovers are the next worm's front door.
Slammer, or Sapphire, 25 January 2003
The fastest. CAIDA's measurements: it "doubled in size every 8.5 seconds", "infected more than 90 percent of vulnerable hosts within 10 minutes", and reached "over 55 million scans per second" across the Internet in under three minutes, infecting "at least 75,000 hosts". Its consequences reached far outside computing: "canceled airline flights, interference with elections, and ATM failures".
Why it was so fast. It was tiny, "a total size of only 376 bytes", so its whole self fitted in one UDP packet of 404 bytes, against "the 4kb size of Code Red, or the 60kb size of Nimda". And because UDP needs no reply, it never waited: Code Red "was latency limited", each thread waiting for a connection to answer or time out, while Slammer "was bandwidth-limited, allowing it to scan as fast as the compromised computer could transmit packets".
What it taught. That human response time is not fast enough. CAIDA's own reflection is that if such a worm had stopped scanning once it was finished, "it would likely take hours or days of effort simply to identify the attack". The patch had been available since before the flaw was even announced.
Worms, and the Ones That Made History
WannaCry, 12 May 2017
Ransomware that spread like a worm. CISA's alert records it "discovered the morning of May 12, 2017", spreading "over several hours" to "hundreds of thousands of infections in over 150 countries", asking a ransom of ".1781 bitcoins, roughly $300". It spread "via the MS17-010/EternalBlue SMBv1.0 exploit", and, as the alert notes, "Microsoft released a security update for the MS17-010 vulnerability on March 14, 2017", eight weeks earlier.
What it taught. That worms did not end with the 1990s; that the payload had become extortion; and that a patch nobody installs is not a defence. It is also why hospitals, railways and factories now treat patching as an operational duty rather than an IT convenience.
The run: what those numbers mean
CAIDA models a scanning worm as random constant spread: each infected host scans random addresses at a constant rate, so infections grow exponentially while targets are plentiful and level off as they run out. The listing works that model against the published figures. Nothing here scans anything; it is arithmetic.
# How fast a scanning worm spreads, worked from the figures its measurers published.
# The model is CAIDA's "random constant spread": each infected host scans random addresses,
# so infections grow exponentially at first and level off as targets run out.
import datetime, math
SPACE = 2 ** 32 # the IPv4 address space a random scanner draws from
def rate_constant(scans_per_second, vulnerable):
"""Chance per second that one infected host finds one more victim, early on."""
return scans_per_second * vulnerable / SPACE
def doubling(k):
return math.log(2) / k
def infected_after(seconds, k, vulnerable, start=1):
"""The logistic curve the model gives."""
growth = math.exp(k * seconds)
return vulnerable * start * growth / (vulnerable + start * (growth - 1))
# ---- 1. what scan rate the measured doubling time implies ------------------------------------
VULNERABLE = 75_000 # "at least 75,000 hosts", CAIDA on Slammer
MEASURED_DOUBLING = 8.5 # seconds, "8.5 (+/-1) seconds" in the first minute
k = math.log(2) / MEASURED_DOUBLING
needed = k * SPACE / VULNERABLE
print('1. SLAMMER, 25 JANUARY 2003: WHAT 8.5 SECONDS MEANS')
print(' vulnerable hosts %s, address space %s' % (format(VULNERABLE, ','), format(SPACE, ',')))
print(' a scan finds a victim once in %s tries' % format(SPACE // VULNERABLE, ','))
print(' to double every %.1f s, each infected host must scan about %s addresses a second'
% (MEASURED_DOUBLING, format(round(needed, -2), ',')))
print(' at 404 bytes a packet that is %.1f Mbit/s from every infected machine'
% (needed * 404 * 8 / 1e6))
# ---- 2. the exponential phase demands more bandwidth than the Internet had -------------------
PEAK_MEASURED = 55_000_000 # scans a second, the whole worm at its peak
demand = VULNERABLE * needed
print()
print('2. WHY THE GROWTH SLOWED')
print(' all %s hosts scanning at that rate: %s scans a second' % (format(VULNERABLE, ','),
format(round(demand), ',')))
print(' the peak actually measured: %s scans a second' % format(PEAK_MEASURED, ','))
print(' the worm asked for %.1f times the scanning the network would carry'
% (demand / PEAK_MEASURED))
# ---- 3. how long a random scanner needs to cover the address space ---------------------------
print()
print('3. COVERAGE AT THE MEASURED PEAK RATE (a random scanner repeats itself)')
for minutes in (1, 3, 10, 30):
scans = PEAK_MEASURED * minutes * 60
covered = 1 - math.exp(-scans / SPACE)
print(' after %2d minutes: %s scans, %.1f%% of all addresses tried at least once'
% (minutes, format(scans, ','), 100 * covered))
# ---- 4. Slammer against Code Red, from each one's own measured figures ------------------------
print()
print('4. TWO WORMS, EACH FROM ITS MEASURERS\' FIGURES')
CODE_RED = (359_000, 14 * 3600, 'Code Red, 19 July 2001')
SLAMMER = (VULNERABLE, 10 * 60, 'Slammer, 25 January 2003')
for hosts, seconds, label in (CODE_RED, SLAMMER):
doublings = math.log2(hosts)
print(' %-28s %s hosts in %s: %.1f doublings, one every %s'
% (label, format(hosts, ','),
'%d hours' % (seconds / 3600) if seconds >= 3600 else '%d minutes' % (seconds / 60),
doublings, ('%.0f minutes' % (seconds / doublings / 60)) if seconds / doublings > 60
else '%.1f seconds' % (seconds / doublings)))
# ---- 5. the window that was open, and how long it had been open ------------------------------
print()
print('5. THE PATCH WAS ALREADY OUT')
EVENTS = [('Slammer', 'CVE-2002-0649 published', datetime.date(2002, 8, 12),
datetime.date(2003, 1, 25)),
('WannaCry', 'MS17-010 released ', datetime.date(2017, 3, 14),
datetime.date(2017, 5, 12))]
for name, what, known, struck in EVENTS:
print(' %-9s %s %s, worm %s: %3d days in between'
% (name, what, known, struck, (struck - known).days))
print(' and Microsoft had shipped the SQL Server fix even before that flaw was announced')Worms, and the Ones That Made History
1. SLAMMER, 25 JANUARY 2003: WHAT 8.5 SECONDS MEANS
vulnerable hosts 75,000, address space 4,294,967,296
a scan finds a victim once in 57,266 tries
to double every 8.5 s, each infected host must scan about 4,700.0 addresses a second
at 404 bytes a packet that is 15.1 Mbit/s from every infected machine
2. WHY THE GROWTH SLOWED
all 75,000 hosts scanning at that rate: 350,240,526 scans a second
the peak actually measured: 55,000,000 scans a second
the worm asked for 6.4 times the scanning the network would carry
3. COVERAGE AT THE MEASURED PEAK RATE (a random scanner repeats itself)
after 1 minutes: 3,300,000,000 scans, 53.6% of all addresses tried at least once
after 3 minutes: 9,900,000,000 scans, 90.0% of all addresses tried at least once
after 10 minutes: 33,000,000,000 scans, 100.0% of all addresses tried at least once
after 30 minutes: 99,000,000,000 scans, 100.0% of all addresses tried at least once
4. TWO WORMS, EACH FROM ITS MEASURERS' FIGURES
Code Red, 19 July 2001 359,000 hosts in 14 hours: 18.5 doublings, one every 46 minutes
Slammer, 25 January 2003 75,000 hosts in 10 minutes: 16.2 doublings, one every 37.0 seconds
5. THE PATCH WAS ALREADY OUT
Slammer CVE-2002-0649 published 2002-08-12, worm 2003-01-25: 166 days in between
WannaCry MS17-010 released 2017-03-14, worm 2017-05-12: 59 days in between
and Microsoft had shipped the SQL Server fix even before that flaw was announcedWorms, and the Ones That Made History
What the run establishes, in order.
Doubling every 8.5 seconds is a demand for bandwidth. With 75,000 vulnerable machines in an address space of 4.3 billion, a random scan finds a victim about once in 57,000 tries, so to double every 8.5 seconds each infected machine must send about 4,700 scans a second, which at 404 bytes a packet is about 15 Mbit/s from every one of them. That is the meaning of bandwidth-limited.
The worm outgrew the network, which is why it slowed. All 75,000 hosts scanning at that rate would need about 350 million scans a second; the peak actually measured was 55 million, about six times less. CAIDA saw the same thing: growth slowed because "significant portions of the network did not have enough bandwidth to allow it to operate unhindered", and some networks shut down under the load.
A random scanner covers the address space quickly but repeats itself. At 55 million scans a second, 90 per cent of all addresses have been tried at least once after about three minutes. CAIDA's page puts this at "a little more than 10 minutes"; the figure that matters, and the one measured rather than modelled, is theirs: most vulnerable machines were infected within ten minutes.
The gap between the two worms is the whole story of the period. Code Red's 359,000 hosts in under 14 hours is a doubling about every 46 minutes; Slammer's 75,000 in 10 minutes is a doubling every 37 seconds. A defence that depends on somebody noticing, deciding and acting can work against the first and cannot work against the second.
Both had a patch. The flaw Slammer used was published in NIST's vulnerability database on 12 August 2002, 166 days before the worm, and CAIDA records that Microsoft's fix came out even before the flaw was announced. The flaw WannaCry used was patched on 14 March 2017, 59 days before. Neither worm defeated a defence; both found machines where the defence had not been applied.
Worms, and the Ones That Made History
Distinctions that carry marks
| Virus | Worm | |
|---|---|---|
| Needs a host program | yes | no |
| Spread depends on | a person running or opening something | the network and the worm's own scanning |
| Speed | days to weeks | minutes |
| Main defence | antivirus, care with files | patching, firewalls, blocking unused services |
| Code Red | Slammer | |
|---|---|---|
| Date | 19 July 2001 | 25 January 2003 |
| Size | about 4 kB | 376 bytes, one UDP packet |
| Limited by | latency, waiting for connections | bandwidth, the link's capacity |
| Doubling | about 46 minutes | 8.5 seconds |
| Hosts | more than 359,000 | at least 75,000 |
What beginners get wrong here
Saying a worm needs a user to open something. That is the virus, and the mass mailing worm; a network service worm arrives at a listening service and needs nobody.
Thinking the biggest worm was the fastest. Code Red infected far more machines than Slammer and spread hundreds of times more slowly; size of population and speed of spread are different things.
Giving the Morris worm one method. RFC 1135 lists sendmail's debug command, the fingerd overflow, trusted-host relationships, and password guessing.
Treating WannaCry as only ransomware. Its payload was ransomware; what made it an emergency was that it spread by itself through a network service.
Saying these attacks were unpatchable. For both Slammer and WannaCry the fix had been published, months and weeks earlier.
Quick revision
- Worm: self-replicating, self-contained, spreads without a user. Propagation: search, connect, copy and run.
- Morris, 2 Nov 1988: sendmail debug, fingerd overflow, rexec and rsh trusted hosts, password guessing. CERT/CC followed.
- Code Red, 19 July 2001: IIS; 359,000 hosts in under 14 hours; the first version's static seed crippled it.
- Nimda, 18 Sept 2001: five mechanisms, including back doors left by earlier worms.
- Slammer, 25 Jan 2003: 376 bytes, one UDP packet; doubling every 8.5 s; 90 per cent of vulnerable hosts in 10 minutes; bandwidth-limited, not latency-limited.
- WannaCry, 12 May 2017: ransomware over MS17-010 SMBv1; patch out since 14 March 2017; 150 countries.
- Random constant spread: exponential at first, levelling as targets run out; speed is scan rate times the density of targets.
Test yourself
1. What is a worm, and how does its propagation phase work? A worm is a self-replicating, self-contained program that usually runs without user intervention and uses network connections to spread from system to system. In its propagation phase it searches for other systems to infect, using host tables, address books, lists of trusted machines or randomly generated addresses; establishes a connection with a system it has found; and copies itself to it and causes the copy to run, whereupon the copy begins searching in turn.
Worms, and the Ones That Made History
2. Describe the Morris worm and what it exploited. Released on the evening of 2 November 1988, it attacked Sun workstations and VAXes running Berkeley Unix. It used a non-standard debug command in sendmail; an overflow in the finger daemon, where more characters were supplied than the gets routine could hold, letting the worm run code of its own; the trusted host relationships used in local networks through rexec and rsh, following hosts.equiv and .rhosts files; and guessing obvious passwords. It led to the creation of CERT/CC.
3. Why did Slammer spread so much faster than Code Red? Because of its size and its choice of protocol. Slammer was 376 bytes, so the whole worm travelled in one 404-byte UDP packet, against about 4 kB for Code Red. Code Red opened TCP connections and each of its threads had to wait for an answer or a timeout, so it was limited by network latency; Slammer needed no reply and could send scans as fast as the machine and its link allowed, so it was limited only by bandwidth. It therefore doubled every 8.5 seconds and infected more than 90 per cent of vulnerable hosts within ten minutes, while Code Red doubled about every 46 minutes.
4. What did Nimda demonstrate? That a worm using several routes at once cannot be stopped by closing one. CERT/CC recorded five mechanisms: email from client to client; open network shares; infection of clients browsing compromised web servers; scanning by clients for directory traversal flaws in IIS servers; and scanning for the back doors left behind by the earlier Code Red II and sadmind worms. That last one showed that the remains of one worm become the entry point of the next.
5. What do Slammer and WannaCry together say about patching? That in both cases the defence existed and had not been applied. The flaw Slammer used was recorded in the national vulnerability database on 12 August 2002, and Microsoft's fix was released even before the flaw was announced, yet the worm spread 166 days later; the flaw WannaCry used was patched on 14 March 2017 and the worm spread 59 days later. Neither worm broke a defence, so the practical lesson is that patching is an operational duty with a deadline, and that because a fast worm outruns human response, defences that do not depend on someone noticing, such as removing unused services and blocking them at the firewall, matter as well.
The rest of this subject
These notes are cut from the University's printed syllabus. Open the syllabus itself for the same subject.