文章目录
- 对之前一道ctf赛题的污点分析
- GitHub Security Lab CTF 4: CodeQL and Chill - The Java Edition
- fastjson1.2.31 漏洞检测
CodeQL污点分析
最近一段时间在学习CodeQL,今天看大佬博客学习了检测fastjson漏洞的流程,感觉比较简单,于是就打算动手编写一个检测文件,顺便也把之前学到的内容串联一下。
要检测的是之前CTF的一道Java赛题,很简单,源文件就几行,不过却写了一小下午。
写完ql代码回头看,里边的内容之前都学过,真正写ql的时候就想不起来了,写完之后又和当初学的时候一样,感叹各位大佬各种思路。这也印证了实践出真知的道理。
源代码如下:
1 2 3 4 5 6 7 8
| @PostMapping({"/hello"}) public String index(@RequestBody String baseStr) throws Exception { System.out.println(baseStr); byte[] decode = Base64.getDecoder().decode(baseStr); ObjectInputStream ois = new SerialKiller(new ByteArrayInputStream(decode), "serialkiller.xml"); ois.readObject(); return "hello"; }
|
逻辑很简单,从路径/hello输入参数 -> Base64解码 -> SerialKiller过滤 -> readObject
那么就可以把source定为所有字段,这个字段可以instanceof官方的RemoteFlowSource,减少一下范围。sink就是readObject。
直接上代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
|
import java import semmle.code.java.dataflow.TaintTracking2 import semmle.code.java.dataflow.FlowSources import DataFlow2::PathGraph
class ReadObjectClass extends Method{ ReadObjectClass(){ this.getDeclaringType().hasQualifiedName("java.io", "ObjectInputStream") and this.hasName("readObject") } }
class MyTaintTracking extends TaintTracking2::Configuration { MyTaintTracking() { this = "MyTaintTracking" } override predicate isSource(DataFlow::Node sourceNode) { sourceNode instanceof RemoteFlowSource } override predicate isSink(DataFlow::Node sinkNode) { exists(MethodAccess ma | ma = sinkNode.asExpr() and ma.getMethod() instanceof ReadObjectClass) } }
from MyTaintTracking mtt, DataFlow2::PathNode source, DataFlow2::PathNode sink where mtt.hasFlowPath(source, sink) select source.getNode(), source, sink, "from $@", sink.getNode(), "this user input"
|
结果如下
什么都没找到。调试一下,看看哪里出错了。
调试过程
首先看一下source和sink,对其进行Quick evaluation,source和sink分别为baseStr和readObject(…),这里没问题。
那就可能是中间断开了。(这里想了好久。。。)
测试发现,是new SerialKiller(new ByteArrayInputStream(decode), “serialkiller.xml”)这里断开了。
于是在MyTaintTracking中添加isAdditionalTaintStep,将这两个node点连接起来。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29
| predicate isTaintedString(Expr expSrc, Expr expDest) { exists(Constructor con, ConstructorCall call, ConstructorCall call1 | expSrc = call1.getArgument(0) and expDest=call and call.getConstructor() = con and con.hasName("SerialKiller") and con.getParameterType(0).toString() = "InputStream" and call1.getArgument(0).getType().toString() = "ByteArrayInputStream" ) }
// predicate isTaintedString(Expr expSrc, Expr expDest) { // exists(Constructor con, ConstructorCall call, ConstructorCall call1 | // expSrc = call1.getArgument(0) and // expDest=call and // call.getConstructor() = con // ) // }
class MyTaintTracking extends TaintTracking2::Configuration { MyTaintTracking() { this = "MyTaintTracking" } override predicate isSource(DataFlow::Node sourceNode) { sourceNode instanceof RemoteFlowSource } override predicate isSink(DataFlow::Node sinkNode) { exists(MethodAccess ma | ma = sinkNode.asExpr() and ma.getMethod() instanceof ReadObjectClass) } }
|
其他
下面分别是GitHub Security Lab CTF 4
和fastjson1.2.31
的ql
文件,具体内容就不分析了,网上讲得已经很详细了。
GitHub Security Lab CTF 4: CodeQL and Chill - The Java Edition
fastjson1.2.31Test.ql