最近遇到的Linux内核内存取证小分析
2022-11-4 02:52:0 Author: xz.aliyun.com(查看原文) 阅读量:37 收藏

Volatility2 下的 profile 制作过程就不写了,提一句,vol2建议用CentOS 7来制作相应文件,不然在其他 Linux 系统(例如Ubuntu),解决软件依赖性得修好长时间(哭~~)

Volatility2:https://www.jianshu.com/p/7288ac54cd5c

Profile

Profile是特定操作系统版本以及硬件体系结构(x86、x64、ARM)中VTypes、共用体、对象类型的集合。

Vtypes 是 Volatility 框架中数据结构定义以及解析的语言,大部分操作系统底层都是使用 C 语言编写的,其中大量使用数据结构来组织和管理相关的变量以及属性。

因为 Volatility 是用 Python 语言编写的,所以我们需要一种方式在Python 源文件中表示 C 语言的数据结构。

VTypes 正是用于实现这一点的。

除了这些组件以外,Profile 还包括如下:

  • 元数据:操作系统的名称(例如:“windows”,“mac”,“linux”),内核版本,以及编译号。
  • 系统调用信息:索引以及系统调用的名称。
  • 常量值:全局变量-在某些操作系统中能够在硬编码的地址处找到的全局变量
  • 系统映射:关键全局变量和函数的地址(仅限 Linux 和 Mac)

但在 Volatility3 中,不再使用配置文件Profile,取而代之,vol3自身带有一个扩展的符号表库Symbols,并且对于大多数Windows内存镜像,可以基于内存映像本身来生成新的符号表。它允许符号表包含基于该操作系统位置(符号位置)的特定偏移量。

也就是说利用官方调试信息提供的那些结构的已知偏移量,可以更轻松、更快速地识别操作系统中的结构。

Symbol Tables

用于分析相关操作系统数据的内核符号表压缩包,其所有文件以JSON数据格式存储,可以是纯json文件.json,也可以是.json.gz或者.json.xz,Volatility3在使用它们时会自动解压。此外,Vol3会在用户主目录下的.cache/volatility3目录下会缓存他们的压缩内容,当前还无法更改这个缓存目录。

Vol3的symbol tables分为两类,上面的Windows Symbol tables作为一类,由于对Mac和Linux采用相同的识别机制,统分为另外一类。

Windows

对于WIndows系统,符号表字符串由所需PDB文件的GUIDAge组成,Volatility会搜索windows子目录下配置的所有文件,并与包含pdb名称,GUID/Age(或者其他压缩形式)的所有元数据进行匹配、利用。如果找不到的话,会从 Microsoft 官方的符号表服务器下载相关的PDB文件,并自动转化成适当的JSON格式,并存储在合适的位置。

可以从适当的 PDB 文件手动构建 Windows 符号表,而执行此操作的主要工具已经内置在 Volatility3了:pdbconv.py。 该文件支持从Volatility3的根路径运行,命令如下:

┌──(kali㉿kali)-[~]
└─$ python3 ./volatility3/framework/symbols/windows/pdbconv.py

Volatility官方也已经给出了Windows符号表:Volatility3官方:Windows符号表下载

Linux/Mac

Volatility3官方:Mac符号表下载

对于 Mac,它只有特定数量的内核,但我们不会经常更新包,因为它有点耗时。

Volitility3官方:Linux符号表(不全)

dwarf2json 可以从 DWARF文件生成 Linux 和 Mac 符号表。而当前,利用内核中包含的调试符号表,是大多数Volatility3插件恢复信息的唯一合适方法。

值得注意的是,只有-- elf的方案在 vol3 中可行,其他使用如Sysmap 解析出来的 json 都是不可行的。(在vol2中生成profile会用到 Sysmap )

./dwarf2json linux --elf /usr/lib/debug/boot/vmlinux-4.4.0-137-generic > output.json

此外,为什么上面说Linux符号表信息不全呢?因为Linux内核易于编译且唯一,无法区分它们,因此官方提供的Linux符号表并不详尽,因此在面对Linux内存取证时,要自行生成符号表;并且,标准内核是被剥离了调试信息的,若想获取带有调试信息的,则需从文件中单独获取。

LiME是Linux可加载内核模块(LKM)Linux的内存提取器,它允许从Linux或者基于Linux的设备(如:Android)获取临时性内存(RAM)。LiME成为第一个允许在Android设备上捕获完整内存的工具,并且最大限度地减少了在获取过程中用户和内核空间进程之间的交互,因此LiME能生成比其他工具更可靠的内存捕获。

基于LiME工具的Android手机动态内存提取

