APC注入

2024-02-02 18:52
文章标签 注入 apc

本文主要是介绍APC注入,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1.APC机制

是一种并发机制,APC函数在线程中被异步回调

线程调用SleepEx、SignalObjectAndWait、MsgWaitForMultipleObjectsEx、WaitForMultipleObjectsEx、WaitForSingleObjectEx函数时会进入警告状态,系统会产生一个软中断,线程再次被唤醒时会检查APC队列执行所有APC函数

内核APC:由系统产生,不涉及到换栈

用户APC:由应用程序产生,在内核、用户层切换时使用不同栈

APC队列:KTHREAD+0x034 指向 KAPC_STATE结构体(存储APC队列)

执行函数

KiServiceExit函数

用于在系统调用(x86sysenter/x64syscall)、异常、中断后回到用户层

_KAPC_STATE.KernelApcPending为1则调用 KiDeliverApc 执行APC函数,执行完再循环遍历

KiDeliverApc函数

执行APC函数

2.APC注入

要注入多线程进程,单线程睡眠了就注入不进去了,注入系统进程需要以管理员权限运行来获取 SeDebugPrivilege特权

Copy
1.获取进程PID、句柄
2.将DLL路径写入进程内存
3.插入APC函数
4.关闭句柄
Copy
#include <iostream>
#include <windows.h>
#include <TlHelp32.h>
#define _tmain wmain // main使用UnicodeDWORD GetProcessPID(LPCTSTR lpProcessName) { // LPCTSTR是指向字符串的指针类型,如果需要修改内容要用LPTSTR/** CreateToolhelp32Snapshot是Windows API* 参数1:指定创建哪个快照,TH32CS_SNAPPROCESS是进程快照,包含所有进程信息* 参数2:进程ID,0表示所有进程*/HANDLE lpSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); // 创建所有进程快照PROCESSENTRY32 p32 = { 0 }; // Windows API中的结构体,用来存储进程快照p32.dwSize = sizeof(PROCESSENTRY32); // 设置结构体正确大小,这样才能填充进程信息Process32First(lpSnapshot, &p32); // Windows API,将全部进程信息写入p32do {if (!lstrcmp(p32.szExeFile, lpProcessName)) { // 进程名正确CloseHandle(lpSnapshot); // 关闭句柄return p32.th32ProcessID;}} while (Process32Next(lpSnapshot, &p32)); // 循环每一个进程
}void EnableDebugPrivilege() {HANDLE hToken;// 打开当前进程令牌,指定 TOKEN_ADJUST_PRIVILEGES 以修改令牌特权if (OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken)) {TOKEN_PRIVILEGES tp; // 用于存储令牌特权信息的结构体tp.PrivilegeCount = 1; // 特权数量为1LookupPrivilegeValue(NULL, SE_DEBUG_NAME, &tp.Privileges[0].Luid); // 指定启用的特权,SE_DEBUG_NAME 对应 SeDebugPrivilege特权tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED; // SE_PRIVILEGE_ENABLED 表示启用特权AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(tp), NULL, NULL); // 将令牌特权信息应用到令牌上CloseHandle(hToken); // 关闭句柄}
}void APCInjectDLL(DWORD PID, LPCWSTR DllPath) {EnableDebugPrivilege(); // 获取 SeDebugPrivilege特权HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, PID); // 获取进程全部权限的句柄DWORD size = (wcslen(DllPath) + 1) * sizeof(WCHAR); // 申请的空间大小,+1是加上\0,乘是因为UnicodeLPVOID pAllocMemory = VirtualAllocEx(hProcess, NULL, size, MEM_COMMIT, PAGE_READWRITE); // 指针指向远程申请的内存WriteProcessMemory(hProcess, pAllocMemory, DllPath, size, NULL); // 写入内存FARPROC pFuncAddr = GetProcAddress(GetModuleHandle(L"kernel32.dll"), "LoadLibraryW"); // 获取Kernel32、LoadLibraryHANDLE hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0); // 创建所有进程快照/** Thread32First是Windows API* 参数1:CreateToolhelp32Snapshot返回的句柄* 参数2:一个指向THREADENTRY32结构体(存储线程信息)的指针*/THREADENTRY32 te = { 0 }; // 每个成员初始化为0te.dwSize = sizeof(te); // 设置结构体正确大小,这样才能填充进程信息Thread32First(hSnap, &te); // 获取所有进程的线程的第一个线程的信息do {if (te.th32OwnerProcessID == PID) { // PID正确,找到目标进程HANDLE hThread = OpenThread(THREAD_ALL_ACCESS, FALSE, te.th32ThreadID); // 通过线程ID打开线程QueueUserAPC((PAPCFUNC)pFuncAddr, hThread, (ULONG_PTR)pAllocMemory); // 插入APC函数CloseHandle(hThread); // 关闭句柄}} while (Thread32Next(hSnap, &te)); // 取下一个线程CloseHandle(hSnap); // 关闭句柄CloseHandle(hProcess);
}/*
* 传参
* 这里是Unicode,Ascii用main和char*
* argv[0]是第一个参数(xxx.exe自身)
*/
int _tmain(int argc, TCHAR* argv[]) {DWORD PID = GetProcessPID(argv[1]); // 传入进程名获取进程PIDAPCInjectDLL(PID, L"C:\\xxx\\x64.dll");return 0;
}

