ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

内存取证实战:从easy_mem_2看Volatility与netscan排查链路

内存取证实战:从easy_mem_2看Volatility与netscan排查链路 拿到那份 memory 镜像的时候我以为是又一道普通的 CTF 内存取证题。文件名叫 easy_mem_2压缩包解开里面是一个 1.2GB 左右的 .raw 文件没有额外的提示没有密码没有附件说明。这类题在攻防演练和技能竞赛里太常见了但真正动手做下来才发现越是叫“easy”的题越考验你对内存取证基础功的掌握程度。这篇文章就完整复盘一下我的排查过程从工具选型、环境准备到进程分析、网络连接追踪再到文件提取和 flag 定位把每一步的思路和命令行都摆出来希望对正在刷内存取证题或者刚接触应急响应的朋友有实际帮助。内存取证的核心说白了就是回答三个问题这个系统在某个时间点发生了什么、正在发生什么、以及下一步可能会发生什么。系统一旦关机很多动态信息就没了但内存镜像完整保留了进程、网络连接、加载的驱动、剪贴板、命令历史、甚至加密过的密码散列。easy_mem_2 这道题表面上是考你找 flag实际上考的是你能不能从一堆看似无关的内存对象里串出一条完整的行为链。1. 重新理解 easy_mem_2 这道题——内存取证到底在考什么1.1 为什么题目要叫 “easy_mem_2”很多刚接触取证的人会小看这类题目觉得 easy 前缀代表简单花几分钟就能出 flag。但实际做过几道题你就会发现easy 级别的题恰恰是考点最纯粹、最不掺杂干扰项的那一类。它的“简单”体现在镜像不会故意做得很脏不会塞满几百个恶意进程来迷惑你也不会要求你做深度的 rootkit 检测。它考的就是最核心的取证流程——进程列表、网络连接、文件扫描、注册表分析、命令行还原。但反过来正因为考点单一它对你的工具熟练度要求反而更高。比如你要在 Volatility 2 和 Volatility 3 之间快速切换要根据镜像特征判断操作系统版本和 profile要能从 netscan 结果里发现异常的外连 IP。任何一个环节卡住都可能让你在“简单题”上浪费大量时间。1.2 这道题的真实考点拆解从我复现下来的结果看easy_mem_2 至少覆盖了以下能力点内存镜像格式识别与操作系统 profile 匹配进程枚举与父子关系分析网络连接痕迹提取尤其是隐藏连接命令行参数还原对于定位恶意行为非常关键内存中的文件对象提取包括可疑的脚本或二进制基于时间线的行为串联这其实就是一次缩小版的 Windows 内存应急响应演练。你面对的不是抽象的概念而是一个具体的、运行中的系统遗留下的心跳。1.3 什么样的人适合用这篇文章来练兵如果你正在准备攻防演练、护网、信息安全技能竞赛或者工作中接到过主机被入侵后需要做研判的临时任务这篇文章适合你。我会把命令一条条列出来并解释输出怎么读但不会事无巨细地教你 Windows 内核原理——那是另一篇长文的体量。你只要有一台装了 Python 的 Linux 机器能跑 Volatility就能跟着复现。2. 取证战场的准备——镜像识别与工具链选型2.1 先别急着跑命令花五分钟看镜像拿到 .raw 文件之后我做的第一件事不是直接启动 Volatility而是先用 file 命令和十六进制查看工具确定文件类型。这一步看起来多余实际能帮你省掉后面大量的试错时间。file mem.raw输出通常是 data 或者 Windows Event Trace Log 等。如果是裸镜像file 输出可能不明确这时候我习惯用 hexdump 看文件头部hexdump -C mem.raw | head -5一个完整的 Windows 内存镜像头部往往带有特定的页表结构特征但肉眼不容易辨识。更靠谱的方式是用 Volatility 2 的 imageinfo 插件直接识别volatility -f mem.raw imageinfo这条命令会枚举可能的操作系统 profile并给出建议。我这边跑出来的结果是 Win7SP1x64 相关的多个候选前面几个的概率排名最高。2.2 Volatility 2 与 Volatility 3 怎么选在我看来这两个版本不是替代关系而是互补关系。实际取证场景中我通常两个都装。Volatility 2 的插件生态最成熟很多老牌分析模块比如 malfind、ldrmodules在 2 版本里最稳定Volatility 3 则不需要指定 profile对较新的 Windows 版本支持更好而且输出格式对自动化脚本更友好。在 easy_mem_2 这个场景里镜像比较老Volatility 2 是最顺手的选择。官方仓库在 GitHub 上可以直接获取注意依赖 pycrypto 需要提前安装编译否则后续很多解密、hash 相关的插件会报错。如果你不想折腾依赖直接装 Volatility 3 也能做但部分插件名完全不同网上搜到的老教程会有些对不上。推荐的组合是Volatility 2 做深度分析Volatility 3 做交叉验证。两道命令互相印证结果可信度更高。2.3 我实际使用的环境与版本简单交代一下我的环境方便大家复现操作系统Ubuntu 22.04 LTS64 位Python2.7专门用于 Volatility 2 Python 3.10用于 Volatility 3Volatility 22.6.1Volatility 32.4.1辅助工具grep、strings、jq、ipinfo 命令行工具提示如果你想在 Windows 主机上做取证分析也可以用 Windows 版的 Volatility但遇到一些底层的页表解析问题时Linux 环境往往更灵活。个人建议还是准备一台取证专用的 Linux 虚拟机或者实体机。3. 从进程列表开始的完整排查链路3.1 pslist 与 pstree先给系统画一张人物关系图拿到镜像后的第一个正式分析动作永远是枚举进程。这就像你进入一个房间先看房间里有哪些人。用 pslist 拿扁平列表用 pstree 拿父子关系。volatility -f mem.raw --profileWin7SP1x64 pslist volatility -f mem.raw --profileWin7SP1x64 pstreepslist 输出里重点看这几个字段Offset进程对象在内存中的地址独特的偏移值有时能帮你判断是否存在 DKOM 隐藏进程Name进程名PID / PPID进程 ID 和父进程 IDThds线程数Start Time进程启动时间我跑完之后前几个进程都是常见的系统进程System、smss.exe、csrss.exe、wininit.exe、winlogon.exe、services.exe、lsass.exe没有异样。但往下看到 explorer.exe 的子树时注意到了一个不太对劲的东西。3.2 可疑进程的识别不是所有 exe 都值得信任在 pstree 输出中有一个进程名字看起来像系统进程但位置不太对。它不是从 C:\Windows\System32 启动的父进程居然是 explorer.exe而且路径出现在一个临时目录下。这种“名为系统进程、实为临时目录程序”的现象是内存取证里非常经典的恶意软件藏匿手法。正常系统进程的父进程链几乎都是固定的比如 services.exe 的子进程一般是各类服务宿主explorer.exe 的子进程一般是用户启动的程序。如果 explorer.exe 下直接挂了一个名字像 svchost 的进程那基本可以断定有问题。我用 pslist 的详细输出交叉验证了这一点volatility -f mem.raw --profileWin7SP1x64 pslist查看该进程的启动时间发现它的启动时间比用户登录时间晚了大概 3 分钟这 3 分钟很可能就是攻击者完成初始入侵并投递恶意负载的窗口期。3.3 cmd 与命令历史还原攻击者在终端里敲了什么进程列表只是静态快照你还需要还原动态行为。Windows 内存里会保留一些进程的命令行参数用 cmdline 插件就能拿到volatility -f mem.raw --profileWin7SP1x64 cmdline输出中能看到每个进程的完整命令行。正常情况下大部分系统进程都是通过固定的服务路径启动的参数不多。但我注意到那个可疑进程的命令行里带着一个很长的参数指向一个 PowerShell 命令。这种用 PowerShell 做远程下载和执行的手法已经是目前恶意攻击和攻防演练里的常态。接着我用了 consoles 插件它在 Win7 内存中可以还原出控制台应用程序的屏幕缓冲区和输入历史volatility -f mem.raw --profileWin7SP1x64 consoles这一步非常关键。控制台中可能残留了攻击者手动输入的命令、脚本内容甚至工具的输出。我在这道题的镜像里看到了几条 net use 和 copy 命令这实际是攻击者在横向移动或者尝试上传工具。个人经验在做内存取证时cmdline 和 consoles 的组合比单独看进程名有效十倍。进程名可以伪造但命令行参数和输入历史很难完全清理干净。尤其是攻防演练中攻击者留下的脚本命令往往直接暴露了行为意图。3.4 按时间线串联进程行为拿到这些信息之后我整理了一个初步的时间线系统启动常规引导进程加载用户登录explorer.exe 启动3 分钟后可疑进程启动命令行带 PowerShell 下载指令随后出现控制台操作记录疑似攻击者进一步操作把这四条串起来基本就能确定这次“事件”的性质不是普通软件崩溃或者系统异常而是有明确入侵特征的行为链。这也让我对接下来的网络连接分析有了更明确的方向——去查这个可疑进程连了哪里。4. netscan 是这道题的关键——网络连接的取证价值4.1 为什么“netscan 内存取证”会成为热词如果你在搜索引擎里查“内存取证”相关的工具技巧会发现 netscan 这个插件出镜率极高。原因很简单在 Windows 内存镜像中网络连接信息分散在多个内核结构里早期只能通过 tcpconn 插件扫描但 Win7 及以上系统必须用 netscan 才能拿到更全面的 TCP/UDP 信息包括处于监听状态的端口和已经建立连接的对端地址。这正好契合了应急响应的核心诉求不管攻击者怎么隐藏文件、如何伪装进程名只要他还想和你通信就必然在内存中留下网络连接的痕迹。4.2 用 netscan 扫描全量连接命令很简单volatility -f mem.raw --profileWin7SP1x64 netscan输出里有很多列重点关注这几项Proto协议类型Local Address本地监听的 IP 和端口Foreign Address对端 IP 和端口State连接状态ESTABLISHED、LISTENING、CLOSE_WAIT 等PID所属进程我在结果中扫了一遍。正常的连接包括本机到本地网关的通信、可能的 DNS 查询连接等但有一个 TCP 连接非常扎眼——一个进程与一个非本网段的公网 IP 建立了 ESTABLISHED 连接使用的端口是 8443。以 8443 作为通信端口本身就是一种规避常见安全设备监测的策略因为 443/80 往往会被严格审查而高位端口更容易被流量设备放行。4.3 从连接到定位PID 是桥梁找到异常连接之后第一件事是确认这个连接属于哪个进程。netscan 输出里直接有 PID把这个 PID 记下来回头跟 pslist 里看到的可疑进程 PID 一对果然完全吻合。这一步看似简单但它是整个取证链条里承上启下的一环。进程列表给了你“谁在运行”网络连接给了你“它在跟谁通信”而 PID 则把这两个证据铆在一起。如果你只做进程分析你会知道有可疑进程如果你只做网络分析你会知道有外部连接只有把两者结合才能形成一个完整的证据闭环。4.4 对端 IP 的分析思路拿到对端 IP 之后我做了两个层面的判断是否属于内网保留地址RFC 1918 范围是否是恶意 IP 库或威胁情报平台标记过的地址在这道题里对端 IP 是一个公网地址而且不是常见的云厂商 IP 段。我直接用在线威胁情报平台查了一下该地址在多个报告中关联过远控木马的控制端。到这里恶意行为已经基本定性这台机器被安装了远控后门定期会向 C2 地址发起连接。注意在真实应急响应中千万不要只凭一个 IP 就下结论。IP 可能被伪造也可能只是攻击者使用的跳板。更严谨的做法是把 IP、进程、文件哈希、命令行参数、启动时间全部放到一起综合研判。但在 CTF 题目中异常连接通常直接指向 flag 所在的位置。5. 从内存里把 flag 与恶意文件抠出来5.1 文件扫描不只是看磁盘还要看内存中映射过的文件进程运行时其加载的可执行文件、脚本、配置文件可能会被缓存到内存中。即使攻击者事后删除了磁盘上的原文件内存中依然可能留有完整的文件对象。用 filescan 可以枚举内存中的文件对象volatility -f mem.raw --profileWin7SP1x64 filescan这条命令的输出会非常多必须配合 grep 来筛选。我先按可疑进程名过滤再把常见后缀.ps1、.bat、.txt、.zip、.exe、.dll筛了一遍。结果发现了一个路径异常的文件位于 C:\Users用户名\AppData\Local\Temp\ 下是一个可执行文件文件名像是随机生成的字符串。5.2 提取文件dumpfiles 实操找到文件对象之后用 dumpfiles 把它从内存中提取出来volatility -f mem.raw --profileWin7SP1x64 dumpfiles -Q 0x000000001e5f4a80 -D ./output/这里 -Q 后面的值就是 filescan 结果里的 Offset 字段-D 指定输出目录。提取出来的文件可能带着 .dat 后缀但用 file 命令检查一下实际类型就好。我提取出的这个文件file 结果显示是 PE32 executable (GUI) Intel 80386也就是一个 32 位 Windows 可执行程序。这意味着攻击者使用的远控工具是 32 位版本即使运行在 64 位系统上也可以正常工作通过 WOW64 机制。这类细小的特征在写取证报告的时候是非常有力的支撑材料。5.3 从转储中直接搜索 flag 字符串题目叫 easy_mem_2flag 通常不会藏得特别深。用 strings 直接扫全镜像往往是最快的方式strings -el mem.raw | grep -i flag我加了 -el 参数因为 Windows 上很多字符串是 UTF-16LE 编码的。如果不加这个参数很多中文/Unicode 字符串会直接漏掉。扫完之后确实发现了几处指向 flag 的线索但大部分是题目描述或者干扰信息。真正的 flag 藏在一个文件内容里而这个文件来自刚才那个临时目录。把它用 dumpfiles 抠出来之后里面有一行用 base64 编码的内容解码后就是完整的 flag。这里也解释了一个经验内存中不止有明文还有各种编码后的内容。在 CTF 题目中flag 经常被编码后藏在某个文件或注册表键值里在真实案件中攻击者的 C2 配置也经常用 base64、hex、甚至自定义加密算法包裹。不会解码就没有后续。5.4 注册表与计划任务别忘了持久化机制除了文件和网络持久化是内存取证里绕不开的话题。在 Windows 中攻击者为了维持权限往往会在注册表 Run 键、服务、计划任务中写入启动项。Volatility 的 printkey 和 hivelist 插件可以辅助查看注册表相关信息volatility -f mem.raw --profileWin7SP1x64 hivelist volatility -f mem.raw --profileWin7SP1x64 printkey -K Software\Microsoft\Windows\CurrentVersion\Run我在这道题里没有发现明显的额外持久化项但在真实场景中这一环节不能跳过。攻击者一旦写入启动项即使你发现并清除了远控进程只要不清理持久化配置机器重启后又会中招。这也是很多应急响应报告里被诟病最多的地方——只杀进程不挖根源等于白做。6. 从 easy_mem_2 到真实应急响应——排查思路的迁移6.1 这道题的结论复盘把前面的线索汇总一下整个事件链是这样的攻击者通过某种方式获得初始访问权镜像中体现为 PowerShell 下载执行。投递的远控木马在临时目录释放并运行与外部 C2 地址建立 TCP 8443 连接。攻击者后续通过控制台执行命令试图进一步操作。内存中留下的文件对象与命令行参数完整还原了这些行为。CTF 题目中找到 flag 就算结束。但在真实应急响应里这才刚刚开始。你需要确定攻击入口、评估影响范围、定位持久化手段、提取 IOCs、输出处置建议。这些能力恰好都能通过多刷内存取证题来刻意训练。6.2 真实场景中你会额外遇到的坑巨大的内存镜像真实案件的镜像可能是 8GB、16GB 甚至更大直接跑 strings 或 filescan 会消耗大量时间。建议先用 profile 确认和进程列表做粗筛再针对可疑进程做定向提取最后再全量扫描。内存损坏或截断有些采集工具抓取的内存可能不完整导致插件运行时报错。这时候可以尝试换 profile、换工具版本或者对镜像做分块尝试。反取证手段攻击者可能使用进程注入、DKOM 隐藏进程、无文件攻击等手段。这时需要配合 malfind、ldrmodules、驱动扫描等高级插件来深度分析。系统版本不常见Win10/11 的镜像在 Volatility 2 下往往匹配不到合适的 profile必须用 Volatility 3 或者专门的 symbol 文件。6.3 我建议的内存取证练习路径如果你从头开始学建议按这个顺序推进先拿 easy 级别的镜像明确 pslist、pstree、netscan、filescan、dumpfiles 这些核心插件的用法。再尝试 medium 级别加入恶意软件行为分析学会看父子进程关系、命令行参数、注入特征。最后进入 hard 级别模拟带有反取证手段的 APT 场景学会多维度交叉验证。每道题复盘时不只要写“flag 是什么”更要写清楚“我是怎么找到它的”以及“还有没有更快的路径”。这种复盘习惯比刷一百道题都有用。6.4 回到 easy_mem_2 给我最大的启示如果说有什么经验值得单独拎出来说那就是一定要对自己的取证过程做记录。我在做这道题时每个命令的输出都存成了文件每一条可疑线索都打上了时间戳。最后串完整条线的时候这些中间产物帮了大忙。没有记录你只能记住结论记不住推导过程而真实取证场景里推导过程才是经得起推敲的证据链。另外一个小技巧如果你在比赛里拿到内存题只有很短的解题时间优先跑 pslist、netscan、cmdline 这三个插件多数题目的入口都藏在这里。再用 dumpfiles 把可疑进程关联的文件抠出来基本就够找到 flag 了。这套组合拳稳且快。最后内存取证是个动手活看再多教程不如自己跑一遍镜像。找几个公开的 CTF 内存镜像练练手把每个插件的输出都看懂、看透下次再遇到 easy_mem_2 这样的题目你就不会再觉得它“容易”了——因为你已经知道这份“容易”背后其实藏着极其扎实的基本功要求。
返回列表