博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
APC注入
阅读量:4605 次
发布时间:2019-06-09

本文共 3020 字,大约阅读时间需要 10 分钟。

0X01 注入原理

      当线程被唤醒时APC中的注册函数会被执行的机制,并依此去调用我们的DLL加载代码,进而完成注入的目的

            具体的流程:

            1 当EXE里的某个线程执行到sleepEX(),或者waitForSingleObjectEX()(其实还有WaitForMultipleObjectsEx

 , SignalObjectAndWait,MsgWaitForMultipleObjectsEx)这几个函数时,会产生一个软中断。

            2 当线程再次被唤醒时,此线程会首先执行APC队列中的被注册的函数。

            3.利用QueueUserAPC()这个API可以在软中断的时间内插入一个函数指针,如果我们插入的是Loadlibrary()执行函数的话,就能达到注入DLL的目的

0x02代码实现

          在注入的操作准备前需要提升权限,使我们有足够的权限去对相应的函数进行操作。

  三步。

      1先OpenProcessToken()打开令牌,

2然后LookupPrivilegeValue()

      3AdjustTokenPrivileges()调整令牌权限,提取完毕进行注入

 

 

注入:

      1先要根据进程ID,开启我们的远程注入线程。

      2开启完毕后,需要进行相应的内存的空间申请VirtualAllocEx(ProcessHandle, NULL, (wcslen(wzDllFullPath) + 1) * sizeof(WCHAR), MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE);

拥有自己的空间后就可以根据路径写入待注入的DLL路径。

      3 用WriteProcessMemory()函数

      4 再根据GetProcAddress(GetModuleHandleA("ntdll.dll"), "LdrLoadDll");   //LadrloadDll得到我们LoadLirbrary()地址

5 最后调用sleepEx()函数,利用QueueUserApc()函数对APC队列进行操作,完成注入。这里是因为sleepEx可以触发这个函数

完整代码如下:

// LoadExe.cpp : 定义控制台应用程序的入口点。//#include "stdafx.h"#include 
#include
using namespace std;typedef struct _UNICODE_STRING{ USHORT Length; USHORT MaximumLength; PWSTR Buffer;} UNICODE_STRING, *PUNICODE_STRING;typedef struct _INJECT_STRUCT { UINT_PTR LdrLoadDllAddress; //4 UNICODE_STRING DllFullPath; //4,4 HANDLE OutHandle;} INJECT_STRUCT, *PINJECT_STRUCT;UINT32 MakeShellCode(UINT8* ShellCodeData, PVOID Address);BOOL InjectByAPC(int ProcessID, int ThreadID, const char *szDllFullPath);int GrantDebugPrivileges();//analyzer.py ---> Start(LoadExeFullPath,Inject,ProcessID,ThreadID,DllPath) LoadExe()//APC 注入int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){ int ProcessID = 0; int ThreadID = 0; if (__argc < 2) { return -1; } if (!strcmp(__argv[1], "Inject")) { GrantDebugPrivileges(); ProcessID = atoi(__argv[2]); ThreadID = atoi(__argv[3]); return InjectByAPC(ProcessID, ThreadID, __argv[4]); } return 0;}//Target,exe BOOL InjectByAPC(int ProcessID, int ThreadID, const char *szDllFullPath){ HANDLE ProcessHandle = NULL; HANDLE ThreadHandle = NULL; if (ProcessID <= 0 || ThreadID < 0) { return FALSE; } printf("Success\r\n"); ProcessHandle = OpenProcess(PROCESS_ALL_ACCESS, FALSE, ProcessID); // if (ProcessHandle == NULL) { return FALSE; } if (ThreadID > 0) { ThreadHandle = OpenThread(THREAD_ALL_ACCESS, FALSE, ThreadID); if (ThreadHandle == NULL) { CloseHandle(ProcessHandle); return FALSE; } } //malloc virtualalloc globalalloc heapalloc new malloc //注入都要在目标进程空间中申请内存 写入Dll的绝对路径 UINT32 DllPathLength = 0; DllPathLength = (UINT32)strlen(szDllFullPath); WCHAR* wzDllFullPath = (WCHAR*)calloc(1, (DllPathLength + 1) * sizeof(WCHAR)); //在LoadEx进程空间中 if (wzDllFullPath == NULL) { return FALSE; } for (int i=0;i

 

转载于:https://www.cnblogs.com/arsense/p/6427472.html

你可能感兴趣的文章
365. Water and Jug Problem
查看>>
队列实现霍夫曼树
查看>>
【Java】图片高质量缩放类
查看>>
详解定位与定位应用
查看>>
【前端开发】 5分钟创建 Mock Server
查看>>
java 从键盘录入的三种方法
查看>>
使用jQuery和YQL,以Ajax方式加载外部内容
查看>>
pyspider 示例
查看>>
JAVA 笔记(一)
查看>>
c# 范型Dictionary实用例子
查看>>
C#实现动态页面静态化
查看>>
可选参数、命名参数、.NET的特殊类型、特性
查看>>
利用CGLib实现动态代理实现Spring的AOP
查看>>
面试之SQL(1)--选出选课数量>=2的学号
查看>>
IIS处理并发请求时出现的问题
查看>>
优先队列小结
查看>>
线程安全与可重入函数之间的区别与联系
查看>>
{Nodejs} request URL 中文乱码
查看>>
异常及日志使用与项目打包
查看>>
努力,时间,坚持,自律
查看>>