ct

这题的ngnix文件没有漏洞,我们看default.conf

我们看到

location /static {
        alias /var/www/static/;
    }

这里有一个很明显的漏洞,/static后面没有加/但是alias后面加了,假如说我们输入../app<,实际上它识别出的是/static../app,然后它匹配到了location /static,然后就会变成/var/www/static/../app,这个实际上代表的意思是下载/var/www/app,那我们就能获取/var/www/下的文件,然后我们看到注释中有写:

JWT: /var/www/app/config.yaml

所以我们直接输入/static../app/config.yaml,我们就把config.yaml下载下来了,那我们就成功获得jwt密钥(我们从注释的说明中可以看到3002和3003端口都需要jwt认证)

下一步我们要寻找其他漏洞了,我们看到注释里3002是调用的这个服务:/var/www/app/config-service

那我们就用前面的漏洞把config-service下载下来看看有没有漏洞

然后我们用ida看看

Polarisctf2026ct (3).png

在这里我们可以看到这里系统调用了一个sed(第196行)

我们看到181行它是用#代替/来分隔的,两个%s是占位符

正常的 sed 替换命令通常长这样:s/正则模式/替换内容/标记

组成部分 示例 (正常情况) 含义
s s 告诉 sed:我要进行替换(Substitute)操作。
第一个 # # 起始分隔符。告诉 sed:后面紧跟的是要找的内容。
.*old.* .*DefaultSSID.* 正则模式.是任意字符,*是任意次数。意思是:匹配包含旧值的整行。
第二个 # # 中间分隔符。告诉 sed:寻找结束,后面开始写要换成什么。
new MyWiFi 替换内容。你想把旧内容改成什么。
第三个 # # 结束分隔符。告诉 sed:替换内容写完了。
标记 (Flags) g 可选标记。比如 g代表全局替换。

例如正常输入:s#.*old.*#MyWiFi#

但是假如我们输入的是cat flag#e,也就是我们手动输入一个#,会导致它提前截断

它读取的是s#.*old.*#cat /flag#e#

s#.*old.*# —— 找到旧值

cat /flag —— 这是要换成的内容。

# —— sed 看到这个井号认为替换内容到此结束了

后面的 e —— sed 接着读,发现后面紧跟一个 e。它会认为这是指令标记。

在 Linux 的 GNU sed 中,e 代表 Execute(执行)。

没有 e 时:sed 只是把文件里的 old 换成字符串 "cat /flag"

有了 e 时:sed 会在完成替换后,立刻把替换后的内容当作一条 Shell 命令丢给系统去运行,然后把运行的结果(即 Flag 的内容)再写回文件里(或者打印出来)。

那我们在ida里溯源一下这个是怎么被调用的

Polarisctf2026ct (4).png

我们看第二个,因为这个在只读数据区

Polarisctf2026ct (5).png

我们发现/api/config/update请求是调用这个函数的

那我们最后用repeater完成我们的攻击

Polarisctf2026ct (2).png

这里要注意一个点

我们生成jwt时的payload不是name:admin,而是role:admin,如图

Polarisctf2026ct (1).png

题目链接:

CTF-Writeups/Polarisctf 2026/ct at main · Zenquiem/CTF-Writeups


ct
https://zenquietus.top/archives/wei-ming-ming-wen-zhang-q4NstC5z
作者
ZenDuk
发布于
2026年03月31日
许可协议