Java查询回显_基于请求响应对象搜索的Java中间件通用回显方法

本文探讨了基于请求响应对象搜索的Java中间件通用回显方法,通过实现HttServletRequest和HTTPServletResonse接口,从线程中搜索这两个对象并获取请求参数,然后写入响应。在Tomcat、Jetty和Weblogic等环境中测试成功,同时讨论了如何瘦身编译后的class文件以适应不同限制,以及在Shiro、Fastjson、Jackson反序列化场景的应用。
摘要由CSDN通过智能技术生成

4599e51bf68949bf4e3794de02de09a7.png

前言

看了很多师傅们在研究针对Java中间件+Java反序列化漏洞回显的

(。。。应该还有挺多,就不翻了)又看到了c0ny1师傅的作品:《java内存对象搜索辅助工具》配合IDEA在Java应用运行时,对内存中的对象进行搜索。比如可以可以用挖掘quest对象用于回显等场景。

按照经验来讲Web中间件是多线程的应用,一般qust对象都会存储在线程对象中,可以通过Thad.curntThad()或Thad.getThads()获取。并且目前回显思路主要是基于加载类,执行static块或者构造方法(原生反序列化、FastJson、Jackson一类的都有):TemlatesIml类的反序列化链,内嵌类的byte,defineClass。

其他反序列化链使用URLClassLoader进行远程加载类。

JNDI远程加载类。所以想到:我们能否写单个类,让它能够触发时,使用2的思路去寻找quest和sonse,从quest中获取命令参数,然后向Resonse中写入呢?

先说结论:可以实现,在Tomcat、Jetty和Weblogic中都可使用(只测了这三,个人觉得其它Java中间件也没差),还测试了Shiro、Fastjson、Jackson反序列化的场景。

Tomcat6+Shiro会报java.io.StamCorrutedExcetion:invadtye:错误,很迷,有空再解决吧。

精简后的编译完的class文件大小在2800-2900B左右,Shiro反序列化用的Cookie值大小可以控制在5000字节左右,勉强可以接受。

响应时间一般在3S内。

基本思路

javax.servlet.htt.HttServletRequest

javax.servlet.htt.HTTPServletResonsejava类中间件的quest和sonse分别实现以上两个接口

从Thad.curntThad()起始搜索实现了如上两个接口的对象

通过HttServletRequest的getHeader方法可以获取到请求头

通过HTTPServletResonse的getWriter方法可以获取到响应的Writer(开始用的ServletResonse的getOututStam接口,但是会报重复获取的OututStam的错误,此处就改为使用getWriter了)

都搜索到后,该执行执行,该输出输出初始代码

