DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T p

⟦9b267033e⟧ TextFile

    Length: 36112 (0x8d10)
    Types: TextFile
    Names: »program.latex«

Derivation

└─⟦4f9d7c866⟧ Bits:30007245 EUUGD6: Sikkerheds distributionen
    └─⟦f36518b41⟧ »./worm/mit.tex.tar.z« 
        └─⟦87f8973c9⟧ 
            └─⟦this⟧ »program.latex« 

TextFile

%%%%
%%%% The Internet Virus of November 3, 1988
%%%% Mark W. Eichin, MIT Project Athena
%%%% 
%%%% $Header: program.latex,v 1.35 89/02/09 21:26:46 jon Locked $
%%%% $Log:	program.latex,v $
%%%% Revision 1.35  89/02/09  21:26:46  jon
%%%% fix unknown label ... stupid mistake
%%%% 
%%%% Revision 1.34  89/02/09  14:09:37  jon
%%%% slight re-wording
%%%% 
%%%% Revision 1.33  89/02/09  00:18:30  jon
%%%% move the information flow figure to the beginning
%%%% 
%%%% Revision 1.32  89/02/08  22:58:34  jon
%%%% remove l1pic and try to fix PATH= formatting problems
%%%% 
%%%% Revision 1.31  89/02/08  18:52:23  jon
%%%% fix awful formatting glitch by using \verbatim
%%%% 
%%%% Revision 1.28  89/02/05  22:31:23  eichin
%%%% Some slight wording changes and some typos.
%%%% 
%%%% Revision 1.27  89/01/28  22:41:56  jon
%%%% fix poor word choice and bad formatting
%%%% 
%%%% Revision 1.26  89/01/27  23:46:26  jon
%%%% fix many typos and some wording
%%%% try to turn the postscript figures into real figures
%%%% 
%%%% Revision 1.25  89/01/20  18:30:41  jon
%%%% fix figure label
%%%% 
%%%% Revision 1.24  89/01/20  00:27:53  jon
%%%% fix mispelling of label and add a figure
%%%% 
%%%% Revision 1.23  89/01/20  00:05:35  jon
%%%% chaper --> section (report --> article)
%%%% 
%%%% Revision 1.22  89/01/19  23:46:51  jon
%%%% typo's pointed out by map.
%%%% 
%%%% Revision 1.21  89/01/19  23:14:29  jon
%%%% reworking of h routine section and hit section plus minor fixes.
%%%% 
%%%% Revision 1.20  89/01/19  01:04:10  jon
%%%% typo fix
%%%% 
%%%% Revision 1.19  89/01/19  00:30:03  jon
%%%% add 2 labels and make references to ports consistent.
%%%% 
%%%% Revision 1.17  89/01/18  14:16:13  jon
%%%% minor changes (prashing, grammar)
%%%% 
%%%% Revision 1.16  88/12/15  22:10:40  jon
%%%% fix typo
%%%% 
%%%% Revision 1.15  88/12/15  22:08:53  jon
%%%% remove GECOS footnote
%%%% 
%%%% Revision 1.14  88/12/13  16:15:19  jon
%%%% \please -> 
%%%% \variable
%%%% 
%%%% Revision 1.13  88/12/10  19:56:17  jon
%%%% minor bogus word fixes and remove second definition of the loopback
%%%% address.
%%%% 
%%%% Revision 1.11  88/11/29  03:56:39  jon
%%%% *** empty log message ***
%%%% 
%%%% Revision 1.10  88/11/28  23:58:07  jon
%%%% add two labels
%%%% 
%%%% Revision 1.9  88/11/28  20:28:25  jon
%%%% *** empty log message ***
%%%% 
%%%% Revision 1.8  88/11/23  04:11:00  eichin
%%%% added pictures.
%%%% 
%%%% Revision 1.7  88/11/23  01:18:11  jon
%%%% remove "stats it" buzzword.
%%%% 
%%%% Revision 1.6  88/11/22  23:33:32  jon
%%%% ran ispell
%%%% 
%%%% Revision 1.5  88/11/22  16:08:35  eichin
%%%% added mkdir label, for strategy reference
%%%% 
%%%% Revision 1.4  88/11/22  11:48:43  eichin
%%%% fixed $$ problems
%%%% 
%%%% Revision 1.3  88/11/22  10:22:30  eichin
%%%% added section on names, and cleaned up some typesetting
%%%% 
%%%% Revision 1.2  88/11/22  07:36:56  eichin
%%%% added most of Bill Sommerfeld's comments. Cleaned up most of type
%%%% style as well.
%%%% 
%%%%
\section{The Program}
\label{progappendix}

