Welcome to the Computer Security Wiki! You can help us by expanding stubs, create new articles and improve current articles.
You can also help us by logging-in or creating an account!


From Malware Wiki
Jump to: navigation, search

MultipleIssues.png This page has multiple issues. These issues most likely include issues with references and manual of style violations. Please help Malware Wiki by correcting these issues.

CreatorRobert "Tap" Morris, Jr.
DateNovember 2nd, 1988
OriginCornell, MIT*
Programming LanguageC
PlatformBSD, SunOS
Damage costs$1 million
This box: view  talk  edit

Morris (also known as the Internet Worm or the Great Worm) is one of the first internet worms. It was the first worm to gain significant media attention and the first to highlight the need for better network security. The worm infects Sun Microsystems Sun-3 systems and VAX computers running variants of 4BSD by exploiting holes in the debug mode of Unix's sendmail program. The worm was made at Cornell, but released at MIT to hide its origin.


The worm arrives on a system by exploiting vulnerabilities present in rsh, fingerd and sendmail in Solaris and BSD systems. If the worm determines that the new machine is infectible, it sends files to the new machine that download the main worm to it.


When Morris runs on a system, it performs several actions to prevent detection. It first sets its own argument to sh, the same process name as the Bourne Shell (a common command shell on Unix-based systems), which prevents the user from finding anything unusual among the running processes. The worm's core dump size is set to 0 bytes, so the worm cannot be found if it crashes or is forced to crash. The worm then reads the current time and stores it for future use.

The worm tries to load object files that are needed to run completely. The worm may run with a -p command line argument, which causes it to delete these files after loading them, and later deletes the disk copy of the running worm itself. It also tries to delete the file /tmp/.dumb. If it fails to load any of the files, does not have at least one object file in its commandline, or has not loaded the l1.c file that it uses to spread to other systems, the worm stops running. The worm then erases the text of the argument array to hide its presence.

The worm scans for network interfaces, as well as their flags and addresses. It will stop running if none are found. It will load the network mask which allows it to determine what addresses are used by the local network. It then kills the process from the -p option, while changing the current process group to avoid killing itself. This action completes the initializations and Morris calls its central routine.

Main Routine

After successfully infecting a system, Morris runs a routine called cracksome, which searches for potential hosts to infect. The worm will run another routine called other_sleep for thirty seconds. The worm will run cracksome again and then fork into two child processes and kill the parent process. The child has all of the information that the parent had; in addition, the child has a new process number, making the worm difficult to find. The Worm then runs through the infect process. The worm will then run other_sleep again for 120 seconds. The worm will also try to send one byte to port 11357 of the address (ernie.berkeley.edu), but this failed as the worm used the TCP command sendto rather than a UDP datagram. This was an attempt by the creator to monitor the worm's spreading over the Internet. If the worm has run for over 12 hours, it will clean up some of its host list entries. The worm checks its pleasequit variable and will stop running if it has used more than 10 words from its dictionary files for passwords.


Morris's cracksome routine searches for other systems to infect and attempts to break weak passwords. The worm reads through the file /etc/hosts.equiv for a list of machines to infect. Machines found with this file are specially tagged by the worm. It may find a second list in the /.rhosts file for infection at a later time. The worm takes advantage of a major security hole by reading the /etc/passwd file, which contains a list of all users on the machine and their encrypted passwords. The Worm will use the the /etc/passwd file to find personal .forward files, used to forward mail to other machines, to get the locations of additional machines to attack.

The worm then begins to attack the systems it found in the files it scanned. The worm will use its own encryption algorithm to choose a possible password, encrypt it, and check it against the encrypted passwords found in the /etc/passwd file. This way, the worm can try a password an infinite number of times without setting off any alarms for failed logins. The first set of password attempts are no password at all, the username, some variation on the username (spelled backwards, or appended to itself), the second value in the GECOS string found in /etc/passwd, remainder of the full name after the first name in the GECOS string (if the first letter is capitalized, it will be tried a second time in lower case) or the previously mentioned name in the GECOS string. The worm attacks 50 accounts each time cracksome is called and stops when it has gone through the list of accounts. Every 10 times cracksome is called, the worm will call the other-sleep function with a 0 argument.

Once the Morris worm has gone through the entire list of accounts, it turns to a built-in dictionary of nicknames, character names, and other names and words that are not found in a standard dictionary, but are reasonable choices for passwords. This dictionary is encrypted to confuse people trying to decompile the program. The worm decrypts the dictionary and tests the decryptions against the encrypted passwords in the /etc/passwd file. The worm may take 9 hours to complete the entire dictionary.