有点多,都贴上有水字数的嫌疑,还是贴gist链接吧。┓(′?`)┏

htts:gist.github.comfnmsd89118c2967cd53c244389564d2f8b368

编译完的class3888字节,好吉利~

为了类能小一些,没有做c0ny1师傅那么细致的搜索分类和剪枝。

为了方便,纯粹使用深度优先搜索(DFS),依次搜索字段

然而接下来为了瘦身,各种先定逻辑还得继续砍砍砍

**PS:**在搜索Tomcat的Request过程中,不知道为何会搜出一个并非当前Request的对象,所以这里限制了Request必须包含cmd头,才认为找到了真的Request,Resonse目前没有发现这个问题。

为代码瘦身

由于Nginx有Cookie4096B长度的限制,Tomcat有8096B的长度限制(感谢c0ny1师傅),所以为了能使用Temlates类的链,编译出的Class文件还是越小越好。

以下内容比较乱,是一个逐渐尝试减小Class文件的过程,没兴趣可以略过

整个分析过程使用classy-0.4.jar来进行对Class文件的分析:

htts:github.comzxh0classy1.初始

? 3888字节

2.去掉可有可无的静态字段

staticClassReqC=HttServletRequest.class;

staticClassResC=HttServletResonse.class;

staticintmax_deth=50;? 3734字节去掉字符串连接:3640字节

删除多余逻辑的限制逻辑

if(deth>50||(q!=nl&am;&am;s!=nl)){

turn;

}3611字节

删除getModifiers的调用(删除一个方法大概60字节的样子?)

3551字节

减少了一个空判断,大概4字节

3547

减少局变量的定义

Classa=obj.getClass();

if(a.isPrimitive()||a.toString().startsWith("java.lang")){

turntrue;

}变为:

if(obj.getClass().isPrimitive()||obj.getClass().toString().startsWith("java.lang")){

turntrue;

}3525,少了22字节

去掉调试时用的rintStackTrace

3488字节

删掉flush和waitFor

3451字节,貌似没少多少

删掉static块和start方法,只保留构造方法触发

3372

删除PrintWriter的变量赋值,删除Testbyfnmsd字符串

3260

删除掉roc的定义,直接跟getInutStam一块调用

3220

合并Scanner相关逻辑为一句:

s.getWriter().rintln(newScanner(Runtime.getRuntime().exec(q.getHeader("cmd")).getInutStam()).useDemiter("\A").next())

3130

以下本应有判断来进行的剪枝,改为使用异常处理兜着

去掉java.lang类的搜索剪枝

obj.getClass().toString().startsWith("java.lang")

节省了toString和startsWith

3009

去掉数组包裹类型的为非rimtive的判断

obj.getClass().getComonentTye().isPrimitive()

2962

去掉全部isPrimitive的判断

2917

去掉搜索时字段值为nl的判断

2908

给类名、字段名、方法名、局部变量名都改为一个字符

2850

这里改局部变量其实不起作用。

去掉是否为静态字段的判断

if((decladField.getModifiers()&am;0x00000008)==0)

2803(最终大小在2800-2900之间,不会差太多,后面不知道又改哪里了,到了2900左右)

瘦身总结

最终结果代码(使用构造方法触发,也可以改成Static,都一样):htts:gist.github.comfnmsd8165cedd9fe735d7ef438b2e977af327

(前面传错了一个中间的bug版本,会重复执行重复回显,感谢l1nk3r师傅早早的帮我发现了)尽量减少引用的方法和类型(包括像字符串连接这种隐式调用)

尽量减少字段、局部变量的定义

能用异常处理兜底的处理,减少判断。

蚊子腿也是肉,把字段名、参数名、变量名改小点(这块不确定,可能只有字段名有效)

比较大的地方主要在ConstantPo和变量定义上(ConstantPo还好理解,变量定义不太明白,后续还是好好在学习学习Class文件结构)测试

由于都是new一个对象或者static块执行,所以偷了个懒,简单写了个js页面,可以看到没有任何的输出语句,只是new了一下对象:

newa();

%>Weblogic(打包有点问题,页面没改成最简版的):Tomcat:Jetty:Tomat8+Shiro反序列化

这里用的Jdk7u21的链(TemlatesIml触发)来new我写的类,memberMe长度5036

懒得部环境的同学,可以用Vhub里面的Shiro环境,(SringBoot用的嵌入式Tomcat9)但是那个得用CommonsBeanutils1的链。3.FastjsonJNDI加载场景(这里用vhub的fastjson1.2.47-rce,SringBoot用的嵌入式Tomcat9)4.weblogic12+Jackson反序列化

这个用的我之前给Jackson提的链,可惜没混到CVE编号,嘤嘤嘤o(╥﹏╥)o其他原来设置了深度优先搜索最大50层,结果weblogic下,quest搜索出来在第50层,sonse在quest下面第51层,所以后来我最大深度改到了52层。

具体使用中使用TemlatesIml需要类链,需要使用Javassist添加AbstractTranslet接口,当然,也可以直接imlements,但是这样又多俩需要实现的接口,class会大一些,具体可以参考:htts:xz.ayun.comt6227一点思考:非HTTP的反序列化,搜Socket对象,然后从getOututStam再往里写能不能行呢?

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值