这篇关于APC注入的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/671645

相关文章

SpringBoot项目注入 traceId 追踪整个请求的日志链路(过程详解)

《SpringBoot项目注入traceId追踪整个请求的日志链路(过程详解)》本文介绍了如何在单体SpringBoot项目中通过手动实现过滤器或拦截器来注入traceId,以追踪整个请求的日志链... SpringBoot项目注入 traceId 来追踪整个请求的日志链路,有了 traceId, 我们在排

SQL注入漏洞扫描之sqlmap详解

《SQL注入漏洞扫描之sqlmap详解》SQLMap是一款自动执行SQL注入的审计工具,支持多种SQL注入技术,包括布尔型盲注、时间型盲注、报错型注入、联合查询注入和堆叠查询注入... 目录what支持类型how---less-1为例1.检测网站是否存在sql注入漏洞的注入点2.列举可用数据库3.列举数据库

PHP防止SQL注入详解及防范

SQL 注入是PHP应用中最常见的漏洞之一。事实上令人惊奇的是,开发者要同时犯两个错误才会引发一个SQL注入漏洞。 一个是没有对输入的数据进行过滤(过滤输入),还有一个是没有对发送到数据库的数据进行转义(转义输出)。这两个重要的步骤缺一不可,需要同时加以特别关注以减少程序错误。 对于攻击者来说,进行SQL注入攻击需要思考和试验,对数据库方案进行有根有据的推理非常有必要(当然假设攻击者看不到你的

PHP防止SQL注入的方法(2)

如果用户输入的是直接插入到一个SQL语句中的查询,应用程序会很容易受到SQL注入,例如下面的例子: $unsafe_variable = $_POST['user_input'];mysql_query("INSERT INTO table (column) VALUES ('" . $unsafe_variable . "')"); 这是因为用户可以输入类似VALUE”); DROP TA

PHP防止SQL注入的方法(1)

(1)mysql_real_escape_string – 转义 SQL 语句中使用的字符串中的特殊字符,并考虑到连接的当前字符集 使用方法如下: $sql = "select count(*) as ctr from users where username ='".mysql_real_escape_string($username)."' and password='". mysql_r

PHP APC缓存函数使用教程

APC,全称是Alternative PHP Cache,官方翻译叫”可选PHP缓存”。它为我们提供了缓存和优化PHP的中间代码的框架。 APC的缓存分两部分:系统缓存和用户数据缓存。(Linux APC扩展安装) 系统缓存 它是指APC把PHP文件源码的编译结果缓存起来,然后在每次调用时先对比时间标记。如果未过期,则使用缓存的中间代码运行。默认缓存 3600s(一小时)。但是这样仍会浪费大量C

Go 依赖注入库dig

简介 今天我们来介绍 Go 语言的一个依赖注入(DI)库——dig。dig 是 uber 开源的库。Java 依赖注入的库有很多,相信即使不是做 Java 开发的童鞋也听过大名鼎鼎的 Spring。相比庞大的 Spring,dig 很小巧,实现和使用都比较简洁。 快速使用 第三方库需要先安装,由于我们的示例中使用了前面介绍的go-ini和go-flags,这两个库也需要安装: $ go g

Web安全之SQL注入:如何预防及解决

SQL注入(SQL Injection)是最常见的Web应用漏洞之一,它允许攻击者通过注入恶意SQL代码来操作数据库,获取、修改或删除数据。作为Java开发者,理解并防止SQL注入攻击是至关重要的。在本篇文章中,我们将详细介绍SQL注入的原理,演示如何在电商交易系统中出现SQL注入漏洞,并提供正确的防范措施和解决方案。 1. 什么是SQL注入? SQL注入是一种通过在用户输入中嵌入恶意SQL代

网络安全(sql注入)

这里写目录标题 一. information_schema.tables 和 information_schema.schemata是information_schema数据库中的两张表1. information_schema.schemata2. information_schema.tables 二. 判断注入类型1. 判断数字型还是字符型注入2. 判断注入闭合是""还是'' 三. 判

Java抽象类使用@Autowired注入实例

示例代码如下: 抽象类 public abstract class AbstractWaterMark {@Autowiredprivate AchievementApplicationService achievementApplicationService;public AchievementApplication queryByCode(String code){return achiev