这是一篇笔记来自于我对论文的阅读:
《二进制比较与反二进制比较 ——对抗1day和0day》
代码相似度比较方法:
目的是获取漏洞所在点,研究某种类型壳程序的共同点。
- 通过符号文件区分函数,在此基础上进行计算校验值,不同级别使用不同的项目组合:寄存器,块地址,操作数,opcode指令等等。
- 节点数,边界数以及调用数作为特征生成签名。
- 基于函数call graph的同构比较。
- 基于同构,指令图形的同形匹配。
- 可执行文件的比较。
- 忽略内存地址和立即数
- 克服顺序依赖:判断指令间依赖关系,后按升序排列。互相依赖的指令为此原有顺序。用来防止优化指令序列带来的烦恼。
- 减少哈希碰撞:短的基本块或删除或与下个基本块关联。
- ……
反二进制比较
给用户安装补丁以抵御攻击争取更多时间。
- 改变符号:对函数名称的改变将使众多依赖符号的比较工具失效。
- 扰乱指令顺序
- 扰乱CFG:类似Bindiff工具依赖于每个函数的CFG签名。增加假的节点,边界或者调用来改变CFG,可以完全破坏CFG签名。eg:增加从来不会我执行的分支。也会影响同构分析。
- proxy调用:破坏CG,类如:call xxx外面包上一层空函数。当然可以在其中增加无用代码来避免反编译工具对空函数的识别。
- 调用不返回:本来是jz A,现在改成 call B {add esp,4 jzA}从来不返回的调用来破坏CFG达到阻碍基本块的分析。
- 共享基本块:类似于优化代码,此外当这个基本块有返回指令时,将会使得匹配非常困难。
- 同一个函数使用多个头:要使假的入口更难识别,构造基本块去调用假入口是个好主意。
以上的部分措施对代码的混淆并不会造成性能下降或者调试困难。用来隐藏补丁所在点的战斗不会停歇,拭目以待吧。
2016年10月14日星期五 1:56