研究方向: 二进制安全、文件格式解析、内存漏洞、漏洞分析、Fuzzing
实验环境: Kali Linux、GCC、GDB、AddressSanitizer、FFmpeg、AFL++
适用对象: Linux 安全研究、漏洞挖掘、逆向分析学习者
实验原则: 使用自编的教学解析器研究内存错误,不运行未知恶意样本。
一、媒体文件为什么能够触发恶意代码执行?
1.1 核心原理
正常情况下,图片、视频、音频只是二进制数据,不具备直接执行代码的能力。
常见媒体文件包括:
- 图片:JPG、PNG、GIF、WebP
- 视频:MP4、AVI、MKV、MOV
- 音频:MP3、AAC、FLAC、WAV
但是,打开这些文件时,操作系统或应用程序必须解析文件内容。
例如:
用户打开 image.jpg
|
v
图片查看器读取文件
|
v
调用图片解析库
|
v
解析文件头、尺寸、元数据
|
v
解码压缩数据
|
v
分配内存并写入像素
|
v
显示图片
如果解析库存在漏洞,攻击者可以构造特殊文件触发异常内存操作。
攻击过程:
攻击者
|
| 构造特殊媒体文件
v
malicious.jpg / malicious.mp4 / malicious.mp3
|
| 用户打开或软件自动预览
v
存在漏洞的媒体解析器
|
| 处理异常长度、索引、压缩数据
v
内存安全漏洞
|
+----> 程序崩溃
|
+----> 内存信息泄露
|
+----> 内存破坏
|
v
满足特定利用条件
|
v
潜在的代码执行
核心结论:恶意文件本身通常不是执行主体,真正执行代码的是存在漏洞的解析程序。
1.2 常见攻击技术
| 技术 | 原理 | 是否能直接触发代码执行 |
|---|---|---|
| Buffer Overflow | 缓冲区越界写入 | 特定条件下可以 |
| Integer Overflow | 整数运算溢出 | 通常需要进一步触发内存错误 |
| Out-of-Bounds Read | 越界读取 | 通常导致崩溃或信息泄露 |
| Use-After-Free | 释放后继续访问内存 | 特定条件下可以 |
| Type Confusion | 错误解释对象类型 | 特定条件下可以 |
| 文件隐写 | 将数据隐藏在媒体内容中 | 通常不能独立执行 |
| Polyglot File | 同一文件满足多种格式结构 | 取决于解析器和执行环境 |
| 文件伪装 | 将可执行程序伪装成媒体文件 | 通常需要用户实际执行程序 |
需要特别区分:
将木马隐藏在图片中,不等于打开图片就能执行木马。
隐写技术通常还需要额外的加载器提取并运行隐藏的数据。
二、Linux 进程内存模型
2.1 进程虚拟地址空间
Linux 程序运行时,操作系统会为进程提供虚拟地址空间。
典型结构如下:
高地址
+-----------------------------+
| Stack(栈) |
| |
| 局部变量 |
| 函数调用栈帧 |
| 返回地址 |
+-----------------------------+
| |
| Memory Mapping |
| |
| 共享库 |
| 文件映射 |
| 匿名映射 |
+-----------------------------+
| |
| Heap(堆) |
| |
| malloc() |
| calloc() |
| new |
+-----------------------------+
| BSS |
| 未初始化全局变量 |
+-----------------------------+
| Data |
| 已初始化全局变量 |
+-----------------------------+
| Text |
| 程序机器指令 |
+-----------------------------+
低地址
注意:这是概念示意图,实际布局会受到操作系统、CPU 架构、ASLR 和程序链接方式影响。
2.2 Stack:栈内存
栈通常用于保存:
- 函数局部变量
- 函数调用状态
- 部分函数参数
- 返回地址
- 临时数据
例如:
void parse_image()
{
char buffer[16];
}
buffer 通常位于函数的栈帧中。
如果程序向其中写入超过 16 字节的数据,就可能发生栈缓冲区溢出。
合法栈缓冲区:
+----+----+----+----+
| A | A | A | A |
+----+----+----+----+
16 Bytes
越界写入:
+-------------------+------------------+
| 合法的 16 字节 | 超出边界的数据 |
+-------------------+------------------+
^
|
内存越界
越界写入可能破坏相邻局部变量或其他栈数据。
某些情况下,关键调用控制数据也可能受到影响,但并非所有栈溢出都能够覆盖返回地址。
2.3 Heap:堆内存
堆用于动态分配内存。
例如:
unsigned char *pixels = malloc(64);
程序申请了 64 字节。
合法访问范围:
pixels[0] ~ pixels[63]
如果执行:
pixels[80] = 0x41;
就发生越界写入。
这种行为可能破坏其他堆对象或内存管理状态。
2.4 CPU 寄存器与程序执行
在 x86-64 架构中:
| 寄存器 | 作用 |
|---|---|
| RIP | 指令指针 |
| RSP | 栈指针 |
| RBP | 常用于栈帧管理 |
| RAX | 通用寄存器 |
| RDI | 通用寄存器,常用于传递参数 |
| RSI | 通用寄存器,常用于传递参数 |
在 ARM64 架构中:
| 寄存器 | 作用 |
|---|---|
| PC | 程序计数器 |
| SP | 栈指针 |
| X0–X7 | 常用于参数传递 |
| X29 | 帧指针 |
| X30 | 链接寄存器 |
正常情况下,CPU 按照程序控制流执行指令。
如果内存破坏影响了程序使用的函数指针、返回地址或其他控制数据,就可能出现控制流劫持。
但是,现代操作系统通常有 ASLR、NX/DEP、Stack Canary、CFI、沙箱等保护措施。
因此:
缓冲区溢出 ≠ 一定能够执行任意代码。
三、图片文件触发漏洞的原理
3.1 JPEG 文件结构
JPEG 通常包含:
JPEG File
|
+-- SOI
| 文件起始标记
|
+-- APP0 / APP1
| JFIF / EXIF 等信息
|
+-- DQT
| 量化表
|
+-- DHT
| 霍夫曼编码表
|
+-- SOF
| 图像尺寸与编码参数
|
+-- SOS
| 扫描开始
|
+-- Compressed Image Data
| 压缩图像数据
|
+-- EOI
文件结束标记
图片解析器需要处理:
- 文件头。
- 图像尺寸。
- 元数据。
- 压缩参数。
- 像素缓冲区。
- 解码结果。
如果长度计算、内存分配或解码过程存在错误,就可能触发漏洞。
3.2 PNG 文件结构
PNG 文件通常由多个 Chunk 组成。
PNG Signature
|
v
IHDR
|
v
IDAT
|
v
IEND
常规 Chunk 结构:
+-------------------------+
| Length 4 Bytes |
+-------------------------+
| Type 4 Bytes |
+-------------------------+
| Data N Bytes |
+-------------------------+
| CRC 4 Bytes |
+-------------------------+
如果解析器没有正确验证 Length,可能发生:
- 越界读取
- 整数溢出
- 错误的内存分配
- 缓冲区溢出
3.3 图片尺寸整数溢出
假设 RGBA 图片每个像素需要 4 字节。
所需内存:
MemorySize = Width × Height × 4
错误代码:
uint32_t width = get_width();
uint32_t height = get_height();
uint32_t size = width * height * 4;
unsigned char *pixels = malloc(size);
问题在于:
uint32_t 最大值为:
4294967295
如果计算结果超过该范围,就会发生无符号整数回绕。
例如:
Width = 65536
Height = 65536
实际计算:
65536 × 65536 × 4
= 17179869184
在 32 位无符号整数中:
17179869184 % 4294967296 = 0
如果程序分配的内存小于后续实际写入量,就可能产生堆缓冲区溢出。
这只是漏洞原理示例,真实图片格式通常还会对尺寸和其他字段施加限制。
3.4 真实案例:CVE-2023-4863
漏洞名称:
libwebp Heap Buffer Overflow
披露时间:2023 年。
漏洞涉及 WebP 无损图像解码中的霍夫曼解码表构建。
简化流程:
特殊构造的 WebP 文件
|
v
libwebp 解码
|
v
霍夫曼解码表处理
|
v
内存边界处理错误
|
v
Heap Buffer Overflow
|
v
潜在的代码执行
这个漏洞影响多个使用存在漏洞的 libwebp 版本的软件,并有真实攻击利用记录。
参考:
https://nvd.nist.gov/vuln/detail/CVE-2023-4863
3.5 真实案例:FORCEDENTRY
漏洞编号:
CVE-2021-30860
攻击目标涉及 Apple iMessage 的附件处理流程。
攻击者发送看似 GIF、实际包含 PDF 数据的附件。
PDF 内部使用 JBIG2 图像压缩结构。
攻击流程:
攻击者发送附件
|
v
iMessage 自动处理
|
v
CoreGraphics 解析 PDF/JBIG2
|
v
整数溢出
|
v
堆内存破坏
|
v
构造复杂计算能力
|
v
进一步实现攻击
该案例的特殊之处在于 JBIG2 Weird Machine。
攻击者利用 JBIG2 的位操作能力,构造出类似逻辑电路的计算结构。
这说明:图像处理操作在特定漏洞条件下,也可能被组合成非预期的计算机制。
参考:
https://projectzero.google/2021/12/a-deep-dive-into-nso-zero-click.html
四、视频文件触发漏洞的原理
4.1 MP4 是容器,不是编码格式
MP4 文件可以包含:
- H.264 视频
- H.265 视频
- AAC 音频
- 字幕
- 时间戳
- 元数据
典型结构:
movie.mp4
|
+-- ftyp
| 文件类型
|
+-- moov
| 影片元数据
| |
| +-- mvhd
| |
| +-- trak
| |
| +-- mdia
| |
| +-- minf
| |
| +-- stbl
|
+-- mdat
|
+-- 视频编码数据
|
+-- 音频编码数据
播放器通常先通过 Demuxer 解析容器,再通过 Decoder 解码音视频数据。
4.2 MP4 Box 长度解析漏洞
普通 MP4 Box 头部通常包含:
4 Bytes: size
4 Bytes: type
错误代码:
uint32_t size = read_be32(data);
uint32_t payload_size = size - 8;
如果:
size = 4
那么:
4 - 8
在 32 位无符号整数中会得到:
4294967292
这种情况称为整数下溢或无符号整数回绕。
如果后续程序错误使用该值,就可能造成:
- 资源耗尽
- 异常内存分配
- 越界读取
- 越界写入
需要注意,MP4 还支持扩展长度和特殊长度值,真实解析器必须按格式规范处理。
4.3 H.264/H.265 解码漏洞
视频解码器需要处理:
- I 帧
- P 帧
- B 帧
- 运动矢量
- 参考帧
- 图像块
- 熵编码
- 像素重建
例如:
uint8_t pixel = reference_frame[y * stride + x];
如果 x、y、stride 或缓冲区范围验证错误,可能出现越界访问。
真实漏洞还可能涉及参考帧生命周期、对象释放、数组索引及复杂的状态管理。
4.4 真实案例:Stagefright
2015 年,Android 媒体框架 Stagefright 被发现存在一系列严重漏洞。
其中:
CVE-2015-1538
涉及 MP4 Atom 解析中的整数溢出问题。
部分攻击场景可以通过 MMS 媒体处理触发,不一定需要用户主动播放视频。
简化流程:
恶意媒体内容
|
v
Android 媒体框架
|
v
MP4 Atom 解析
|
v
整数溢出
|
v
内存破坏
|
v
潜在的远程代码执行
参考:
https://source.android.com/docs/security/bulletin/2015-08-01
五、音频文件触发漏洞的原理
5.1 MP3 文件结构
典型 MP3 文件可能包含:
music.mp3
|
+-- ID3v2
| |
| +-- 歌曲名称
| +-- 艺术家
| +-- 专辑
| +-- 封面图片
|
+-- MPEG Audio Frame 1
|
+-- MPEG Audio Frame 2
|
+-- MPEG Audio Frame 3
|
+-- ...
|
+-- 可选尾部标签
MP3 解码器需要处理:
- 帧头
- 比特率
- 采样率
- Huffman 编码
- Side Information
- Bit Reservoir
- 音频样本重建
如果实现存在边界检查错误,就可能发生内存安全问题。
5.2 ID3 元数据解析漏洞
例如,解析器使用固定长度数组保存歌曲标题:
char title[64];
memcpy(title, tag_data, tag_length);
如果 tag_length 超过 64,可能导致栈缓冲区溢出。
攻击者不一定需要修改实际的 MP3 音频数据,也可能利用元数据解析过程中的漏洞。
5.3 音频缓冲区整数溢出
音频解码器可能需要计算 PCM 缓冲区大小:
BufferSize =
Samples × Channels × BytesPerSample
如果乘法发生整数溢出,可能分配不足的内存。
后续写入音频样本时,就可能发生堆缓冲区溢出。
5.4 专辑封面攻击面
MP3 可以嵌入专辑封面。
例如:
MP3 文件
|
v
ID3 元数据
|
v
APIC 封面字段
|
v
JPEG / PNG 图片
|
v
图片解码器
因此,播放 MP3 时发生的漏洞,不一定来自 MP3 解码器,也可能来自封面图片解析组件。
六、从内存破坏到代码执行的完整过程
6.1 攻击链条
第一阶段:输入控制
攻击者构造特殊媒体数据
|
v
第二阶段:触发漏洞
解析器发生越界访问
|
v
第三阶段:内存破坏
对象、长度或控制数据受损
|
v
第四阶段:利用条件
攻击者需要满足特定内存布局、
控制能力及防护绕过条件
|
v
第五阶段:控制流异常
程序可能执行非预期路径
|
v
第六阶段:潜在代码执行
在成功利用时获得受影响进程
权限范围内的执行能力
6.2 为什么漏洞不一定能够执行代码?
现代系统存在多种防护机制。
| 防护技术 | 作用 |
|---|---|
| ASLR | 随机化内存地址 |
| NX / DEP | 防止普通数据页直接执行机器代码 |
| Stack Canary | 检测部分栈内存破坏 |
| CFI | 限制控制流跳转 |
| Sandbox | 限制进程访问系统资源 |
| ARM PAC | 保护部分指针完整性 |
因此:
程序崩溃
≠
控制流劫持
≠
任意代码执行
≠
获得系统最高权限
每一步都需要独立的技术证据。
七、Kali Linux 实验环境搭建
7.1 安装工具
sudo apt update
sudo apt install -y \
build-essential \
gcc \
clang \
gdb \
valgrind \
ffmpeg \
exiftool \
xxd \
file \
binutils \
afl++
检查:
gcc --version
clang --version
gdb --version
ffprobe -version
afl-fuzz -V
建议使用专用 Kali Linux 虚拟机,提前创建快照。
7.2 创建实验目录
mkdir -p ~/media-security-lab/{src,build,samples,reports}
cd ~/media-security-lab
目录:
media-security-lab/
|
+-- src/
| +-- image_parser.c
| +-- mp4_parser.c
| +-- audio_parser.c
| +-- fuzz_box.c
|
+-- build/
|
+-- samples/
|
+-- reports/
八、实验一:复现图片解析器堆缓冲区溢出
8.1 编写程序
nano src/image_parser.c
代码:
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
int main(void)
{
size_t buffer_size = 16;
uint8_t *pixels = malloc(buffer_size);
if (pixels == NULL) {
return 1;
}
uint8_t image_data[24];
memset(image_data, 0x41, sizeof(image_data));
// 故意缺少长度检查
memcpy(pixels, image_data, sizeof(image_data));
printf("Image decoding finished\n");
free(pixels);
return 0;
}
这是模拟图片解码器内存写入的教学程序,不是实际 JPEG 解码器。
8.2 编译
gcc -g -O0 \
-fsanitize=address \
-fno-omit-frame-pointer \
-o build/image_parser \
src/image_parser.c
8.3 运行
./build/image_parser
预期出现类似:
ERROR: AddressSanitizer: heap-buffer-overflow
WRITE of size 24
0x... is located 0 bytes after
16-byte region
8.4 原理分析
程序分配:
16 Bytes
实际写入:
24 Bytes
内存示意:
+----------------------+----------------+
| 合法的 16 字节 | 越界的 8 字节 |
+----------------------+----------------+
^
|
越界位置
AddressSanitizer 检测到了超出分配边界的写入。
8.5 GDB 分析
编译独立调试版本:
gcc -g -O0 \
-o build/image_parser_debug \
src/image_parser.c
启动:
gdb ./build/image_parser_debug
常用命令:
break main
run
next
info locals
print pixels
print buffer_size
x/16xb pixels
backtrace
由于存在未定义行为,未使用 Sanitizer 的程序可能崩溃,也可能看似正常运行。
九、实验二:复现 MP4 长度整数下溢
9.1 创建程序
nano src/mp4_parser.c
代码:
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
int main(void)
{
uint32_t box_size = 4;
uint32_t header_size = 8;
// 故意缺少最小长度检查
uint32_t payload_size = box_size - header_size;
printf("Box size: %" PRIu32 "\n", box_size);
printf("Header size: %" PRIu32 "\n", header_size);
printf("Payload size: %" PRIu32 "\n", payload_size);
return 0;
}
9.2 编译
gcc -g -O0 \
-o build/mp4_parser \
src/mp4_parser.c
9.3 运行
./build/mp4_parser
输出:
Box size: 4
Header size: 8
Payload size: 4294967292
9.4 原理
32 位无符号整数计算:
4 - 8
发生回绕:
4294967292
如果解析器后续错误使用这个长度,可能引发其他安全问题。
本实验只证明整数下溢,不代表已经发生内存破坏。
9.5 修复
if (box_size < header_size) {
fprintf(stderr, "Invalid MP4 box size\n");
return 1;
}
uint32_t payload_size = box_size - header_size;
十、实验三:复现音频元数据栈缓冲区溢出
10.1 创建程序
nano src/audio_parser.c
代码:
#include <stdio.h>
#include <stdint.h>
#include <string.h>
void parse_title(const uint8_t *data, size_t length)
{
char title[16];
// 故意缺少长度检查
memcpy(title, data, length);
printf("Audio title parsed\n");
}
int main(void)
{
uint8_t metadata[32];
memset(metadata, 'A', sizeof(metadata));
parse_title(metadata, sizeof(metadata));
return 0;
}
10.2 编译
gcc -g -O0 \
-fsanitize=address \
-fno-omit-frame-pointer \
-o build/audio_parser \
src/audio_parser.c
10.3 运行
./build/audio_parser
预期输出包含:
ERROR: AddressSanitizer: stack-buffer-overflow
WRITE of size 32
10.4 分析
目标缓冲区:
16 Bytes
实际复制:
32 Bytes
超出了合法栈数组范围。
10.5 修复
void parse_title(const uint8_t *data, size_t length)
{
char title[16];
if (length >= sizeof(title)) {
fprintf(stderr, "Audio title too long\n");
return;
}
memcpy(title, data, length);
title[length] = '\0';
printf("Title: %s\n", title);
}
十一、Kali Linux 分析真实媒体文件
注意:下面的工具也需要读取或解析文件。真正可疑的样本应在更新过软件的隔离虚拟机中分析,不要直接在主机上打开。
11.1 识别文件类型
file suspicious.jpg
file suspicious.mp4
file suspicious.mp3
作用:
识别文件内容特征,而不只是查看扩展名。
11.2 查看文件头
xxd -l 256 suspicious.jpg
xxd -l 256 suspicious.mp4
xxd -l 256 suspicious.mp3
常见特征:
| 格式 | 特征 |
|---|---|
| JPEG | FF D8 FF |
| PNG | 89 50 4E 47 0D 0A 1A 0A |
| WebP | RIFF,偏移 8 为 WEBP |
| MP4 | 常见为偏移 4 的 ftyp |
| MP3 | 可能以 ID3 或 MPEG 音频帧开始 |
文件头正常不代表文件安全。
11.3 查看图片元数据
exiftool suspicious.jpg
关注:
- 图像尺寸
- EXIF 元数据
- 文件格式
- 异常长度
- 不常见的标签
11.4 分析 MP4
ffprobe -v error \
-show_format \
-show_streams \
suspicious.mp4
查看视频信息:
ffprobe -v error \
-select_streams v:0 \
-show_entries stream=codec_name,width,height,pix_fmt \
-of json \
suspicious.mp4
查看音频信息:
ffprobe -v error \
-select_streams a \
-show_entries stream=codec_name,sample_rate,channels \
-of json \
suspicious.mp4
11.5 分析 MP3
exiftool suspicious.mp3
ffprobe -v error \
-show_format \
suspicious.mp3
重点关注:
- ID3 元数据
- 音频编码
- 音频时长
- 封面图片
- 文件格式是否一致
11.6 计算哈希
sha256sum suspicious.jpg
sha256sum suspicious.mp4
sha256sum suspicious.mp3
哈希可以用于样本识别和记录,但不能单独判断文件是否恶意。
十二、使用 GDB 分析崩溃
12.1 启动 GDB
gdb ./build/image_parser_debug
12.2 常用命令
| 命令 | 作用 |
|---|---|
run |
运行程序 |
break main |
在 main 设置断点 |
next |
单步执行,不进入函数 |
step |
单步进入函数 |
continue |
继续执行 |
backtrace |
查看调用栈 |
info registers |
查看寄存器 |
info locals |
查看局部变量 |
x/32xb 地址 |
查看 32 字节内存 |
disassemble |
查看反汇编 |
12.3 x86-64 与 ARM64 区别
x86-64:
info registers rip rsp rbp
ARM64:
info registers pc sp x29 x30
如果 Kali Linux 运行在 ARM64 设备或虚拟机中,应使用 ARM64 寄存器名称。
十三、使用 AFL++ 进行模糊测试
13.1 Fuzzing 原理
初始样本
|
v
AFL++ 变异输入
|
v
运行目标解析器
|
v
收集执行覆盖率
|
v
发现崩溃或超时
|
v
保存异常输入
|
v
GDB / Sanitizer 分析
13.2 创建测试解析器
nano src/fuzz_box.c
代码:
#include <stdio.h>
#include <stdint.h>
int main(int argc, char **argv)
{
if (argc != 2) {
return 1;
}
FILE *fp = fopen(argv[1], "rb");
if (!fp) {
return 1;
}
uint8_t header[8];
if (fread(header, 1, 8, fp) != 8) {
fclose(fp);
return 0;
}
fclose(fp);
uint32_t size =
((uint32_t)header[0] << 24) |
((uint32_t)header[1] << 16) |
((uint32_t)header[2] << 8) |
(uint32_t)header[3];
// 教学用异常触发点
if (size < 8) {
fprintf(stderr, "Invalid box size\n");
__builtin_trap();
}
printf("Payload size: %u\n", size - 8);
return 0;
}
这里使用 __builtin_trap() 人为触发异常,不是真实内存漏洞。
13.3 编译
afl-clang-fast \
-g -O1 \
-o build/fuzz_box \
src/fuzz_box.c
13.4 创建初始样本
mkdir -p samples/seed
python3 - <<'PY'
from pathlib import Path
Path("samples/seed/box.bin").write_bytes(
b"\x00\x00\x00\x08ftyp"
)
PY
13.5 启动 AFL++
afl-fuzz \
-i samples/seed \
-o reports/afl \
-- ./build/fuzz_box @@
AFL++ 会不断改变输入数据,寻找能够触发异常的测试样本。
13.6 查看崩溃样本
find reports/afl -type f -path '*/crashes/id:*'
查看样本:
xxd <样本路径>
使用 GDB:
gdb --args ./build/fuzz_box <样本路径>
执行:
run
backtrace
通过该实验可以学习:
- 输入变异。
- 执行覆盖率。
- 崩溃样本保存。
- 异常输入分析。
- 漏洞根因定位。
十四、如何判断媒体文件是否存在安全风险?
不能仅凭文件异常或播放器崩溃就判断存在可利用漏洞。
建议分为五个阶段。
阶段一:静态检查
文件类型
|
文件头
|
元数据
|
容器结构
|
编码信息
阶段二:隔离环境测试
在虚拟机中使用更新过的解析工具处理文件,记录异常行为。
阶段三:定位崩溃
使用:
- GDB
- AddressSanitizer
- Valgrind
确定程序出现异常的位置。
阶段四:分析漏洞根因
重点研究:
- 长度检查是否正确。
- 是否存在整数溢出。
- 是否发生越界访问。
- 是否存在对象生命周期错误。
- 是否错误信任文件中的偏移量。
阶段五:评估影响
区分:
文件格式异常
|
v
解析失败
|
v
程序崩溃
|
v
确认内存安全漏洞
|
v
评估可利用性
|
v
潜在代码执行
这些阶段不能简单画等号。
十五、媒体文件安全分析检查清单
文件基础信息
文件结构
内存安全
动态分析
漏洞结论
十六、推荐学习路线
第一阶段:C 语言与内存
学习:
- 指针
- 数组
- malloc/free
- Stack
- Heap
- 结构体
- 整数类型
- 大小端
目标:理解内存访问错误如何产生。
第二阶段:二进制文件格式
学习:
- JPEG
- PNG
- WebP
- MP4
- MP3
- WAV
目标:能够使用十六进制工具分析文件结构。
第三阶段:漏洞分析
学习:
- Buffer Overflow
- Integer Overflow
- Out-of-Bounds
- Use-After-Free
- Type Confusion
目标:能够定位简单的内存安全漏洞。
第四阶段:调试技术
学习:
- GDB
- AddressSanitizer
- Valgrind
- 反汇编
- 调用栈
- CPU 寄存器
目标:能够解释程序崩溃的原因。
第五阶段:Fuzzing
学习:
- AFL++
- libFuzzer
- 覆盖率
- 样本变异
- 崩溃去重
- 测试用例最小化
目标:能够对自编解析器进行自动化安全测试。
第六阶段:真实漏洞研究
重点案例:
- CVE-2023-4863:WebP 堆缓冲区溢出。
- CVE-2021-30860:FORCEDENTRY。
- CVE-2015-1538:Stagefright。
目标:能够阅读公开漏洞分析、理解补丁修改,并在隔离环境中验证已修复的缺陷。
十七、参考资料
真实漏洞
CVE-2023-4863
https://nvd.nist.gov/vuln/detail/CVE-2023-4863
FORCEDENTRY 技术分析
https://projectzero.google/2021/12/a-deep-dive-into-nso-zero-click.html
Android Stagefright 安全公告
https://source.android.com/docs/security/bulletin/2015-08-01
分析工具
FFmpeg / FFprobe
https://ffmpeg.org/documentation.html
GDB
https://www.sourceware.org/gdb/documentation/
AddressSanitizer
https://clang.llvm.org/docs/AddressSanitizer.html
AFL++
ExifTool
十八、最终总结
图片、视频、音频文件触发恶意代码执行的核心机制:
攻击者构造特殊媒体文件
|
v
用户打开文件或软件自动处理
|
v
媒体解析器读取不可信数据
|
v
长度、索引、内存分配等处理错误
|
v
触发内存安全漏洞
|
v
可能造成崩溃、信息泄露或内存破坏
|
v
在满足特定利用条件时
|
v
可能实现代码执行
必须掌握的五个核心知识点:
- 文件格式: 理解媒体文件的二进制结构,以及解析器如何读取文件。
- 内存模型: 理解 Stack、Heap、虚拟地址空间和 CPU 控制流。
- 漏洞原理: 掌握缓冲区溢出、整数溢出、越界访问等常见问题。
- 漏洞分析: 使用 GDB、AddressSanitizer、FFmpeg 等工具定位异常。
- 自动化测试: 使用 AFL++、libFuzzer 对解析器进行模糊测试。
最重要的结论:
图片、视频和音频文件通常不会自行执行恶意代码。攻击者利用的是处理这些文件的软件中的漏洞。媒体文件是输入载体,解析器是漏洞触发点,内存破坏是常见中间环节,而代码执行只是满足进一步利用条件后可能出现的结果。
理解这一完整过程,是学习文件解析漏洞、二进制安全、媒体解码器安全和漏洞挖掘的重要基础。
浙公网安备 33010602011771号