Understanding Polymorphic Viruses
By Jeff Silverman
This essay is an executive summary about Polymorphic Virus. It
explains what a polymorphic virus is, the details about how to write one,
and why they are so hard to detect. The risks from polymorphic viruses
are compared against other viruses. Finally, I propose some suggestions
for strategies which IS managers could take which will reduce the threat
of damage due to viruses.
A discussion of terms
- virus
- a computer program which attaches itself to other computer
programs and causes them to do something that harms the computer, or the
data in the computer, or the network which connects to the computer.
Some writers distingush between "viruses" and "worms".
- worm
- A worm is
a stand alone program as opposed to a program that attaches to another
program; for the purposes of this discussion there is little difference.
- Payload
-
The "payload" of a virus is the part of the software that actually does
the damage; the rest of the virus is used to break the security.
- Signature
-
Each virus has a "signature"; the "signature" is a string of bytes, which, if it
appears, is diagnostic of the virus. Care must be taken when picking signatures, because if a signature is common then it
will snare uninfected programs by mistake, this is a "false alarm".
if the signature is too long, then it will fail to detect encrypted viruses
and polymorphic viruses. Picking good signatures is key to a high probability of detection and a low false alarm rate.
- Virus scanner
- A "virus scanning program" is a program that scans other programs looking
for viruses. From the point of view of a virus scanning program,
a virus is a string of bytes. The scanner works by comparing the
contents of all of the programs in a computer against a database of viruses.
For the purposes of this discussion, there are three kinds of viruses:
a "normal" virus, an "encrypted" virus, and a "polymorphic" virus.
"Normal" viruses are not encrypted in any way, and you can examine how
they work using a standard debugger or disassembler. "Encrypted"
viruses have two parts, a decryption routine and an encrypted payload.
The payload includes a compatible encryption routine so that virus can
infect other machines. A "polymorphic" virus is similar to an encrypted
virus, except that the decryption routine has been cleverly coded in chunks,
and each chunk ends with a jump instruction to the next chunk. The
chunks come in different sizes and orders and there can be junk bytes in
between the chunks. Thus, there is no consistent signature for the
virus and detection is very difficult.
Why are polymorphic viruses so dangerous?
We can measure the quality of a virus scanning program using three figures
of merit: speed (fast is good), the probability of detection (ideal is
1.0) and the probability of false alarm (ideal is 0.0). The
problem with measuring Pd rates and Pfa rates
is that the process of detecting viruses is deterministic, so if your virus
scanner misses a virus on a first pass, it will miss it on subsequent passes. Nevertheless,
it is possible that a virus scanner manufacturer may pick signatures that are too short,
which will give many false alarms, or too long, which may miss a virus variant.
Real virus scanning programs have Pd rates approaching 1.0,
and Pfa rates approaching .00 for unencrypted viruses, especially
if you keep the software and the signature files up to date. See
for example The
Virus Test Center anti virus tests for April 2000 for details.
However, for encrypted viruses and for polymorphic viruses the signatures
can be as short as three bytes. So virus scanning is not a universal
panacea.
There are viruses out there that will format your hard drive, and flash
your BIOS. Are polymorphic viruses any worse than these? In
terms of the damage done, no. However Polymorphic viruses are more
dangerous than normal or encrypted viruses because they are very hard to
detect. There is no string of bytes that consistently identifies
an infected file. So a system can be infected for a long time, and
infect other machines, without anybody being aware of the problem.
One proposed method of detecting polymorphic viruses (see Symantec's
"How to
manage Polymorphic Viruses") is to create a "black box" in RAM and
run the program. If the program attempts to modify something it isn't
supposed to, then it is a virus. The problem with this approach is
that the virus could use some logic to run only a certain fraction of the
time, or after a certain date. Determining whether a program is infected
is equivalent to the halting problem in Turing's Theorem.
Here is an example of a comment about how difficult it is to detect
a polymorphic virus (From McAfee):
The DAME, or Dark Avenger Mutating Engine, was submitted in
February, 1992. DAME is not actually a virus itself, but rather a polymorphic
encryption engine which is used as part of the viruses indicated in this
entry. The encryption produced by the encryption engine is extremely complex,
with no more than three bytes remaining constant within replicated samples.
As a result, viruses encrypted with this engine can only be identified
by the presence of the encryption engine itself.
The problem with 3 bytes remaining in the signature is that the odds become
very large for a false alarm. If you have a random stream of bytes,
you are virtually assured that after 16 MB, you'll see the three bytes.
Modern disk drives are three orders of magnitude larger than this.
What does a polymorphic virus look like?
Consider the following code fragment of a "normal" virus. This virus resets
a controller and then reboots the PC, which is pretty innocuous as these
things go. Here is the code
00001
# reboot.s
00002
#
00003
# An assembly language program t
o reset the hard drive controller and then reboot a PC
00004
00005 0000
8816 0080
mov 0x80,dl
00006 0004
8826 000D
mov 0x0d,ah
00007 0008
CD
13 int 0x13
00008 000A
CD
19 int 0x19
00009
end
The "signature" of this virus is 88 16 00 80 88 26 00 0d cd 13 cd 19,
which is 12 bytes long. Now, if I want to change this by adding NOP
instructions, I can. The virus becomes 88 16 00 80 90 88 26 00 0d
90 90 cd 13 90 90 90 cd 19. That's relatively simple. If I
want to get more sophisticated, I can add jump instructions and other instructions
which really don't do anything.
00001
# reboot.s
00002
#
00003
# An assembly language program t
o reset the hard drive controller and then reboot a PC
00004
00005 0000
EB 10
jmp L1
00006 0002
90
nop
00007 0003
8826 000D
L2: mov 0x0d,ah
00008 0007
EB 0F
jmp L3
00009 0009
90
L4: nop
00010 000A
90
nop
00011 000B
CD
13 int 0x13
00012 000D
90
nop
00013 000E
90
nop
00014 000F
90
nop
00015 0010
CD
19 int 0x19
00016
00000012> L1:
00017 0012
8816 0080
mov 0x80,dl
00018 0016
EB EB
jmp L2
00019 0018
88FF
L3: mov bh,bh
00020 001A
EB ED
jmp L4
00021
end
This is still the same payload as the original example, but now it looks
nothing at all like the original program. It's signature is eb 10
90 88 26 00 0d eb 0f 90 90 cd 13 90 90 90 cd 19 88 16 00 80 88 ff eb ed
and looks very different from the original, but it is still the same payload.
There is some theoretical work about executing code and seeing what
it does, but this approach is doomed to failure. The virus code can
sense if the virus scanning program is active, and change its function
if it is. Or the virus code can sense the date and not act until
a certain day. Can you imagine trying to track down a virus that
only ran when the minute of the hour was a multiple of 3? It would
do its thing at 12:12 but not at 12:13 or 12:14?
So what are we to do?
There are some things we as an industry can do that just won't work.
-
User Education. A lot of the articles about polymorphic viruses are
surprisingly old. For example, I found a paper, http://www.bocklabs.wisc.edu/~janda/polymorf.html,
on polymorphic viruses dated Jan 24, 1993. And all of this time,
we have been telling our users to not engage in dangerous computing practices,
but they still do. For example, users keep sending binary files such
as executables, word for windows files, Excel spreadsheets, through E-mail.
-
Better virus scanners. The problem with this approach is that it
is theoretically possible for a virus to detect when a virus detector is
running and inactivate itself.
-
Integrity verification systems. such as tripwire. An integrity verification
system is a program which scans all of the executables in a system, and
for each executable, generates a checksum. From time to time, the
integrity verification system recalculates the checksum and generates an
exception if the check sum changed. This feature could even be built
into the operating system, so that the integrity of the executable is checked
each time the image is activated. The problem here is that viruses
can hide in .dlls, in libraries, or in scripts. Also, building a
standardized mechanism for storing checksums invites viruses which attack
that storage mechanism. Finally, tripwires require a rigorous seperation
of read-only code and configuration information, which is the antithesis
of design in the MS-Windows and Windows/NT systems.
-
Better operating systems. The problem here is that there are
better operating systems. Linux, FreeBSD, OpenBSD, Solaris are all
available for the PC platform and all are significantly more secure, cheaper
(both software and hardware), reliable, and better performing than MS-Windows.
Although there are worms and viruses for UNIX and Linux, it is a lot harder
to infect a UNIX machine than a Windows machine because UNIX was designed
from day one to be a multiuser multitasking operating system with security.
Quite frankly, until the market is willing to vote with its dollars, viruses
will continue to be a problem.
-
Firewalls. The problem with firewalls is that they generally pass
E-mail, and viruses propogate through E-mail. Firewalls are good
for other things, however, and no sysadmin worth his or her salt should
go without one.
-
Embrace heterogeneous computing. Just as humans can't get feline
leukemia, and cats don't get AIDS, heterogeneous computing saves us from
disaster. So why did I just submit my three year plan to my management
which says that I will become efficient by promoting homogeneous computing
solutions built around PCs running Linux? The problem is that while
heterogeneous computing makes life easy for software developers and system
administrators, it also makes it easy for hackers and evil doing scum.
A virus for Intel/Linux will have a hard time on a solaris system, especially
if its solaris/SPARC. A virus of Intel/Linux will have a hard time
running on Alpha/Linux, or Linux on System/390. Again, Windows only
runs on Intel. We have to trade that against sysadmin efficientcy
and the problems of managing code on multiple platforms.
-
Better logging of internet traffic. The problem here is that better
logging will generate reams of data, and without tools to analyze those
logs, it will swamp an already overworked IS staff. Further, I can
think of few things more boring than pouring over logs. If we put
stateful logging analyzers in place, then we might get a handle on what's
going wrong, but then, why not put that state engine in the applications
we're logging?
Although none of these alternatives will Fix The Problem, none of them
will hurt and all are useful and ought to be done.
Then, there are some ideas which I have not seen in the literature that
might be helpful:
-
Two levels of system privilege. The ordinary privilege level is for
tasks such as user management and configuration changes, but not changing
executable images or installing software. The extraordinary privilege
level is for software installation tasks. The system cannot enter
the extraordinary privilege level without making much noise. So it
would not be possible to modify executables easily.
-
Store executables on read-only file systems. This is easy, nay, trivial
on UNIX machines. Simply create partitions for /sbin, /bin, and /usr
(you might have to symlink /usr/local/etc to /etc or similar). It is more
challenging on MS-WIndows (including W2K) machines because the file systems
that hold executables also hold read/write storage. Also, some .DLL
files are writable, and programs can store state information there, along
with executable code. This also raises issues with software licensing,
which is not much of a problem in the UNIX world but Microsoft gets passionate
about that sort of thing. An executable on a read-only file system
is intrinsically secure, so long as the file server itself is not compromised.
The file server could have a minimalist, highly secure operating system.
-
A wholesale abandonment of MS-Windows. I know that this sounds like
microsoft bashing. Everybody says that Microsoft builds secure operating
systems, and that W2K finally got it right. But there is more to
security than the operating system - security also has to be designed into
the applications and the layout of files in file systems. Microsoft
didn't do that, and now they are scrambling with patch after patch after
patch. With Windows/XP, Microsoft is deploying an automated patching
tool. Anybody who has studied Quality using the W. Edwards Deming
approach knows that that's not quality, that's putting a band-aid on the
problem. In particular, there are some things Microsoft could do
to improve the security of their systems:
-
Microsoft should follow the UNIX lead and lay out all of the system executables
in one place, all application executables in another, all configuration
files in another place. Instead of one big files (well, really two
big files) for system configuration, each application should have its own
configuration file. If two applications have to work together, then
each application ought to read the others configuration file.
-
Microsoft loves to use binary files for things, which make it more difficult
for people who want to inspect files for damage. Microsoft changes
file formats in incompatible ways, again, making it more difficult for
people who want to invest in building tools. Microsoft should commit
to using ASCII text format and then upgrade the format in backwards compatible
ways.
-
Microsoft needs to engage its customers in a dialog on how to build systems.
I have participated in any of a number of fora in which participants have
expressed anger at Microsoft's practices, clearly, the company is not listening.
One way to start would be to publish its bug lists.
Compare the Microsoft approach with the Open Software Development approach. The mailing lists are alive with controversy and argument about the Best Way to do things. I am currently engaged in a dialog with a software engineer at Red Hat
about how to improve the software installation procedure. Neither of us feel this
is an extraordinary thing to do.
-
Proper staffing levels and competency levels for sysadmins. One would
think that with the .coms that are going .gone, there would be a glut of
sysadmins, and this problem would go away. In general, I don't see
that. What's more, a lot of the sysadmins who are getting laid off
have no formal security training and little knowlege of computers beyond
their immediate jobs. They went too high, too fast, and it will take
a while before they are useful for anything else. I advocate that
sysadmins ought to have software development backgrounds. Why?
Because ultimately, they are managing software - they need to know at a
gut level what works and what doesn't. They need to know how to test.
They need to write process documentation. I am trying to hire people,
but I'm not going to hire somebody who has typographical errors on their
resume.
- One thing that has worked very nicely for me, in a university setting,
is hiring high school kids at a slight premium over what McDonald's is
paying. In general, they are anxious to get the training and experience.
That might not work for you. I also have a lot of concern that I
am training the next generation of hackers, so I spend a lot of time talking
about the economic and ethical considerations of hacking.
-
I have some scripts which invoke various Linux based hacker tools.
I run nmap on all of my machines periodically, and note any changes from
nominal. I also run snort from time to time. These aren't universal
panaceas, but, they will, for example, detect an infection of back orofice.
The pattern here is that our current practices aren't working. We
can manage our systems and do the profit-making things we're expected to
do if we're constantly patching and repatching in response to directives
from SANS. This is not to say that
we should ignore what SANS and CERT tell
us, but rather, that we can't get multiple security advisories a week and
expect to make progress on other things we're supposed to do.
Conclusions
I described polymorphic viruses, and how they are similar to and different
from other viruses. I explained why polymorphic viruses were so much
more dangerous than other viruses. I described some ideas that I
have seen in the literature, and some ideas I have conceived on my own
which I would like to see developed.
© 2001 By Jeff Silverman. At the moment, I
am reserving all rights. For permission to reproduce, please E-mail
me.
HTML
4.01 transitional validation.
see new web server .web server .web server .