Are you tired of hearing how dangerous some sinister new piece of malicious code could be? Depressed by stories of how fiendishly successful malware writers are? I hear you, and that's why I asked my fellow ESET researchers for examples of malware failures, malicious code that did not work out as well as the folks behind it had hoped. They came up with plenty and I have written them up here, along with some thoughts on why creating perfect malware is just not possible.
Too Fast, Too Furious
One significant category of “bad” malware is code that spread too fast for its own good. We still see cases of this today, but the problem dates back to the early days of virus writing when some programmers sought the holy grail of “the good virus,” a piece of code that spread by itself and performed a useful task. While these efforts invariably fell short of their goal, sometimes with negative consequences, their creators were typically not interested in making money from them.
Achieving broad distribution in a short amount of time was sometimes seen as a goal in itself. However, even as virus code writing morphed into malicious code making, driven by greed-based goals such as building an army of compromised machines to rent out to bag guys, or stealing data from infected systems, the problem of “too much, too soon” continued to thwart some projects. As an example, consider Win32/Conficker.
Anyone who follows malware closely will be forgiven for groaning at the mere mention of Conficker, not least because it can honestly be described as “the malware that wouldn’t die.” Conficker has certainly garnered a lot of ink on We Live Security. First seen in 2008, it managed to infect millions of computers in a short period of time, presumably in an effort to create a large botnet that could be leveraged for profit (such as fees for use as a DDoS or spam engine). However, Conficker was so good at being infectious it not only attracted a lot of attention very quickly, it proved very difficult to eradicate. For example, Conficker was still #7 in the Virus Radar Top Ten Threats table for October of 2013.
[Update January 4, 2013: Conficker moved up to #6, see Global Threat Trends (.PDF)]
Ironically, Conficker inflicted massive costs on companies around the world even though its creators never got to leverage its moneymaking potential. While estimates of Conficker’s economic cost rose as high as $9.1 billion by 2009, an exact number is hard to calculate. Yet some affected companies were prepared to state their losses thereby allowing researchers to document many millions of dollars in lost revenue and productivity. As the Conficker Working Group fought to prevent the spread of the code, this comment from the SRI analysis of Variant C indicated how bad things could have been if Conficker had flown under the radar:
“if organized into a coordinated offensive weapon, this multimillion-node botnet poses a serious and dire threat to the Internet.”
Fortunately, as David Harley points out, Conficker “spread so rapidly and successfully that it quickly drew attention to itself from security researchers, operating system vendors, and law enforcement.” In effect, the entire malware campaign literally became “too hot” for the botnet operators to use, says Harley: “they ultimately ended up having to abandon their creation, without having made any substantial money off of it.”
More than a few would-be cyber criminals have failed the challenge of getting their malware out there in sufficient quantity to achieve their goals while at the same time avoiding attention that would scupper their plans. Consider the 2012 outbreak of Flashback, a Trojan that targeted Mac OS X systems. Partly because the world of OS X sees relatively few outbreaks of malicious code, Flashback drew attention to itself by its very success, prompting a reaction that meant its creators could not maximize revenue ahead of fixes that blocked it and prevented its spread. Flashback was a click fraud Trojan that could have been generating as much as $10,000 per day in revenue from hijacked ads although that is hard to verify. What we do know is that it was wiped out in relatively short order.
Testing and anticipating
We should not conflate two very different versions of the “too fast, too furious” problem. There is code that spreads too fast for the intended task, and code that spreads faster than its creator intended due to errors or oversights in coding. A classic and timely example of the latter is the Morris Worm which was released onto the Internet 25 years ago this month from an MIT computer by Cornel University graduate student Robert Tappan Morris. This self-replicating program
invaded VAX and Sun-3 computers running versions of Berkeley UNIX, and used their resources to attack still more computers. Within the space of hours this program had spread across the U.S., infecting hundreds or thousands of computers and making many of them unusable due to the burden of its activity. (A Tour of the Worm, Don Seeley.)
We know from subsequent studies of the incident that a rapid and crippling spread was not what the author of this code intended. Although the Internet was still evolving from the ARPANET research network at the time and only about 60,000 computers were connected to it, the worm infected about 6,000 of them, requiring them to be cleaned up (some had been crashed by the code and there was potential for unsaved research work to have been lost).
The Morris worm might have progressed to more it had been better written. Buggy code caused large numbers of unnecessary files to be created, making its presence felt. An ‘are you there?’ call was included in the worm, but a bug resulted in copies that didn’t respond appropriately to termination requests. When you read Gene Spafford’s The Internet Worm Program: An Analysis, you realize that testing of the worm before its release was inadequate to say the least. You could read that as good news if you attributed malicious motives to Robert Tappan Morris, in other words, it could have done more damage than it did; on the other hand, the bugs arguably led to discovery sooner rather than later, which was a good thing.
As our earlier examples showed, achieving the ideal rate of infection continues to be a challenge for those who would use malicious code for profit. I am not aware of any studies on how to optimize this aspect of malware but it should be possible to represent this is in a graph.
What is not possible is adequate testing of malware before it is released into the wild, which is called that for a reason. Predicting all of the possible permutations of system hardware and software and connectivity that your code will encounter is a practical impossibility. Even if you are targeting a known and closed environment, what guarantees do you have that it will not change tomorrow, the day after you release your code, introducing elements and eventualities which you did not foresee? Of course, if you don’t care about collateral damage from your efforts, the lack of adequate test facilities is not a problem, you just use the real world as your test bed.
The quality assurance issue
So, a lot of malware is released into the wild with bugs in the code, and this can be a good thing. Antivirus researchers are sometimes alerted to new malware due to it malfunctioning, and this may happen in time to prevent more widespread problems. In 1995 the world was introduced to macro viruses, spread by manipulation of Microsoft’s risky implementation of macro capabilities (macros, or stored and programmed keystroke sequences, had been safely implemented in the 1980s by Lotus and WordPerfect which stored them in special files, separate from document data; Microsoft chose to allow macros to be embedded in documents).
It did not take long for malware writers to see that a macro virus could be used to spread an executable virus file and this was tried with WM/Nuclear which carried a virus dropper. This could have enabled a file or boot infection, but due to poor coding, that element of the malware failed (it did succeed in erasing system files on April 5 on some machines, as well as adding a message protesting French nuclear testing in the Pacific to some print jobs). What this malware did achieve is alerting more security people to the potential impact of macro viruses.
The Win32/Bugbear worm was designed to spread via email as an attachment and drop a backdoor or keylogger Trojan on infected systems. It also tried to spread by copying itself with a random file name to shared folders on infected systems but failed to distinguished between shared resources, thereby causing networked printers to spew binary garbage (unintentionally alerting users of the network to the fact that they had a problem).
Sometimes poor quality has curious knock-on effects. Consider Win32/Magistr, a particularly nasty memory resident worm that appeared in 2001 and contained code to overwrite all disk files with the text “YOUARESHIT” and erase CMOS and flash, and hard drive data. The virus had numerous bugs which led to meaningless email output and file infections that simply destroyed the target executable. One intended function of the code was to infect one of the files in the Windows directory, copy it to shared volumes, then email it as an attachment, an infected executable. This likely led to something called the sulfnbk.exe hoax, a warning message that went viral in email, probably because, as David Harley put it, “someone assumed that an infected copy of the file was ‘the virus’ rather than one example of a file infected by the virus.” This was back around 2001 when as David points out, “there was a persistent miasma of misinformation based on confusion between infected files and the actual virus, and it spilled over into more than one virus hoax.”
One of the first well-known viruses of the DOS era was Jerusalem and it had a self-infection check. This became standard practice in malware to prevent all manner of bad outcomes that could occur if self-replicating code tried to infect itself. However, a bug in the first version of Jerusalem, which spread via disk infection, caused it to add itself to the end of .EXE files repeatedly, until the program file was too big to fit into memory. In some cases, the virus did not detect the end of files correctly, and would overwrite parts of them, rendering them useless. Another DOS era virus, Pakistani Brain, which first appeared in 1987, overwrote the last cluster on floppy disks, marking it as bad in the File Allocation Table (FAT) regardless of whether there was anything stored there or not.
In 1991, the first DOS cluster virus appeared: Dir II virus. Also referred to as a file “underwriting” virus Dir II stored its code in a cluster on the disk, and modified the directory entry table (DET) portion of the file allocation table so that executable files pointed to that cluster as the start of the file. It then stored the location of the original starting cluster in unused fields of the DET. This caused no problems while the virus was resident in memory to handle the translocation of the starting cluster, but if a user ran the CHKDSK utility, or removed the virus without fixing the DET entries, all the files on the disk ended up being crosslinked to the virus code.
When Whale appeared in 1991 was, at 9216 bytes, the largest virus yet seen. It had 32 “heads” and indeed due to its complexity didn’t always work. One of the problems was the ‘in memory’ on-the-fly encryption/decryption of the routines and the size of the pre-fetch queue. That was bytes on the 8088 (more common processor) but 6 bytes on the 8086 (less common) and would fail on those systems. Antivirus pioneer Dr. Alan Solomon wrote: “This virus is so large and clumsy that on most computers it doesn’t actually work at all. As a result, the main replication method is anti-virus researchers sending specimens to each other.”
A pattern can be perceived here: virus writers failing to anticipate the conditions under which their code is run. This is one of the most persistent causes of “bad” malware, ironically reminiscent of that highly persistent cause of vulnerabilities in “good” software, failure to think what happens if the code is not run in the intended manner or for the intended purpose. (For example: “Here is an easy way for a document to carry out simple tasks automatically, upon opening, with no need for any user interaction. What could possibly go wrong?”)
Clearly, malicious code writing has not grown out of this problem. Take the relatively recent field of smartphone infection. The worm called SymbOS/Cabir that propagates through Bluetooth enabled Nokia phones hunts for other phones even when there was no provider network in range, thereby draining the infected phone’s battery.
Hopefully, this review of malware gone bad will help you see malware writers as the flawed creatures they are. Whether they are driven by the hubris of thinking themselves the exception to the rule and can achieve what nobody else has, the "good virus", or they are careless criminals who get caught or stopped due to their coding errors, malware makers are not as formidable as the headlines sometimes portray them. Maybe my next foray into the realm of reassurance will be cases of "criminals caught on YouTube," which happens more than you might think.
Many thanks to fellow researchers David Harley, Righard Zwienenberg, and Aryeh Goretsky, for feeding me examples of malware mistakes, the most persistent of which continues to be the belief that you, the creator of a piece of malware, can predict exactly what will happen after it is released.