Profile制作

不同的操作系统(Windows、Linux、macOS)、不同的发行版(比如 Ubuntu 22.04 vs CentOS 7),甚至不同版本的操作系统内核,它们在内存中存储信息的方式是完全不同的。vol2使用profile进行内存信息的标记

对于 Windows 系统,微软发布的版本相对固定,Volatility 官方自带了绝大多数常见 Windows 版本的 Profile。 但 Linux 开源且碎片化严重,各个发行版(Ubuntu, Debian, CentOS 等)都会自己编译内核,更新也非常频繁。Volatility 不可能内置所有 Linux 内核的配置文件。因此:

  • 如果你拿到一个 Linux 的内存镜像,你通常需要先查出它具体的内核版本号(比如 5.15.0-76-generic)。
  • 然后去开源仓库找别人做好的。
  • 如果找不到,你就得按照教程,自己搭建一个相同内核版本的 Linux 虚拟机,编译提取出 system.mapmodule.dwarf,打包成自己专属的 Profile。

扫描系统

在开始制作之前,你必须知道这个内存镜像是从什么系统、什么内核版本里扣出来的。 、可以通过 strings memory.vmem | grep "Linux version" 命令来碰运气,或者先用 Volatility 3 的 banner 插件扫一下。

下载内核包

知道了版本,你需要去 Ubuntu 的官方历史镜像源(比如中科大源镜像站的 pool 目录)下载与这个版本完全一致的内核文件。需要下载三个关键文件:

  1. linux-headers-..._all.deb (通用内核头文件)
  2. linux-headers-..._amd64.deb (特定架构的头文件)
  3. linux-modules-..._amd64.deb (内核模块包)

提取 System.map

System.map 也就是内核符号表,这个不需要自己算,它直接就躺在刚才下载的 linux-modules(内核模块包)里面。 你只需要像解压普通压缩包一样,把那个 .deb 文件解压,在 data/boot/ 目录下就能直接找到 System.map-5.4.0-100-generic。直接把它提取出来重命名为 System.map 即可。

炼制 module.dwarf

这个 module.dwarf 包含了内核数据结构的大小和偏移量,必须在你指定的那个系统环境里现熬现煮(编译) 出来。这也是为什么以前大家都要装个同版本的 VMware 虚拟机。可以使用 Docker 替代了虚拟机,这样更轻量。

制作系统docker镜像

debian

1
2
3
4
5
6
7
8
9
10
11
├── dockerfile
└── src
├── linux-headers-5.4.0-100_5.4.0-100.113_all.deb
├── linux-headers-5.4.0-100-generic_5.4.0-100.113_amd64.deb
├── linux-modules-5.4.0-100-generic_5.4.0-100.113_amd64.deb
└── tools.zip
# dockerfile是自己写的用于构建Docker镜像的脚本
# tools.zip 是从 volatility/tools 保存并压缩的
# linux-headers-5.4.0-100_5.4.0-100.113_all.deb 是通用内核头文件
# linux-headers-5.4.0-100-generic_5.4.0-100.113_amd64.deb 是特定架构的内核头文件
# linux-modules-5.4.0-100-generic_5.4.0-100.113_amd64.deb 是内核模块包
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
FROM ubuntu:20.04

# 将环境设置为非交互环境
ENV DEBIAN_FRONTEND=noninteractive

COPY ./src/ /src/

RUN sed -i 's/archive.ubuntu.com/mirrors.ustc.edu.cn/g' /etc/apt/sources.list \
&& sed -i 's/security.ubuntu.com/mirrors.ustc.edu.cn/g' /etc/apt/sources.list \
&& apt update --no-install-recommends \
&& apt install -y gcc dwarfdump build-essential unzip kmod linux-base

WORKDIR /src

RUN unzip tools.zip \
# 需要根据实际的内核版本修改此处
&& dpkg -i linux-headers-5.4.0-100_5.4.0-100.113_all.deb \
&& dpkg -i linux-headers-5.4.0-100-generic_5.4.0-100.113_amd64.deb

WORKDIR /src/tools/linux

