
Github发布CodeQL后,一直保持着关注,从17年就有类似的想法在尝试,在CodeQL中有很多不谋而合的点,查询语句刚上手虽然有些别扭,稍微适应了下感觉还好,值得好好学习一下
接下来看一下如何发现Java Deserialization Vulnerabilities。
攻击者在Java应用 deserialization
时注入不可信数据进而可以执行任意代码。
java.io.ObjectInputStream
中的 readObject
是个危险方法。常见的用法如下:
1 | ObjectInputStream ois = new ObjectInputStream(input); |
readObject
方法的作用是从数据流中读取并返回该对象。那么我们都知道当构造序列化数据时插入恶意代码,则可以在 deserialization
时产生非预期结果,甚至可以执行任意代码。
使用CodeQL发现不安全的deserialization
我们可以使用CodeQL来发现 deserialization
漏洞,当然我们首先找到 deserialization
进行的位置,然后需要跟踪不可信的数据是否可以到达 deserialization
调用方法。
首选我们编写一个查询语句去寻找 readObject
调用。
1 | import java |
这段codeql代码的意思是寻找名称为 readObject
且类型为 java.io.ObjectInputStream
的方法。
上文这段代码会返回很多结果,其中大部分都是安全的。因此我们要定位到那些可读取脏数据的调用上。进行污点跟踪主要靠 RemoteFlowSource
和 flowsTo
。RemoteFlowSource
的作用是发现可以由用户控制的输入点,例如http请求参数。谓词 flowsTo
的作用是监控数据流是否从 source
到达 sink
。
首先将查询重构为一个类,来定义我们感兴趣的 sink
。也就是 readObject
的调用集合,这里是脏数据流入的地方。
1 | class UnsafeDeserializationSink extends Expr { |
接下来我们定义 sink
, source
定义于 RemoteFlowSource
,完整的查询语句如下。
1 | import java |
当然,上边只查询了 java.io.ObjectInputStream.readObject
这一个方法,其它反序列化框架也有类似的漏洞,例如Kryo、XmlDecoder、XStream、SnakeYaml等。
完整的反序列化漏洞查询语句如下。
1 | import java |
参考链接:https://lgtm.com/rules/1823453799/ https://securitylab.github.com/research/insecure-deserialization
- Post title:利用CodeQL寻找Java Deserialization Vulnerabilities
- Post author:langu_xyz
- Create time:2020-05-04 21:00:00
- Post link:https://blog.langu.xyz/利用CodeQL寻找Java Deserialization Vulnerabilities/
- Copyright Notice:All articles in this blog are licensed under BY-NC-SA unless stating additionally.