With the basics of boot sectors behind us, let’s explore a sophisticated boot sector virus that will overcome the rather glaring limitations of the KILROY virus. Specifically, let’s look at a virus which will carefully hide itself on both floppy disks and hard disks, and will infect new disks very efficiently, rather than just at boot time.
Such a virus will require more than one sector of code, so we will be faced with hiding multiple sectors on disk and loading them at boot time. To do this in such a way that no other data on a disk is destroyed, while keeping those sectors of virus code well hidden, will require some little known tricks. Additionally, if the virus is to infect other disks after boot-up, it must leave at least a portion of itself memory-resident. The mechanism for making the virus memory resident cannot take advantage of the DOS Keep function (Function 31H) like typical TSR programs. The virus must go resident before DOS is even loaded, and it must fool DOS so DOS doesn’t just write over the virus code when it does get loaded. This requires some more tricks, the exploration of which will be the subject of this chapter.
Basic Structure of the Virus
Our new boot sector virus, named STEALTH, will have three parts. First, there is a new boot sector, called the viral boot sector. This is the sector of code that will replace the original boot sector at Track 0, Head 0, Sector 1. Secondly, there is the main body of the virus, which consists of several sectors of code that will be hidden on the disk. Thirdly, there is the old boot sector, which will be incorporated into the virus.
When the viral boot sector is loaded and executed at startup, it will go out to disk and load the main body of the virus and the old boot sector. The main body of the virus will execute, possibly infecting the hard disk, and installing itself in memory (as we will discuss in a moment) so it can infect other disks later. Then it will copy the original boot sector over the viral boot sector at 0000:7C00H, and execute it. The last step allows the disk to boot up in a normal fashion without having to bother writing code for startup. That’s important, because STEALTH will infect the partition boot sector on hard drives. The code in that sector is completely different from DOS’s boot sector. Since STEALTH saves the original boot sector, it will not have to go around carrying two boot sectors with it, one for floppies and one for hard disks. Instead, it simply gobbles up the code that’s already there and turns it to its own purposes. This strategy provides the added benefit that the STEALTH virus will be completely operating system independent.
The Copy Mechanism
The biggest part of designing the copy mechanism is deciding how to hide the virus on disk, so it does not interfere with the normal operation of the computer (unless it wants to).
Before you hide anything, you’d better know how big it is. It’s one matter to hide a key to the house, and quite another to hide the house itself. So before we start deciding how to hide STEALTH, it is important to know about how big it will be. Based on the size of the INTRUDER virus in Chapter 4, we might imagine
STEALTH will require five or ten sectors. With a little hindsight, it turns out that six will be sufficient. So we need a method of quickly and effectively hiding 6 sectors on each of the various types of floppy disks, and on hard disks of all possible types.
It would be wonderful if we could make the virus code totally invisible to every user. Of course, that isn’t possible, although we can come very close. One tricky way of doing it is to store the data on disk in an area that is completely outside of anything that DOS (or other operating systems) can understand. For floppy disks, this would mean inventing a non-standard disk format that could contain the DOS format, and also provide some extra room to hide the virus code in. DOS could use the standard parts of the disk the way it always does, and the non-standard parts will be invisible to it. Unless someone writes a special program that a) performs direct calls to the BIOS disk functions and b) knows exactly where to look, the virus code will be hidden on the disk. This approach, although problematic for floppies, will prove useful for hiding the virus on the hard disk.
In the case of floppies, an alternative is to tell DOS to reserve a certain area of the disk and stay away from it. Then the virus can put itself in that area and be sure that DOS will not see it or overwrite it. This can be accomplished by manipulating the File Attribute Table. This method was originally employed by the Pakistani Brain virus, which was written circa 1986. Our STEALTH virus will use a variant of this method here to handle 360 kilobyte and 1.2 megabyte disk formats for 5 1/4" diskettes, and 720 kilobyte and 1.44 megabyte 3 1/2" diskette formats.
Let’s examine the 3 1/2" 720 kilobyte diskette format in detail to see how STEALTH approaches hiding itself. This kind of diskette has 80 tracks, two sides, and nine sectors per track. The virus will hide the body of its code in Track 79, Side 1, Sectors 4 through 9. Those are the last six sectors on the disk, and consequently, the sectors least likely to contain data. STEALTH puts the main body of its code in sectors 4 through 8, and hides the original boot sector in sector 9. However, since DOS normally uses those sectors, the virus will be overwritten unless it has a way of telling DOS to stay out. Fortunately, that can be done by modifying the FAT table to tell DOS that those sectors on the disk are bad.
DOS organizes a diskette into clusters, which consist of one or more contiguous sectors. Each cluster will have an entry corresponding to it in the FAT table, which tells DOS how that cluster is being used. The FAT table consists of an array of 12 bit entries, with as many entries as there are clusters on the diskette. If a cluster is empty, the corresponding FAT entry is 0. If it is in the middle of a file, the FAT entry is a pointer to the next cluster in the file; if it is at the end of a file, the FAT entry is FF8 through FFF. A cluster may be marked as bad (to signal DOS that it could not be formatted properly) by placing an FF7 Hex in its FAT entry.
When DOS sees an FF7 in a FAT entry, it does not use the sectors in that cluster for data storage. DOS itself never checks those clusters to see if they are bad, once they are marked bad. Only the FORMAT program marks clusters bad when it is in the process of formatting a disk. From there on out, they are never touched by DOS. Thus a virus can mark some clusters bad, even though they’re really perfectly fine, and then go hide there, assured that DOS will leave it alone. On a 720 kilobyte diskette, there are two sectors in each cluster. Thus, by marking the last three clusters on the disk as bad in the two FAT tables, the virus can preserve six sectors at the end of the diskette.
In the event that the diskette is full of data, the virus should ideally be polite, and avoid overwriting anything stored in the last clusters. This is easily accomplished by checking the FAT first, to see if anything is there before infecting the disk. Likewise, if for some reason one of those sectors is really bad, the virus should stop its attempt to copy itself to the diskette gracefully. If it does not, the diskette could end up being a useless mess (especially if it is a boot disk) and it wouldn’t even contain a working copy of the virus. If there is a problem at any stage of the infection process, the virus will simply abort, and no permanent damage will be done to the disk.
On the other hand, we could design the virus to be more agressive. It might be somewhat more successful (from a neo-darwinian point of view) if it infects the diskette even when the disk is full, and it will have to overwrite a file to infect the disk successfully. While we do not implement such an approach here, it would actually be easier than being polite.
Similar strategies are employed to infect 360 kilobyte and 1.2 megabyte 5 1/4" diskettes, and 1.44 megabyte 3 1/2" diskettes, as explained in detail in the code in Appendix E. There do exist other diskette formats, such as 320 kilobyte 5 1/4", which the virus will simply stay away from. If STEALTH encounters anything non-standard, it just won’t infect the diskette. It will have plenty of formats that it can infect, and obsolete or non-standard formats are relatively rare. Failing to infect the one-in-a-thousand odd ball is no great loss, and it saves a lot of code. As an exercise, you may want to modify the virus so it can infect some different formats.
Hiding data on a hard drive is a different matter. There are so many different drives on the market that it would be a major effort for STEALTH to adapt to each disk drive separately. Fortunately, hard drives are not set up to be 100% occupied by DOS. There are non-DOS areas on every disk. In particular, the first boot sector, which contains the partition table, is not a part of DOS. Instead, DOS has a partition assigned to it, for its own use. Any other area on disk does not belong to DOS.
As it turns out, finding a single area on any hard disk that does not belong to DOS, is not too difficult. If you take the DOS program FDISK and play with it a little, creating partitions on a hard drive, you’ll soon discover something very interesting: Although the first boot sector is located at Track 0, Head 0, Sector 1, FDISK (for all the versions I’ve tested) does not place the start of the first partition at Track 0, Head 0, Sector 2. Instead, it always starts at Track 0, Head 1, Sector 1. That means that all of Track 0, Head 0 (except the first sector) is free space. Even the smallest ten megabyte disk has 17 sectors per track for each head. That is plenty of room to hide the virus in. So in one fell swoop, we have a strategy to place the virus on any hard disk. (By the way, it’s only fair to mention that some low level hard disk formatting programs do use those sectors to store information in. However, letting the virus overwrite them does not hurt anything at all.)
Once a strategy for hiding the virus has been developed, the copy mechanism follows quite naturally. To infect a disk, the virus must:
- Determine which type of disk it is going to infect, ahard disk or one of the four floppy disk types.
- Determine whether that disk is already infected, or ifthere is no room for the virus. If so, the copy mechanism should not attempt to infect the disk.
- Update the FAT tables (for floppies) to indicate thatthe sectors where the virus is hidden are bad sectors. 4) Move all the virus code to the hidden area on disk.
- Read the original boot sector from the disk and writeit back out to the hidden area in the sector just after the virus code.
- Take the disk parameter data from the original bootsector (and the partition information for hard disks) and copy it into the viral boot sector. Write this new boot sector to disk as the boot sector at Track 0, Head 0, Sector 1.
In the code for STEALTH, the copy mechanism is broken up into several parts. The two main parts are routines named INFECT_HARD, which infects the hard disk, and INFECT_FLOPPY, which infects all types of floppy drives. The INFECT_FLOPPY routine first determines which type of floppy drive it is dealing with by reading the boot sector and looking at the number of sectors on the drive (the variable SEC_COUNT in Table 2). If it finds a match, it calls one of the routines INFECT_360, INFECT_720, INFECT_12M or INFECT_144M, which goes through the details of infecting one of the particular diskette types. All of these routines are listed in Appendix E.
The Search Mechanism
Searching for uninfected disks is not very difficult. We could put an ID byte in the viral boot sector so when the virus reads the boot sector on a disk and finds the ID, it knows the disk is infected. Otherwise it can infect the disk. The STEALTH virus uses its own code as an ID. It reads the boot sector and compares the first 30 bytes of code (starting after the boot sector data area) with the viral boot sector. If they don’t match, the disk is ripe for infection.
The code for a compare like this is incorporated into the routine IS_VBS:
IS_VBS: push si ;save these push di cld mov di,OFFSET BOOT ;set up for a compare mov si,OFFSET SCRATCHBUF+(OFFSET BOOT-OFFSET BOOT_START) mov cx,15 repz cmpsw ;compare 30 bytes pop di ;restore these pop si
ret ;return with z properly set which returns a z flag if the disk is infected, and nz if it is not. BOOT is the label for the start of the code in the boot sector. BOOT_START is the beginning of the boot sector at 7C00H. IS_VBS is called only after a boot sector is read from the disk by the GET_BOOT_SEC routine into the scratch data area SCRATCHBUF. The code to read the boot sector is:
GET_BOOT_SEC:
push ax mov bx,OFFSET SCRATCHBUF ;buffer for boot sec mov dl,al ;drive to read from mov dh,0 ;head 0 mov ch,0 ;track 0 mov cl,1 ;sector 1 mov al,1 ;read 1 sector mov ah,2 ;BIOS read function int 13H ;go do it pop ax ret
which reads the boot sector from the drive specified in al.
So far, fairly easy. However, the more serious question in designing a search mechanism is when to search for a disk to infect. Infecting floppy disks and hard disks are entirely different matters. A user with a hard disk on his machine will rarely, if ever, boot from a floppy. Often, booting from a floppy will be an accident. For example a user might leave a diskette in drive A when he goes home from work, and then comes in the next morning and turn his machine on. Normally such a disk will not be a boot disk with DOS on it, and it will cause an error. The user will see the error and take it out to boot from the hard drive as usual. However, the boot sector on the floppy disk was loaded and executed. The infection mechanism for moving from a floppy disk to a hard disk must take advantage of this little mistake on the user’s part to be truly effective. That means hard drives should be infected at boot time. Then if a user leaves an infected diskette in drive A and turns on his machine, his hard drive is infected immediately. No other operation is necessary.
On the other hand, once a hard disk has the virus on it, it may come into contact with dozens or even hundreds of floppy diskettes during one day. In order to infect them, the virus must be present in memory when the diskettes are in the floppy drive. That means when the virus is loaded from a hard drive, it must become memory-resident and stay there. Then, it must activate whenever some appropriate action is performed on the floppy diskette by other programs. In this way, the computer becomes an engine for producing infected floppy disks.
So what action on the floppy drive should trigger the infection sequence? It should certainly be something that happens frequently, yet at the same time it should require a bare minimum of extra disk activity. Both search and infection should happen simultaneously, since floppy disks can easily be removed and inserted. If they were not simultaneous, the search could indicate an uninfected diskette on drive A. Then the infection routine could attempt to infect an already infected disk if the user were given time to change disks before the infection routine got around to doing its job.
An ideal time to check the floppy disk for the virus is when a particular sector is read from the disk. That can be a frequent or rare occurrence, depending on which sector we choose as a trigger. A sector near the end of the disk might be read only rarely, since the disk will rarely be full. At the other extreme, if it were to trigger when the boot sector itself is read, the disk would be infected immediately, since the boot sector on a newly inserted floppy drive is read before anything else is done. The STEALTH virus takes the most agressive approach possible. It will go into the infection
Figure 15: Infect Logic
sequence any time that the boot sector is read. That means that when the virus is active, any time you so much as insert a floppy disk into the drive, and do a directory listing (or any other operation that reads the disk), it will immediately become infected. The virus must churn out a lot of floppies in order for a few to get booted from.
To implement this search mechanism, the STEALTH virus must intercept Interrupt 13H, the BIOS disk service, at boot time, and then monitor it for attempts to access the boot sector. When such an attempt is made, the virus will carefully lay it aside for a bit while it loads the boot sector from that diskette for its own use, checks it with IS_VBS, and possibly infects the diskette. After the virus is finished with its business, it will resume the attempt to read the disk and allow the program that wanted to access the boot sector to continue its operation unhindered.
Code for this type of an interrupt trap looks like this:
INT_13H: sti ;interrupts on cmp ah,2 ;we want to intercept reads jnz I13R ;pass anything else to BIOS cmp dh,0 ;is it head 0?
jnz I13R ;nope, let BIOS handle it cmp ch,0 ;is it track 0?
jnz I13R ;nope, let BIOS handle it
RF0: cmp dl,80H ;is it the hard disk?
jnc I13R ;yes, let BIOS handle read cmp cl,1 ;no, floppy, is it sector 1?
jnz I13R ;no, let BIOS handle it call CHECK_DISK ;is floppy already infected? jz I13R ;yes so let BIOS handle it call INFECT_FLOPPY ;else go infect the diskette
;and then let BIOS go
;do the original read I13R: jmp DWORD PTR cs:[OLD_13H] ;BIOS Int handler
where OLD_13H is the data location where the original Interrupt 13H vector is stored before it is replaced with a vector to INT_13H. CHECK_DISK simply calls GET_BOOT_SEC and IS_VBS after saving all the registers (to pass them to the BIOS later to do the originally requested read).
The Anti-Detection Mechanism
The STEALTH virus uses some more advanced anti-detection logic than previous viruses we’ve studied. They are aimed not only at avoiding detection by the average user, who doesn’t know computers that well, but also at avoiding detection by a user armed with sophisticated software tools, including programs designed specifically to look for viruses.
The main part of the STEALTH virus is already hidden on disk in areas which the operating system thinks are unusable. On floppy disks, only the viral boot sector is not hidden. On hard drives, the whole virus is exposed in a way, since it is sitting on Track 0, Head 0. However, none of those sectors are accessed by programs or the operating system, although the FDISK program rewrites the partition boot sector.
Since the virus is already intercepting Interrupt 13H to infect disks, it is not too difficult to add a little functionality to the viral interrupt handler to hide certain sectors from prying eyes. For example, consider an attempt to read the boot sector on a 1.2 megabyte diskette: STEALTH traps the request to read. Instead of just blindly servicing it, the virus first reads the boot sector into its own buffer. There, it checks to see if this sector is the viral boot sector. If not, it allows the caller to read the real boot sector. On the other hand, if the real boot sector belongs to STEALTH, it will read the old boot sector from Track 79, Head 1, Sector 15, and pass that to the caller instead of the viral boot sector. In this way, the viral boot sector will be invisible to any program that uses either DOS or BIOS to read the disk (and the exceptions to that are pretty rare), provided the virus is in memory. In the same way, the BIOS write
Figure 16: Viral Read Logic.
function can be redirected to keep away from the viral boot sector, redirecting any attempts to write there to the old sector.
In addition to hiding the boot sector, one can hide the rest of the virus from any attempts to access it through Interrupt 13H. On hard drives, STEALTH does not allow one to read or write to sectors 2 through 7 on Track 0, Head 0, because the virus code is stored there. It fools the program making a read attempt by returning a data block of zeros, It fools the program trying to write those sectors by returning as if it had written them, when in fact the writing was bypassed.
Additionally, any attempt to read or write to sectors on the floppy drive could be trapped and returned with an error (carry flag c set). That is what one would expect, if the clusters marked as bad in the FAT really were bad. STEALTH does not go that far though, since DOS protects those sectors pretty well already. You may want to try to incorporate that extension in as an exercise, though.
With these anti-detection procedures in place, the main body of the virus is well hidden, and when any program looks at the boot sector, it sees the old boot sector. The only ways to detect the virus on a disk are (a) to write a program to access the disk with the hardware directly, or (b) to boot from an uninfected disk and examine the boot sector of the potentially infected disk. Of course, the virus is not very well hidden in memory.
Installing the Virus in Memory
Before the virus passes control to the original boot sector, which will load DOS, it must set itself up in memory somewhere where it won’t get touched. To do this outside of the control of DOS is a bit tricky. The basic idea involved here is that DOS uses a number stored at 0040:0013 Hex, which contains the size of available memory in kilobytes. This number is set up by the BIOS before it reads the boot sector. It may have a value ranging up to 640 = 280H. When the BIOS sets this parameter up, it looks to see how much memory is actually installed in the computer, and reports it here. However, something could come along before DOS loads and change this number to a smaller value. In such a situation, DOS will not use all the memory that is available in the system, but only what it’s told to use by this memory size variable. Memory above that point will be reserved, and DOS won’t touch it.
The strategy for loading STEALTH into memory is to put it in the highest physical memory available, determined by the memory size, as the BIOS has set it. Then STEALTH subtracts a sufficient number of kilobytes from the memory size variable to protect itself. In this way, that memory will be kept away from DOS, and used by STEALTH when Interrupt 13H is called.
The two responsibilities of the viral boot sector are to load the main body of the virus into memory, and then to load and execute the original boot sector. When the BIOS loads the viral boot sector (and it loads whatever is placed at Track 0, Head 0, Sector 1), that sector first moves itself into the highest 512 bytes of memory (within the 640 kilobyte limit). In a machine with 640K of memory, the first unoccupied byte of memory is at A000:0000.
Figure 17: The Virus in RAM.
(A) Viral boot sector (B) Viral boot sector (C ) Viral boot sector moves itself to high loads the rest of virus installs Int 13H and memory. and old boot sector. moves old boot
sector to execute.
A000:0000 A000:0000 A000:0000
Viral BS
|
Viral BS
|
9820:7000
0000:7C00
0000:004C
|
Viral BS
| ||||
9820:7000
0000:004C
| |||||||
Old BS
| |||||||
Main
Body of
Virus
|
Main
Body of
Virus
| ||||||
Viral BS
|
Old BS
| ||||||
F000:2769
|
9820:0054
| ||||||
0000:7C00
The boot sector will move itself to the first 512 bytes just below this. Since that sector was compiled with an offset of 7C00 Hex, it must relocate to 9820:7C00 Hex (which is right below A000:0000), as desired. Next, the viral boot sector will read the 6 sector long main body of the virus into memory just below this, from 9820:7000 to 9820:7BFF. The original boot sector occupies 9820:7A00 to 9820:7BFF (since it is the sixth of six sectors loaded). The viral boot sector then subtracts 4 from the byte at 0040:0013H to reserve 4 kilobytes of memory for the virus. Next, the viral boot sector reroutes Interrupt 13H to the virus. Finally, it moves the original boot sector from 9820:7A00 to 0000:7C00 and executes it. The original boot sector proceeds to load DOS and get the computer up and running, oblivious to the fact that the system is infected.
A Word of Caution
The STEALTH virus code is listed in Appendix E. At the risk of sounding like a broken record, I will say this virus is highly contagious. You simply don’t know when it is there. It hides itself pretty well, and once it’s infected several disks, it is easy to forget where it’s gone. At that point, you can kiss it goodbye. Once a floppy disk is infected, you should re-format it to get rid of the virus. If your hard disk gets infected, the safest way to be rid of it is to do a low level format of Track 0, Head 0. Of course, IDE drives won’t let you do that too easily. Alternatively, you can write a program that will save and restore your partition sector, or you can run FDISK on the drive to overwrite the partition sector. Overwriting the partition sector will keep the virus from executing, but it won’t clean all its code off your system. Obviously, if you’re going to experiment with this virus, I suggest you only do so on a system where you can afford to lose all your data. Experiment with this virus at your own risk!
Post a Comment
Write Your Precious Comments Here.!