Finally, the worm will look for words in the file /usr/dict/words, a standard list of dictionary words. It will try lower case versions of words that are capitalized in the file. It is estimated that going through the entire file would take the worm 4 weeks.


The other_sleep routine attempts to find other worms on the system. When called, it checks the global variable other_fd. If this variable is negative, it waits the number of seconds specified by its argument, and then runs again. If the variable is not negative, the worm listens for signals from other worms on the network. If it detects a signal that might be another worm, the worms exchange two pre-specified numbers to check if they are related. If they are, the listening worm transmits a random number to the other worm. If the random number produced is odd, the pleasequit global variable in the listening worm is set to 1, causing it to exit once it reaches the bottom of the main loop. Otherwise, the pleasequit variable of the other worm is set to 1.


The worm's first determines whether a target system can be infected. This includes whether or not there is already a running worm on the target system, if the worm has made previous failed attempts to infect it, and if it even exists.

Once a legitimate target is found, the worm calls the other_sleep function with an argument of 1 and begins its attack routines. The first is called try_rsh. This attack method operates by creating a duplicate process that attempts to remotely execute on the target machine. If this child process succeeds in its task, it returns the file descriptors of the open pipe back to the main worm in order to receive the new worm process. If it fails, the file descriptors are closed, the child process is killed, and the worm attempts the try_fingerd method.

The try_fingerd attack method exploits a vulnerability in the Unix fingerd function, . The worm takes advantage of this, calling fingerd with a 536 character argument. This overwrites the 512 character buffer of the fingerd function. The additional 24 characters end up overwriting the system stack, which controls what functions are called next opening up command interpreter which the worm then uses to send itself to the target system. This was one of the more impressive aspects of the worm, as the Finger program is very simple and no one had thought to check for a vulnerability in the program until the worm appeared.

If either of the two techniques described above succeed, the routine sendworm is called, sending a set of object files to the target machine, including the program l1.c, which opens a connection to the original worm, allowing it to create a duplicate process in the new machine.

If the two other infection methods fail, the worm resorts to its try_sendmail attack routine. This routine takes advantage of a vulnerability in the TCP networks of BSD systems that allows someone to send mail to a process rather than a user account. The worm exploits this by sending a mail message with a carefully constructed recipient string. This string sets up a command that deletes the header of the message being sent and passes the body of the message to a command interpreter, causing it to subsequently compile a copy of code that then opens a connection and pulls a copy of the worm onto the new computer. If this attack fails, the control returns to its infect function, which marks the host as immune.


Due to an oversight in its structure, Morris's population control methods weren't executed as expected, causing the worm to spread at a tremendous rate. Computers all over the United States that were connected to the Internet crashed, froze, or were drastically slowed down. The estimated cost of dealing with the worm at each installation ranged from $200 to more than $53,000. Teams of programmers from Berkeley and Purdue Universities worked overnight to stop the worm and came up with two separate solutions, as they had little ability to communicate with each other. It took several days for the Internet to return to normal, as many sites had disconnected.

Total damages are unknown. John McAfee estimated that the damages were about $96 million, but some accused him of creating a self-serving estimate. Other estimates place the damage as high as $186 million. More reliable estimates place the toll at a mere $1 million, citing mostly downtime while cleaning computers of the worm. The number of computers infected was originally placed at 6,200 (10% of the internet at the time), but later lowered to about 2,000.

Other Facts

While Morris was able to perform its infection routines, some researchers have noted that the quality of the worm's coding is mediocre at best. One researcher cites examples of unused variables, unused routines, variables called before they are initialized, unreferenced routines and bugs, among other things. In many cases calls to system routines are not checked for success. Rather than using hash buckets or sorted lists, which could be implemented by an advanced computer science student, the worm searched through linear lists, which used more system resources and takes less programming knowledge. The creator also had the worm take little advantage of the root password being broken. The creator also had apparently little experience with UNIX shell coding, as in one shell script used by the worm uses the test line if [ -f sh ] to search for the presence of a file named sh. This allowed users to prevent infection by placing a directory named sh, which causes the test to fail.


Don Seeley, Department of Computer Science, University of Utah. "A Tour of the Worm."

Eugene H. Spafford, Department of Computer Sciences, Purdue University. "The Internet Worm Program: An Analysis", Purdue Technical Report CSD-TR-823. 1988.11.29, revised 12.08

Project MAC ("Switzerland") MIT Project on Mathematics and Computation, "The Robert Morris Internet Worm."