Aj链任意写文件后续带来的RCE深入分析
1674701160110592 WEB安全 992浏览 · 2025-03-12 15:13

题目及其附件是选自CISCN国赛半决赛华南赛区的ezjava

但是题目环境是不出网的

链子分析



然后里面传入的jdbcBean,继承了序列化的接口



看到数据库连接

继承DatasourceServiceImpl接口,调用了testDatasourceConnectionAble方法



感觉要打jdbc,版本



看到pom.xml的依赖



有个aj依赖,搜一下感觉能打链子

aj的链子



那就是利用jdbc触发readobject方法

但是我优点不太理解任意写文件能干吗?

但是我们还是要先将链子给弄出来先



成功写入

然后题目的readObject方法,我们就可以直接触发,不需要走CC链,同时也没有CC链的依赖给我们



那么这里应该就是jdbc触发readObject进入序列化,然后我们再反射调用UserBean里面的readObject方法,

然后就能够触发a.put剩下的就是走aj链的后半段

最后的exp

但是有个问题,如果环境出网那么我们可以利用写入so文件触发rce

如果不出网呢?又该如何办呢?



出网

1、写so文件加载

这个挺多文章的,就贴几篇了,先不分析

https://xz.aliyun.com/news/14019?time__1311=eqUxuiDti%3Dn8KDsD7%2BPD%3DPitqGQdtNdx&u_atoken=39d34b07e59c8f4ac504085362d06917&u_asig=0a472f9217417912578338619e003e



https://z3r4y.blog.csdn.net/article/details/139052904?fromshare=blogdetail&sharetype=blogdetail&sharerId=139052904&sharerefer=PC&sharesource=git_clone&sharefrom=from_link



https://www.kinsomnia.cn/index.php/2024/06/04/2024ciscn-ezjava/

2、写恶意类加载

Evil.java

利用

javac Evil.java

生成.class恶意的二进制文件

利用getbyte方法

或者直接在命令行里面

即可生成

然后放入aj链的payload里面去



把生成的字节码贴在fake_mysql_gui上面



然后就会在jre\classes下面生成一个恶意类



那么我们去调用它,直接调用类名就行

然后把生成的base64字节码贴到gui上面即可



个人这种方法的话要比写so文件简单一点,因为他不需要调用太多的工具,但是前提是要清楚知道jre\classes路径在哪。

因为本地我是知道这个路径的,由于比赛awd是有靶机,也是能看到这个java的路径的,所以才想到这个方法

不出网

1、用charsets.jar包

将恶意类打包成jar



这里尝试了很久一直不成功,于是我新建了一个测试类

编译后,然后在Test.class文件所在的目录下运行

发现rt.jar和charsets.jar是自动开启的





因为我们Test中调用charsets.jar中的字符集,所以加载这个jar包很正常

那么当我们把它注释掉之后呢?

这里我新建了一个新的Test





依旧会开启

随后我拉了一个linux的镜像



上传测试

运行Test(有字符集的), 发现没有找到,那如果找到了应该就是opened了



运行NewTest,找不到opened charsets.jar的字样,说明也正常。

经过调试后发现原来是我windows的原因,Windows下会自动加载charsets.jar

也就是说在windows里面你要是直接运行app.jar的话会导致你无法完成覆盖,

因此我们

我们先把charsets.jar解压,用7z啥的解压工具直接解压



右击然后以IDEA来打开项目



为了保持最小体积,抛弃其他类(需要保留ExtendedCharsets类,不然无法加载其他类)。这里就选择覆盖sun.nio.cs.ext.IBM33722

内容为

编译好之后,替换掉原来的.class文件,然后打包



windows环境

要是本地的话基本上得直接覆盖了,就是把刚刚编译好的jar包直接放到jre/lib/目录下面



因为我们的覆盖已经算是写入文件了,所以我们带着这个Accept头就可以触发覆盖掉的恶意类



linux环境

同理如果我们是直接覆盖charsets.jar的话也是ok的



但是我还是想尝试一下写入

开始的时候我是只修改了一个class文件,然后去覆盖的,结果是太大了,根本无法写入

后来我想着能不能删掉其他的class,只带一个class呢?

答案是可以的



因为只要保留ExtendedCharsets.class即可

还有你要恶意调用的类名

成功覆盖了原来的jar包



但是读取是错误的



然后我发现可能是我用的是window上面的charsets.jar编译的原因,然后我把docker环境的charsets.jar下载下来

保留ExtendedCharsets.class和恶意调用类重新编译

上传覆盖即可

然后accept接受那个参数就能调用恶意类了





2、becl

题目不出网如何回显?还是根据镜像得知java版本是小于JDK8u251的存在BCEL的利用方式,可通过这样来实现回显RCE

但是这个是需要有jre/classes的目录存在的

web-一写一个不吱声,就出现这样的情况,所以就顺带记录一下

恶意类EvilEcho.java

编译好之后,

把base64编码写在exp的payload位置,同时改一下文件位置,改成下%JAVA_HOME%jre/classes/



看到生成后再利用反射调用



即可执行命令,并且获得回显



简单粗暴

直接利用jdbc文件读取的方式读flag即可





总结

aj链子带来的任意写文件还是很有意思的,感觉踩坑能力又变强力!

0 条评论
某人
表情
可输入 255