CentOS 5.5编译LiME

编译LiME

[[email protected] CentOS]# tar -zxvf LiME.tar.gz
[[email protected] CentOS]# cd /home/yunwei/Desktop/malware/LiME/src/
[[email protected] src]# make
make -C /lib/modules/2.6.18-194.el5/build M="/home/yunwei/Desktop/malware/LiME/src" modules
make[1]: Entering directory `/usr/src/kernels/2.6.18-194.el5-x86_64'
  Building modules, stage 2.
  MODPOST
  LD [M]  /home/yunwei/Desktop/malware/LiME/src/lime.ko
make[1]: Leaving directory `/usr/src/kernels/2.6.18-194.el5-x86_64'
strip --strip-unneeded lime.ko
mv lime.ko lime-2.6.18-194.el5.ko
[[email protected] src]# ll
total 1176
-rw-r--r-- 1 root root   2557 Sep 28  2017 disk.c
-rw-r--r-- 1 root root 168240 May 20 10:44 disk.o
-rw-r--r-- 1 root root  41984 May 20 11:46 lime-2.6.18-194.el5.ko
-rw-r--r-- 1 root root   1920 Sep 28  2017 lime.h
-rw-r--r-- 1 root root   1151 May 20 10:44 lime.mod.c
-rw-r--r-- 1 root root  81632 May 20 10:44 lime.mod.o
-rw-r--r-- 1 root root 505173 May 20 10:44 lime.o
-rw-r--r-- 1 root root   6614 Sep 28  2017 main.c
-rw-r--r-- 1 root root 175408 May 20 10:44 main.o
-rw-r--r-- 1 root root   1661 Sep 28  2017 Makefile
-rw-r--r-- 1 root root   1722 Sep 28  2017 Makefile.sample
-rw-r--r-- 1 root root      0 May 20 10:44 Module.markers
-rw-r--r-- 1 root root      0 May 20 10:44 Module.symvers
-rw-r--r-- 1 root root   3889 Sep 28  2017 tcp.c
-rw-r--r-- 1 root root 166152 May 20 10:44 tcp.o

抓取内存

/home/centos/Desktop/forensic/centos5.lime为自定义路径

## 进入内核模式抓取内存
[[email protected] src]# insmod lime-`uname -r`.ko path=/home/yunwei/Desktop/malware/centos5.lime format=lime
## 再次抓取内存前要先运行以下命令退出内核模式
[[email protected] src]# rmmod lime

制作元数据

dwarf2dump使用

安装调试文件导出工具dwarfdump

  • 下载与编译libdwarf
## 解压Libdwarf
[[email protected] src]# git clone https://github.com/tomhughes/libdwarf.git
[[email protected] src]# tar -zxvf libdwarf.tar.gz

## 光盘安装依赖包
[[email protected] src]# cd /media/CentOS_5.5_Final/CentOS/
[[email protected] src]# rpm -ivh /media/CentOS_5.5_Final/CentOS/elfutils-libelf-0.137-3.el5.x86_64.rpm 
[[email protected] libdwarf]# rpm -ivh elfutils-libelf-devel-static-0.137-3.el5.x86_64.rpm elfutils-libelf-devel-0.137-3.el5.x86_64.rpm elfutils-libelf-0.137-3.el5.x86_64.rpm

## 编译安装 libdwarf
[[email protected] CentOS]# cd /home/yunwei/Desktop/malware/libdwarf
[[email protected] CentOS]# ./configure
[[email protected] libdwarf]# make

### 若没有报错,则表示安装正确。
[[email protected] libdwarf]# cd dwarfdump/
[[email protected] dwarfdump]# make install
cp dwarfdump /usr/local/bin/dwarfdump
cp ./dwarfdump.conf /usr/local/lib/dwarfdump.conf
cp ./dwarfdump.1 /usr/local/share/man/man1/dwarfdump.1
[[email protected] dwarfdump]# dwarfdump -h
### 输入dwarfdump -h若没有报错,则表示安装正确。
  • 生成内存镜像
