hw结束以后就花了12天左右去一个写java静态分析审计kit,结果完成的不咋地,把当时的思路想法分享一下,大家感兴趣的可以看看,集思广益。思路碰撞
工具产生动机:之前分析泛微oa漏洞,发现一些漏洞成因以及相关的危险函数都是一模一样,但是每次公布出来的漏洞url都是一小部分。这种大型项目开发流程并不规范,漏洞很多。但是因为代码量太大,审计过程中就容易忽略。所以想写一个工具出来,防止遗漏某些存在同样漏洞的接口,顺便捡漏(通过历史漏洞危险函数去捡漏)。
我的思路:
1。确定漏洞函数(通过自己分析,或者历史漏洞函数),
2。通过路由确定路由start函数
3。找到调用链路。如果能确定存在这样一条程序调用流是:从start函数-》……-》漏洞函数target,就基本上一定几率确定它存在漏洞啦可以继续分析。这个跟source->flow->sink没有什么区别,我简化表述。
思路的不足以及误区:
-
漏洞成因不同:有些漏洞是传参方式不同引起的,顺着刚刚静态分析思路去排查,可能并不会到漏洞函数那里去。以及存在参数类型太复杂的情况
-
java语法本身的复杂性,多态,继承这些特性也是够喝一壶的。
工具能实现效果:
-
1: 历史漏洞复现分析。【输入入口函数以及危险函数直接打印从入口函数到危险函数的调用过程。】
-
2:寻找历史漏洞漏网之鱼
-
3:发现新漏洞
实现过程:
-
1.使用静态java分析类库去获取项目中java文件相关信息(感谢novy师傅给我一个tip),比如javaparse去解析一个java项目,可以得到每个java文件的所有信息(包名,类名,类中方法名,参数名称,方法调用……)
-
2.存储解析后java文件信息(可以使用程序缓存,文件,数据库等等进行存储)
-
3.通过搜索找到从start函数-》target危险函数调用
搜索思路:
-
正向:根据start函数找到start函数所在的文件,根据之前存储的信息找到start函数内部的函数调用,跟进遍历函数调用递归直到函数结束或者找到target危险函数。
-
逆向:先找到target危险函数涉及的调用(直接调用和各种间接调用)然后从start函数找到这些调用的调用过程。
实现过程中的问题:
-
1.数据量大,以何种方式存储和搜索都需要进一步思考和优化。上面思路过于粗暴导致程序过慢。这是静态分析弊端(我当时还打算写一个动态分析),中型java项目中涉及的类,方法都成百上千更不要说大型项目啦,就算及时全部存储成功,搜索起来也是非常庞大的数据量。
-
2.很多项目使用Maven引用很多第三方jar包,就要么把所有jar反编译以后再分析,或者直接分析jar两个选择,这两种思路都需要你利用一些类库或者第三方工具进行转换。一个jar包调用另一个jar包,存储的数据量也是庞大的。调用过程也比较复杂
-
3.javaparse/其他同样功能的库 不能获取它没有解析过的文件中的方法或者类名。就是它当前正在解析的java文件可能引用其他java文件中的类/方法,当我让它在当前文件中获取这个类相关信息,它就会报错啦,这个时候你需要使用其他工具asm,spoon等它们不会报错
-
4.搜索寻找的过程中,一个函数内部有很多函数调用,因此可以需要根据项目需要进行排除一些不必要的package如javax log exception等,减少搜索次数以及递归次数
优点:看起来思路简单☠
其他可以代替工具
-
codeql :大部分项目还是可以使用的,直接编译完成形成数据库以后以后使用query.ql就可以查询成功。但是有的项目使用它提供的语法找不到对应的类(可能和项目结构有关系吧)。需要进一步处理以及学习语法
-
iast:一种动态分析工具
-
github其他开源项目:好像之前有师傅写过一些这种数据流分析工具。后续有空会去学习一下。
Final:
工具是工具,可以简化一定工作量,但是必要的分析工作还是不可缺少的。好工具和个人能力都不可缺少。
原文始发于微信公众号(天才少女Alpha):代码审计工具编写
- 左青龙
- 微信扫一扫
-
- 右白虎
- 微信扫一扫
-
评论