

Possible Virus Attacks Against Integrity Programs And How To Prevent Them

                Vesselin Bontchev, research associate
               Virus Test Center, University of Hamburg
          Vogt-Koelln-Strasse 30, 2000 Hamburg 54, Germany
              bontchev@fbihh.informatik.uni-hamburg.de


    With the advent of the polymorphic viruses it is becoming
    obvious that the virus-specific scanners have exhausted
    themselves.  Currently one of the most powerful methods to
    detect viruses is the so-called integrity programs.  They
    will certainly be used more frequently in the future.  Yet,
    they are also not a universal anti-virus protection tool.
    In the current paper we will try to show the different ways
    in which viruses could attack integrity checking programs.
    When appropriate, we will also demonstrate what can be done
    against these attacks.

1.  Introduction.

There are three main kinds of anti-virus programs [McAfee].
Essentially these are scanners, monitors and integrity checkers.

1.1.  Scanners.

Scanners are programs that scan the executable objects (files and boot
sectors) for the presence of code sequences that are present in the
known viruses.  Currently, these are the most popular and the most
widely used kind of anti-virus programs.  There are some variations of
the scanning technique, like virus removal programs (programs that can
"repair" the infected objects by removing the virus from them),
resident scanners (programs that are constantly active in memory and
scan every file before it is executed), virus identifiers (programs
that can recognize the particular virus variant exactly by keeping
some kind of map of the non-modifiable parts of the virus body and
their checksums), heuristic analyzers (programs that scan for
particular sequences of instructions that perform some virus-like
functions), and so on.

The reason that this kind of anti-virus program is so widely used
nowadays is that they are relatively easy to maintain.  This is
especially true for the programs which just report the infection by a
known virus variant, without attempting exact identification or
removal.  They consist mainly of a searching engine and a database of
code sequences (often called virus signatures or scan strings) that
are present in the known viruses.  When a new virus appears, the
author of the scanner needs just to pick a good signature (which is
present in each copy of the virus and in the same time is unlikely to
be found in any legitimate program) and to add it to the scanner's
database.  Often this can be done very quickly and without a detailed
disassembly and understanding of the particular virus.

Furthermore, scanning of any new software is the only way to detect
viruses before they have the chance to get executed.  Having in mind
that in most operating systems for personal computers the program
being executed has the full rights to access and/or modify any memory
location (including the operating system itself), it is preferable
that the infected programs do not get any chance to be executed.

At last, even if the computer is protected by another (not
virus-specific) defense, a scanner will still be needed.  The reason
is that when the non virus-specific defense detects a virus-like
behavior, the user usually wants to identify the particular virus,
which is attacking the system - for instance, to figure out the
possible side-effects or intentional damage, or at least to identify
all infected objects.

Unfortunately, the scanners have several very serious drawbacks.

The main one is that they must be constantly kept up-to-date.  Since
they can detect only the known viruses, any new virus presents a
danger, because it can bypass a scanner-only based protection.  In
fact, an old scanner is worse than no protection at all - since it
provides a false sense of security.

Simultaneously, it is very difficult to keep a scanner up-to-date.  In
order to produce an update, which can detect a particular new virus,
the author of the scanner must obtain a sample of the virus,
disassemble it, understand it, pick a good scan string that is
characteristic for this virus and is unlikely to cause a false
positive alert, incorporate this string in the scanner, and ship the
update to the users.  This can take quite a lot of time.  And new
viruses are created every day - with a current rate of up to 100 per
month.  Very few anti-virus producers are able to keep up-to-date with
such a production rate.  One can even argue that the scanners are
somehow responsible for the existence of so many virus variants.
Indeed, since it is so easy to modify a virus in order to avoid a
particular scanner, lots of "wannabe" virus writers are doing it.

However, the fact that the scanners are obsolete as a single line of
defense against the computer viruses, became obvious only with the
appearance of the polymorphic viruses.  These are viruses, which use a
variable encryption scheme to encode their body and which even modify
the small decryption routine, so that the virus looks differently in
each infected file.  It is impossible to pick a simple sequence of
bytes that will be present in all infected files and use it as a scan
string.  Such sequence simply does not exist.  Some polymorphic
viruses can be detected using a wildcard scan string, but more and
more viruses appear today, which cannot be detected even if the scan
string is allowed to contain wildcard bytes...

The only possible way to detect such viruses is to understand their
mutation engine in detail.  Then one has to construct an algorithmic
"scanning engine" specific to the particular virus.  However, this is
a very time-consuming and effort-expensive task, so many of the
existing scanners have problems with the polymorphic viruses.  And we
are going to see more such viruses in the future.  The Bulgarian virus
writer known under the handle Dark Avenger has even released a
"mutating engine" - a tool for building extremely polymorphic
viruses...  Very few scanners are able to detect the viruses, which
are using it, with 100 reliability.

One last drawback of the scanners is that scanning for lots of viruses
can be very time-consuming.  The number of currently existing viruses
is about 1,600 and is expected to reach 3,000 at the end of 1992.
Indeed, some scanners use clever scanning methods like fixed-point
scanning, top-and-tail scanning, hashing and so on.  The detailed
description of these methods is outside the scope of this paper, but
as has been proved in [Cohen90], scanning is not cost-effective in the
long run, despite the scanning method used.

1.2.  Monitors.

The monitoring programs are memory resident programs, which constantly
monitor some functions of the operating system.  Those are the
functions that are considered to be dangerous and indicative for
virus-like behavior.  Such functions include modifying an executable
file, direct access of the disk bypassing the operating system, and so
on.  When a program tries to use such a function, the monitoring
program intercepts it and either denies it completely or asks the user
for confirmation.