\iffalse
XS.c XS96.c checkother.c cksub.c crack1.c crack3.c crack3sub.c
decode.c decode2.c hit_finger.c hit_rexec.c hitshell.c if_init.c
justreturn.c makemagic.c other_sleep.c s1778.c s21e0.c strreverse.c
stuffsmtp.c
\fi

This Appendix describes the virus program subroutine by subroutine.
For reference, the flow of information among the subroutines is
shown in Figure \ref{collectfig}.

\begin{figure*}[tp]
\vspace{7.7in}
\special{psfile=collect.ps hoffset=-36 voffset=-108}
\caption{The structure of the attacking engine.\label{collectfig}}
\end{figure*}

\subsection{Names}
The core of the virus is a pair of binary modules, one for the VAX
architecture and the other for the Sun architecture. These are
linkable modules, and thus have name lists for their internal
procedures. Many of the original names are included here with the
descriptions of the functions the routines performed.

It is surprising that the names are included, and astonishing that
they are meaningful. Some simple techniques, such as randomizing the
procedure names, would have removed a number of clues to the function
of the virus.

\subsection{main}
The main module, the starting point of any C language program, does
some initialization, processes its command line, and then goes off
into the loop which organizes all of the real work.

\subsubsection{Initialization}

The program first takes some steps to hide itself. It changes the
``zeroth'' argument, which is the process name, to \prog{sh}. Thus, no
matter how the program was invoked, it would show up in the process
table with the same name as the Bourne Shell, a program which often
runs legitimately.

The program also sets the maximum core dump size to zero blocks. If
the program crashed\footnote{For example, the virus was originally
compiled using 4.3BSD declaration files. Under 4.2BSD, the alias name
list did not exist, and code such as the virus which assumes aliases
are there can crash and dump core.} it would not leave a core dump
behind to help investigators. It also turns off handling of write
errors on pipes, which normally cause the program to exit.

The next step is to read the clock, store the current time in a local
variable, and use that value to seed the random number generator.

\subsubsection{Command line argument processing}
The virus program itself takes an optional argument \prog{-p} which must
be followed by a decimal number, which seems to be a process id of the
parent which spawned it. It uses this number later to kill that
process, probably to ``close the door'' behind it.

The rest of the command line arguments are ``object names''. These are
names of files it tries to load into its address space. If it can't
load one of them, it quits. If the \prog{-p} argument is given, it
also deletes the object files, and later tries to remove the disk
image of running virus, as well as the file
\filename{/tmp/.dumb}. (This file is not referenced anywhere else in
the virus, so it is unclear why it is deleted.)

The program then tried a few further steps, exiting (``bailing out'')
if any of them failed:
\begin{items}
\item It checked that it had been given at least one object on the
command line.
\item It checked to see if it had successfully loaded in the object
\filename{l1.c}.
\end{items}

If the ``-p'' argument was given, the program closes all file
descriptors, in case there are any connections open to the parent.

The program then erases the text of the argument array,
to further obscure how it was started (perhaps to hide anything if one
were to get a core image of the running virus.)

It scans all of the network interfaces on the machine, gets the flags
and addresses of each interface. It tries to get the point-to-point
address of the interface, skipping the loopback address. It also
stores the netmask for that network \cite{rfc950}.

Finally, it kills off the process id given with the ``-p'' option. It
also changes the current process group, so that it doesn't die when
the parent exits. Once this is cleaned up, it falls into the
\subroutine{doit} routine which performs the rest of the work.

\subsection{doit routine}
This routine is where the program spends most of its time.

\subsubsection{Initialization}
Like the main routine, it seeds the random number generator with the
clock, and stores the clock value to later measure how long the virus
has been running on this system.

