Featured image of post Polaris CTF 招新赛 Web 方向复盘

Polaris CTF 招新赛 Web 方向复盘

记录我在 Polaris CTF 招新赛中完成的几道 Web 题目思路,以及赛后的总结与反思。

1. ezpollute

分析源码,是一个Node.js + Express 网站,

1启动一个 Web 服务

2提供一个接口 /api/config,让用户提交 JSON 配置

3提供一个接口 /api/status,去启动一个新的 node 子进程,检查“Node.js 是否正常运行”

开发者显然知道 __proto__ 常常和原型污染有关,所以他写了个“黑名单”:
如果发现传进来的键名是 __proto__,就拒绝。

不过 in 不只检查对象自己有没有这个属性,还会检查它原型链上的属性。

BUT 没拦 constructor.prototype
由于 key in target 会沿原型链找,config 上虽然没有自有属性 constructor,但它能从 Object.prototype 继承到,所以可以一路递归到 Object.prototype,形成原型污染。

构造payload拿下

XMCTF{9fa42f10-38fa-4963-b4ca-a21beabee11e}

2. ez_python

分析app.py, Flask框架

考点是 Python 对象属性递归合并导致的任意属性覆盖

`POST /` 会在 `request.data` 非空时执行 `merge(json.loads(request.data), instance)`

- `merge()` 可递归修改 `instance.config.filename`

- `GET /read` 会执行 `open(instance.config.filename).read()`,形成任意文件读取

3、Broken Trust

/api/profile 存在未鉴权 SQL 注入,可直接泄露管理员资料。用该 UID 登录后可访问 /api/admin?action=backup&file=…,直接拿到flag

先随便注册一个

知道了 只有管理员可以拿到权限

Dirsearch扫描发现/api/profile

BP改个抓包方式

打出管理员UID,基本搞定了

用管理员UID登录,路径不对,想到路径穿越,慢慢试,试出来,

直接flag

4.only-real

1>

F12提示了账号密码

登入进去之后f12把disabled全部删除

2>

看看能不能进行JWT伪造(JSON Web Token)

JWT(JSON Web Token)伪造是 Web 安全中非常经典且重要的一个考点。在 CTF 的 Web 方向中,它通常是你从“普通访客”跨越到“管理员”并最终拿到 Flag 的关键钥匙。

我们可以把 JWT 想象成一张“电子通行证”,服务器一旦签发给你,之后就不再查询数据库,而是直接通过查验这张通行证上的印章(签名)来确认你的身份。JWT 伪造的核心原理,就是利用服务端验证机制的漏洞,自己伪造出一枚能够以假乱真的“印章”,从而随意篡改通行证上的身份信息。

为了理解它是怎么被伪造的,我们需要先拆解这张通行证的结构。

JWT 的基础结构

一个标准的 JWT 看起来是一串由两个点 . 分隔的长字符串(例如 xxxxx.yyyyy.zzzzz),它由三部分组成,每部分都经过了 Base64Url 编码:

  1. Header(头部): 声明了这块 Token 的类型(JWT)和所使用的签名算法(比如 HS256 或 RS256)。

JSON

{ “alg”: “HS256”, “typ”: “JWT” }

  1. Payload(负载): 存放实际的有效信息,比如你的用户名、角色、过期时间等。

JSON

{ “user”: “guest”, “role”: “user” }

  1. Signature(签名): 这是防伪的关键。服务器用一个只有它自己知道的密钥(Secret),按照 Header 里指定的算法,对 Header 和 Payload 进行加密计算得出的结果。

BP改jwt发包

发现改user=admin回显未登录,alg=none,sub: “0"全部回显”无效cookie”

遂,JWT伪造失败

Wait,学习大佬的wp发现可能是一个弱密钥(正好学到利用jwtcracker工具,可以去csdn上看看,很简单,一学就会,不过爆破的时间有点长,最好问问GPT格式是啥,能省好多时间)

芜湖,爆出来了cdef,

这题其实直接dirsearch直接能扫出来,可能考点在only_real_revenge吧,我们那题再见

5.only_real_revenge

同上一题思路一样,用图片马尝尝咸淡,抓包再改回php,同时把伪造JWT传上

访问直接出flag啦

6.DXT

本体环境是一个“MCP 工具包管理后台”,它平时做的事是:

  1. 你上传一个 .dxt 包

  2. 它解开这个包

  3. 读取里面的 manifest.json(相当于说明书)

  4. 按说明书里的内容,把这个 MCP server 启动起来

  5. 然后问它:
    “你有什么工具可以给我展示?”