RUN echo 'MODULE_LICENSE("GPL");' >> module.c && \
# 需要根据实际的内核版本修改此处
sed -i 's/$(shell uname -r)/5.4.0-100-generic/g' Makefile && \
make && \
mv module.dwarf /tmp
1
2
3
# 运行以下命令构建并运行容器,并把module.dwarf从/tmp目录中复制出来
docker build --platform linux/amd64 -t profile .
docker run --platform linux/amd64 --rm -it profile /bin/bash

如果不想敲命令行去复制Docker容器中/tmp目录下的module.dwarf,也可以使用vscode的Docker插件或者Docker-Desktop辅助

最后我们将 module.dwarfSystem.map 用deflate压缩算法压缩成一个zip压缩包放到volatility/volatility/plugins/overlays/linux目录下即可

可以使用 vol.py --info 命令查看 Profile 是否能被成功识别

redhat

用以下命令解压kernel-3.10.0-1160.el7.x86_64.rpm 并从boot中提取System.map-3.10.0-1160.el7.x86_64

1
2
3
4
mkdir test
cp kernel-3.10.0-1160.el7.x86_64.rpm test
cd test
rpm2cpio kernel-3.10.0-1160.el7.x86_64.rpm | cpio -idmv

1
2
3
4
5
6
├── dockerfile
└── src
├── kernel-3.10.0-1160.el7.x86_64.rpm
├── kernel-devel-3.10.0-1160.el7.x86_64.rpm
├── libdwarf-20201201.tar.gz
└── tools.zip
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
FROM centos:7

COPY ./src/ /src/

WORKDIR /src

RUN sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-*.repo \
&& sed -i 's|#baseurl=http://mirror.centos.org/centos|baseurl=https://mirrors.aliyun.com/centos|g' /etc/yum.repos.d/CentOS-*.repo \
&& sed -i 's|baseurl=http://mirror.centos.org/centos|baseurl=https://mirrors.aliyun.com/centos|g' /etc/yum.repos.d/CentOS-*.repo \
&& yum clean all \
&& yum makecache

RUN yum install -y gcc make unzip elfutils-libelf-devel

# 需要根据实际的内核版本修改此处
RUN yum localinstall -y kernel-3.10.0-1160.el7.x86_64.rpm \
&& yum localinstall -y kernel-devel-3.10.0-1160.el7.x86_64.rpm

RUN tar -xzvf libdwarf-20201201.tar.gz \
&& cd libdwarf-20201201 \
&& chmod +x * \
&& ./configure \
&& make install \
&& cd .. \
&& unzip tools.zip \
&& cd /src/tools/linux \
&& echo 'MODULE_LICENSE("GPL");' >> module.c \
# 需要根据实际的内核版本修改此处
&& sed -i 's/$(shell uname -r)/3.10.0-1160.el7.x86_64/g' Makefile \
&& make \
&& mv module.dwarf /tmp/module.dwarf

# 清理 yum 缓存以减小镜像体积
RUN yum clean all

Symbols制作

一个vol3的SymbolTables其实就是一个json文件

Volatility 2 需要一个叫 Profile 的 ZIP 压缩包(里面装了 module.dwarfSystem.map)。到了 Volatility 3,官方对整个工具的底层架构进行了大换血,抛弃了原来那种略显笨重的压缩包机制,改用了一种全新的格式:ISF (Intermediate Symbol Format,中间符号格式)

制作系统docker镜像

debian

1
2
3
4
├── dockerfile
└── src
├── dwarf2json
└── linux-image-unsigned-5.4.0-100-generic-dbgsym_5.4.0-100.113_amd64.ddeb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
FROM ubuntu:20.04

# 将环境设置为非交互环境
ENV DEBIAN_FRONTEND=noninteractive

COPY ./src/ /src/

RUN sed -i 's/archive.ubuntu.com/mirrors.ustc.edu.cn/g' /etc/apt/sources.list \
&& sed -i 's/security.ubuntu.com/mirrors.ustc.edu.cn/g' /etc/apt/sources.list \
&& apt update --no-install-recommends\
&& apt install -y gcc dwarfdump build-essential unzip

WORKDIR /src

