Linux Memory Grabber 用于转储 Linux 内存并创建 Volatility(TM) 配置文件的脚本。 Hal Pomeranz ([email protected]), 2020-02-01
“如果说我看得比别人更远,那是因为我站在巨人的肩膀上。” —— 艾萨克·牛顿
很多人应该为这个简单小工具的实现而获得感谢:
—— 微软的优秀团队,感谢他们提供了 AVML
—— Joe Sylve,感谢他在 LiME 上的工作
—— 整个 Volatility(TM) 开发团队的持续付出。 我尤其要感谢 Andrew Case,他在我开发工具的过程中回答了许多烦人的问题。
—— David Anderson,感谢他对 libdwarf 和 dwarfdump 的持续支持
—— MoonSols 的 Matt Suiche。在我构建工具时, 我的设计目标是“让它像 DumpIt 一样易用”(如果你需要 捕获 Windows 内存,我知道没有比它更容易使用的工具了)。 所以,感谢你的灵感,Matt!
—— 提供想法和代码使工具变得更好的人:
Julien —— 备选输出/构建目录和案例 ID 标签,
如果不是以 root 身份运行则中止
Jonathon Poling —— 与 Julien 类似的想法
Jeff Bryner —— 为每次捕获创建 volatilityrc 文件
社区因所有这些努力而变得更好。我选择 以 Creative Commons “署名”许可(CC BY)发布我的工具, 以使其尽可能广泛地可用。
要分析 Linux 内存,首先需要能够捕获 Linux 内存。 AVML 效果很好,但如果你的系统没有 /proc/kcore 或 /dev/crash,那么你将需要 Joe Sylve 的 Linux Memory Extractor (LiME)。 但是你需要在要抓取 RAM 的系统的内核上 编译一个 LiME 模块。
Volatility(TM) 在分析 Linux 内存映像方面非常出色。但它需要 一个与捕获内存的系统匹配的配置文件。 构建配置文件意味着在相应的系统上编译一个 C 程序 并使用 dwarfdump 获取关键内核数据结构地址。 你还需要 /boot 目录下的 System.map 文件副本。
如果你碰巧有目标系统的副本,你可以在克隆机上 构建 Volatility(TM) 配置文件,如果需要,还可以构建 LiME 来从目标系统捕获和分析内存。但在许多情况下, 目标系统的副本是不可用的。因此,你可能需要在 目标机器上构建你的 Volatility(TM) 配置文件和 LiME。
这可不是一件轻松的事。涉及许多步骤, 以及一些相当底层的 Linux 命令。我的目标是 创建一个可以(由专家)安装在 U 盘上并分发给现场代理的软件包。 U 盘用户应该能够插入 U 盘,运行一个命令, 然后成功获取目标机器的内存映像 和可用的 Volatility(TM) 配置文件。结果就是我的 lmg(Linux Memory Grabber) 脚本。
如果你对取证纯净性要求严格,这个工具可能不适合你。 我们来讨论一下我的工具与目标系统交互的一些方式:
可移动介质 —— 该工具设计从便携式 USB 设备(如 U 盘)运行。 你将把一个可写入设备插入目标系统,该设备可能被系统上的 恶意用户或恶意软件作为攻击目标。插入设备的操作会 改变机器的状态(例如,创建日志条目、mtab 条目等)。 如果设备未被操作系统自动挂载,用户必须通过 root shell 手动挂载设备。
编译 —— 创建 Volatility(TM) 配置文件涉及在目标机器上编译代码。 当 AVML 不工作时,构建 LiME 也是如此。 因此,将执行 gcc,读取头文件,链接库等。 lmg 通过将 TMPDIR 设置为 lmg 运行的 USB 设备上的目录, 尽量减小对目标机器文件系统的影响。 这意味着编译器创建的中间文件将被写入 U 盘, 而不是目标机器的本地文件系统。
依赖关系 —— 为了在 Linux 上编译内核代码,目标机器需要一个可用的 开发环境,包括 gcc、make 等,以及所有适当的包含文件和共享库。 特别是,内核头文件需要存在于本地机器上。 这些依赖关系可能在目标上不存在。 在这种情况下,用户面临着选择:要么安装适当的依赖关系(如果可能), 要么无法为系统构建 Volatility(TM) 配置文件。
恶意软件 —— lmg 使用目标机器上的 /bin/bash、gcc、zip 和许多其他程序。 如果系统已被攻破,lmg 使用的应用程序可能不可信。 一个更完整的解决方案是为 lmg 在便携式 USB 设备上创建一个安全执行环境, 但这超出了这个初始概念验证的范围。
内存 —— 所有运行的命令都会导致目标系统的内存发生变化。 捕获 RAM 总是会创建工件,但在这种情况下,除了运行 RAM 转储程序之外, 还有大量的编译、文件系统访问等。
尽管如此,lmg 是一个非常方便的工具,可以让技能较低的代理 从目标系统中捕获有用的内存分析数据。
请注意,如果 AVML 失败,lmg 会在 USB 设备上查找 与目标机器的内核版本和处理器架构匹配的现有 LiME 模块。 如果找到,lmg 不会重新编译。同样,你也可以选择不让 lmg 为目标创建 Volatility(TM) 配置文件,以尽量减少对目标系统的影响。
lmg 在调用 gcc 和 zip 等程序时使用相对路径。 因此,如果你希望从备选介质运行这些程序,只需在运行 lmg 之前 相应更新 $PATH 即可。
首先,按照 lmg 附带的 INSTALL 文档中的说明准备一个 U 盘。
当你想要获取 RAM 时,将 U 盘插入目标系统。 在大多数 Linux 系统上,新的 USB 设备会自动挂载到 /media 下。 假设你的 U 盘最终挂载到 /media/LMG。
然后,以 root 身份运行 "/media/LMG/lmg"。这是交互模式, 在 lmg 为系统构建 LiME 模块和/或创建 Volatility(TM) 配置文件之前, 会提示用户确认。如果你不想被提示,请使用 "/media/LMG/lmg -y"。
其他一切自动完成。脚本运行后,你将在 U 盘上获得一个新目录:
".../capture/-YYYY-MM-DD_hh.mm.ss"
lmg 支持 -c 选项,用于指定一个案例 ID 目录名,以替代默认的 "-YYYY-MM-DD_hh.mm.ss" 目录。
无论使用哪个目录名,该目录都将包含:
-YYYY-MM-DD_hh.mm.ss-memory.lime —— RAM 捕获文件 -YYYY-MM-DD_hh.mm.ss-profile.zip —— Volatility(TM) 配置文件 -YYYY-MM-DD_hh.mm.ss-bash —— 目标系统 /bin/bash 的副本 volatilityrc —— Volatility 配置文件原型
volatilityrc 文件定义了捕获的内存和插件的适当位置。有关如何使用此文件, 请参阅下面的使用示例。
/bin/bash 的副本有助于确定内存捕获中 bash 进程的 shell 历史数据结构地址。 有关如何使用此可执行文件的更多详细信息,请参见 https://github.com/volatilityfoundation/volatility/wiki/Linux-Command-Reference#linux_bash (或参考下面的使用示例)。
请注意,有时你可能不希望将数据写入运行 lmg 的介质—— 例如,如果 lmg 工具位于只读介质(如 DVD-ROM)上。lmg 支持 -d 选项来指定 不同的输出目录。默认情况下,所有编译都在目标目录中进行, 但用户可以使用 -B 选项指定备选编译目录。
以下是使用 lmg 工具的示例,其中包括直接在 U 盘上使用 Volatility(TM) 来分析捕获的映像。在我的测试机器上,U 盘位于 /dev/sdb, 并且未被操作系统自动挂载。因此,我手动执行了所有操作。
[root@localhost ~]$ sudo -s [sudo] password for lab: [root@localhost lab]# mkdir -p /mnt/usb [root@localhost lab]# mount /dev/sdb1 /mnt/usb
[root@localhost lab]# /mnt/usb/lmg -y AVML is /mnt/usb/avml/avml-x86_64 Dumping memory in "lime" format to /mnt/usb/capture/localhost.localdomain-2020-02-01_08.16.55 This could take a while...Done! Grabbing a copy of /bin/bash...Done! Writing volatilityrc to /mnt/usb/capture/localhost.localdomain-2020-02-01_08.16.55...Done! make -C //lib/modules/4.18.0-147.3.1.el8_1.x86_64/build M="/mnt/usb/volatility-master/tools/linux" clean make[1]: Entering directory '/usr/src/kernels/4.18.0-147.3.1.el8_1.x86_64' make[1]: Leaving directory '/usr/src/kernels/4.18.0-147.3.1.el8_1.x86_64' rm -f module.dwarf make -C //lib/modules/4.18.0-147.3.1.el8_1.x86_64/build CONFIG_DEBUG_INFO=y M="/mnt/usb/volatility-master/tools/linux" modules make[1]: Entering directory '/usr/src/kernels/4.18.0-147.3.1.el8_1.x86_64' CC [M] /mnt/usb/volatility-master/tools/linux/module.o Building modules, stage 2. MODPOST 1 modules WARNING: modpost: missing MODULE_LICENSE() in /mnt/usb/volatility-master/tools/linux/module.o see include/linux/module.h for more information CC /mnt/usb/volatility-master/tools/linux/module.mod.o LD [M] /mnt/usb/volatility-master/tools/linux/module.ko make[1]: Leaving directory '/usr/src/kernels/4.18.0-147.3.1.el8_1.x86_64' dwarfdump -di module.ko > module.dwarf make -C //lib/modules/4.18.0-147.3.1.el8_1.x86_64/build M="/mnt/usb/volatility-master/tools/linux" clean make[1]: Entering directory '/usr/src/kernels/4.18.0-147.3.1.el8_1.x86_64' CLEAN /mnt/usb/volatility-master/tools/linux/.tmp_versions CLEAN /mnt/usb/volatility-master/tools/linux/Module.symvers make[1]: Leaving directory '/usr/src/kernels/4.18.0-147.3.1.el8_1.x86_64' adding: module.dwarf (deflated 90%) adding: boot/System.map-4.18.0-147.3.1.el8_1.x86_64 (deflated 79%)
[root@localhost lab]# cd /mnt/usb/capture/localhost.localdomain-2020-02-01_08.16.55 [root@localhost localhost.localdomain-2020-02-01_08.16.55]# ls localhost.localdomain-2020-02-01_08.16.55-bash localhost.localdomain-2020-02-01_08.16.55-memory.lime localhost.localdomain-2020-02-01_08.16.55-profile.zip volatilityrc [root@localhost localhost.localdomain-2020-02-01_08.16.55]# ../../volatility-master/vol.py --conf-file=volatilityrc linux_banner Volatility Foundation Volatility Framework 2.6.1 Linux version 4.18.0-147.3.1.el8_1.x86_64 ([email protected]) (gcc version 8.3.1 20190507 (Red Hat 8.3.1-4) (GCC)) #1 SMP Fri Jan 3 23:55:26 UTC 2020
[root@localhost localhost.localdomain-2020-02-01_08.16.55]# gdb localhost.localdomain-2020-02-01_08.16.55-bash GNU gdb (GDB) Red Hat Enterprise Linux 8.2-6.el8_0 Copyright (C) 2018 Free Software Foundation, Inc. License GPLv3+: GNU GPL version 3 or later http://gnu.org/licenses/gpl.html This is free software: you are free to change and redistribute it. There is NO WARRANTY, to the extent permitted by law. Type "show copying" and "show warranty" for details. This GDB was configured as "x86_64-redhat-linux-gnu". Type "show configuration" for configuration details. For bug reporting instructions, please see: http://www.gnu.org/software/gdb/bugs/. Find the GDB manual and other documentation resources online at: http://www.gnu.org/software/gdb/documentation/.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from localhost.localdomain-2020-02-01_08.16.55-bash...Missing separate debuginfo for /mnt/usb/capture/localhost.localdomain-2020-02-01_08.16.55/localhost.localdomain-2020-02-01_08.16.55-bash
Try: dnf --enablerepo='debug' install /usr/lib/debug/.build-id/b6/858d77c486b7b596f22956149bbc9f8058d98d.debug
Reading symbols from .gnu_debugdata for /mnt/usb/capture/localhost.localdomain-2020-02-01_08.16.55/localhost.localdomain-2020-02-01_08.16.55-bash...(no debugging symbols found)...done.
(no debugging symbols found)...done.
(gdb) disass history_list
Dump of assembler code for function history_list:
0x00000000000ccea0 <+0>: endbr64
0x00000000000ccea4 <+4>: mov 0x24b09d(%rip),%rax # 0x317f48
0x00000000000cceab <+11>: retq
End of assembler dump.
(gdb) quit
[root@localhost localhost.localdomain-2020-02-01_08.16.55]# ../../volatility-master/vol.py --conf-file=volatilityrc linux_bash -H 0x317f48
Volatility Foundation Volatility Framework 2.6.1
Pid Name Command Time Command
13822 bash 2020-01-30 20:25:39 UTC+0000 uname -a 13822 bash 2020-01-30 20:25:39 UTC+0000 ls 13822 bash 2020-01-30 20:25:39 UTC+0000 sudo -s 13822 bash 2020-01-30 20:25:39 UTC+0000 fg [... 更多输出未显示 ...]