【2026版】最新恶意代码逆向分析,从零基础到精通,收藏这篇就够了!

张开发
2026/4/10 10:36:22 15 分钟阅读

分享文章

【2026版】最新恶意代码逆向分析,从零基础到精通,收藏这篇就够了!
【2026版】最新恶意代码逆向分析从零基础到精通收藏这篇就够了免责声明锦鲤安全的技术文章仅供参考此文所提供的信息仅供网络安全人员学习和参考未经授权请勿利用文章中的技术资料对任何计算机系统进行入侵操作。利用此文所提供的信息而造成的直接或间接后果和损失均由使用者本人负责。如有侵权烦请告知我们会立即删除并致歉。本文所提供的工具仅用于学习禁止用于其他请在24小时内删除工具文件谢谢1. 简介我们的目标是撰写一系列有关恶意软件分析的文章并解释从简单的恶意软件二进制文件到最复杂的恶意软件涵盖大量主题例如解包、API 解析、C2 提取、C2 模拟当然还有逆向工程。除了一些动态分析之外也许还可以使用一些反混淆技术。必要时我将介绍其他主题例如COM组件对象模型、密码学、IDC/IDA Python以及帮助读者更好地理解分析所需的一切内容。在本系列文章中我将使用几种工具并尝试指出可以在哪里使用它们来使事情变得更简单。我们将分析不同的示例每个示例都有不同的难度级别并讨论一些代码行。将一篇文章分成不同的部分以避免阅读变得如此疲惫。在 bilibili 可看本章节完整视频https://www.bilibili.com/video/BV1kDkNYaEbc/?spm_id_from333.999.0.0vd_source6c9924e717cda25d98f1fbb213e223ad本篇文章为万字长文建议收藏。1.简介2.必备工具3.恶意软件分析目标4.初步信息收集5.解包概念复习6.代码注入审查7.脱壳方法8.脱壳提取二进制文件9.逆向分析恶意样本备注前面部分基础知识翻译自国外作者亚历山大2. 必备工具分析工具IDA,X64DBG工具插件ScyllaHide它是一个高级反调试库可挂钩多个函数以隐藏恶意软件的调试活动https://github.com/x64dbg/ScyllaHide/releasesDbgChild它提供对由调试进程创建的子进程的自动检测并在主进程派生新进程时自动附加 x64dbg 的新实例从而在很多机会中节省您的时间。 DbgChild 可从以下位置获取https://github.com/David-Reguera-Garcia-Dreg/DbgChildLabelless这是一个非常值得推荐的插件为逆向者提供了两个关键功能x64dbg 和 IDA Pro 之间的标签、函数名、全局变量和注释同步。为调试进程动态转储内存中的区域这将很有用例如在任务 API 解析和/或字符串解码后转储二进制文件。Labelless 插件可以从以下地址下载https://github.com/a1ext/labeless/releases所有剩余的工具将在我们的分析和未来的许多文章中展示。2. 恶意软件分析目标我们在分析二进制文件时要寻找什么3.1 内存分析这是一种极其强大的技术在过去 10 年中已证明其无限的价值并在调查过程中用作了解恶意软件感染事件、其后果、副作用的首选方法并使获取大量证据成为可能可能很难从磁盘或任何其他来源收集。3.2 网络分析它是一个非常有用的资源例如 pcap 文件可以通过流量分析来理解和检测未经授权的通信C2 - 命令和控制通道并进行工件收集例如二进制文件、恶意文档和 Cobalt beacon。3.3 文件系统/磁盘分析任何调查的最后一个领域我们可以分析和检测对手入侵、破坏、欺诈、泄漏当然还有恶意软件感染的副作用。通过恶意软件分析有机会从邪恶的来源了解对手的意图和目标而不仅仅是其影响。换句话说你可以学习技术、技巧、规避策略如果幸运的话你可以收集重要的文件来做出正确的归因大多数时候这是一项艰巨的任务。3.4 关键分析1、二进制打包了吗如果是那么恶意软件使用的是众所周知的加壳器还是自定义的加壳器2、恶意软件使用的网络通信技术/API 集是什么诸如 /*/Winsock2、Wininet、COM组件对象模型或较低版本的技术如 WSKWinsock 内核之类的级别//*甚至是自定义实现的技术正在使用哪种技术3、是否使用了任何代码注入或挂钩技术哪一个4、使用哪些反取证技术有没有反调试技术防拆反虚拟机/沙箱5、有API/DLL 编码吗6、字符串是否加密7、恶意软件使用哪些同步基元有时它们隐藏重要的反调试技术。8、恶意软件使用哪些加密算法9、威胁使用哪些持久性方法注册表、服务、任务或内核驱动程序10、是否有任何 shellcode 被注入到操作系统进程中11、恶意软件是否安装了文件系统微型过滤器驱动程序12、如果安装了内核驱动程序是否安装了任何回调一种现代挂钩或计时器3.5 本篇文章目标1、解压恶意软件2、提取并解密其 C2 的配置数据4. 初步信息收集本章分析的样本 hash 如下sha2568ff43b6ddf6243bd5ee073f9987920fa223809f589d151d7e438fd8cc08ce292使用快速分析工具主要是内嵌了沙箱api我们这里用的是免费的 Malware Bazaar#图一#根据图一中信息有以下几个重要信息1、目标恶意软件似乎来自Hancitor 家族。2、它使用EnumerateProcesses() 函数因此了解是否有任何特殊原因例如代码注入;3、WriteProcessMemory()的触发方式与我们通常在解包过程和代码注入中看到的那样因此这里没有消息是个好消息。当我们再去了解这个家族基本能确定就是 c2 类型远控木马了5. 解包概念复习每次我听到有人谈论拆包时印象似乎都会转化为相同的结论这可能不是那么容易。当然正如我们之前提到的解包样本可能是可能的字符串解密和 API/DLL 解析之前的第一步例如但我们需要从某个地方开始并有一个目标。5.1 打包程序的原因1、它使恶意代码对 AV “隐藏”。当然它并不那么隐蔽但它是一种软规避技术让分析师的生活变得有点困难最终会给防御带来一些问题。2、打包样本并未揭示实际恶意软件的实际目的。3、由于需要规避许多反分析技术反调试器和反 vm 技巧因此可能很难动态解压缩它。4、恶意软件通常使用自定义例程将有价值的代码打包到多个层中。5、最终整个恶意软件或仅解压缩代码可能是多态的。5.2 加壳特征1、它们已用于64 位二进制文件。2、IAT 导入地址表 可能已被删除或者最多只能有一个导入的函数。3、大多数字符串都是加密的。4、内存完整性经过检查和保护因此无法从内存中转储干净的可执行文件因为原始指令没有在那里完全解码。5、指令被虚拟化混淆装逼说是虚拟化就是替换指令干等价的事比如112切换成151-52令人惊讶的是它被翻译成RISC 指令系统指令。6、这些虚拟化指令在内存中加密。7、混淆是基于堆栈的因此使用静态方法处理虚拟化代码非常困难。8、大多数虚拟化代码都是多态的因此有许多虚拟指令引用相同的原始指令。9、有数千行虚假的 “push” 指令当然其中许多都包含死代码和无用的代码。10、这些保护程序使用无条件跳转实现代码重新排序。11、所有这些现代加壳程序都使用代码扁平化、许多反调试和反 vm 技术。12、并非所有 x64 指令都是虚拟化的因此您会发现一个二进制代码其中包含虚拟化和非虚拟化本机指令的混合。13、大多数时候函数的序言和尾声不是虚拟化的。14、原始代码部分可以“拆分” 和/或分散在程序中因此指令和数据会混合在一起。15、引用导入函数的指令可能会归零甚至替换为 NOP因此在此//“引用” 将被动态恢复//。有时这些相同的引用不是归零但替换为使用 RVA 到同一导入地址的跳转指令也称为//“IAT 混淆”//。16、在 shellcode 和常见恶意软件中使用时API 名称经过哈希处理。17、从native register 到 virtualized register 的转换通常是一对一的但并非总是如此。此外还有一个上下文切换组件负责将寄存器和标志信息传输到虚拟机上下文中。18、虚拟机处理程序来自数据块。19、许多本机API 被重定向到转发调用的存根代码。20、使用混淆技术例如常量展开、基于模式的混淆、控制间接、内联函数、代码复制和主要不透明的谓词。5.3 解包前的观察与思考1、恶意软件真的打包了吗2、拥有打包代码的证据是什么3、恶意软件是执行自我注入还是远程注入4、恶意软件是否执行自我覆盖5、payload 写入何处6、有效负载将如何执行7、在解包过程之后有什么证据证明有解压的代码8、是否有其他打包层5.4 打包特点以下是当我们确定程序是恶意的时候用来评判是否被打包加壳的特点1、二进制示例具有很少的导入 DLL 和函数。2、有许多混淆字符串。3、存在特定的系统调用。4、非标准部分名称。5、非常见的可执行二进制部分只有 .text/.code 部分应该是可执行的6、意外的可写部分。7、高熵部分通常高于 7.0但并非总是 - 这是一个弱指标。8、部分的原始大小和虚拟大小之间存在很大差异。9、零大小的部分。10、缺少与网络通信相关的 API。11、缺乏恶意软件功能的基本 API例如勒索软件中的 Crypt/* 功能。12、不寻常的文件格式和标头。13、指向 .text/.code 节以外的其他部分的入口点。14、资源部分.rsrc 部分的大小很大在代码中后跟LoadResource 函数。15、存在叠加层。16、在 IDA Pro 上打开它并在彩色条上观察大量数据或未探索的代码。要强调的是不能以一个特点来确定恶意程序就是打包了要根据多个条件来对应才能更加确定比如以下特点不一定准确1、大多数示例使用 LoadLibrary() 后跟 GetProcAddress() 动态解析其 API反射代码注入情况除外。2、网络 API 也可以动态解析。3、格式错误的标头在第一次分析时可能有点难以检测到。4、Big resource 部分可能不相关因为它可能仅包含 GUI 构件和数字证书。5、可能混合了加密/混淆的字符串和纯文本字符串因此很难确定二进制文件是否打包。5.5 反调试与反虚拟机1、反调试技术时间检查、CPUID、堆检查、调试标志检查、NtSetInformationThread() 等因此建议使用反调试器插件例如 x64dbg/x32dbg 上的 ScyllaHide https://github.com/x64dbg/ScyllaHide2、检查 VMware、VirtualBox、Hyper-V 和 Qemu 工件的反 VM 技巧。3、文件名、主机名和帐户检查避免使用哈希值作为文件名。4、虚拟机上的可用磁盘大小建议至少 100 GB5、测试虚拟机上的处理器数量两个或更多是合适的6、正常运行时间尝试保持虚拟机快照的正常运行时间超过 20 分钟。7、许多无意义的调用结果不再使用和不存在的 API伪 API。8、用作反调试技术的异常处理程序。9、清除软件断点并操纵寄存器 DR#防断点技术10、使用典型算法例如 crc32、conti add/_ror13,…的哈希函数。11、对 Process Hacker、Process Explorer、Process 等知名工具进行恶意代码检查Monitor 等建议在使用这些可执行二进制文件之前重命名它们。在某些情况可以尝试不同调试器如 WinDbg来分析一些恶意软件威胁这些威胁仅针对环 3 调试器而不是内核调试器最近的案例是 GuLoader 恶意软件。5.6 恶意二进制文件修复难题1、DOS/PE 标头可能已在内存中被销毁或被压缩库修改。2、在许多情况下当您从内存中提取二进制文件时您需要清理它因为在其 DOS 头MZ 签名和 PE 头之前有一些垃圾。3、入口点 EP 可能已归零或错误。4、解压缩的二进制文件可能会因为已被转储而销毁其 Import 表并且其地址引用虚拟地址映射版本而不是未映射版本因此显示未对齐的部分或无部分。5、基址错误。6、PE 格式的字段存在一些不一致之处。7、可能很难确定 OEP Original Entry Point它通常出现在使用间接调用例如调用 [eax] 或 jmp [eax]从解包程序代码转换后出现。此外存在未解析的 API 可能证明恶意代码没有解析到达 OEP。按时OEP 是可执行文件在打包之前的入口点EP。打包后新的 EP 将与 打包程序 本身相关联。8、互斥锁被用作两个解包层之间的一种“解锁密钥”。在这种情况下如果没有第一阶段发生则解包的第二阶段不会发生如果发生了则确认互斥锁的存在。9、代码可能正在执行自我覆盖。10、解压代码的第一阶段不从任何目录运行而只从特定目录运行。11、您可以提取诱饵二进制文件。在许多实际情况下恶意软件作者将一个或多个无用的可执行文件打包为诱饵以消耗分析师的时间。因此明智的做法是不要在第一次尝试时相信你已经从内存中解压缩了正确的二进制文件。这个问题列表非常有限并且对解压的二进制文件有无穷无尽的其他可能的副作用。当然对于这些提出的问题中的每一个都存在不同的解决方案它们将在本系列的下一篇文章中进行解释并给出示例。无论如何处理某些问题的几种方法是1、从另一个可执行文件或从自己的恶意软件样本复制一个好的 PE 标头并对齐部分考虑解压缩的二进制文件是未映射的.text 部分通常以 0x400 开头还是映射的.text 部分通常以 0x1000 开头。2、通过修复其各自的原始地址来对齐解包的二进制文件映射地址的各个部分和 Raw size 原始大小。此操作通常会修复导入表并可以可视化导入的功能没有任何问题。注意可能的“陷阱”一些脱壳的二进制文件不会显示其 Import Table 导入表直到您对齐了它们的部分。但是其他恶意软件威胁则不会即使在解压缩二进制文件后在 Import Table 中也不显示条目但具有很多功能这并不意味着您犯了任何错误它确实会让恶意软件动态解析其所有 API。3、重建 IAT 并强制使用 OEP原始入口点。4、如果您在查找 OEP 时遇到问题请记住OEP 可能在 IAT 之后出现解决。在这种情况下一种可能的方法是检查 IAT 是否已解析检查 x64dbg 或 OllyDbg 上的模块化调用或者在恶意软件的关键操作期间执行的关键 API 上设置断点CryptoAcquireContext()因为当执行到达这些关键 API时IAT 肯定会得到解决。之后建议寻找到特定内存地址的无条件跳转甚至是间接调用例如调用 [eax]。另一种有趣的方法是使用调试器的图形可视化在 x64dbg 上为 “g”并在最后的“代码块”处检查这些转换点内存地址的间接调用或无条件跳转。最后一个专门的工具可能会帮助您找出 OEP。正如你所注意到的没有单一的方法可以做到这一点。5、调整基址以匹配从内存中转储的段基址。6、为了检测执行自我覆盖的恶意软件我们可以尝试在//.text/.code 部分//。在这种情况下我们可以选择在代码编写或执行期间触发此断点。7、在两阶段解包情况下第一个解包的二进制文件可能是 DLL。因此取决于上下文中将 DLL 二进制文件转换为可执行文件可能很有用并且有很多方法可以完成此任务但我最喜欢的方法是编辑 PE 标头以更改 Characteristics 字段并将导出函数的条目作为入口点。5.7 修复工具1、PEBear 是由 Aleksandra Doniec又名 Hasherezade编写的一款出色的工具用于可视化 PE 标头的详细信息并修复许多二进制问题。您可以从以下位置下载此工具 https://github.com/hasherezade/pe-bear-releases2、Pestudio 是 Marc Ochsenmeier 编写的一款出色的工具主要用于分类和收集潜在恶意软件的不同信息。该工具免费和付费版本可在此处获得https://www.winitor.com/features3、CFF Explorer 是 Explorer Suite 的一部分它是一个著名的 PE 编辑器用于可视化和修复 PE 标头。Explorer Suite 可从以下网址下载https://ntcore.com/?page/_id3884、pe/_unmapper 是 Aleksandra Doniec又名 Hasherezade编写的另一个可以使用的工具用于将 PE 二进制文件从映射版本转换为未映射版本从而修复所有 PE 对齐问题。该工具可从以下位置下载 https://github.com/hasherezade/libpeconv/tree/master/pe/_unmapper5、Scylla 是一个了不起的 x86/x64 导入重构器已经嵌入到 x64dbg 中。如果您需要独立版本可以从以下网址下载https://github.com/NtQuery/Scylla6、HxD 是一个出色的十六进制编辑器例如我们可以使用它来手动检查和修复 PE 标头。可以从以下网址下载 https://mh-nexus.de/en/hxd/7、XVI32 Hex Editor 是另一个有趣的十六进制编辑器它非常适合清理转储的内存区域以隔离解压的二进制文件。XVI32 十六进制编辑器可从以下位置下载 http://www.chmaas.handshake.de/delphi/freeware/xvi32/xvi32.htm再次记住解包脱壳只是恶意软件分析过程中的第一个障碍许多其他困难的挑战如字符串去混淆、API 解析、C2 配置提取、C2 仿真和其他主题也在列表中。该项目将在下一篇文章中介绍几种解包情况和所有这些提到的任务。6. 代码注入审查代码注入是 Window 系统上支持的操作当然它是一种非常有用的规避方法因为恶意软件能够将恶意代码注入写入进程本身自我注入或远程远程注入的内存区域有些人使用术语“段”中并且此有效负载将在目标上下文上执行无论它是否成为它的一部分并且不会留下很多证据。此外当恶意负载继续在所谓的良好进程例如explorer.exe 和 svchost.exe中运行时源进程恶意软件可以干净地终止自身。最后这是一种逃避安全防御的隐蔽方法。6.1 注入技术6.1.1 DLL 注入主要 APIOpenProcess()、VirtualAllocEx()、WriteProcessMemory 和 CreateRemoteThreat | NtCreateThread() | RtlCreateUserThread()6.1.2 PE 注入主要 APIOpenThread(),SuspendThread(), VirtualAllocEx(), WriteProcessMemory(), SetThreatContext() 和 ResumeThreat() | NtResumeThread()6.1.3 反射注入CreateFileMapping()、Nt/MapViewOfFile()、OpenProcess()、memcpy() 和Nt/MapViewOfSection()在最后可以通过调用OpenProcess()、CreateThread()、NtQueueApcThread()、CreateRemoteThread() 或RtlCreateUserThread()。有趣的是变体也可以使用VirtualQueryEx() 和 ReadProcessMemory()。6.1.4 APC注入这种代码注入技术允许程序通过附加到APC 队列在特定线程中执行代码。当线程退出可警报状态时由 SleepEx()、SignalObjectAndWait()、MsgWaitForMultipleObjectsEx()、WaitForMultipleObjectsEx() 或 WaitForSingleObjectEx()等调用发起将执行注入的代码。因此通常还可以看到CreateToolhelp32Snapshot()、Process32First、Process32Next()、Thread32First()、Thread32Next()、QueueUserAPC() 和 KeInitializeAPC()参与此技术。6.1.5 挖空或替换进程简而言之恶意软件使用这种技术来“耗尽”进程的全部内容并在其中插入恶意内容。一些涉及的 API 包括CreateProcess()、NtQueryProcessInformation()、GetModuleHandle()、Zw/NtUnmapViewOfSection()、VirtualAllocEx()、WriteProcessMemory()、GetThreadContext()、SetThreadContext() 和 ResumeThread()。6.1.6 AtomBombing此技术是先前技术APC 注入的变体其工作原理是将恶意负载拆分为单独的字符串为每个给定字符串创建一个 Atom将它们复制到 RW 段中使用 GlobalGetAtomName() 和 NtQueueApcThread()并使用 NtSetContextThread() 设置上下文。因此其他 API 的列表是 OpenThread()、GlobalAddAtom()、GlobalGetAtomName() 和 QueueUserAPC()。6.1.7 进程分身这种技术可以作为流程空心化的一种演变来处理。这两种技术之间的主要区别在于虽然 Process Hollowing 在恢复之前替换了进程的内容图像但 Process Doppelgänging 能够在创建进程之前替换图像方法是在加载目标图像之前用恶意图像覆盖目标图像。这里的关键概念是 NTFS 操作在事务中执行因此事务中的所有这些操作要么一起提交要么不提交任何操作。同时恶意图像只存在它在事务内部可见对任何其他进程都不可见。因此恶意图像被加载到内存中恶意软件从文件系统中删除恶意负载通过回滚事务因为该文件以前从未存在过。此技术涉及一些 APICreateTransaction()、CreateFileTransaction()、NtCreateSection、NtCreateProcessEx()、NtQueryInformationProcess()、NtCreateThreadEx() 和 RollbackTransaction()。6.1.8 进程重影Process Herpaderping这种技术类似于 Process Doppelgänging但有一个微妙的其程序的差异。进程 Herpaderping 基于这样一个事实即安全防御通常通过在内核端使用PsSetCreateProcessNotifyRoutineEx() 或在驱动程序的 DispatchCleanup 例程期间IRP/_MJ/_CLEANUP该函数在创建线程后调用。这就是关键问题如果攻击者创建并映射一个进程然后该攻击者能够修改文件映像然后创建线程因此安全产品能够检测到此类恶意负载。尽管如此此检查顺序可以包括攻击者是否能够在磁盘上创建恶意二进制文件、打开其句柄、使用NtCreateSection 函数将其映射为图像部分并包括 SEC/_IMAGE 标志、使用部分句柄//NtCreateProcesEx() 创建进程、将文件内容修改为听起来不像恶意内容//并使用此//“良好图像”创建线程 NtCreateThreadEx()。/*/*关键是当线程被创建时会触发进程回调并检查磁盘上文件的内容好的所以安全防御认为一切都很好因为磁盘上的镜像是无害的但真正的恶意在内存中。换句话说安全防御无法有效地检测磁盘上不同于内存上的映像的此类映像。用于此技术的几个 APICreateFile()、NtCreateSection()、NtCreateProcessEx() 和 NtCreateThreadEx ()。6.1.9 hook注入Hooking Injection要使用这种技术我们将看到涉及 Hooking 活动如 SetWindowsHookEx() 和 PostThreadMessage() 的函数被用来注入恶意 DLL。6.1.10 额外窗口内存注入使用此技术恶意软件威胁通过使用额外 Windows 内存称为 EWM将代码注入进程其大小最大为 40 字节并在注册 Windows 类期间附加类的实例。诀窍在于附加的 spaced 足以存储一个指针该指针可能会将执行转发给恶意代码。此技术涉及的一些可能的 API 包括FindWindowsA()、GetWindowThreadProcessId()、OpenProcess()、VirtualAllocEx()、WriteProcessMemory()、SetWindowLongPtrA() 和 SendNotify()。6.1.11 传播注入此技术已被 RIG Exploit Kit 和 Smoke Loader 等恶意软件威胁用于将恶意代码注入explorer.exe进程中等完整性级别和其他持久性进程中它基于枚举//EnumWindows() → EnumWindowsProc → EnumChildWindowsPr() → EnumChildWindowsProc → EnumProps() → EnumPropsProc → GetProp 窗口实现 SetWindowsSubclass()//的方法有关https://docs.microsoft.com/en-us/windows/win32/api/commctrl/nf-commctrlsetwindowsubclass。您可能还记得此函数会安装 Windows 子类回调并且如您所知回调在安全领域中被解释为挂钩方法。它是如何工作的找到子类化窗口后检查 UxSubclassInfo 和/或 CC32SubclassInfo它们提供子类标头就可以保留旧的窗口过程但我们也可以通过更新 CallArray 字段为窗口分配一个新过程。当事件发送到目标进程时将调用新过程然后旧过程也会被调用保持先前和预期的行为。因此恶意软件将恶意负载 shellcode 插入内存并使用 SetPropA() 更新子类过程。调用此新属性通过 windows 消息时执行将转发到有效负载。此技术涉及的一些 Windows API 包括FindWindow()、FindWindowEx()、GetProp()、GetWindowThreadProcessId()、OpenProcess()、ReadProcessMemory()、VirtualAllocEx()、WriteProcessMemory()、SetProp() 和 PostMessage()。下面显示了来自恶意软件威胁的代码注入序列的一个非常常见的示例IDA Pro 的反编译输出当然您将能够通过本节前面提供的信息来识别所使用的技术7. 脱壳方法分类和主要描述解包技术相当复杂但一般来说有解压缩恶意软件样本的方法很少例如使用调试器、自动化工具、Web 服务甚至编写自己的解压缩代码来静态完成任务。选择的方法取决于特定的环境和情况。7.1 调试器特定函数断点一个调试器特定的函数断点。这是最著名的方法包括将恶意软件加载到调试器中并在众所周知的 API 上设置软件断点其中大多数与内存管理和操作有关以及查找要从内存中提取的可执行文件和/或 shellcode。使用 x64dbg/x32dbg在其 CLI 上为 [ctrl]g 或 bp非常简单可以在以下 API 上插入软件断点CreateProcessInternalW() VirtualAlloc() VirtualAllocEx() VirtualProtect( ) | ZwProtectVirtualMemory() WriteProcessMemory() | NtWriteProcessMemory() ResumeThread() | NtResumeThread() CryptDecrypt() | RtlDecompressBuffer() NtCreateSection() MapViewOfSection() | ZwMapViewOfSection() UnmapViewOfSection() | ZwUnmapViewOfSection() NtWriteVirtualMemory() NtReadVirtualMemory()7.2 脱壳注意事项重点1、在恶意软件到达其入口点后在系统断点之后设置断点。2、如前所述建议使用反调试插件在少数情况下忽略从 0x00000000 到 0xFFFFFFFF 范围的所有异常在 x64dbg 上转到“选项”→“首选项”→“例外”以包含此范围。3、有时忽略异常可能是一个坏主意因为恶意软件可能是它们调用解包过程。此外在本文中脱离上下文存在使用中断和异常来调用 API 的威胁。4、通过使用 MSDN 了解所有列出的 API 及其各自的参数是成功解开恶意软件威胁的关键知识。5、如果你使用的是VirtualAlloc()建议在其出口点ret 10上设置断点。此外有时通过设置写入内存断点可以更轻松地跟踪 dump 上分配的内容。6、在某些情况下恶意软件会将其有效负载提取到内存中但会销毁 PE 标头因此您将重建整个标题尽管使用像 HxD 这样的十六进制编辑器的过程很简单。7、提取的有效负载可能采用映射或非映射格式。如果它是映射格式那么可能 Import 表搞砸了你需要通过 PEBear 最喜欢的方法 手动重新对齐部分标题或使用 pe/_unmapper 等工具来修复它们。您可能需要修复基址和入口点是否为零。8、要重建已销毁的 IAT建议使用 Scylla嵌入在 x64dbg 上。它必须输入 OEP找到它的方法之一是查找由 jmp eax、call eax、call [eax] 等指令给出的代码转换。9、很少有解压缩的恶意软件样本在 IAT 中没有任何功能因此有两种可能性要么部分未对齐映射版本要么解压缩的恶意软件动态解决其所有功能。10、在 x64dbg 上使用“g” 热键可能有助于可视化块中的代码并找到到 OEP 的可能转换。11、查找 OEP 的另一个不错的选择是通过 PIN 等代码插桩https://www.intel.com/content/www/us/en/developer/articles/tool/pin-a-dynamic-binaryinstrumentation-tool.html。12、tiny/_tracer https://github.com/hasherezade/tiny/_tracer项目已废除 等工具使用 PIN 更轻松地执行检测可用于了解恶意软件调用的函数对于解压缩和了解反分析技术非常有用还可以查找可能的 OEP。13、在许多机会中解压缩的代码可能只是恶意软件的第一阶段因此有必要重复步骤来解压缩下一阶段。14、很少有恶意软件示例执行自我覆盖因此您可能必须在 .text 部分上设置断点以检测解压缩的二进制执行。在分析恶意软件时很多恶意软件在执行完其恶意行为后会进行自我覆盖即自我删除以消除痕迹使得分析和检测变得更加困难。因此分析者可能需要在恶意软件的//.text节区即代码段设置断点//以便在恶意软件解压缩并开始执行解压缩后的二进制代码时能够捕获到其行为。.text节区是程序代码存放的地方设置断点可以帮助分析者监控和分析恶意软件的实际执行流程和行为模式15、根据提取的二进制文件例如 shellcode它可能无法用完特定的进程上下文因此有必要将其注入到正在运行的进程例如explorer.exe中以执行进一步的分析。16、如何检查提取的恶意软件是否可能是最终的恶意软件没有明确的答案通过从 DLL 中查找网络函数如WS2/_32.dll Winsock 和 Wininet.dll、纯文本字符串、加密函数主要恶意软件是一种勒索软件和许多其他证据。主要在重新对齐部分和/或重建 IAT 之后在 IDA Pro 上提取代码。7.3 调试器 DLL 加载中断这是一种古老而简单的技术通过在加载的每个 DLL 上停止调试器并检查内存中可能提取的 PE 格式文件的内存映射来解压缩恶意软件注意不要只关注 RWX 段因为许多恶意软件在 RW 区域中提取其有效负载并且在将执行上下文传输到提取的可执行文件之前不久他们使用 VirtualProtect()将区域的权限更改为 RWX。毫无疑问它可能会消耗一些时间但在许多情况下它仍然有效。常见调试器x64dbg、OllyDbg 和 Immunity Debugger具有一个配置选项用于在每次 DLL 加载时中断。在x64dbg 上此选项位于 Options → Preferences → Events 中并标记 DLL 加载。在 OllyDbg 上您可以转到“选项”→“调试选项”→“事件”并标记“在新模块 DLL 上中断”。7.4 自动化脱壳工具恶意软件分析师可以使用工具来自动化解包过程。Aleksandra Doniec Hasherezade 为实现此目标提供了出色的工具hollows/_hunterhttps://github.com/hasherezade/hollows/_hunter/releasesPE-Sieve https://github.com/hasherezade/pe-sieve/releasesmal/_unpackhttps://github.com/hasherezade/mal/_unpack/releases命令hollow/_hunter.exe /pname /loop /imp mal/_unpack.exe /exe /timeout timeout: ms pe-sieve64.exe /pid pe-sieve64.exe /pid /dmode 3 /imp 3包含一些附加信息的解压缩二进制文件将保存到该工具创建的目录中。7.5 进程脱壳从内存中提取二进制文件的另一种简单且有限的方法是通过 Process Hacker 双击正在运行的进程转到“内存”选项卡查找有趣的区域/基址 RWX双击它并按“保存”按钮。当然在自我注入的情况下更容易找到恶意的二进制文件/payload。例如在远程注入的情况下您需要反转恶意软件以了解要注入的目标进程或者进行“有根据的猜测”并在 explorer.exe 或 svchost.exe 等已知目标上查找注入的代码。同样这是一种有限且简单的方法但有时可以节省时间。7.6 编写脱壳程序虽然这种方法听起来很耗时但编写 Python 代码来完成脱壳是很常见的主要是在 shellcode 情况下或者在处理恶意软件线程使用多种反 vm 和反调试技术的情况下。此外我们还有一个优势可以在处理类似的恶意软件案例时自动化解包过程。8. 脱壳提取二进制文件经过前边的各种知识铺垫终于可以开始正式进行样本分析环节看到的知识不会不要紧遇到不会的才要学要查要实践。8.1 IAT 表审查首先将样本放到PE-bear进行查看是否存在有价值的信息我们开始是将样本丢过沙箱的正常来说是会有网络相关DLL调用的按现在来看很可能被加壳了。因为是个dll文件所以我们可以将它放到x64/32dbg进行分析从导出表能看到它初始名字可能是cool.dll8.2 加壳特征确认我们再通过pestudio查看文件映射和内存映射的大小差别.data段差别是很大的又更加一步确定被加壳过了当然不止这一点能确定但文件与内存大小差距很大的基本是加壳过的。8.3 调试器断点脱壳因为是dll文件并且有五个导出函数我们可以尝试加载第一个导出函数分析x64dbg启动命令改为“C:/Windows/SysWOW64/rundll32.exe” C:/Users/Administrador/Desktop/sample/_1.bin,#1更改后要重新启动会话加载到达程序入口点的时候使用快捷键ctrlg下经典函数断点断点附加说明在技术点问题整理中VirtualAlloc (在其出口点) VirtualProtect ResumeThread下断点在virtualalloc的返回值处在剩余两处下断点第一次断点保存的内容目前看不出什么直到第三次触发的内存地址发现了MZ头但是为M8Z这是aplib压缩的特征我们转到内存布局进行保存通过工具XVI32CTRLf查找字符串之后往上找找就能看到正常的MZ头我们只需要把MZ之前的数据清理掉就可以辨别特征修复方法都是靠积累没有什么可研究的不用钻牛角尖平时做好笔记就可以修复完成保存后再在PE-bear打开就能看到实际恶意程序的相关IAT表了网络调用也出现了剩下的便是找IDA老婆进行逆向分析具体行为功能了9. 逆向分析恶意样本首先我们要先记得这依旧是个DLL文件所以它的功能基本是切割的我们首先来解密他的外联数据获取恶意软件的url9.1 解密数据获取IOC我们来到Unexplored之所以来看这里其实就是因为字符串没发现url或者IP相关那他很可能没有解密也很可能就在这个未知区域我们能看到这里有pbData并且有一个函数对这三个进行了交叉引用byte/_10004000 (16 bytes)pbData (8 bytes)unk/_10004018 (likely 0x2000 bytes)这个时候我们先不管是做什么的我们直接“x”来到交叉引用我们可以看到三个数据都被作为参数传到了不同的子函数内。这里第一个是分配内存分配了2000h的内存第二个函数我们看到了一些计算目前看不出什么记得有意义的函数进行改名备注格式名字自己标识原子例程名来到第三个子例程那就是加解密相关的了我们得一步一步来了看不懂没关系首先他已经弃用了之后这个函数就是获取或创建加密提供者CSP不理解没关系继续往下走CryptCreateHash函数调用CSP句柄SHA1算法0x800400新CSP哈希对象地址。整体来说就是我们知道了他用了SHA1算法对句柄或者对象不太了解的先不管这个。此函数整体就是添加数据到指定哈希对象根据参数我们可以知道对象句柄是新创建的pbData是指针也就是pbData处存放的八个字节而这个dwDatalen是8也就是说这可能在输出SHA1哈希并且被加密就是那八字节生成密钥这里我们要根据他的参数进行对应解释1、老csp句柄2、一个 ALG/_ID 结构用于标识要为其生成密钥的 对称加密 算法这里是0x6801对应RC43、新CSP句柄4、指定密钥类型这里是0x280011根据微软解释这里必须要用0x00800000将与其他任何/dwFlags 结合使用/预定义值以及按位OR操作看不懂没关系我也看不懂但我们要知道RC4密钥是40位也就是5字节0x285、新密钥的接收地址我们来捋一下密钥顺序首先他用pbData的8字节生成了一个SHA1值之后SHA1作为KDF延伸出最终的RC4解密密钥a. pbData - C58B00157F8E9288(shift-e提取)b. pbData - SHA1(20字节)c. SHA1 → CryptHashData() → CryptDeriveKey() → RC4 密钥5 字节继续就是CryptDecrypt函数参数1、hkey解密的密钥句柄也就是最终的RC4密钥2、哈希对象句柄这里是03、布尔值这里是14、0忽略5、重点要解密的缓冲区指针意思就是解密a1区域长度为pdwDatalen的数据长度基本不用想了就是2000我们严谨点假设为2000剩下的要解密数据也不用想了对吧就是剩下的unk/_10004018现在是无路可退。只能这样子推理了。9.2 解密首先我们将pbData进行sha1处理C58B00157F8E9288接着我们记得RC4是5字节也就是40位数16进制1个是4位取出来10个数11f668918f提取一部分先进行解密iochttp://newnucapi.com/8/forum.phphttp://gintlyba.ru/8/forum.phphttp://stralonz.ru/8/forum.php其实还有个更简单的办法就是直接在CryptDecrypt() 上设置一个断点找到指定最终解密内存区域直接等结束提取内存就好了9.3 行为功能分析最难的结束了来到简单的基本跟着分析即可一个函数一个函数的看就能知道导出函数的执行顺序逻辑了《网络安全从零到精通全套学习大礼包》96节从入门到精通的全套视频教程免费领取如果你也想通过学网络安全技术去帮助就业和转行我可以把我自己亲自录制的96节 从零基础到精通的视频教程以及配套学习资料无偿分享给你。网络安全学习路线图想要学习 网络安全作为新手一定要先按照路线图学习方向不对努力白费。对于从来没有接触过网络安全的同学我帮大家准备了从零基础到精通学习成长路线图以及学习规划。可以说是最科学最系统的学习路线大家跟着这个路线图学习准没错。配套实战项目/源码所有视频教程所涉及的实战项目和项目源码学习电子书籍学习网络安全必看的书籍和文章的PDF市面上网络安全书籍确实太多了这些是我精选出来的面试真题/经验以上资料如何领取加图片描述](https://i-blog.csdnimg.cn/direct/6d41d41d77204bfc9459b7a3d079371f.png)配套实战项目/源码所有视频教程所涉及的实战项目和项目源码学习电子书籍学习网络安全必看的书籍和文章的PDF市面上网络安全书籍确实太多了这些是我精选出来的面试真题/经验以上资料如何领取文章来自网上侵权请联系博主

更多文章