[[email protected] malware]# tar -zxvf volatility.tar.gz
[[email protected] malware]# cd volatility/tools/linux/
## 错误
[[email protected] linux]# make
make -C //lib/modules/2.6.18-194.el5/build CONFIG_DEBUG_INFO=y M="/home/yunwei/Desktop/malware/volatility/tools/linux" modules
make[1]: Entering directory `/usr/src/kernels/2.6.18-194.el5-x86_64'
  CC [M]  /home/yunwei/Desktop/malware/volatility/tools/linux/module.o
/home/yunwei/Desktop/malware/volatility/tools/linux/module.c:214: error: redefinition of ‘struct module_sect_attr’
/home/yunwei/Desktop/malware/volatility/tools/linux/module.c:221: error: redefinition of ‘struct module_sect_attrs’
/home/yunwei/Desktop/malware/volatility/tools/linux/module.c:375:5: warning: "STATS" is not defined
/home/yunwei/Desktop/malware/volatility/tools/linux/module.c:391:5: warning: "DEBUG" is not defined
make[2]: *** [/home/yunwei/Desktop/malware/volatility/tools/linux/module.o] Error 1
make[1]: *** [_module_/home/yunwei/Desktop/malware/volatility/tools/linux] Error 2
make[1]: Leaving directory `/usr/src/kernels/2.6.18-194.el5-x86_64'
make: *** [dwarf] Error 2

### 注释掉 198,7 ~ 221,7,编译问题就解决了
/*
#if LINUX_VERSION_CODE == KERNEL_VERSION(2,6,18)
....
struct module_sections module_sect_attrs;

#endif
*/

## 注释代码之后,编译输出状态

[[email protected] linux]# make
make -C //lib/modules/2.6.18-194.el5/build CONFIG_DEBUG_INFO=y M="/home/yunwei/Desktop/malware/volatility-2.6/tools/linux" modules
make[1]: Entering directory `/usr/src/kernels/2.6.18-194.el5-x86_64'
  CC [M]  /home/yunwei/Desktop/malware/volatility-2.6/tools/linux/module.o
/home/yunwei/Desktop/malware/volatility-2.6/tools/linux/module.c:354:5: warning: "STATS" is not defined
/home/yunwei/Desktop/malware/volatility-2.6/tools/linux/module.c:370:5: warning: "DEBUG" is not defined
  Building modules, stage 2.
  MODPOST
  CC      /home/yunwei/Desktop/malware/volatility-2.6/tools/linux/module.mod.o
  LD [M]  /home/yunwei/Desktop/malware/volatility-2.6/tools/linux/module.ko
make[1]: Leaving directory `/usr/src/kernels/2.6.18-194.el5-x86_64'
dwarfdump -di module.ko > module.dwarf
make -C //lib/modules/2.6.18-194.el5/build M="/home/yunwei/Desktop/malware/volatility-2.6/tools/linux" clean
make[1]: Entering directory `/usr/src/kernels/2.6.18-194.el5-x86_64'
  CLEAN   /home/yunwei/Desktop/malware/volatility-2.6/tools/linux/.tmp_versions
make[1]: Leaving directory `/usr/src/kernels/2.6.18-194.el5-x86_64'

https://beguier.eu/nicolas/articles/security-tips-3-volatility-linux-profiles.html

先运行Volatility3 的banners插件,以确定必要的内核版本。

┌──(root㉿SanDieg0)-[/mnt/d/volatility3]
└─$ python3 vol.py -f /mnt/f/backup2/dump.mem banners.Banners
Volatility 3 Framework 2.4.0
Progress:  100.00               PDB scanning finished
Offset  Banner

0x3e6001a0      Linux version 5.4.0-84-generic ([email protected]) (gcc version 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04)) #94~18.04.1-Ubuntu SMP Thu Aug 26 23:17:46 UTC 2021 (Ubuntu 5.4.0-84.94~18.04.1-generic 5.4.133)
0x3f191d94      Linux version 5.4.0-84-generic ([email protected]) (gcc version 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04)) #94~18.04.1-Ubuntu SMP Thu Aug 26 23:17:46 UTC 2021 (Ubuntu 5.4.0-84.94~18.04.1-generic 5.4.133)
0x710b7c88      Linux version 5.4.0-84-generic ([email protected]) (gcc version 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04)) #94~18.04.1-Ubuntu SMP Thu Aug 26 23:17:46 UTC 2021 (Ubuntu 5.4.0-84.94~18.04.1-generic 5.4.133)
0x7bd00010      Linux version 5.4.0-84-generic ([email protected]) (gcc version 7.5.0 (Ubuntu 7.5.0-3ubuntu1~18.04)) #94~18.04.1-Ubuntu SMP Thu Aug 26 23:17:46 UTC 2021 (Ubuntu 5.4.0-84.94~18.04.1-generic 5.4.133)

注意:banners.Banners插件只能识别 Linux 镜像的banner信息,不识别 Windows。

然后我们需要符号表(symbol tables)。根据上面写的dwarf2json生成 json 的命令,是需要我们提供 /usr/lib/debug/boot目录下的vmlinux文件,但是系统往往不会自带该文件,然后发现在/boot目录下有一个相同名字的 vmlinux 文件,但是并不可用。

