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看看
.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里溯源一下这个是怎么被调用的
.png)
我们看第二个,因为这个在只读数据区
.png)
我们发现/api/config/update请求是调用这个函数的
那我们最后用repeater完成我们的攻击
.png)
这里要注意一个点
我们生成jwt时的payload不是name:admin,而是role:admin,如图
.png)
题目链接:
CTF-Writeups/Polarisctf 2026/ct at main · Zenquiem/CTF-Writeups