Computer viruses come closer to 'life' than any other computer software. At the present, the virus is the only software that routinely contains the ability to detect itself, detect software which it has and hasn't infected, and to detect hostile (anti-virus) software. The virus often mounts a stronger self-defense than other software, and unlike other software, is self-installing and self-reproducing. The problem is compounded by geometric increases in the number of new viruses and new virus authors, compared with decreases in the number of anti-virus companies and products.
A living software system is needed to fully defend against other living software without excessive requirement of user intervention.
Many concepts within the world of computing have names coming from life: kill a job, abort a task, spawn a process, create a program. A hard disk dies. But of greater interest is that many of the concepts seem inspired by life. To make a machine fault tolerant, for instance, is exactly what organisms strive for -- to develop an immune system that will aid in surviving adverse circumstances.
Computer users are obviously interested in preserving the life of their machines. In organizations, there is something that may be of even greater interest, however: in building systems that are capable of preserving their own lives. Building self-preservation into a computer system is important whenever a) the support staff cannot respond rapidly enough to preserve through intervention; b) the support staff is not adequately trained to respond; c) the support staff is over-taxed or has other duties that prevent their life-support intervention; d) the costs of introducing self-preservation are less than the costs of human intervention; e) the information maintained by the system is so critical that the organization wants fault-tolerance in which the system can protect itself in essential ways if the support staff responds too late or incorrectly, but which can accept human assistance when offered in a correct and timely fashion.
It cannot be said that today's computer shows much outward sign of life. Most are little better than a wrist watch, being able to show a limited range of output based on a limited range of input. While both watch and computer may be "set in motion" to perform processes at a later date, neither does much to adapt to a changing environment. For instance, the watch does not know when it enters a different time zone, or when it is running slow or fast. The computer's word processing software is unaware what the user is writing, or whether he or she has even left the room.
Jeffrey Kephart of IBM has recently proposed more life-like anti-virus software, modeling the biological immune system. His paper contains seminal ideas for the anti-virus field, but its focus is narrower than the present paper. Nevertheless, we will cite Kephart's paper from time to time in this one.
The essential ingredients of life are worth study and imitation to ensure return on our computing investment. In this paper, we propose giving computing systems more capability, not authority. HALcan be prevented.
The standard defense against computer viruses is the virus scanner, which looks for viruses previously known to the scanner's developer by checking sectors and files for short strings of code known to be found in specific viruses, and believed to be unique to the virus (and perhaps related viruses). Many anti-virus products also contain a memory-resident version of this technology which is able to find some known viruses.
As Kephart has explained, such anti-virus techniques are doomed. Several factors point to an end to scanning as the exclusive weapon against viruses: the rate of emergence of new viruses, the changing rate of infection of computers, and the emergence of stealth and polymorphic viruses that are able to defeat the technology.
The rate at which new viruses are emerging seems to be a constant, log function of time. Kephart forecasts about 10 million different DOS viruses by the year 2000.
Our own assessment of the situation concludes that the nature of the function is the same as Kephart concluded, with the number doubling every eight months. Our analyses resembles that of Kephart quite closely, except that the daily rate of production of new viruses appears to be much higher than Kephart believes. At a minimum, we must conclude that the number of different viruses today exceeds 15,500, since that number have been separately described here at Safe@Home.
Our own research - and that of other researchers - has found that the probability of infection has been increasing worldwide.
In each country we have surveyed (China, Hong Kong, Japan, Singapore, Taiwan, Thailand, and the U.S.), we have asked the question, "Please estimate the percentage of your office computers that were infected by a virus in each of the years listed. For example, if half of your office computers were infected at one time or another during 1993, enter "50" for 1993. If you are not sure, please guess." We averaged across respondent answers to obtain an estimated average for the country, then averaged across countries to produce the table below.
Year | Average Infection Rate |
---|---|
1988 | 6% |
1989 | 9% |
1990 | 13% |
1991 | 16% |
1992 | 19% |
1993 | 22% |
Note that the values for 1993 are only for the period January through May. Our surveying ended in 1993, but we can likely assume that infection rates have continued to climb since then.
Scanning for viruses was probably an unnecessary defense when the probability of infection by a virus was very low. It was certainly "adequate." Today, however, the probability of infection has risen. Just as checking a radar screen once a week is not adequate in time of war, checking a machine for infection once a week is no longer adequate.
The suggestion of scanning for viruses from memory using a resident scanner cannot be made to work, if traditional approaches are used. Anti-virus product vendors reluctantly admit that their resident products do not detect polymorphics; users discover that the number not detected is becoming a more important issue than the number detected, and that scanners are drifting behind. Indeed, if a resident scanner used just 20 bytes of information to detect a file virus, with 5,000 viruses the scanner must be 100,000 bytes in size, requiring an unacceptable amount of memory and slowing the machine unacceptably.
The most serious problem to confront scanners is the emergence of stealth viruses (which may impair the ability of a scanner to see the virus in a file or sector when the virus is resident) and polymorphic viruses (which, through multiple arrangements of the code they add, impair the ability of a scanner to detect them using traditional scan string technology).
The number of stealth viruses has risen steadily, with increasing proportions of new viruses incorporating stealth techniques. Today, stealth boot viruses are commonly found on machines protected by traditional scanners.
Polymorphic viruses pose another grave threat to traditional scanning. Such viruses are often based on a "polymorphic engine" - code which can be added to a virus and which makes the result take on a different string of bytes in each copy. Engines include the Cybertech Mutation Technology, Dark Avenger's Mutation Engine (MtE), Simulated Metamorphic Encryption Generator (SMEG), Trident Polymorphic Engine (TPE), the Virus Creation Laboratory (VCL), and more. Such engines take a non-polymorphic virus as input and then output the virus with polymorphic qualities. The availability of such engines has obviously made the task of writing a polymorphic virus straightforward. With these engines, virus authors no longer need to write their own polymorphic code. This cuts down on their production cycle and as a result, the number of polymorphics has grown even faster than the number of non-polymorphics. Today, over 400 viruses are known to use a polymorphic engine, and another 150 polymorphic viruses exist that do not use any "off-the-shelf" engine. Quite understandably, scanners have a difficult time detecting such polymorphic viruses.
Some of these engines make the viruses highly polymorphic and difficult to detect using a traditional scanner. For instance, Girafe which uses the Trident Polymorphic Engine (TPE) is able to create 1616 different copies of itself about 8,446,774,000,000,000,000 different morphs! Anti-virus vendor response was predictable: try to reverse engineer a polymorphic virus, then try to detect its engine. However, scanner success has been limited, as we learn when Virus Bulletin tests scanners against polymorphics.
To develop a computing system that is capable of preserving its own life, we can begin by looking at some of the mechanisms of biological life, and consider how those mechanisms might be built metaphorically within the computing system. It is not our intent to create life, or to pretend we are creating life, but rather to try to learn a lesson or two from nature.
All life recognizes "us" and "them." It treats them with indifference when they do not threaten, but defends against attack. A white blood corpuscle can usually distinguish between a foreign cell and those of its host. Cut your skin, and your body sends in the troops to heal and defend. All higher organisms seem to be able to recognize their own species... A self-defending computer system must be capable of reacting to the introduction of foreign software or perhaps use by "foreign" users.
Note: computer features such as manual scanning for viruses or passwords offer intermittent detection of intruders. They differ from that employed by organisms primarily in that organisms engage in such detection in "real-time" or continuously, as well as in the amount of judgment used: mammals, for instance, are likely to use auditory, visual, tactile olfactory, and other clues in monitoring, and may use complex algorithms for determining whether another is alien.
Put a stick in your eye, and your body immediately identifies a problem. Put a stick in your disk drive, and your machine may not notice a problem until that drive is accessed. Add a virus to a file or boot sector, and a standard computer notices nothing.
An organism responds to an injury by repairing the damage. Blood or sap may flow to the injury from healthy parts of the organism. If a stand of aspen is partially destroyed by fire, the other aspen, through an interconnected root system, send nutrients to the aspen closest to the fire, to assist them in regenerating new trees. Computer systems offer some degree of fault tolerance. Such fault tolerance may be based in the hardware of a network server, the protections of a UPS, or the copies of files backed up to tape. But fault-tolerance and self-repair differ in fundamental ways. Our computers are poor at sensing damage to hardware or software; they are poor at distinguishing between such things as the deliberate deletion of a file and the accidental, unwanted deletion of the file. And a human's replacement of a failed component or deleted file can hardly be considered self-repair.
Of the full range of behaviors available to an organism, it might be considered that the majority are dangerous. A bird can fly into a stationary object. A child can walk into the road. Life persists because organisms are capable of learning to avoid danger. While college students seem to learn more than daisies, even daisies turn to face the sun. Computers have shown little interest in learning. While they are adequate at storing files, programmers have done little other than to permit the saving of user preferences.
Most animals communicate with members of their own species for mutual defense. Most organisms have internal communication systems, using nerve impulses and chemicals in the blood, for the same purpose. While computers have various communications capabilities, these normally require human intervention if they are to be used for system defense. Support staff sometimes even elect to eliminate such communication when they find their systems threatened. (For instance, some firms have downed their servers or terminated e-mail connections when they have found systems infected with a virus.)
The life of an organism eventually comes to an end, and so to prevent the life of the species from ending, organisms reproduce. Computer users have counted on computer manufacturers for this task with hardware, and the only common software which normally makes additional copies of itself is the computer virus. DISKCOPY is a program that can be forced to reproduce, if it happens to reside on the source drive, but it requires user assistance.
As previously noted, computer viruses come closer to "life" than any other computer software. At the present, the virus is the only software that routinely contains the ability to detect itself, detect software it has and hasn't infected, and to detect hostile (anti-virus) software. The virus often mounts a stronger self-defense than other software, and unlike other software, is self-installing and self-reproducing.
A living software system is needed to fully defend against other living software without excessive requirement of user intervention.
Most viruses contain a means of recognizing themselves in files, sectors, and memory.
The Ontario virus determines if it is in memory by placing FF in AH, calling interrupt 21h, and then determining if AX=0 (if so, it is resident.). It determines if it has infected a COM file by determining if the fourth byte of the file is "V." It determines if it has infected an EXE file by determining whether the instruction pointer in the header is set to 1.
A variety of viruses, from Akuku Copmpl to Zero bug set the date of infected files to 62 seconds, to avoid re-infecting them.
Many viruses are able to recognize certain anti-virus software, and respond differently to such software than to programs designed for other purposes. For instance:
If the user runs a program ending in AV, AN, OT, or SCAN, the Pinworm virus does not infect it, but rather changes its minimum required memory in the header (0Ah) to FFFFh, thus making it unusable. This will disable many scanners (MSAV, NAV, TBAV, TNTAV, SCAN, F-PROT, etc.). Running such a program will produce a "Not enough memory" error.
Some viruses go after the databases stored by anti-virus products. For instance, the Encroacher virus deletes CPAV's chklist.cps. This file contains the integrity (or checksum) data on each program in that directory. Upon call, Encroacher erases this file if found, forcing the anti-virus software to constantly update its data, effectively making this feature unreliable.
Some viruses simply go after anti-virus products, trying to erase them. For example, Encroacher erases the CPAV.EXE and VSAFE.COM before infection.
Many viruses take steps to prevent damage to themselves. For instance:
Brain stores the original boot sector, and six extension sectors containing the main body of the virus, in available sectors which are then flagged as bad sectors in the FAT13 . By flagging them bad, Brain assures that a file will not overwrite the virus.
Pinworm prevents damage by preventing detection. It deletes CHKLIST.MS and CHKLIST.CPS (checksum databases maintained by MSAV and CPAV) in the current directory whenever a file is infected, even if they have been protected by file attributes.
Encryption is another form of self-defense in viruses. Pinworm contains two encryption routines. The outer routine makes the virus polymorphic, the inner routine prevents disassembly or debugging. The virus has no constant bytes, and no operations in constant locations in the decryptor, making it a full polymorphic. The garbage sometimes consists of randomly retrieved one-operands, sometimes a constant fill of a single one-operand. The virus selects between these types of garbage code randomly in order to prevent scanners from detecting the actual garbage code.
Some viruses contain code to prevent disassembly or debugging. A powerful example of this is Pinworm, which is resistant to DEBUG, Sourcer, and SoftIce. Many other viruses are also "disassembly-resistant."
If a computer virus is damaged, it may have the means of recovering from the damage. For example, if a boot virus is resident when it is removed from a master boot record or boot record, if the virus has not been disabled in memory, it is able to reinfect the sector that has just been "cleaned" when that sector is next accessed. If the virus is removed from a file while resident, it will likely recognize that it is no longer in the file, and may re-infect the file - sometimes during the session in which it was removed.
Viruses do not generally sense damage to themselves, although some will react strongly to modifications, and others can perform self-repair.
A virus named Sylvia 2.1 makes an effort to protect its message. If the virus sees that the first 144 words of the virus have been changed, it displays a hostile message and puts the computer into an endless loop.
Two strains of Natas provide examples of a "multi-partite" virus, infecting both the master boot sector and files. Because the viruses are polymorphic, only a few products are capable of even detecting the virus. (For instance, one version of one scanner could detect all copies of the first version in files, but only about 1 in 1,700 instances of the second version in files.) But if an anti-virus product detects and removes it from files (as some imperfect anti-virus product might do), but fails to remove it from the master boot sector, the virus returns with the next boot.
Computer viruses show little sign of learning, little means of adapting to adverse conditions. Some, however, intentionally behave differently depending on the presence of anti-virus software.
Virus authors, of course, have shown substantial interest in both learning and adaptation, and claims have been made that today's best viruses have improved more over last year's best than have this year's best anti-virus products improved over last year's best. MSAV (Microsoft AntiVirus) is identical in DOS 6.22 to that which shipped with DOS 6.0 beta.
A computer virus may communicate with other viruses, as when a program containing a resident virus is run. Such a virus always performs a "residence check," asking whether another of the same species is already resident. In the event that it receives the correct answer to its query, it does not go resident.
Making additional copies is the greatest single capability of computer viruses, the chief distinguishing factor between the virus and other software. Viruses show profound skills in making additional copies of themselves, and their installed base increases as fast as that of commercial products, without any sales or marketing effort.
We focus here on what might be done to permit a computer system to recognize the introduction of viruses and other unwanted software, to identify the new software, to automatically eliminate it if it is defined as not wanted or dangerous, and to restore itself to its state prior to infection.
The computer system will be considered to be two or more computers, interlinked via cabling and supporting software.
All modules must be aware of what anti-virus components are resident, and respond accordingly. For instance, if a behavior blocker is resident, a scanner should not scan memory by default. If a behavior blocker is not resident, it should scan memory.
While self-recognition is critical in an anti-virus system, it may be as important for anti-virus products to be undetectable by viruses as it has been for viruses to be undetectable by anti-virus programs.
In general, because many viruses look for anti-virus software by name, modules of an anti-virus product should be capable of operating under any name, while still able to find the corresponding components.
Recognition of intruders is done by scanners. The scanner is provided with a list of possible intruders, and searches for each of them wherever it looks. This approach works only with known intruders.
The police department takes a different approach. While they may use wanted posters on occasion, they more often watch for violations of rules (the speeder) and suspicious behavior associated with rule violators.
The most efficient way to recognize an alien within the computer is to create a list of programs known to and approved by the organization, and then only permit the execution of this software. All unknown software will be considered suspect, and execution of it will not be permitted until it has been examined.
In this paradigm, any number of techniques can be used to define a set of software as "ok." Such techniques can include scanning by dozens of different scanners, examination of program file sizes and comparison with master copies, heuristic scanning, etc. Once the software is established to be ok, the organization can checksum it, storing the checksums in a database. Then, a memory-resident monitor can be run that checks the program's stored checksum against its current checksum just before giving the program permission to run. If the checksum is not found in the stored database, the resident monitor can prohibit the execution of the software.
Organizations vary in their need to permit/deny permission for the use of new software. In some organizations, users may install their own software and do as they please; in others, users must make formal requests and wait for staff to install software in their machines.
The approach described here can be tailored to this range of organizations, categorized from very restrictive - no "new" software can be authorized and run, to very responsive - any new software must first be checked (automatically) before being approved. Real-time checking can be done with a variety of scanners, including heuristic scanners, and once permission is given, the software's checksums can be automatically added to the approved software database.
Checksumming has been used with considerable success in detecting viruses, but its many drawbacks have not always been addressed with products. For instance, checksumming can spread an infection of a resident virus that infects on file open, close, or directory traversal. Thus the system must prevent such viruses from going resident. Most checksummers do not include a behavior-blocking resident program.
A second sound strategy for detection of aliens is the use of "goat" or "decoy" files that are well-understood by other components of the anti-virus system, and which are, by design and use, more likely to be infected. In the mines of the last century, miners often kept a canary in a cage as a means of detecting lethal gasses: because a canary was more sensitive to such gasses, a dead canary meant danger.
A third strategy is that of behavior blocking, a tactic employed by AVAST!, AVAST32, and some other products. This program heuristically recognizes virus behavior, and is able to stop efforts to go resident, trace, tunnel, infect, etc. without requiring knowledge of the specific virus. Behavior blocking is a powerful defense because, while there are many viruses, there are only a small number of virus behaviors. If all such behaviors can be blocked, then the product will be able to block all new viruses, and the proliferation of new viruses causes no problem for the user.
But the life-like approach of a good anti-virus product doesn't come merely from the use of one or more techniques for recognizing the difference between self and alien, but from the intelligent combination of techniques.
It is desirable for anti-virus software to use multiple clues to determine if a file is infected. For instance, if a scanner detects an MtE virus in just one file, it should ask the user or (better) query the log produced by an activity monitor to determine if the file has been run recently. If so, and this is the only "infected" file, it is likely a false alarm.
If a behavior blocker sees virus activity, it should consider calling a standard scanner to determine if the source contains an infection. If none found, it should call a heuristic scanner, to determine if this is a new virus.
Detecting a virus should use a combination of checksumming, traditional scanning, and heuristic code analysis to determine if an infection is present. Most modules of most products use just one of these approaches, leaving it up to the user to judge whether an infection is present. Software should follow the same kinds of reasoning as a virus expert in reaching a conclusion. Such an approach would nearly eliminate false alarms.
The reported detection of a virus must be preceded by some intelligent thought. We have seen anti-virus products that found virus X in a file that was smaller than the virus, found it in a database, found it in a file type the virus would not infect. We have seen products false alarm when they found a scan string 70,000 bytes from the location where the scan string should be found. And every user has managed to use one product to find a virus in memory after scanning with another product. We get calls about a single instance of truly rare viruses; usually these calls prove to be false alarms. Each of these false alarms could have been prevented by more intelligent design.
Modules should be able to determine if they have been damaged, and then perform self-repair (see below). But if module A is to call module B, it should first check module B for damage. If damage is found, it should be the responsibility of module A to find another copy of B and replace it, or to place a request for module B, and not call it until a replacement copy is obtained.
Damage detection should use as many clues as possible, including a full checksum of the entire file, to ensure no undetected damage.
Many anti-virus products have some ability to detect that they have been infected, but this ability is generally primitive. For instance, if a stealth file virus infects the program, it is unlikely that an anti-virus product is able to detect any change in itself if the virus is resident. Since running an anti-virus program that is infected with a stealth virus first runs the virus, such a weakness in damage detection can spread the virus. Anti-virus software should be part of the solution, not part of the problem.
All modules should be able to repair themselves, whether or not a stealth virus is resident.
Many anti-virus programs urge the user to run them from a write-protected floppy. This may be a sound approach for the use of weak software, but it must not be necessary for the strong software of tomorrow. Modern use of a computer does not require the user to insert floppy disks in drives. Floppy drives are too slow, and disks are too easily lost or damaged. Users cannot be counted on to do the right thing, and most weak products are run from the hard disk, despite vendor recommendations. Vendors should heed the advice "physician, heal thyself."
To a small degree, we have come to expect our software to learn our preferences, adapt to our own style of using it. For instance, software which is user-configurable is often able to remember user preferences. But learning and adaptation are one of the most un-lifelike aspects of anti-virus software. Consider some alternatives to the present state of affairs:
When a scanner detects a file infected with a known virus, it should form the hypothesis that the machine is infected, it should begin treatment for that virus. Machines are rarely infected with two viruses, and rarely have just one instance of a file virus. Upon first detection of a virus, the anti-virus software might re-check memory for this virus, begin a more precision scan for this virus, and otherwise adjust to the facts at hand. There is no reason why the user should have to answer the question "Do you want to clean this file?" 300 times.
The anti-virus software should have a memory for recent viruses found, and focus on such viruses in its work.
If a virus is found through checksum change or heuristic scan, an intelligent response would be for the software to study the machine to determine the best scan string, then study the machine to learn what file types it infects, how many bytes it adds, how it adds to the files. In a heavily infected machine, it is reasonable for the software to learn how to remove the virus, recording its best guess at removal instructions. The product might then backup infected files, clean one set, and ask the user to try these programs, to see if they still operate correctly. If so, the anti-virus software can remove the infected backups; if not, the software could try another removal method.
Learning and adaptation need not be completely automated. While it might be desirable for the anti-virus system to infer how to remove a virus from a file by a thoughtful look at the file, it is not always possible to determine what has happened to various bytes of the original file, and thus not easy to learn how to repair based on a single infected file. An alternative is to set aside a research machine, in which software will exercise the virus, creating enough copies that it is able then to write its own detection and removal instructions, and test these instructions. Such instructions can then be used on production systems.
In the early days of anti-virus products, vendors tried writing a single module that would do everything. Eventually, vendors created more modular products, usually with a central module that claimed to do nearly everything, and extra modules that could do a few more things. In the future, anti-virus software will probably consist of many modules. Such modularity permits customers to only load and run the features they need, giving the user faster loading times, greater speed of operation, and more customizability.
The default weakness of modular software is a lack of inter-component communication. Rather than sell an organism, vendors are tempted to sell cells of the organism, hoping that the user will arrange them to resemble life. The full advantages of a modular architecture are achieved only when each module can work in harmony with the others, calling upon others as needed for various tasks. To achieve this requires inter-component communication.
Non-resident modules should check for the correct operation of resident modules, and not duplicate those functions if present. Thus a scanner should not check memory for viruses that could not be there if a resident behavior blocker is stopping them. But it must check memory for any virus that it is known the blocker doesn't block, and it must check memory quite carefully if the blocker is not running. Little actual intelligence is required for such programming - only motivation to do it right for once.
Resident modules and executing stand-alone programs should call non-resident modules as needed. For instance, a behavior blocker should call a scanner for identifying a suspect file or sector by name, providing the blocker has successfully stopped the virus. If a virus goes resident, moving past the blocker, the blocker should not call a scanner, as it could become infected. Similarly, it is appropriate for a scanner to consult an on-line hypertext virus information database if it finds a virus, displaying information about the virus found if the user wishes.
No module should call any other module into execution without first checking it for infection. The task is simple - simply compare early bytes of the program to be called with a checksum stored in the calling program. And yet the task is simply ignored by many of today's anti-virus products.
Viruses make additional copies of themselves with great abandon, and without consulting with the user. In contrast, the anti-virus product may take 30 minutes to install, requiring dozens and dozens of decisions by the user. This is unacceptable.
While it is not appropriate for anti-virus software to procreate without permission, it is appropriate for mortals to be capable of installing it prior to retirement. And it might be desirable for such software to be essentially self-installing, once basic permission was granted by the user.
[Back to index] [Comments (0)]