0×01导言
在计算机科学中,笼统语法树是源代码语法结构的一种笼统表明,它以树状的办法体现编程言语的语法结构,树上的每个节点都对应为源代码中的一种语法结构。笼统语法树能够说是静态代码剖析中最常用的,也是最中心的技能之一,经过笼统语法树能够很便利构建模型,判别源码中是否存在缺点特征。
本文简略构建了一个判别模型,去测验寻觅Fast *** ON 的gadgets。
0×02前置常识
Fast *** ON 是阿里开源的由Java言语编写的高性能 *** ON库,现在在国内大范围的运用。Fast *** ON 在版别小于1.2.25时存在反序列化缝隙,能够运用形成长途代码履行。而最近又报出版别小于1.2.48时存在修正绕过,已知多个国内Top N的互联网公司均呈现该缝隙导致的web侵略事情。
Fast *** ON的反序列化缝隙从功用上讲是因为Fast *** ON答应将json字符串直接转化成java方针,这个功用一般被称为反序列化。而Fast *** ON 在反序列化时,也便是由json字符串生成java方针的时分会履行方针类的结构函数,set最初的办法,get最初的办法,而且因为反序列化的特性,咱们能够经过方针类的set办法自在的设置类的特点值,这就及其简略形成RCE。
1.2.25版别今后,Fast *** ON 增加了一个checkAutoType 办法,用来防护反序列化缝隙,其防护理念能够总结为:
新增autotype设置,用来装备是否答应反序列化恣意类, 默许封闭。
新增黑名单检查,在黑名单中的类都不答应反序列化。
这样防护理念也意味着,假如用户敞开了autotype设置,咱们只需求找到一个不在Fast *** ON黑名单中的类,就相同或许施行进犯。事实上黑名单的防护办法,一般来说都靠谱,每过一段时间就会报出绕过。比方最近就爆出的两个不在黑名单的类能够完成RCE。
ch.qos.logback.core.db.JNDIConnectionSource
com.zaxxer.hikari.HikariConfig
这两个类都是运用了JNDI 注入技能完成RCE,其缝隙触发特征是适当显着的。比方com.zaxxer.hikari.HikariConfig类的触发点就只有两句java代码。
简略的来说便是一个可控变量作为InitialContext类下lookup办法的参数,就能够完成RCE。
(关于JNDI注入完成长途代码履行的细节问题,不是本文重视的要点,有爱好的同学能够去检查:深化了解JNDI注入与Java反序列化缝隙运用 – FreeBuf专栏·安全引擎)
已然特征十分显着,会不会有其他类也和HikariConfig类相同能够协助咱们完成RCE?现在咱们就来测验下去寻觅下这个类。
0×03寻踪
咱们收拾下作业思路:
反编译不在Fast *** ON黑名单中的jar包,生成java源码文件。
由java源码文件生成AST语法树。
对语法树进行条件判别,筛选出契合条件的类。
测验结构poc。
反编译代码
这儿咱们首要作业是把本地maven的缓存目录 ~/.m2/repository下缓存的jar包去重后,悉数进行反编译。在这儿咱们能够根据jar包途径判别下java 包在不在Fast *** ON 黑名单中,关于在黑名单中的jar 包就没必要进行反编译了(后来发现这个判别好像不是很靠谱,会有误判和漏判,但在可接受的范围内)。
反编译运用FernFlower,这是一个指令行的下java反编译东西,能够很轻松的完成jar的完好反编译。
反编译指令如下:
java -jar fernflower.jar jarToDecompile.jar decomp/
(其间jarToDecompile.jar是需求反编译的jar文件,decomp是反编译后的生成文件所寄存的目录)
该指令履行完后,会在decomp目录生成一个jarToDecompile.jar的文件,直接运用unzip 指令解压这个生成的文件,即可看见源码。
def decomplier(file):
"""
反编译
:param file:
:return:
"""
cmd = "java -jar ~/tools/FernFlower.jar " + file + " /Users/xxxxxxx/source/ > /dev/null 2>&1"
os.system(cmd)
jar_file_name = file.split('/')[-1]
jar_file_path = "/Users/xxxxxxx/source/" + jar_file_name
target_dir = jar_file_name.split('.')[:-1]
source_dir = '.'.join(target_dir)
source_dir = '/Users/xxxxxxx/source/' + source_dir
unzip_cmd = "unzip " + jar_file_path + " -d " + source_dir + " > /dev/null 2>&1"
os.system(unzip_cmd)
return source_dir
值得注意的是Fast *** ON 在1.2.41 版别后将黑名单改成hash的办法,不再以明文展现。那么,咱们怎么能获取到原始的黑名单呢?这儿需求凭借大牛的作业效果,fastjson-blacklist这个项目完成了暴破Fast *** ON黑名单hash原文的功用,而且同享出现已爆炸出来的黑名单原文。
生成AST语法树
这儿的方针是把反编译生成的源文件解析成笼统语法树的办法。
python中生成java语法树的库叫javalang,它能很便利的生成java的笼统语法树。
装置指令:
pip install javalang
运用javalang生成java语法树十分便利,只是只需求两行代码。
import javalang
tree = javalang.parse.parse("package javalang.brewtab.com; class Test {}")
生成的语法树如下图所示:
javalang 会将每一种语法结构都映射为一个类方针。从上图能够看出,整个源文件被映射成CompilationUnit方针,它有package、imports和types 3个首要特点,别离表明包名信息,导入类信息,以及源码文件中的类型声明。一起这个三个特点也是被笼统为相应的类方针。比方包名信息被笼统为PackageDeclaration方针,类声明被映射为ClassDeclaration 方针。[1][2][3]黑客接单网