It then tries \subroutine{hg}. If that fails, it tries
\subroutine{hl}. If that fails, it tries \subroutine{ha}.

It then tries to check if there is already a copy of the virus running
on this machine. Errors in this code contributed to the large amounts
of computer time taken up by the virus. Specifically:
\begin{items}
\item On a one-in-seven chance, it won't even try to test for another
virus.
\item The first copy of the virus to run is the only one which
listens for others; if multiple infections occur ``simultaneously''
they will not ``hear'' each other, and all but one will fail to listen
(see section~\ref{interlock}).
\end{items}

The remainder of the initialization routine seems designed to send a
single byte to address 128.32.137.13, which is \host{ernie.berkeley.edu},
on port 11357. This never happens, since the author used the
\subroutine{sendto} function on a TCP stream connection, instead of a
UDP datagram socket.\footnote{If the author had been as careful with
error checking here as he tried to be elsewhere, he would have noted
the error ``socket not connected'' every time this routine is
invoked.} We have no explanation for this; it only tries to send this
packet with a one in fifteen random chance.

\subsubsection{Main loop}
An infinite loop comprises the main active component of the virus. It
calls the \subroutine{cracksome} routine\footnote{This name was actually in
the symbol table of the distributed binary!} which tries to find some
hosts that it can break in to. Then it waits 30 seconds,
listening for other virus programs attempting to break in, and tries
to break into another batch of machines.

After this round of attacks, it forks, creating two copies of the
virus; the original (parent) dies, leaving the fresh copy. The child
copy has all of the information the parent had, while not having the
accumulated CPU usage of the parent. It also has a new process id,
making it hard to find.

Next, the \subroutine{hg}, \subroutine{hl}, and \subroutine{ha}
routines search for machines to infect (see Appendix \ref{hroutines}). The
program sleeps for 2 minutes, and then checks to see if it has been
running for more than 12 hours, cleaning up some of the entries in the
host list if it has.

\label{pleasequit}
Finally, before repeating, it checks the global variable
\variable{pleasequit}. If it is set, {\it and}\ if it has tried more
than 10 words from its own dictionary against existing passwords, it
quits. Thus forcing \variable{pleasequit} to be set in the system
libraries will do very little to stem the progress of this
virus\footnote{Although it was suggested very early \cite{spaf1}.}.

\subsection{Cracking routines}
This collection of routines is the ``brain'' of the virus.
\subroutine{cracksome}, the main switch, chooses which of four
strategies to execute. It is would be the central point for adding
new strategies if the virus were to be further extended. The virus
works each strategy through completely, then switches to the next
one. Each pass through the cracking routines only performs a small
amount of work, but enough state is remembered in each pass to
continue the next time around.

\subsubsection{cracksome}
The \subroutine{cracksome} routine is the central switching routine of the
cracking code. It decides which of the cracking strategies is actually
exercised next. Again, note that this routine was named in the global
symbol table. It could have been given a confusing or random name, but
it was actually clearly labelled, which lends some credence to the
idea that the virus was released prematurely.

\subsubsection{Phase 0}
\label{phase0}
The first phase of the \subroutine{cracksome} 
routines reads through the \filename{/etc/hosts.equiv} file
to find machine names that would be likely targets. While this file
indicates what hosts the current machine trusts, it is fairly common
to find systems where all machines in a cluster trust each other, and
at the very least it is likely that people with accounts on this machine will
have accounts on the other machines mentioned in \filename{/etc/hosts.equiv}.

It also reads the \filename{/.rhosts} file, which lists the set of machines
that this machine trusts root access from. Note that it does not take
advantage of the trust itself \cite{baldwin} but merely
uses the names as a list of additional machines to attack. Often,
system managers will deny read access to this file to any user other
than root itself, to avoid providing any easy list of secondary
targets that could be used to subvert the machine; this practice would 
have prevented the virus from discovering those names, although
\filename{/.rhosts} is very often a subset of \filename{/etc/hosts.equiv}.