RUN dpkg -i linux-image-unsigned-5.4.0-100-generic-dbgsym_5.4.0-100.113_amd64.ddeb \
&& chmod +x dwarf2json \
# 下面这里的文件名需要根据系统版本进行修改,具体文件名可以通过解压上面的ddeb包得到
&& ./dwarf2json linux --elf /usr/lib/debug/boot/vmlinux-5.4.0-100-generic > Ubuntu_5.4.0-100-generic.json \
&& mv Ubuntu_5.4.0-100-generic.json /tmp
1
2
3
4
# 运行以下命令构建并运行容器,并把json文件从/tmp目录中复制出来
# 我这里由于用的是ARM架构的Macbook,所以需要指定平台,x86的设备可以不写
docker build --platform linux/amd64 -t profile .
docker run --platform linux/amd64 --rm -it profile /bin/bash

redhat

1
2
3
4
5
├── dockerfile
└── src
├── dwarf2json
├── kernel-debuginfo-3.10.0-1160.el7.x86_64.rpm
└── kernel-debuginfo-common-x86_64-3.10.0-1160.el7.x86_64.rpm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
FROM centos:7

COPY ./src/ /src/

WORKDIR /src

RUN sed -i 's/mirrorlist/#mirrorlist/g' /etc/yum.repos.d/CentOS-*.repo \
&& sed -i 's|#baseurl=http://mirror.centos.org/centos|baseurl=https://mirrors.aliyun.com/centos|g' /etc/yum.repos.d/CentOS-*.repo \
&& sed -i 's|baseurl=http://mirror.centos.org/centos|baseurl=https://mirrors.aliyun.com/centos|g' /etc/yum.repos.d/CentOS-*.repo \
&& yum clean all \
&& yum makecache

RUN yum install -y gcc make unzip elfutils-libelf-devel

# 需要根据实际的内核版本修改此处
RUN yum localinstall -y kernel-debuginfo-common-x86_64-3.10.0-1160.el7.x86_64.rpm \
&& yum localinstall -y kernel-debuginfo-3.10.0-1160.el7.x86_64.rpm

RUN chmod +x dwarf2json \
&& ./dwarf2json linux --elf /usr/lib/debug/usr/lib/modules/3.10.0-1160.el7.x86_64/vmlinux > Centos_3.10.0-1160.el7.x86_64.json \
&& mv Centos_3.10.0-1160.el7.x86_64.json /tmp

# 清理 yum 缓存以减小镜像体积
RUN yum clean all

Linux 内存取证核心命令与实战全书

取证前期准备与环境配置

系统信息获取与配置验证

  • Vol2 查看内核和发行版信息: vol.py -f mem.raw --profile=LinuxDebian_5_10_0-21-amd64_profilex64 linux_banner
  • Vol2 验证 Profile 是否载入成功: vol.py --info | grep Profile | grep Linux
  • Vol3 查看当前可用 Profile (ISF符号表): vol3.py IsfInfo | grep linux

进程与命令历史溯源

寻找异常运行程序、揪出恶意父子进程调用关系,以及提取黑客在终端敲下的每一行命令。

1. 进程全景扫描

  • Vol2 查看基础运行进程: vol.py -f mem.raw --profile=Linux_Profile linux_pslist
  • Vol3 查看基础运行进程: vol3.py -f 1.mem linux.pslist
  • Vol3 查看进程树(含父子层级关系): vol3.py -f 1.mem linux.pstree
  • Vol3 深度扫描进程(寻找隐藏或已结束的残存进程): vol3.py -f 1.mem linux.psscan

2. 命令行与参数提取

  • Vol2 提取 Bash 历史命令记录: vol.py -f mem.raw --profile=Linux_Profile linux_bash
  • Vol3 提取 Bash 历史命令记录: vol3.py -f 1.mem linux.bash
  • Vol2 查看正在运行的进程及启动参数: vol.py -f mem.raw --profile=Linux_Profile linux_psaux
  • Vol3 列出进程附带的命令行参数: vol3.py -f 1.mem linux.psaux

文件系统与内存映射榨取

从错综复杂的内存块中精准定位被删除的配置文件、恶意脚本或被打包准备外传的压缩包。

1. 文件与挂载全局扫描

  • Vol2 查看挂载了哪些文件系统: vol.py -f mem.raw --profile=Linux_Profile linux_mount
  • Vol3 列出进程挂载点信息: vol3.py -f 1.mem linux.mountinfo
  • Vol2 快速定位桌面文件: vol.py -f 1.mem --profile=Linux_Profile linux_find_file -L | grep "Desktop"