Unlike the scanners, the monitors are not virus-specific and therefore
need not to be constantly updated.  Unfortunately, they have other
very serious drawbacks - drawbacks that make them even weaker than the
scanners as an anti-virus defense and almost unusable today.

The most serious drawback of the monitors is that they can be easily
bypassed by the so-called tunneling viruses.  The reason for this is
the total lack of memory protection in most operating systems for
personal computers.  Any program that is being executed (including the
virus) has full access to read and/or modify any area of the
computer's memory - including the parts of the operating system.
Therefore, any monitoring program can be disabled because the virus
could simply patch it in the memory.  There are other clever
techniques as interrupt tracing, DOS scanning, and so on, which allow
the viruses to find the original handlers of any operating system
function.  Afterwards, this function can be called directly, thus
bypassing any monitoring programs, which watch for it.

Another drawback of the monitoring programs is that they try to detect
a virus by its behavior.  This is essentially impossible in the
general case, as proven in [Cohen84].  Therefore, they cause many
false alarms - since the functions that are expected to be used by the
computer viruses usually have pretty legitimate use by the normal
programs.  And if the user gets used to the false alerts, s/he will be
likely to oversee a real one.

The monitoring programs are also completely useless against the slow
viruses, described later in this paper.

1.3.  Integrity checking programs.