The program then reads the entire local password file,
\filename{/etc/passwd}. It uses this to find personal \filename{.forward}
files, and reads them in search of names of other machines it can
attack. It also records the user name, encrypted password, and {\it
GECOS}
%%%\footnote{one of the fields of the UNIX user information data.
%%%It is only named in the documentation on changing it, the original
%%%meaning seems to have been lost.}
information string, all of which are
stored in the \filename{/etc/passwd} file. Once the program 
scanned the entire file, it advanced to Phase 1.

\subsubsection{Phase 1}
\label{obviouspw}
This phase of the cracking code attacked passwords on the local
machine. It chose several likely passwords for each user, which were
then encrypted and compared against the encryptions obtained in Phase
0 from \filename{/etc/passwd}:
\begin{items}
\item No password at all.
\item The user name itself.
\item The user name appended to itself.
\item The second of the comma separated {\it GECOS} information fields,
which is commonly a nickname.
\item The remainder of the full name after the first name in the
{\it GECOS} fields, i.e. probably the last name, with the first letter
converted to lower case.
\item This ``last name'' reversed.
\end{items}

All of these attacks are applied to fifty passwords at a time from
those collected in Phase 0. Once it had tried to guess the
passwords for all local accounts, it advanced to Phase 2.

\subsubsection{Phase 2}
Phase 2 takes the internal word list distributed as part of the
virus (see Appendix~\ref{dict}) and shuffles it. Then it takes
the words one at a time and decodes them (the high bit is set on all
of the characters to obscure them) and tries them against all
collected passwords. It maintains a global variable \variable{nextw}
as an index into this table. The main loop uses this to
prevent \variable{pleasequit} from causing the virus to exit until
at least ten of the words have been checked against all of the
encryptions in the collected list.

Again, when the word list is exhausted the virus advances to Phase 3.

\subsubsection{Phase 3}
Phase 3 looks at the local \filename{/usr/dict/words} file, a 24474
word list distributed with 4.3BSD (and other UNIX systems) as a
spelling dictionary. The words are stored in this file one word per
line. One word at a time is tried against all encrypted passwords. If
the word begins with an upper case letter, the letter is converted to
lower case and the word is tried again.

When the dictionary runs out, the phase counter is again advanced to 4
(thus no more password cracking is attempted).

\subsection{H routines}
\label{hroutines}
The ``h routines'' are a collection of routines with short names,
such as \subroutine{hg}, \subroutine{ha}, 
\subroutine{hi}, and \subroutine{hl}, which search for other hosts to attack.

\subsubsection{hg}
The \subroutine{hg} routine calls \subroutine{rt\_init} (if it has not
already been called) to scan the routing table, and records all
gateways except the loopback address in a special list.  It then tries
a generic attack routine to attack via \prog{rsh},
\prog{finger}, and SMTP.  It returns after the first successful attack.

\subsubsection{ha}
\label{ha}
The \subroutine{ha} routine goes through the gateway list and
connects to TCP port 23, the telnet port, looking for gateways which are
running telnet listeners.  It randomizes the order of such gateways
and calls 
\subroutine{hn} (our name) with the network number of each gateway.
The \subroutine{ha} returns after \subroutine{hn} reports that it has
succeeded broken into a host.

\subsubsection{hl}
The \subroutine{hl} routine iterates through all the addresses for the
local machine calling \subroutine{hn} with the network number for
each one.  It returns if \subroutine{hn} indicates success in breaking
into a host.

\subsubsection{hi}
The \subroutine{hi} routine goes through the internal host list (see
section~\ref{phase0}) and tries to attack each host via \prog{rsh},
\prog{finger}, and SMTP.  It returns if when one host is infected.

\subsubsection{hn}
\label{hn}
The \subroutine{hn} routine (our name) followed \subroutine{hi} takes a
network number as an argument.  Surprisingly it returns if the network
number supplied is the same as the network number of any of the
interfaces on the local machine.  For Class A addresses it uses the
Arpanet IMP convention to create possible addresses to attack
(net.[1-8].0.[1-255]).  For all other networks it guesses hosts number
one through 255 on that network.  It randomizes the order of this list of possible
hosts and tries to attack up to twenty of them using \prog{rsh},
\prog{finger}, and SMTP.  If a host does not accept connections on
TCP port 514, the \prog{rsh} port, \subroutine{hn} will not try to
attack it. If a host is successfully attacked \subroutine{hn} returns.