能不能不用banners插件?我是刚开始学的,看了看最近比赛的内存取证的WP,很多都是直接strings然后提取出来的。。。

借助Docker直接获取dbgsym文件安装在指定系统

https://tttang.com/archive/1762/#toc_dbgsym

Docker集成了我们需要的系统版本,这样就直接省去了重新搭建系统的麻烦,(我用的WSL2,WSL2没法像正常Linux系统安装Docker,可以去下载一个Docker Desktop,开启相应设置)

获取源文件网址:https://launchpad.net/ubuntu/+archive/primary/+files/ ,按需选择下载。

┌──(root㉿SanDieg0)-[/mnt/d/volatility3]
└─$ git clone https://github.com/volatilityfoundation/dwarf2json
┌──(root㉿SanDieg0)-[/mnt/d/volatility3]
└─$ cd dwarf2json
┌──(root㉿SanDieg0)-[/mnt/d/volatility3]
└─$ go build
┌──(root㉿SanDieg0)-[/mnt/d/volatility3]
└─$ wget https://launchpad.net/ubuntu/+archive/primary/+files/linux-image-unsigned-5.15.0-48-generic-dbgsym_5.15.0-48.54_amd64.ddeb
┌──(root㉿SanDieg0)-[/mnt/d/volatility3]
└─$ cd ../
┌──(root㉿SanDieg0)-[/mnt/d/volatility3]
└─$ docker run -it --rm -v $PWD:/volatility ubuntu:18.04 /bin/bash
┌──(root㉿DockerID)-[/]
└─$ cd volatility/dwarf2json
┌──(root㉿DockerID)-[/volatility3/dwarf2json]
└─$ dpkg -i linux-image-unsigned-5.4.0-84-generic-dbgsym_5.4.0-84.94_amd64.ddeb
┌──(root㉿DockerID)-[/volatility3/dwarf2json]
└─$ ./dwarf2json linux --elf /usr/lib/debug/boot/vmlinux5.4.0-84-generic > linux-image-5.4.0-84-generic.json 
#退出Docker
┌──(root㉿SanDieg0)-[/mnt/d/volatility3/]
└─$ cp linux-image-5.4.0-84-generic.json ./volatility3/volatility3/framework/symbols/linux

Vol3的符号表编译完成,然后按照正常内存取证的步骤解析内存镜像就好了

Examples

2022 Sekai CTF | symbolic-needs 1

按照上面构造符号表的方法,先判断当前系统版本和Linux 内核版本,再制作符号表,这个题目很巧,给了Ubuntu 22.04 Linux-version 5.15.0-43-generic,当前版本,Vol2是不支持的,必须用Vol3。

┌──(root㉿SanDieg0)-[/mnt/d/volatility3]
└─$ wget https://launchpad.net/ubuntu/+archive/primary/+files/linux-image-unsigned-5.15.0-43-generic-dbgsym_5.15.0-43.46-generic_amd64.ddeb
┌──(root㉿SanDieg0)-[/mnt/d/volatility3]
└─$ cd ../
┌──(root㉿SanDieg0)-[/mnt/d/volatility3]
└─$ docker run -it --rm -v $PWD:/volatility ubuntu:22.04 /bin/bash
┌──(root㉿DockerID)-[/]
└─$ cd volatility/dwarf2json
┌──(root㉿DockerID)-[/volatility3/dwarf2json]
└─$ dpkg -i linux-image-unsigned-5.15.0-43-generic-dbgsym_5.15.0-43.46_amd64.ddeb
┌──(root㉿DockerID)-[/volatility3/dwarf2json]
└─$ ./dwarf2json linux --elf /usr/lib/debug/boot/vmlinux-5.15.0-43-generic > linux-image-5.15.0-43-generic.json 
#退出Docker
┌──(root㉿SanDieg0)-[/mnt/d/volatility3/]
└─$ cp linux-image-5.4.0-84-generic.json ./volatility3/volatility3/framework/symbols/linux
┌──(root㉿SanDieg0)-[/mnt/d/volatility3/]
└─$ python3 vol.py -f /mnt/f/20022Sekai/dump.mem linux.bash
Volatility 3 Framework 2.4.0
PID Process CommandTime Command

1863    bash    2022-08-29 13:45:56.000000    72.48.117.53.84.48.110.95.119.51.95.52.114.51.95.49.110.33.33.33

https://www.qqxiuzi.cn/bianma/ascii.htm

最近祥云杯也有一道内存取证题目,不过可以直接非预期出,就不放祥云杯了


文章来源: https://xz.aliyun.com/t/11800
如有侵权请联系:admin#unsafe.sh