According to Dr.  Fred Cohen's definition [Cohen84], a computer virus
is a program that can `infect' other programs by modifying them to
include a possibly evolved copy of itself.  Therefore, in order to be
a virus, a program must be able to infect.  And, in order to infect,
the program must cause modifications to the programs that are
infected.  Therefore, a program, which can detect that the other
executable objects have been modified, will be able to detect the
infection.  Such programs are usually called integrity checkers .

The integrity checkers compute some kind of checksum of the executable
code in a computer system and store it in a database.  The checksums
are re-computed periodically and compared with the stored originals.
Several authors point out that in order to avoid forging attempts from
the part of the virus, the checksums must be cryptographically strong.
This can be achieved by using some kind of trap-door one-way function,
which is algorithmically difficult to be inverted.  Such functions
include DES, MD4, MD5, and so on.  But, as has been shown by [Radai],
this is not mandatory.  A simple CRC is sufficient, if implemented
correctly.

There are several kinds of integrity checkers.  The most widely used
ones are the off-line integrity checkers , which are run to check the
integrity of all the executable code on a computer system.  Another
kind are the integrity modules , which can be attached (with the help
of a special program) to the executable files, so that when started
the latter will check their own integrity.  Unfortunately, this is not
a good idea, since not all executable objects can be "immunized" this
way.  Additionally, the "immunization" itself can be easily bypassed
by stealth viruses, as described later in this paper.  The third kind
of integrity software are the integrity shells .  They are resident
programs, similar to the resident scanners, which check the integrity
of an object only at the moment when this object is about to be
executed.  These are the least widespread anti-virus programs today,
but the specialists predict them a bright future [Cohen90].

The integrity checking programs are not virus-specific and therefore
do not need constant updating like the scanners.  They do not try to
block virus replication attempts like the monitoring programs and
therefore cannot be bypassed by the tunneling viruses.  In fact, as
demonstrated by [Cohen90], they are currently the most cost-effective
and sound line of defense against the computer viruses.

They also have some drawbacks.  For instance, they cannot prevent an
infection - they are able only to detect and report it after the fact.
Second, they must be installed on a virus-free system, otherwise they
will compute and store the checksums of already infected objects.
Therefore, they must be used in a combination with a scanner at least
before installation.  This is needed, in order to ensure that the
system they are being installed on is virus-free.  Third, they are
prone to false positive alerts.  Since they detect changes, not
viruses, any change in the programs (like updating the software with a
new version), is likely to trigger the alert.  Sometimes this can be
avoided or at least reduced by using some intelligent heuristics and
educating the users.  Fourth, while the integrity checkers are able to
detect the virus spread and identify the newly infected objects, they
usually cannot determine the initially infected object, i.e., the
source of the infection.

Despite the drawbacks mentioned, the integrity checking programs are
the currently most powerful line of defense against computer viruses
and are likely to be used more widely in the future.  Therefore, we
should expect that new viruses will appear, which will target the
integrity programs in the same way as the polymorphic viruses are
targeting the scanners and the tunneling viruses are targeting the
monitors.  Let's see what kinds of attacks are possible against the
integrity checking programs and how these programs can be improved to
avoid them.

2.  Possible virus attacks against the integrity checking programs.

2.1.  Stealth viruses and fast infectors.

The first generic attack against both the scanners and the integrity
checkers came with the appearance of the stealth viruses.  When such a
virus is active in memory, it intercepts the access requests to the
infected objects.  It then modifies their results in such a way, that
these objects look as if they are not infected.

The first stealth virus was Brain - a boot sector infector.  Writing a
stealth file infector is much more difficult, since a lot more things
have to be considered by the virus writer.  However, such viruses are
perfectly possible and several of them already exist.  The first fully
stealth file infector was the Bulgarian virus Number of the Beast .
Currently there are also semi-stealth viruses - viruses which only
hide the increase of the file size after infection.  However, they are
not of particular interest, since they cannot defeat most intelligent
integrity checking programs.

If a fully stealth virus is active in the computer memory during the
integrity check, all infected objects will look as non-infected, or in
fact not modified.  Therefore, the integrity checking program will not
report anything unusual.

Also, if the stealth virus is also a fast infector (a virus, which
infects files not only when they are executed, but also when they are
accessed for whatever reason), the process of computing the checksum
of every file will cause its infection.  The reason for this is that
the files must be opened and read (therefore - accessed) in order
their checksum to be computed.  This will provide the virus (if it is
present in the memory and active) with the possibility to infect them.
And all currently known stealth viruses are fast infectors as well.

The only remedy to this is to ensure that no virus is active in the
computer memory during the integrity check.  There is only one 100
foolproof way to do this - to cold boot the computer that is about to
be checked from a non-infected write-protected system diskette.  This
way we can make both the stealth and the fast infecting viruses
obsolete - since they will not be active in the memory during the
check and they have no way to play their subverting tricks.

Unfortunately, the usage described above of an anti-virus program is
often considered inconvenient by most users.  In fact, most users
never use the program this way.  That is why, most integrity checking
programs usually have different levels of safety and only the most
secure one requires the user to boot from a system diskette.  The
intelligent integrity checkers can even keep track of how often the
most secure mode is used and to remind the user if s/he does not use
it often enough.

There is yet another possibility, which gets more and more widely used
lately.  It consists of using the so-called anti-stealth techniques.
These techniques are, in fact, very similar to the tricks that the
tunneling viruses use to bypass the monitoring programs.  The
integrity checkers that use anti-stealth techniques try to bypass the
stealth viruses much in the same way as the tunneling viruses try to
bypass the monitors.  Such techniques are often very useful, but they
must not be abused.  It is important to emphasize that they are not
fool-proof, due to the complete lack of memory protection in the
operating systems for personal computers.  Usually it is possible to
circumvent them by using just a combination of the known stealth
techniques.

If a program wants to bypass the stealth viruses reliably, it must
access the disk sector by sector, using direct calls to the ROM BIOS
(not interrupts!).  It must bypass the whole operating system and
interpret the disk structure itself.  Even then, great care has to be
taken to avoid some pitfalls that can be used by a clever stealth
virus.  However, if the program does all this, it will become very
incompatible - with any kind of disks accessed through an installable
device driver.  At first sight this may not look like a great
restriction, but such disks include SCSI disks, hardcards, CD-ROMs,
networked drives, encrypted partitions (e.g., with the program
DiskReet from the Norton Utilities package), compressed disks (e.g.,
with Stacker, SuperStor, DoubleDisk), special large partitions (e.g.,
created by Disk Manager), SUBSTed and JOINed disks, and so on.  A
virus writer can safely ignore this - his creation will spread widely
enough even if it does not infect such disks.  However, an anti-virus
program can never permit itself to be so widely incompatible, or it
simply will not be used.  Therefore, the integrity checking programs
that use anti-stealth techniques must turn the tricks off at least in
the cases mentioned above.

Therefore, the users should be aware that any claims of the sort of
"our program is able to bypass any stealth virus" are nothing more
than marketing tricks.  They should be taken with a pinch of salt.

Remember:  the only 100 foolproof anti-stealth technique is to cold
booting the computer from a non-infected write-protected system
diskette, to ensure that no virus is present in memory.

A third way to avoid the stealth viruses is described in [Cohen91].
It consists of taking a snapshot of a clean state of the system
(including the boot sectors, the operating system, the device drivers,
the command interpreter, the startup files, and even the memory
structure and the contents of the registers of the CPU).  Each time
the system is rebooted, it is fist restored to that known clean state.
This way, we can make sure that no virus is active in memory at that
time.  This method is very useful and convenient especially against
boot sector viruses.  It is significantly less convenient if it is
implemented completely - especially in environments when the system
startup configuration is changed relatively often.

2.2.  Companion viruses.

The integrity checking programs detect modifications of the executable
files.  Therefore, to avoid detection, the viruses could try not to
modify the files themselves.  For instance, they change their
execution path instead.  The particular implementation is operating
system dependent; in our examples we shall assume mainly MS-DOS.

When the user enters the name of a file to be executed from the
command line, the command interpreter first looks for a file with the
same name as the one entered by the user and a .COM extension.  Only
if such file is not found, the command interpreter tries the .EXE and
.BAT extensions (in this order) and if none is found, the same search
(in the same order) is performed in every directory listed in the PATH
variable.  Only if no file that has any of these three extensions is
found, the command interpreter outputs the well-known "Bad command or
filename" message.

2.2.1.  Regular companions.

The search procedure described above can be used by a virus.  It can
locate a file with an .EXE extension and put the virus body in the
same directory and with the same file name as the file being
"infected" but with a .COM extension.  This way the virus will make
sure that the next time the user enters the name of the main file from
the command line, the virus will be executed instead.  It can then
perform its task (e.g., "infect" in this way other file(s)) and pass
control to the main file by executing it directly (the Exec function
call does not perform any PATH or file extension search - it is done
only by the command interpreter).

Such viruses already exist.  They are called regular companion viruses
or more simply "companions." The first one was the relatively unknown
Bulgarian virus, called TP Worm.  Today several other such viruses
exist.  Some of them are memory resident, and some even employ a
limited range of stealth tricks.

Such viruses are usually not considered particularly dangerous.  The
reason is that they tend to spread only inside a particular computer
system.  Since people do not often execute files from floppy disks or
include the floppy disk drives in their paths, these viruses have
almost no chance to spread between computers.

Unfortunately, relying on this might be dangerous.  It is perfectly
possible to design and implement a well-spreading companion virus.
Such virus will be memory resident.  It will place its copies and mark
them as hidden.  (The files with the Hidden attribute set still can be
executed - unlike the files with the System attribute set).  Then, it
could intercept the FindFirst and FindNext functions of the operating
system and "hide" the presence of this file, even if a file manager
that can show the hidden files is used.  The virus could even be a
fast infector - it could infect (i.e., create its copy in a hidden COM
file) not only when EXE files are executed, but also when they are
copied.  This way it will have more chances to spread to floppy disks
and from them - to other computers.

The companion viruses are a particularly dangerous form of virus
attack in some environments, like Novell NetWare.  Under Novell
NetWare it is possible to mark some executable files as ExecuteOnly .
This will make them unreachable for any kind of access (except
execution) by anyone, including the supervisor.  Once set, this
attribute cannot be reset any more.  The only thing that can be done
is to delete the file - and even this can be done only by the
supervisor.  If the directory that contains .EXE files protected in
this way has access rights, which allow file creation and/or renaming,
a companion virus could spoof the protected file by creating in the
same directory a file with the same name and a .COM extension.  If the
effective access rights of the newly created files permit that, the
virus could even set its attributes to ExecuteOnly , thus preventing
even the supervisor from detecting the attack.  This kind of attack
has been first described in [Cohen92].

In the attack described above, it is obvious that not only the
ExecuteOnly attribute is unable to stop the virus spread, but it also
effectively prevents the supervisor from performing regular backups
and integrity checks, and therefore noticing the attack.  And, from a
MS-DOS workstation, this attribute does not effectively prevent read
access to the files, protected by it.  Indeed, the attacker could us a
LoadOverlay function call, in order to get a copy of the file in the
memory of the local workstation.  Once the executable image is there,
it could be stored in a local file, examined, etc.  The EXE files
present some difficulties to this approach, since the LoadOveraly
function will perform the necessary relocation and the image of the
file in memory will not be an exact copy of the file.  However, this
could be easily bypassed, by loading the file twice at different
memory segments and using the difference between the two loaded images
to construct an EXE header and an equivalent set of relocation items.

With the appearance of more modern command interpreters, other kinds
of companion spoofing became possible.  Even with COMMAND.COM it is
possible to spoof a BAT file by a COM or EXE companion much in the
same way as an EXE file can be spoofed by a COM companion.  With 4DOS
used as command interpreter a new kind of executable extension is
introduced - the BTM files, which are searched for after the EXE files
but before the BAT files in the execution path.  Therefore, under 4DOS
a BAT file can be spoofed by a BTM, an EXE, or a COM companion.  4DOS
also allows the user to define new executable extensions by setting
special environment variables.  All files with these extensions can be
spoofed by either BAT, or BTM, or EXE, or COM companions.  A clever
virus could randomly generate companions of the possible extension
range, in order to reduce the possibility of being detected.

What can be done against this kind of attack?  It is relatively
trivial to make the integrity checking programs aware of it.  They
just need to inspect every directory for files with the same name but
with different executable extensions and to alert the user if such
files are found.  Some care must be taken to handle the new extensions
as with the 4DOS example above.  For this purpose the integrity
checkers must provide the user the possibility to define all the
executable extensions that have to be checked.  Also, s/he must have
the possibility to indicate the search order of these extensions
(e.g., COM -> EXE -> BTM -> BAT -> ZIP).

2.2.2.  PATH companions.

Instead of putting its body in a file in the same directory, but with
an extension that is searched earlier than the original one, a virus
could simply put its body in a file with any executable extension, but
in a directory that comes earlier in the PATH variable than the
directory of the original file.  This will have the same effect - when
the user types the name of the file, the virus will be executed first.
Such viruses are called PATH companions.

This trick is less operating system dependent, since relatively many
operating systems with hierarchical file structure have the concept of
the PATH variable, while the multiple executable extensions exist
mainly in a few weird OSes like VMS or MS-DOS.  Under Unix, of
instance, the PATH trick is quite popular, but mainly for creating
trojan horses, not viruses.

Again, this attack presents a significantly more considerable danger
in a Novell Netware environment.  A PATH companion virus could infect
all executable files in all directories - regardless how well they are
protected.  It is sufficient that at least one writeable directory
exists - e.g., the user's home directory.  The virus could insert the
name of the writeable directory at the beginning of the PATH variable
and create copies of its body in it with names, designed to spoof the
executable files in the protected directories.  Even if no writeable
directory on the server exists, the virus could use a directory on the
local workstation instead.  Indeed, the infection will exist only from
the point of view of the user being attacked - it will not be able to
spread between users.  Nevertheless, the attack provides enough
dangerous possibilities.

What can be done to prevent such viruses?  Well, basically the same
that is done to prevent the regular companions.  However, this time
the whole file system must be searched for files with the same name
and different executable extensions.  This often uses too much memory
and is too time-expensive, especially if the file system includes all
networked drives.

An intelligent shortcut is to store the contents of the PATH variable
used by the user and check only the directories in it.  An even more
intelligent approach consists of parsing the contents of the user's
AUTOEXEC.BAT file and fetching the contents of the PATH variable from
there, optionally allowing the user to change it (e.g., to add more
directories to be checked).  This approach is even more useful when
the user boots from a diskette and the normal contents of the PATH
variable is not available.  And, as we tried to emphasize in the
previous section, this is the only safe way to use an integrity
checking program.

Still, this shortcut does not work against a PATH companion, which
modifies the PATH variable in memory, in order to make it include the
special directory, which contains the virus body.  Again, this
modification cannot be prevented, because of the lack of memory
protection in the operating system.  It could, however, be detected by
some kind of resident integrity checking program (i.e., an integrity
shell).

2.2.3.  Alias companions.

The latest additions to the MS-DOS operating system, namely 4DOS and
the DOSKEY program, allow the user to define command-line macros,
called aliases.  The commands defined in them will be executed before
any file with executable extension.  This, of course, opens a gaping
hole for alias-based viruses - viruses that install an alias to spoof
a particular executable file (regardless of its extension).
Fortunately, such viruses, while possible in theory, do not represent
a significant danger.  They would be very much system-dependent and
the alias technique is not widely used and standardized.  However, the
approach should be considered, since a virus could use it as an
alternative way of spreading (besides a more "conventional" way of
infection).

Since the alias technique is not standardized, it is less easy to look
for and prevent this kind of attack.  A 4DOS-based approach could be
to parse the AUTOEXEC.BAT file for the ALIAS command and also check
all files that contain aliases (they are used by this command).  A
DOSKEY -aware approach is more difficult.

2.3.  Infection of unusual objects.

The alias companions are a particular case of a more general approach
- to infect unusual objects, that are unlikely to be checked by an
integrity program.  We shall try to list some possibilities.

According to the von Neumann's principle, there is no strict
difference between executable code and data.  One man's code is
another man's data and vice versa.  The source code of a program is
considered to be a program by the humans, but is treated as data by
the editors and the compilers.  Therefore it can be infected by a
source-code virus.  At first glance it seems rather unlikely that such
a virus will remain undetected.  Still, finding the offending code in
a 10,000-line C program could be quite troublesome.  Especially if the
code is designed in the style of the "Obfuscated C Contest." A very
good example of source code tampering that leaves no traces is
described in [Thompson].

Some more examples include:

    - The macro files used by some spreadsheets (Lotus 1-2-3 for
      instance) and word processors can be used to spread viruses, as
      has been demonstrated in [Highland].

    - The LIB files contain object libraries - perfectly executable
      compiled code that can be infected.

    - The OBJ files themselves are prone to infection - their format
      has been described in detail in the manuals, so the
      implementation of an OBJ -file infector is just a question of
      time.

    - Some integrity programs check only the code in the master boot
      sector.  This can be quite dangerous, as demonstrated by the
      StarShip virus, which infects the computer by modifying only
      three bytes of the partition table data!  (In fact, it is
      possible to achieve the same by modifying only one byte.)

    - The device drivers are perfectly infectable and indeed there are
      already several viruses that can infect them.

    - The files with extension .PIF under Microsoft Windows contain a
      pointer to the proper executable file.  Therefore, a virus could
      modify this pointer, so that its spoofing body is executed
      first.

    - Since version 3.1, Microsift Windows has introduced a
      conception, called Object Linking and Embedding (OLE).
      Effectively it consists of introducing in the data files a
      pointer to the application that is designed to process them.
      Again, this pointer could be modified and the true application -
      spoofed by a companion-like virus.

    - The Dynamically Linked Libraries (DLLs) in Microsoft Windows and
      OS/2 also contain executable and therefore infectable code.

    - The Novell Loadable Modules (NLMs) under Novell NetWare 3.11
      also contain executable code that can be infected.  Indeed, the
      format of those files differs considerably from the format of
      the MS-DOS executables, but it is only a matter of time before
      the virus writers learn to exploit it.

    - Under some operating systems (e.g., Unix), the compiler
      generates some temporary object files during the compilation.
      These files are usually created in a world-writeable directory
      and deleted after the compilation.  If the access to these
      temporary files is not restricted, a virus could infect them
      just before they are linked with the system libraries to produce
      an executable file.

All these attacks are not dangerous by themselves, since any virus
that depends only on them is not likely to spread very far.  However,
they can be used in a combination with the conventional methods.
Therefore, they should be detected, otherwise some copies of the virus
risk to survive the disinfection and to cause a second epidemy.  This
could be quite expensive...

What can be done against these attacks?  Most of them are only of
theoretical interest nowadays, so it is useless to force regular
integrity checking of everything that could be infected in theory.
However, the integrity programs must be designed to be flexible enough
and to provide the user the possibility to define what files have to
be checked (and how often) him/herself.  Also, there should be a
possibility to check the integrity of all files present on the system
- including those that are supposed to contain only non-executable
(and non-interpretable) data.  The latter is a good practice not only
against viruses but also against other kinds of integrity corruption.

2.4.  The DOS file fragmentation attack.

This kind of attack has been described in [Kabay].  It is specific to
MS-DOS.

The operating system is contained in two files (IO.SYS and MSDOS.SYS
or IBMBIO.COM and IBMSYS.COM), which are loaded during the bootstrap
process.  However, at boot time there is no operating system to
interpret the contents of the disk as a file system.  Therefore, the
first of these files is loaded in memory not as a file, but as
consecutive sectors.  In the same time, the integrity checking
programs usually treat the operating system files as regular files and
check them in the normal way.  A virus could use this discrepancy to
infect the system and remain undetected by the integrity checking
software.

The virus could place its body over the first cluster occupied by the
first DOS file.  Then it should allocate a new cluster (from the free
disk space), store the original contents of the first cluster there,
and fix the FAT chain in such a way, that the newly allocated cluster
is re-linked at the beginning of the file.  The old first cluster
(which now contains the virus body) is removed from the chain of
clusters allocated for this file and is marked somehow as used - for
instance by marking it as bad, or by "hiding" it using the stealth
approach.

A program which now computes the checksum of the file by considering
it to be a normal file will be fooled to believe that the file has not
been changed - since the logical structure and the contents of the
clusters allocated to this file has not been changed indeed.  However,
the location of the file on the disk will be different and this will
cause the virus body to be loaded at boot time.  It could then install
itself in memory, intercept some controls, then load the original
first cluster and transfer control to it.

To avoid this kind of attack, the integrity checking software must be
aware of it and treat the two hidden DOS files in a special way.  It
should not only check their contents as files, but also their position
as sectors on the hard disk.  This is relatively trivial to be
achieved, but it is amazing how few producers of integrity checking
software know about this kind of attack at all.

2.5.  Deleting the database of checksums.

A very trivial, but surprisingly successful attack a virus could
perform consists of just locating the database, where the integrity
checking program stores the checksums of the executable objects and
simply deleting it.  When the file, containing the database, suddenly
disappears, many integrity checkers will consider that they are going
to be installed for the first time on this system.  They will then
begin duly to checksum all executable objects again and to rebuild the
database of checksums.  Some of the existing integrity checkers are
doing this even without requesting confirmation from the user.
Unfortunately, this means that the new database will contain checksums
of the already infected objects...

Such viruses already exist.  One of them (Peach) targets the database
of checksums, created by Central Point Anti-Virus.  Another virus
(Tequila) simply removes the 10-byte checksum, attached to the
executable files by McAfee Associates' VIRUSCAN (it attaches such
checksums to the executable files when it is run with the /AV option).
Yet another virus (Groove), targets a whole set of integrity programs.
It looks for the files with the default names of the database of
checksums that these programs create, and simply deletes them.

Protection against this kind of attack is relatively simple.  The
integrity checking programs must not automatically assume that they
should run in installation mode, if no database of checksums is
available.  They must be installed with a separate installation
program instead.  Also, they must provide a flexible way to the user
to select the name of the file, where the database of checksums is to
be stored.  They also must allow the user freely to rename the program
that performs the integrity check, to prevent the virus from doing
some cheap tricks, like examining the two startup files (CONFIG.SYS
and AUTOEXEC.BAT), in order to find the exact name of the file with
the checksums.

On the other side, the users must know that the only safe place for
the database that contains the checksums of the executable objects is
off-line, on a write-protected floppy, out of the reach of any virus.

2.6.  Diskette-only infectors.

Usually the integrity checking programs are used to watch the
integrity of the hard disks only.  They do not try to compute
checksums of the executable objects on the floppy disks, because the
floppy disks are often modified, exchanged between computer systems,
and so on.

Therefore, a virus that infects only floppy disks, will not be
detected by such an integrity program.  And indeed, most of the
currently available integrity checking products are unable to detect
such old and well-known viruses like Brain and VirDem [Solomon].

Some people claim that a diskette-only infector is not a very viable
and dangerous virus.  However, the Brain virus has proved that the
former is not true.  This diskette-only infector was so widespread,
that we are still unable to eradicate it completely.  As to the
latter, consider a virus, which infects only floppy disks, but
slightly corrupts data files on the hard disks.  The corruption is not
likely to be discovered soon, even in the hard disk is protected by an
integrity checking system - because the integrity checking programs
usually do not check the data files (it will take a lot of time to
check all data files, and most of them are often modified anyway).
Since the file corruption occurs slowly, it is likely that the already
corrupted files will be transferred in the backups, thus making the
restoration of the system impossible.  A virus with such a destructive
payload already exists (the Nomenklatura virus).  One only needs to
combine its payload with a diskette-only infector, like Brain.

2.7.  Infecting only modifiable objects.

There is a class of executable files, which cause a lot of troubles to
the integrity checking software.  Those are the programs that modify
their image in the files - for instance, to store some configuration
data.  Regardless that designing such programs is widely considered as
a bad practice, self-modifiable programs exist, are widely used, and
are likely to be continued to be created in the future.  Such programs
include e.g., Borland's SideKick and Turbo PASCAL, McAfee's VIRUSCAN,
the program SETVER, which comes with DOS 5.0, and others.

Since these programs often modify themselves, they will trigger the
integrity checking programs, because the latter are designed to detect
modifications.  To avoid such false positives, most of the integrity
checking packages allow the user to create a set of exceptions - a
list of executable objects that are to be excluded from the integrity
control.

However, a virus could use this security hole, look for the most
popular self-modifying programs (by searching the whole file system,
or just by examining the two startup files), and to infect only them.
If such a self-modifying program is executed during the startup, this
will provide the virus with the excellent possibility to spread, yet
it will remain undetected by the integrity checking software.  Even if
the regular integrity check detects the modification, the user is
likely not to pay attention to the alert, since it is well known that
the program, which has triggered the alert is self-modifying.

What can be done against this kind of attack?  Well, improving the
integrity checking software cannot help very much.  The best solution
is not to use any self-modifying programs at all.  If the users firmly
decide to stop using this kind of software (just like they decided to
stop using programs that apply some kind of copy protection scheme),
maybe the software producers will turn to a better programming
practice.  Self-modification of the executable objects can and should
be avoided.  This will close a security hole, which can be exploited
by computer viruses.

2.8.  Slow viruses.

The slow viruses are a natural extension of the idea to infect only
floppy disks, or only objects, which are known to often modify
themselves.

These viruses represent probably the greatest danger to the integrity
checking software.  We call them "slow" viruses as opposed to the fast
infectors, because they are rather selective regarding the objects
they decide to infect.  Their spread lacks the spectacular speed of
the superfast infectors like Dir II, but they can remain undiscovered
for much longer time and spread wider in the long run.

The slow viruses use one intrinsic flaw of the integrity checking
software.  The integrity checking programs do not detect viruses -
they detect modifications.  Whether the modifications are caused by a
virus or not is left to the user to decide.  The slow viruses choose
to infect programs only in these cases when the latter are created or
modified by the user.  This usually occurs when a file is copied or
re-compiled.  If an integrity checker is run after a slow virus has
infected its victim, the user will get a report that a new executable
file has appeared or that an old one has been modified.  However, this
is unlikely to cause any suspicions, since the new (or modified) file
is copied there (or recompiled) by the user him/herself.

Such viruses already exist.  The first of them was the Bulgarian virus
Darth Vader.  This virus infects only COM files, only when they are
written to, and only when they contain a large enough block of zeroes
to hold the virus body.  The virus uses the fact that during the
execution of the COPY command, MS-DOS copies the COM files in one pass
- since they are known not to exceed 64 Kb.  Therefore, the virus is
certain to find the whole file in memory by intercepting the Write
request and looking where the address of the buffer to be written
points to.  It then tries to locate a sufficiently large block of
zeroes in this buffer, copies itself there and adjusts the first three
bytes of the buffer to contain an instruction that will transfer
control to the virus body.  This is all; the virus even does not
bother to write to the infected files itself.  It knows that DOS will
do it itself when executing the COPY command.

Surprisingly, the virus has not been created as an attack against the
integrity checking software (although it evades all integrity checking
programs very successfully).  The initial idea of its author was to
bypass the monitoring programs.  His reasoning was that since they are
monitoring the modification of the executable files, a safe way to
evade them will be to infect only when the user requests modification
of these files (via the WriteHandle request) him/herself.  And indeed,
the virus successfully evades these programs.  It can even "bypass"
the diskette write protection tabs - since when the user copies a COM
file to a diskette the write protection tab is removed.  The virus
achieves this without even having a critical error handler - it just
does not need it.

Another virus of this kind is the Bulgarian virus Compiler.  This one
has been designed probably against the programmers, since it infects
mainly when a program is re-compiled - when the size of the file (the
virus infects only EXE files) is modified.  However, in most
environments this does not occur very often, so the virus is unlikely
to spread very widely.  Besides, it is a multi-partite virus, which
infects the master boot record and at least this will be detected by
the integrity checking software - if it is installed before the virus
(i.e., on a clean system).

The last virus that successfully evades the integrity checkers is of
Russian origin and is known under the name StarShip.  It is rather
common in Russia.  It has been probably designed especially as an
attack against the integrity checking software.  The virus contains
several interesting tricks:  it installs itself in the video memory,
infects the hard disk by modifying only three bytes in the partition
table data, is polymorphic, multi-partite, uses the stealth
technology, and so on.

A detailed description of this virus is outside the scope of this
paper.  It is sufficient to say that when an infected file is
executed, the virus creates a fake partition in the master boot
record, by modifying the parameters of the active one.  When the
computer is rebooted, the virus is loaded and receives control.  It
relocates itself to the video memory, then transfers control to the
boot sector of the original DOS partition.  While the virus is active
in memory, it infects all executable files in drives A:  and B:  (the
floppy disk drives) when they are created or modified.

If an integrity checker is installed on the computer before the virus
attacks it, the attack will be discovered (because it modifies the
master boot record).  However, if the computer is already infected
when the integrity program is installed, the latter will not be able
to detect the further spread of the virus.  And the virus spreads
rather well - mainly when the executable files are copied to floppies.
In fact, the virus tries to maximize the number of infected machines,
instead of the number of infected executable objects - a common
characteristic of the slow viruses, which is likely to be used more
frequently in the future.

This particular virus does not present a significant danger to the
West, because it is incompatible with most of the modern hardware and
software platforms:  monochrome video cards (including monochrome
VGAs), MS-DOS with version higher than 3.30, large hard disk
partitions (above than 32 Mb) and so on.  It also contains a quite
visible audio-visual payload, which is unlikely to remain unnoticed
for a long time.

However, all the viruses described above present a dangerous trend -
ideas, which if combined can make the life very difficult to the
integrity checking software.

What can be done against the slow viruses?  Very little, having in
mind that they exploit an intrinsic flaw of the integrity checking
programs...  A possible solution is a careful implementation of
integrity shells as proposed in [Cohen89].

The idea is to have a resident program, which checks the integrity of
the programs before they are executed.  However, the program also
keeps the so-called dependency paths and checks the integrity of all
files the currently executed program depends on.  This may include
overlays called by the program, macro files, data files that it uses
and so on.  When the user copies a program, the integrity shell
remembers that the copy depends on the original and checks the
integrity of both when either of them is executed.  (It also checks
whether the two match.) The case of the virus that infects only when
executable objects are copied to diskettes can be solved by having the
integrity shell check that the copy and the original match immediately
after the copying process.

Unfortunately, implementing the above conception can be very
time-expensive.  If the program loading takes too much time because
all its dependency files have to be checked too, the user is likely to
turn the protection off.

2.9.  A combined attack.

Almost all the attacks described above have been "tried" by the virus
writers, by implementing them in some virus - at least to demonstrate
that it is possible and "can be done." However, most of these viruses
have been "demonstration-only" and not able to spread widely.  Let's
try to imagine what can be done by just combining the different kinds
of attack listed above.  This (imaginary) virus will be a slow
infector, so we shall name it Kuang [Gibson].  Since it combines only
the currently known infection techniques, it is just a matter of time
before such viruses begin to appear.  The reader is invited to try to
figure out him/herself how well such virus will spread and how well
prepared is the line of anti-virus defense that s/he currently uses
against such viruses.

Kuang comes with an infected utility that you get from a BBS or a
public archive site, from the boot sector of a data-only diskette that
you have forgotten in your boot drive, or from a shrink-(re)wrapped
commercial package produced by a company that decides to save some
money on the quality assurance procedures.  When you execute it, it
installs itself in memory in such a way that comparing the listings of
MEM/DEBUG before and after the RAM infection will not show any
differences.  This is possible by installing the virus in some holes
in the operating system (like the Tiny virus), in the video memory
(like the StarShip virus), and some other places.

After it becomes active, Kuang does not infect anything at once.  If
you now turn your system off, it will be gone - until the next time
you execute the infected utility.  However, it carefully watches for
any executable object being modified and infects it.  Since it is a
multi-partite virus, it is able to infect almost anything - boot and
master boot sectors, COM and EXE files, overlays, device drivers (like
the SVC 6.0 virus), .OBJ files, libraries...  The only condition is
that some modification is performed with the object - that is, a
Create or Write occurs to it (like the Darth Vader, StarShip and
Compiler viruses do).

The virus will spread slowly - mostly when the user copies files or
formats diskettes.  When infecting the files, Kuang uses multiple
infection strategies.  It tries not to modify the intended file size -
if the file contains a block of zeroes (or even of any single byte
that is repeated over and over), the virus uses this area to put its
body (like the Phoenix and Squisher viruses do).  If an EXE file has a
sufficiently large EXE header, the virus compresses the relocation
items (like the Phoenix.2000 virus does) in order to free space for
its body.

Kuang watches for a file with an archive extension (ARC, ARJ, HYP,
LHZ, PAK, ZIP, or ZOO) for being opened.  When this happens, the virus
changes its behavior.  It becomes a fast infector - it begins to
infect all executable files (executable in the broad sense, including
.OBJ files and libraries) when they are opened (not only when they are
modified) and to disinfect them when they are closed (unless they are
newly created).  This behavior remains until the archive file is
closed.  This will ensure that all files being archived will go into
the archive infected and all files extracted from the archive will be
infected too.

During the infection/disinfection of the files during archiving as
described above, the virus uses the tunneling technology (like the
Frodo virus) to avoid the possibly present monitoring programs.  (This
technique is not needed during the normal slow infection, since then
the user will not be surprised by a message that a file is about to be
modified - because it was the user him/herself who initiated the
modification.)

Furthermore, while active in memory, Kuang uses the stealth technology
(like the Number of the Beast virus), in order to prevent from being
detected by simply comparing the copy of the file with the original or
by using the /V switch of the COPY command.

Just in case somebody detects it, Kuang uses armouring tricks (like
the Whale or Fish viruses), in order to make the code more difficult
to disassemble, debug, and understand.

Additionally, it uses a polymorphic technique, comparable with the one
used in the V2Px viruses, or in Dark Avenger's Mutating Engine (MtE),
so that even when detected and disassembled, it will be extremely
difficult to produce a scanner that will be able to locate and
recognize it with 100 reliability...

At last, the virus can be made to be Novell NetWare-aware and to
exploit any security holes in the settings of the directory and file
rights.  As described in [Cohen92], under Novell NetWare it is not
trivial to setup all the protection rights and attributes in a way
that will make virus spread impossible.  There are many LANs out
there, which are not configured in a secure way.  Therefore, a clever
virus should be able to exploit this.

3.  Conclusion.

The integrity checking software is the currently strongest line of
defense against computer viruses.  However, there are several possible
ways in which this software can be attacked by them.  Therefore,
extreme care should be taken by the producers of such software to
avoid the possible pitfalls.  In the same time, there is a need for
good integrity testing tools, which will permit the users to test the
quality of the integrity checking software themselves.  There is also
a need for a good set of heuristics that will permit the integrity
program to decide reliably whether a modified executable object is
really infected or not.

4.  References

[Cohen84]  Fred Cohen, Computer Viruses - Theory and Experiments,
           Computer Security:  A Global Challenge, Elsevier Science
           Publishers B.  V.  (North-Holland), 1984, pp.  143-158.

[Cohen89]  Fred Cohen, Models of Practical Defenses Against Computer
           Viruses, Computers Security, 8 (1989), 2, pp.  149-160.

[Cohen90]  Fred Cohen, A Cost Analysis Of Virus Defenses, A Short
           Course On Computer Viruses, ASP Press, 1990, ISBN
           1-878109-01-4, pp.  155-160.

[Cohen91]  Fred Cohen, A Note On High-Integrity PC Bootstrapping,
           Computers Security, 10 (1991), pp.  535-539.

[Cohen92]  Fred Cohen, Some Initial Results from the QUT Virus
           Research Network, Proc.  2nd Int.  Virus Bulletin Conf.,
           September 1992, pp.  xv-xxv.

[Gibson]   William Gibson, Neuromancer, Ace Books, N.Y., ISSBN
           0-441-56959-5.

[Highland] Harold Highland, A Macro Virus, Computers Security, 8
           (1989), pp.  178-188.

[Kabay]    M.  E.  Kabay, Conference Report:  the First International
           Anti-Virus Product Developers' Conference, Virus News and
           Reviews, January 1992, pp.  2-7.

[McAfee]   John McAfee, The Virus Cure, Datamation, February 15, 1989,
           pp.  29-40.

[Radai]    Yisrael Radai, Checksumming Techniques for Anti-Viral
           Purposes, Proc.  1st Int.  Virus Bulletin Conf., September
           1991, pp.  39-68.

[Solomon]  Alan Solomon, Slipping Past the Checksummers, Virus News
           International, September 1992, pp.  24-26.

[Thompson] Ken Thompson, Reflections on Trusting Trust, Turing award
           lecture, CACM, August 1984.