\subsubsection{Usage}
The ``h routines'' are called in groups in the main loop; if the first
routine succeedes in finding a vulnerable host the remaining routines
are not called in the current pass. 
Each routine returns after it finds one vulnerable host.  The
\subroutine{hg} routine is always called first, which indicates the virus
really wanted to infect gateway machines.  Next comes \subroutine{hi}
which tried to infect normal hosts found via \subroutine{cracksome}.
If \subroutine{hi} fails, \subroutine{ha} is called, which seemed to try
breaking into hosts with randomly guessed addresses on the far side of
gateways.  This assumes that all the addresses for gateways had been
obtained (which is not trivial to verify from the convoluted code in
\subroutine{{rt init}}),
and implies that the virus would prefer to infect a gateway and from
there reach out to the gateway's connected networks, rather than
trying to hop the gateway directly.  If \subroutine{hg},
\subroutine{hi}, and \subroutine{ha} all failed to infect a host, then
\subroutine{hl} is called which is similar to \subroutine{ha} but uses
for local interfaces for a source of networks.

It is not clear that \subroutine{ha} and \subroutine{hl} worked.
Because \subroutine{hn} returns if the address is local,
\subroutine{hl} appears to have no chance of succeeding.  If alternate
addresses for gateways are indeed obtained by other parts of the virus
then \subroutine{ha} could work.  But if only the addresses in the
routing table were used it could not work, since by definition these
addresses must be on a directly connected network.  Also, in our
monitoring we never detected an attack on a randomly generated
address.  These routines do not seem to have been functional.

\subsection{Attack routines}
There are a collection of attack routines, all of which try to obtain a
Bourne Shell running on the targeted machine. See Appendix \ref{hook} for a
description of the
\filename{l1.c} program, used by all the attack routines.


\subsubsection{hu1}
The \subroutine{hu1} routine is called by the Phase 1 and Phase 3
\subroutine{cracksome} subroutines. Once a password for user name
guessed correctly, this routine is called with a host name read from
either the user's
\filename{.forward} or \filename{.rhosts} files.  In order to assume
the user's id it then tries to
connect to the local machine's \prog{rexec} server using the guessed
name and password.  If successful it runs an \prog{rsh} to
the target machine, trying to execute a Bourne Shell, which it uses to
send over and compile the
\filename{l1.c} infection program. 

\subsubsection{Hit SMTP}
This routine make a connection to TCP port 25, the SMTP port, of a remote
machine and used it to take advantage of the sendmail bug. It
attempts to use the debug option to make \prog{sendmail} run a
command (the ``recipient'' of the message), which transfers the
\filename{l1.c} program included in the body of the message.

\subsubsection{Hit finger}
The ``hit finger'' routine tries to make a connection to TCP port 79, the finger
port, of the remote machine. Then it creates a ``magic packet'' which
consists of
\begin{items}
\item A 400 byte ``runway'' of VAX ``nop'' instructions, which can be
executed harmlessly.
\item A small piece of code which executes a Bourne Shell.
\item A stack frame, with a return address which would hopefully point
into the code.
\end{items}

Note that the piece of code is VAX code, and the stack frame is a VAX
frame, in the wrong order for the Sun. Thus, although the Sun finger
daemon has the same bug as the VAX one, this piece of code cannot
exploit it.

\begin{figure*}[tp]
\begin{verbatim}
        pushl   $68732f         push '/sh<NUL>'
        pushl   $6e69622f       push '/bin'
        movl    sp,r10          save address of start of string
        pushl   $0              push 0 (arg 3 to execve)
        pushl   $0              push 0 (arg 2 to execve)
        pushl   r10             push string addr (arg 1 to execve)
        pushl   $3              push argument count
        movl    sp,ap           set argument pointer
        chmk    $3b             do "execve" kernel call.
\end{verbatim}
\caption{VAX intructions for the \prog{finger} attack.\label{vaxcode}}
\end{figure*}

The attack on the finger daemon is clearly a lysogenetic ``viral''
attack (see Section~\ref{rose}), since although a worm doesn't modify
the host machine at all, the finger attack does modify the running
finger daemon process.  The ``injected DNA'' component of the virus
contained the VAX instructions shown in Figure~\ref{vaxcode}.