2. 文件句柄与内存映射定位

  • Vol2 查看进程当前打开的文件: vol.py -f mem.raw --profile=Linux_Profile linux_lsof
  • Vol3 列出进程的所有内存映射: vol3.py -f 1.mem linux.lsof (或使用 linux.proc.Maps
  • Vol3 列出进程映射的所有 ELF 可执行文件/库: vol3.py -f 1.mem linux.elfs

3. 文件物理提取与恢复

  • Vol2 提取指定 inode 的文件: vol.py -f 1.mem --profile=Linux_Profile linux_find_file -i 0xffff9ce28fe300e8 -O
  • Vol2 完整恢复系统文件目录结构: sudo python2 ~/vol.py -f mem.raw --profile=Linux_Profile linux_recover_filesystem --dump-dir=./

网络连接与环境变量排查

还原后门 C2 连接特征,并从环境变量中挖掘隐藏的越权线索和密钥 Token。

1. 网络状态分析

  • Vol2 查看网络连接状态与端口: vol.py -f mem.raw --profile=Linux_Profile linux_netstat
  • Vol3 查看底层网络套接字连接: vol3.py -f 1.mem linux.sockstat

2. 环境变量与权限审查

  • Vol3 列出进程的环境变量(常用于查 Token/凭证): vol3.py -f 1.mem linux.envvars
  • Vol3 列出进程权限与能力 (Capabilities): vol3.py -f 1.mem linux.capabilities
  • Vol3 检查是否存在凭证共享(提权行为特征): vol3.py -f 1.mem linux.check_creds

恶意软件、Rootkit 检测与高级分析

针对内核级 Rootkit、挂钩 (Hook) 隐藏、无文件注入等 Linux 高级对抗手段的深层挖掘(注:底层 Hook 检测通常 Vol3 表现更优异且全面)。

1. 内核模块与注入代码排查

  • Vol2 查看已加载的内核模块: vol.py -f mem.raw --profile=Linux_Profile linux_lsmod
  • Vol2 查看被隐藏的内核模块: vol.py -f mem.raw --profile=Linux_Profile linux_hidden_modules
  • Vol3 检查隐藏内核模块(通过比对 sysfs): vol3.py -f 1.mem linux.check_modules
  • Vol2/Vol3 扫描可疑进程与注入代码: vol.py -f mem.raw --profile=Linux_Profile linux_malfind (两者命令结构类似,均为寻找无文件恶意代码块的利器)。

2. 底层 Hook 与劫持检测

  • Vol3 检查系统调用表 (sys_call_table) 是否被 Hook: vol3.py -f 1.mem linux.check_syscall
  • Vol3 检查 IDT (中断描述符表) 篡改: vol3.py -f 1.mem linux.check_idt
  • Vol3 检查网络协议栈指针篡改: vol3.py -f 1.mem linux.check_afinfo
  • Vol3 检查键盘记录器 (探测键盘通知链): vol3.py -f 1.mem linux.keyboard_notifiers
  • Vol3 检查 TTY 终端设备是否被窃听: vol3.py -f 1.mem linux.tty_check

特殊取证场景与疑难处置技巧

常规套路走不通时的底层调试、日志分析与暴力破解。

1. 系统日志与加密恢复

  • Vol3 读取内核环形缓冲区日志: vol3.py -f 1.mem linux.kmsg(极重要技巧!相当于提取了系统运行时的 dmesg 输出,常能发现内核报错、恶意驱动加载的蛛丝马迹)。
  • Vol2 恢复 Truecrypt 密钥: vol.py -f mem.raw --profile=Linux_Profile linux_truecrypt_passphrase(需配合 yara 模块使用)。

2. 终极兵器:Volshell 底层交互分析

  • 启动交互式 Shell: vol.py -f mem.raw --profile=Linux_Profile linux_volshell -v
  • 疑难处置策略: 当常规插件因为内核版本细微差异报错,或者遇到非标准 CTF 魔改题目时,直接进入 Volshell。使用 ps() 罗列进程,proc() 抓取当前进程上下文;利用 db()dd()dq() 直接读取十六进制内存数据;使用 dis(address) 对可疑内存段强行反汇编;或通过 dt(object) 根据 C 语言结构体模板强行解析内存块。此方法相当于直接给静止的内存镜像挂上了 GDB 调试器,是安全研究员的终极手段。