3. 污点追踪基础:什么是污点、污点源、污点传播规则、污点汇聚点

好,咱们今天聊点实在的。

污点追踪,英文叫 Taint Tracking。这玩意儿说白了,就是给数据贴标签。你想想看,在逆向分析的时候,我们最关心什么?无非就是「用户输入的数据,到底流到哪里去了」。用户输入的数据,我们称之为「脏数据」,也就是污点。

3.1 什么是污点

污点,英文叫 Taint。它不是一个物理概念,而是一个逻辑标记。

我习惯把污点理解成「数据上的一个记号」。就像你在快递盒上贴了个「易碎品」标签,系统会一直盯着这个盒子,看它被搬到了哪里、被谁签收了。

在程序里,污点就是某个内存地址或寄存器上的一个标记。这个标记告诉我们:「嘿,这数据来自外部,不可信!」

核心定义:污点 = 数据 + 标记。标记本身不改变数据值,只改变我们对数据的信任度。

举个例子。假设用户输入了一个字符串 "admin' OR 1=1--"。这个字符串本身只是一串字符,但一旦我们给它打上污点标记,系统就会知道:「这玩意儿可能是个 SQL 注入 payload,得盯着它。」

3.2 污点源

污点源,就是污点从哪里来。说白了,就是程序从外部接收数据的所有入口。

常见的污点源有哪些?我列一下:

  • 网络输入:recv()、read()、getsockopt() 等函数接收的数据
  • 文件输入:fread()、fgets()、mmap() 读取的文件内容
  • 用户输入:scanf()、getchar()、命令行参数 argv
  • 环境变量:getenv() 获取的环境变量值
  • 进程间通信:管道、共享内存、消息队列中的数据

我在项目中遇到过最坑的一次,是某个程序从环境变量里读取了数据库密码。当时我们只标记了网络输入,完全没注意到环境变量这个入口。结果呢?攻击者通过修改环境变量,直接绕过了我们的检测。嗯,从那以后,我每次做污点分析,都会先列一个完整的污点源清单。

我的建议:做污点分析时,先把程序的所有外部输入接口列出来。别漏了。漏一个,可能就漏了一个漏洞。

3.3 污点传播规则

污点传播规则,就是污点怎么在程序里「传染」。

你想想看,如果用户输入了一个污点数据,然后程序把这个数据赋值给另一个变量,那另一个变量是不是也该变成污点?没错,这就是传播。

传播规则一般分两种:

  1. 显式传播:数据直接赋值、拷贝、运算。比如 a = b,如果 b 是污点,那 a 也是污点。
  2. 隐式传播:通过控制流间接影响。比如 if (tainted_data) { x = 1; } else { x = 2; },虽然 x 没有被直接赋值污点数据,但它的值受污点数据控制。这种传播更隐蔽,也更难追踪。

我个人的习惯是,先做显式传播,再做隐式传播。因为隐式传播的误报率太高了,搞不好整个程序都变成污点了。

来看个简单的代码示例:

// 污点源:用户输入
char *user_input = get_user_input();  // user_input 被标记为污点

// 显式传播
char *buffer = user_input;  // buffer 也被标记为污点

// 运算传播
int len = strlen(user_input);  // len 也被标记为污点

// 隐式传播
if (user_input[0] == 'A') {
    char *msg = "Starts with A";  // msg 是否被标记?看规则怎么定
}

这里要注意,隐式传播的规则不同工具实现不一样。有的工具会标记 msg,有的不会。我个人倾向于不标记,因为误报太多。

我曾经踩过的坑:有一次我开启了隐式传播,结果整个程序的变量几乎全被标记了。分析结果完全没法用。后来我学乖了,先关掉隐式传播,等找到可疑路径再手动分析。

3.4 污点汇聚点

污点汇聚点,英文叫 Sink。就是污点数据最终到达的地方,也是我们最关心的位置。

为什么关心汇聚点?因为污点数据到了这些地方,就可能触发漏洞。

常见的汇聚点包括:

汇聚点类型 典型函数 可能触发的漏洞
内存操作 memcpy()、strcpy()、sprintf() 缓冲区溢出
命令执行 system()、exec()、popen() 命令注入
SQL 查询 mysql_query()、sqlite3_exec() SQL 注入
文件操作 fwrite()、fputs()、write() 文件写入漏洞
跳转指令 jmp、call、ret 控制流劫持

说白了,污点追踪就是回答一个问题:「从污点源到污点汇聚点,有没有一条路径?」如果有,那这条路径就可能是一个漏洞。

3.5 知识体系总览

下面这张图,是我自己总结的污点追踪核心逻辑。你看一眼,基本就明白整个体系了。

污点追踪核心逻辑 污点源 网络/文件/用户输入 污点传播规则 显式传播 + 隐式传播 污点汇聚点 内存/命令/SQL/文件 分析流程 1. 识别所有污点源(外部输入接口) 2. 定义传播规则(显式/隐式) 3. 标记所有汇聚点(危险函数/指令) 4. 追踪污点从源到汇聚点的路径 输出:污点路径 → 潜在漏洞

这张图其实就讲了三件事:污点从哪里来(源),怎么走(传播),到哪里去(汇聚点)。你把这个逻辑理清了,污点追踪就算入门了。

一个小技巧:刚开始做污点分析时,别贪多。先盯住一个污点源,一个汇聚点,把路径跑通。跑通了,再扩展。我当年就是这么一步步来的。

好了,污点追踪的基础概念就这些。说白了,就是给数据贴标签、看它怎么跑、最后到哪去。下一节我们会聊具体的工具实现,到时候拿实际代码来演示,你会更有感觉。


公众号:蓝海资料掘金营,微信deep3321