The \subroutine{execve} system call causes the current process to be
replaced with an invocation of the named program; \filename{/bin/sh}
is the Bourne Shell, a UNIX command interpreter.  In this case, the
shell winds up 
running with its input coming from, and its output going to, the
network connection.  The virus then sends over the \filename{l1.c}
bootstrap program.

\subsubsection{Hit rsh}
This unlabeled routine
%%%\footnote{at $21e0_{16}$}
tries \prog{rsh} to the
target host (assuming it can get in as the current user). It tries
three different names for the \prog{rsh} binary,
\begin{items}
\item \filename{/usr/ucb/rsh}
\item \filename{/usr/bin/rsh}
\item \filename{/bin/rsh}
\end{items}
If one of them succeeds, it tries to resynchronize (see
Appendix~\ref{resynch}) the connection; if that doesn't succeed within
thirty seconds it kills off the child process. If successful the
connection can then be used to launch the \filename{l1.c} ``grappling
hook'' program at the victim.

Note that this infection method doesn't specify a user name to attack;
if it gets into the remote account, it is because the user that the
virus is running as also has an 
%%% due to the user having an
account on the other machine which trusts the originating machine.

\subsubsection{Hit rexec}
The \subroutine{{hit rexec}} routine uses the remote
execution system which is similar to \prog{rsh}, but designed for use by
programs. It connects and sends the user name, the password, and
\filename{/bin/sh} as the command to execute. 
%%% It checks to see if the
%%% request succeeded, and tries to use one of the password/account
%%% pairs guessed earlier to get in.

\subsubsection{makemagic}
This routine tries to make a telnet connection to each of
the available addresses for the current victim. It broke the connections
immediately, often producing error reports from the telnet
daemon, which were recorded, and provide some of the earliest reports
of attack attempts.\footnote{On fast machines, such as the DEC VAX
3200, there may be no record of these attacks, since the connection is
handed off fast enough to satisfy the daemon.}

If it succeedes in reaching the host, it creates a TCP listener on a
random port number which the infected machine would eventually connect
back to.

\subsection{Grappling Hook}
\label{hook}
A short program, named \filename{l1.c}, is the common grappling
hook 
\iffalse
(See section~\ref{l1pic} for an overview.)
\fi
that all of
the attack routines use to pull over the rest of the virus. It is robustly
written, and fairly portable. It ran on a number of machines which
were neither VAX or Sun, loading them down as well, but only making
them peripheral victims of the virus.

The first thing it does is delete the binary it was running from. It
checks that it has three arguments (exiting if there aren't three of
them). It closes all file descriptors and then forks, exiting if the
fork fails.  If it succeeds, the parent exits; this leaves no
connection from the child to the infection route.

Next, it creates a TCP connection back to the address given as
the first argument, and the port given as the second. Then it sends
over the magic number given as the third. The text of each argument is
erased immediately after it is used. The stream connection is then
reused as the program's standard input and output.

A loop reads in a length (as a network byte order 32-bit integer) and
then a filename.  The file is unlinked and opened for write, and then
the file itself is read in (using the number of bytes read in
earlier.) On any error, all of the files are unlinked. If the length
read in is -1, the loop exits, and a Bourne Shell is executed
(replacing the \filename{l1} program, and getting its input from the
same source.)

\subsection{Install Routines}
There are a variety of routines used to actually move the virus from
one machine to the other. They deal with the ``virus protocol''
connection made by the \filename{l1.c} injected program or with the shell
that it spawns.

\subsubsection{resynch}
\label{resynch}
The \subroutine{resynch} routine sends commands to a remote shell,
requesting that it echo back a specific randomly chosen number. It
then waits a certain amount of time for a response. This routine is
used to indicate when the various subprograms of the infection procedure
have compiled or executed and a Bourne Shell prompt is available
again.

\subsubsection{waithit}
\label{mkdir}
This routine does much of the high level work. It waits (up to 2
minutes) for a return connection from a victim (which has had
\filename{l1.c} injected into it.) It then tries to read a magic
number (which had been previously sent to that victim as a command
line argument to the \filename{l1} program) and gives up after ten
seconds.

