codeql测试fastjson
codeql测试fastjson
前言
首先要清楚,fastjson的利用链主要集中在getter和setter方法中,如果getter或者setter的方法中存在一些危险操作,比如JNDI查询之类的调用的话,如果参数可控就可以导致JNDI注入,而且fastjson的防御方式为黑名单,所以会层出不穷fastjson的绕过gadgets
鉴于fastjson的漏洞原理较为简单,且source(用户输入的源头)和sink(危险的函数)较为明确,所以可以使用codeql对一些常见的库进行fastjson利用链的挖掘
定义入口点(source)
fastjson的source相对比较好定义,所有fastjson的入口函数都是getter和setter这些函数,所以对应的source就为这些getter和setter,在codeql查询中,其实相当于将所有的函数按照用户所需要的过滤规则拿出来,所以我们只需要定义过滤的规则
对于getter和setter的规则,这里其实并不是一定要有对应的属性,只要前三个字母开头是get,并且第四个字母大写即可
getter的规则:
- 以get开头
- 没有函数参数
- 是 code database 中的函数
- 为 public方法
- 函数名长度要大于3
setter的规则:
- 以set开头
- 函数参数为一个
- 是 code database 中的函数
- 为public方法
- 函数名长度大于3
- 返回值为
void
所以我们可以根据这几个规则写出对应的source
,转换为ql
语句为:
1 | class FastjsonSetMethod extends Method{ |
定义危险函数
这里危险函数不仅仅是JNDI注入的函数,也可以是DNS查询之类的函数
JNDI
函数的规则:
- 这个函数名为
lookup
- 这个函数所在的类实现了”javax.naming.Context”接口
使用ql语言,描述为
1 | class JNDIMethod extends Method{ |
确定搜索方法(sink)
因为在fastjson中,有两个输入点,一个是get方法所在类的属性,一个是在fastjson触发的时候所传入的参数,为了方便起见,没有定义确定的source,一般来说能满足get方法最后到lookup的类相对较少,所以可以在查询结束以后再人工进行一次确认
这里没有用fastjson的全局的污点追踪,而是直接通过语法结构查找对应的利用链
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 h0ld1rs的博客!
评论