利用链寻找利器 CodeQL:如何精准定位二次反序列化漏洞
真爱和自由 WEB安全 202浏览 · 2025-03-26 17:51

利用链寻找利器 CodeQL:如何精准定位二次反序列化漏洞

简单介绍

CodeQL 是一个由 GitHub 开发的安全工具,用于静态代码分析。它能够检查多种编程语言的代码,以发现潜在的安全漏洞、缺陷和违反编码规范的问题。CodeQL 使用一个名为 CodeQL Workbench 的图形界面来管理代码分析,并且可以通过命令行工具 codeql 来执行。

CodeQL 的主要特点包括:

1 支持多种编程语言:CodeQL 支持多种编程语言,包括 Java、C/C++、Go、Python、Ruby、Node.js、PHP、Rust 等。

2 自动代码分析:CodeQL 能够自动分析代码库,无需人工干预,从而发现潜在的安全问题。

3 自定义规则:用户可以创建自定义规则来识别特定的问题,并且可以与其他开发者共享这些规则。

4 与 GitHub 集成:CodeQL 可以直接集成到 GitHub 中,允许开发者在其代码仓库中运行代码分析。

二次反序列化查找

利用场景

首先先给出这次利用的场景,现在已知我可以调用getter方法,然后需要查找二次反序列化的调用链

step1寻找getter方法

分析

我的思路就是先寻找所有的getter方法,该如何筛选出是一个getter方法呢?各位学过fatsjson的应该知道fastjson的赛选getter方法的逻辑,我们来回顾一下

首先是以getter开头,然后第四个字母必须是大写的,然后后面还有对参数的限定,并且希望getter是一个public方法

那在codeql语言中应该如何编写呢?

编写语句

首先就是Method类

它有一个谓词方法

isPublic:Holds if this element has a public modifier or is implicitly public.

getName: Gets the name of this element.

hasNoParameters: Holds if this callable does not have any formal parameters.

fromSource:Holds if this element pertains to a source file.

总的来说代码实现了一个这样的效果

1 this.getName().indexOf("get") = 0:

此条件用于检查方法名称是否以 "get" 开头。这通常用于获取方法(Getter)命名约定,符合 Java Bean 的标准,以便于访问对象的属性。

2 this.getName().length() > 3:

这一条件确保方法名称的长度大于 3,意味着方法名称不仅仅是 "get"。例如,合法的方法名称如 "getAge" 或 "getName" 都符合这一条件。

3 this.isPublic():

这行代码检查该方法是否是公共的。公共方法可以被任何其他类访问,这通常是获取属性的方法所需的访问级别。

4 this.fromSource():

此函数可能用来确定该方法是否为源代码中的方法而不是动态生成的方法。这是一个条件检查,以确保我们只关注源代码中定义的方法。

5 this.hasNoParameters():

最后,这个条件检查该方法是否没有参数。Getter 方法通常不需要参数,因为它们是为了返回对象的属性值而设的。



我们看效果如何

可以看到有1000多个结果,数量很多



随便点几个,看看是不是符合我们的要求

确实都是public,然后都是getter方法,符合要求

二次反序列化逻辑

分析

这里我如何判断这个getter方法是不是能够二次反序列化呢?

首先得有readobject方法吧

比如我们找一个以前出现过二次反序列化的

SignedObject的getObject方法

RMIConnector的findRMIServerJRMP方法



都是有readobject的

编写codeql语句

MethodAccess 类表示对方法的调用(即“方法访问”)

每当代码中调用某个方法时,都会生成一个 MethodAccess 实例

getMethod()

返回表示该 MethodAccess 对应的被调用方法 (Method 类型)。

例如,access.getMethod() 返回了当前方法调用的目标方法。

getEnclosingCallable()

返回包含此方法调用的父函数或方法。换句话说,它返回包含此调用的函数或方法的定义。

例如,在一个方法内部调用另一个方法时,它会返回外部的方法。

所以我的语句意思就是

用于查找在某个方法中调用 readObject 方法的情况

我们看下效果



可以看到是有一个getobject的



正是我们的getter方法,而且内部有二次反序列化的逻辑

POC构造

如果这里getContent是可以控制的,那么就可以实现二次反序列化

跟进getContent方法

是在父类Message中

本质上是一个ByteSequence对象

我们看ByteSequence如何构造

接受一个byte对象,而且是public的



我们先简单构造一下,看看能否二次反序列化调用


1 条评论
某人
表情
可输入 255
用户MlpZMvEOW1
2025-05-05 04:50 0 回复
怎么联系