After the connection is established, all of the current ``objects'' in
storage in the virus are fed down the connection into the victim. Then
it tries to resynchronize, and if it succeeds, sends down commands to
\begin{items}
\item set the \command{PATH} of the victim shell
\item try to delete \prog{sh} in the current directory (\filename{/usr/tmp})
\item if the delete fails, pick a random name to use
instead~\footnote{Since the delete command used (\command{rm -f}) did not
remove directories, creating a directory \filename{/usr/tmp/sh}
stoped the virus\cite{spaf2}.  However, the virus would still use CPU
resources attempting to link the objects, even though it couldn't
write to the output file (since it was a directory).} 
\item scan the list of objects, looking for names ending in \filename{.o}
\item link and run each of these, with the command line arguments
\begin{items}
\item \command{-p \$\$}, where \command{\$\$} is the process id of the victim
shell
\item each object name
\end{items}
\item resynchronize; if this fails, assume that the virus succeeded
(since the \command{-p} option tells the virus to kill off the parent
shell) and set flag bit 1 of the host list entry (the host list is
detailed in section~\ref{hosts}).
\item delete the compiled program, and go on to the next object.
\end{items}

Thus, to add another machine type, the virus merely needs to be
started with a new object binary as a command line option, which will
then be propagated to the next infected host and tried.

Note that the path used here was
\filename{PATH=} \filename{bin: } \filename{/usr/bin: } \filename{/usr/ucb}
which is certainly reasonable on most systems. This protects
systems with ``unusual'' filesystem layouts, and suggests that complete
consistency among systems makes them more vulnerable.

\subsection{Host modules}
\label{hosts}
These are a set of routines designed to collect names and addresses of
target hosts in a master list.  Each entry contains up to six
addresses, up to twelve names, and a flags field.

\subsubsection{Name to host}
This routine searches the host list for a given named host, returns
the list entry describing it, and optionally adds it to the list if it
isn't there already.

\subsubsection{Address to host}
This routine searches the host list for a given host address, returns
the list entry describing it, and optionally adds it to the list if it
isn't there already.

\subsubsection{Add address/name}
These two routines added an address or a name to a host list entry,
checking to make sure that the address or name was not already known.

\subsubsection{Clean up table}
This routine cycles through the host list, and removes any hosts which
only have flag bits 1 and 2 set (and clears those bits.) Bit 1 is set
when a resynchronize (in \subroutine{waithit}) fails, probably indicating
that this host ``got lost''. Bit 2 is set when a named host has no
addresses, or when several different attack attempts fail. Bit 3 is
set when Phase 0 of the crack routines successfully retrieves an
address for the host.

\subsubsection{Get addresses}
This routine takes an entry in the host table and tries to fill in the the
gaps. It looks up an address for a name it has, or looks up a name for the
addresses it has. It also includes any aliases it can find.

\subsection{Object routines}
These routines are what the system uses to pull all of its pieces into
memory when it starts (after the host has been infected) and then to
retrieve them to transmit to any host it infects.

\subsubsection{Load object}
This routine opens a file, determines its length, allocating the
appropriate amount of memory, reads it in as one block, decodes the
block of memory (with XOR). If the object name contains a comma, it
moves past it and starts the name there.

\subsubsection{Get object by name}
This routine returns a pointer to the requested object. This is used
to find the pieces to download when infecting another host.

\subsection{Other initialization routines}

\subsubsection{if init}
This routine scans the array of network interfaces. It gets the flags
for each interface, and makes sure the interface is UP and RUNNING
(specific fields of the flag structure). If the entry is a point
to point type interface, the remote address is saved and added to the
host table. It then tries to enter the router into the list of hosts
to attack.

\subsubsection{rt init}
This routine runs \prog{netstat -r -n} as a subprocess. This shows the
routing table, with the addresses listed numerically. It gives up
after finding 500 gateways. It skips the default route, as well as the
loopback entry. It checks for redundant entries, and checks to see if
this address is already an interface address. If not, it adds it
to the list of gateways.

After the gateway list is collected, it shuffles it and enters the
addresses in the host table.

