Possible Virus Attacks Against Integrity Programs and How to Prevent Them
[Bontchev92a] Proc. 2nd Int. Virus Bull. Conf., 1992, pp. 131–141.
Vesselin Bontchev, research associate Virus Test Center, University of Hamburg Vogt-Koelln-Strasse 30, 2000 Hamburg 54, Germany bontchev@fbihh.informatik.uni-hamburg.deAbstract: 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 shall try to show the different ways in which viruses could attack integrity checking programs. When appropriate, we shall 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 why this kind of anti-virus program is so widely used nowadays is because 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.
Finally, 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 behaviour, 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 alarm, 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 proven in [Cohen90], scanning is not cost-effective in the long run, despite the scanning method used.
1.2. Monitors
The monitoring programs (sometimes called behaviour blockers) 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 behaviour. 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 nowadays.
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 belonging to the operating system. Therefore, any monitoring program can be disabled because the virus could simply patch it in 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 have attempted to intercept it.
Another drawback of the monitoring programs is that they try to detect a virus by its behaviour. 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 normal programs. And if the user gets used to the false alarms, 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, that 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 nowadays, 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 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 alarms. Since they detect changes, not viruses, any change in the programs (like updating the software with a new version), is likely to trigger the alarm. 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 will 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 has been 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 could try to 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. Nowadays 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 a 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 use 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 alarm 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
LIBfiles contain object libraries—perfectly executable compiled code that can be infected. -
The
OBJfiles themselves are prone to infection—their format has been described in detail in the manuals, so the implementation of anOBJ-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
StarShipvirus, 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
.PIFunder 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' VirusScan (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 VirusScan, 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 alarm, since it is well known that the program, which has triggered the alarm 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 one.
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 behaviour. 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 behaviour 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...
Finally, 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.