L3HCTF bypass出题人视角

本文分享了L3HCTF中一道Java上传绕过题目的出题思路和解题细节。主要涉及了如何绕过后缀限制、可见字符检测以及黑名单检测。通过利用Java与Tomcat对编码解析的不同,以及BCEL字节码技术,展示了在无网络环境下的RCE实现。同时,提到了JNDI注入中可能被忽视的doLookup方法作为绕过手段。
摘要由CSDN通过智能技术生成

@yzddmr6

自己在L3HCTF中出了一道java上传绕过题目bypass。其中题目中的一些trick不仅仅是用于CTF出题,对于实战渗透也是有一定的帮助。今天跟大家分享一下出题时的一些思考跟解题细节。

题目有三道过滤

1. 绕过后缀

public static String checkExt(String ext) {
        ext = ext.toLowerCase();

        String[] blackExtList = {
                "jsp", "jspx"
        };
        for (String blackExt : blackExtList) {
            if (ext.contains(blackExt)) {
                ext = ext.replace(blackExt, "");
            }
        }

        return ext;
    }

后缀jsp/jspx会被替换为空,用双写绕过:jsjspp。常规操作

2. 绕过可见字符检测

第二阶段题目中直接用getString获取FileItem的内容,然后传入了checkValidChars函数检测。checkValidChars函数主要功能是检测content中是否存在连着两个以上的字母数字,如果匹配成功则提示上传失败。

String content = item.getString();
boolean check = checkValidChars(content);
...
    public static boolean checkValidChars(String content) {
        Pattern pattern = Pattern.compile("[a-zA-Z0-9]{2,}");
        Matcher matcher = pattern.matcher(content);
        return matcher.find();
    }

这里其实是模拟了一个WAF的场景,因为很多WAF对于文件上传都会有很粗暴的拦截,碰到jsp标签就给干死。

乍一看似乎并不可能被绕过,因为只要连着两个字母数字就会被检测到,让人不由得想起了CTF经典题目《php无字母数字webshell》。但是java不像php一样支持变量函数,需要从其他地方下手。

这里就用到了一个trick:FileItem.getString()对于编码的解析跟Tomcat解析jsp是有差异的,默认为ISO-8859-1

public String getString() {
    byte[] rawdata = this.get();
    String charset = this.getCharSet();
    if (charset == null) {
        charset = "ISO-8859-1";
    }

    try {
        return new String(rawdata, charset);
    } catch (UnsupportedEncodingException var4) {
        return new String(rawdata);
    }
}

而Tomcat对于jsp编码的解析主要在org.apache.jasper.compiler.EncodingDetector这个类,其中有很多默认用ISO-8859-1无法直接解析的编码。

private EncodingDetector.BomResult parseBom(byte[] b4, int count) {
        if (count < 2) {
            return new EncodingDetector.BomResult("UTF
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值