@V1ll4n
在《编译拾遗(一)》中,我们介绍了基本的静态代码行为分析的思路。在文章中抛出了很多很有难度的技术话题,得到了很多用户比较正面的反馈。在和用户读者交流的过程中,“污点追踪”这个词被反复提及,包括我们团队内部的技术同学在 PoC 的时候,也编写了一个“Demo”去实现“污点追踪”的效果。
| 污点追踪:关注的是指定的“污点”数据从输入源流动到程序中可能危险的操作中的路径。在安全领域,污点追踪主要用于潜在的安全漏洞,如数据泄露或者注入攻击。 |
注意:污点分析是只有“安全领域”的概念,实际在编译领域并没有一个叫污点分析的概念。与之对应的过程应该叫“数据流分析”或者“变量支配分析”。
| 甚至特别有意思的是,做安全的同学大多数并不了解“污点分析”背后的基本计算机科学逻辑,很多安全领域的论文都把它当成研究课题,这其实是不合适的。 |
基本概念
我们使用一段伪代码来描述污点追踪的问题和挑战:
| JavaScript |
这段代码非常简单,那么我们总结一下这个过程:

要对这一段代码进行分析,需要思考如下几个问题:
- 上面的代码是伪代码,那么不完整代码如何分析行为?
- 函数过程间分析,我们应该怎么实现函数跳转?过程间分析带来的挑战有哪些?
- IF 如何处理?每个分支都要步入吗?
- 输入从 file.ReadFile 中读取,那么我们应该从 ReadFile 开始分析吗?
在本篇文章中,我们尝试会对上面几个问题都有一个明确的解答,大家可以认真阅读,最后思考一下看看和自己想象的静态行为分析到底有没有差别。
从污点分析的角度看,这里存在两个重要概念:源(Source)和汇(Sink)。源是指数据可进入的地方,这里,源是 "ReadFile" 函数,用于读取外部用户可能控制的数据。汇,是指数据可以影响的地方,在这段代码中是 "System" 函数,它执行 bash 命令。
我们可以看到源(Source)是 ReadFile("test.txt"),这个读取的文件内容被赋值给了 s,然后 s 被传递给函数 w,最后作为命令参数在 System 这个汇(Sink)里执行。所以从源到汇形成了一个可能的污点传播路径。
污点追踪的“最大缺陷”
当我们明白了基本概念之后,本节内容将指出“污点追踪”这种思考逻辑的一个缺陷:思维方向固定是从 ReadFile(),但是我们有时候不能去观察所有的文件 IO 部分。如果读取了一个文件,并在内存中处理的链路非常长,那么分析过程将会无比痛苦。
很多时候,作为一个“人”,我们的思维实际上并不是“污点追踪”,而是“逆向污点追踪”,人去搜索源码,搜索到所有执行命令的地方,然后观察执行命令的地方在哪儿被使用了,一层一层向上追踪,观察输入的部分能不能控制执行命令。我们惊奇的发现,大多数人居然更愿意接受“逆向污点追踪”思考方式,毕竟面

本文探讨了污点追踪在安全领域的应用,澄清了污点分析与数据流分析的区别,并通过JavaScript代码示例展示了过程间分析的挑战和如何通过IR进行有效分析。文章强调了逆向污点追踪在复杂代码中的实用价值和编译视角下的正逆向追踪策略。
最低0.47元/天 解锁文章
1万+

被折叠的 条评论
为什么被折叠?