MCP (Model Context Protocol) 的语境下,.dxt 文件代表的是 Desktop Extension(桌面扩展)

简单来说,它就像是给 AI 助手(如 Claude Desktop)准备的“一键安装包”。

1. .dxt 文件到底是什么?

本质上,一个 .dxt 文件就是一个压缩包(ZIP 格式),它把一个 MCP 服务器运行所需的所有东西都打包在了一起。它的结构通常包含:

  • manifest.json:这是整个扩展的“大脑”,告诉 AI 这个工具有什么功能、叫什么名字、需要怎么启动。

  • 服务器代码:比如 Node.js 或 Python 编写的工具逻辑。

  • 依赖项:运行这些代码需要的库文件。

2. 它在 MCP 里面是用来做什么的?

在没有 .dxt 之前,如果你想给你的 Claude 增加一个“搜索本地文件”或者“操作数据库”的功能(即安装一个 MCP Server),你通常需要:

  1. 安装 Node.js 或 Python 环境。

  2. 手动修改复杂的 config.json 配置文件。

  3. 处理各种环境变量和路径问题。

有了 .dxt 文件后:

  • 一键安装:你只需要把这个 .dxt 文件拖进支持 MCP 的客户端(比如 Claude Desktop),它就自动装好了。

  • 封装环境:它解决了“在我电脑上能跑,在你那里报错”的问题,把环境依赖都打包好了。

  • 自动配置:它会自动在后台帮你写好配置,不需要你手动去翻文件夹改 JSON。

3. 注意:它正在变身

虽然你现在看到的是 .dxt,但根据最新的标准,这个格式正在演变为 .mcpb (MCP Bundle)。它们的作用是一样的,都是为了让非技术用户也能像安装 Chrome 插件一样,轻松地给 AI 增加新技能。

总结一下:

如果你正在折腾 MCP 相关的开发,.dxt 就是你的发布工具;如果你只是使用者,它就是你的安装包

这道题真的学到好多
用dirsearch扫描1>发现网站的后端很可能是 Go 语言写的,因为pprof是GO程序常见的性能分析/调试工具简单说,开发者本来是拿它来:

  • 看程序占了多少内存

  • 看程序开了多少并发线程

  • 看程序运行时在干什么

2>/debug/pprof/heap

这个是看内存使用情况的。

/debug/pprof/trace

这个是更细的运行轨迹。

/health、/ping

这两个一般是健康检查接口

/metrics

这个一般是监控指标接口

很多程序会把:

  • 请求数量

  • 响应时间

  • 内存占用

  • CPU 使用情况

这种数据放在这里,给 Prometheus 之类的监控系统抓取。

/static/

这一般表示静态资源目录,比如:

  • 图片

  • CSS

  • JS

  • 前端文件

2>状态码:

200-访问成功

301-跳转

403-禁止访问

404-资源不存在

405-方法不允许

3>按照GPT给的优先级,先访问/debug/pprof

allocs

历史内存分配情况
可以理解成:过去内存都分给谁用了。

heap

当前还活着的内存对象
就是现在内存主要被谁占着。

goroutine

当前所有 goroutine 的堆栈信息
也就是程序当前“并发任务”的运行现场。

threadcreate

程序创建系统线程的情况
可以理解成程序开过哪些更底层的线程。

block

看哪些地方发生了阻塞
比如某些操作卡住了。

mutex

看锁竞争情况
就是多个地方抢同一把锁。

trace

程序运行轨迹
像更细的运行录像。

cmdline

程序启动命令
也就是这个程序启动时是怎么运行起来的。

symbol

把地址映射成函数名
偏底层,一般是给分析工具用的。

参考佬的WP:

分析前端源码,这页前端本质上就是一个“上传包 → 查看服务列表 → 启停/删除服务 → 查看服务详情”的管理面板;真正有价值的攻击面几乎都集中在它调用的那几个 /api/* 接口上,而不是页面样式本身。

前端唯一的“文件合法性检查”,就是看文件名后缀是不是 .dxt

然后就是codex帮着写的exp和伪造的.dxt文件了

就做出来这么多题,这几天也参加了几个出色的CTF战队的面试,在AGENT时代,想要担任一名合格的WEB手 还是要有比较坚实的基础,让自己变得更强和让AGENT更强并不冲突,加油