\subsection{Interlock routines}
\label{interlock}
The two routines \subroutine{checkother} and \subroutine{othersleep}
are at the heart of
the excessive propagation of the virus. It is clear that the author
intended for the virus to detect that a machine was already infected, and
if so to skip it. The code is actually fraught with timing flaws and
design errors which lead it to permit multiple infections, probably more
often than the designer intended\footnote{This behavior was noted by both
looking at the code and by creating a testbed setup, manually running a
program that performs the checking and listening functions.}.

An active infection uses the \subroutine{othersleep} routine for two
purposes, first to sleep so that it doesn't use much processor
time, and second to listen for requests from ``incoming'' viruses. The
virus which is running \subroutine{othersleep} is referred to as the
``listener'' and the virus which is running \subroutine{checkother} is
referred to as the ``tester''.

\subsubsection{Checkother}
The tester tries to connect to port 23357 on the local machine (using
the loopback address, 127.0.0.1) to see if it can connect to a
listener. If any errors occur during this check, the virus assumes
that no listener is present, and tries to become a listener itself.

If the connection is successful, the checker sends a magic
number\footnote{$874697_{16}, 8865431_{10}, 041643227_{8}$}, and listens
(for up to 300 seconds) for a magic number from the
listener\footnote{$148898_{16}, 1345688_{10}, 05104230_{8}$}.  If the
magic number is wrong, the checker assumes it is being spoofed and
continues to run.

The checker then picks a random number, shifts it right by three
(throwing away the lower three bits) and sends it to the listener. It
expects a number back within ten seconds, which it adds to the one
sent. If this sum is even, the sender increments \variable{pleasequit},
which (as noted in section~\ref{pleasequit}) does very little.

Once it has finished communicating (or failing to communicate) with
the listener, the checker sleeps for five seconds and tries to become
a listener. It creates a TCP stream socket, sets the socket
options to indicate that it should allow multiple binds to that
address (in case the listener {\it still} hasn't exited, perhaps?) and
then binds the socket to port 23357, and listens on it (permitting a
backlog of up to ten pending connections.) 

\subsubsection{Othersleep}
The \subroutine{othersleep} routine is run when the main body of the virus
wants to idle for a period of time. This was apparently intended to help the
virus ``hide'' so that it wouldn't use enough processor time to be
noticed. While the main program sleeps, the listener code waits to see
if any checkers have appeared and queried for the existence of a
listener, as a simple ``background task'' of the main virus.

The routine first checks to see if it has been set up as a listener;
if not, it calls the normal \subroutine{sleep} function to sleep for the
requested number of seconds, and returns.

If it is set up as a listener, it listens on the checking port with a
timeout. If it times out, it returns, otherwise it deals with the
connection and subtracts the elapsed real time from the time out
value.

The body of the listener ``accepts'' the connection, and sends a magic
number to the checker. It then listens (for up to 10 seconds) for the
checker's magic number, and picks a random number. It shifts the
random number right by three, discarding the lower bits, and sends it
up to the checker; it then listens (for up to 10 seconds) for a random
number from the checker. If any of these steps fail, the connection is
closed and the checker is ignored.

Once the exchanges have occurred, the address of the incoming
connection is compared with the loopback address.
If it is not from the loopback address, the attempt is ignored. If it
is, then if the sum of the exchanged random numbers is odd, the
listener increments \variable{pleasequit} (with little effect, as
noted in section~\ref{pleasequit}) and closes the listener connection.

\iffalse
\subsection{Flow Diagrams}
\label{diagrams}
The following diagrams show the flow of data and control in some of
the more complex parts of the virus. The first shows how the
``grappling hook'' (\prog{l1.c}) was launched from an infected machine
into a victim machine. The second shows how the virus gathers
information about the host it has infected and organizes an attack on
another host.

\subsubsection{l1 Infection Path}\label{l1pic}

The common infection mechainism used to copy the virus into a vulnerable host is shown in Figure \ref{l1fig}.

\begin{figure*}[tp]
\vspace{3.75in}
\special{psfile=l1picture.ps hoffset=-108 voffset=-468}
\caption{The common infection mechanism.\label{l1fig}}
\end{figure*}
\fi