| 项目 | 内容 |
|---|---|
| 平台题名 | L杯-签到 check-01 |
| 分类 / 难度 | Web / Easy(签到) |
| 入口 | http://<host>/ |
| 提交物 | flag{...} |
一、观察
打开入口只有一个深色主题的欢迎页,中间是一个终端风格窗口,正文写着:
$ ./welcome --hint
有些东西,不需要攻击。
页面上没有任何输入框、按钮或链接。这句话本身是第一个提示:不需要攻击,也就是说不用去找接口打漏洞,答案就在页面本身。
二、查看网页源代码
Ctrl+U(或右键 → 查看网页源代码)。渲染时看不见的 HTML 注释里有:
<!--
Hint:
Sometimes developers leave debug interfaces behind.
-->
开发者有时会把调试接口留在线上。那么下一步就是找「调试开关」。
三、触发调试输出
按最常见的调试参数写法,直接在 URL 加 query string:
curl "http://<host>/?debug=1"
这次返回的不再是欢迎页:
-----------------
Environment: production
Debug flag: enabled
FLAG: flag{xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx}
-----------------
拿到的就是本题 flag。
几个容易踩的点
?debug(不带值)不会触发——代码里判断的是真值。?debug=0也不会触发。?debug=1、?debug=true都可以。如果不想被 shell 吞掉,注意在 URL 里加引号。- 这个参数是 GET 的,所以浏览器地址栏直接改也行,不必用 curl。
四、完整命令
# 1. 看页面源码,找注释里的 debug 提示
curl -s "http://<host>/" | grep -i hint
# 2. 带调试参数请求
curl -s "http://<host>/?debug=1"
# 3. 提取 flag
curl -s "http://<host>/?debug=1" | grep -oE 'flag\{[^}]+\}'
五、知识点与思路沉淀
- 不要只看渲染后的页面。HTML 注释、隐藏元素、JS 变量、
data-*属性都算「页面隐藏信息」,Ctrl+U永远是 CTF Web 的第一步。 - 注释里的 hint 就是路线,不是噪声。看到 “debug interfaces” 就应该直接联想到
?debug=1//debug/?test=1这一族开关,逐个试过去。 - 真值判断:这类后端通常写
if ($_GET['debug'])或if (getenv('DEBUG')),空串和"0"在 PHP 里是假值,所以必须给真值。 - 生产环境把调试接口带上线,是真实世界里极常见的信息泄露成因(
/debug、/actuator、/phpinfo.php、/.env都属于同一类)。
六、真实环境验证
本 writeup 的路径在一次性容器里实测通过,输出:
-----------------
Environment: production
Debug flag: enabled
FLAG: flag{check01_local_ok}
-----------------
(实际比赛环境里 flag 由平台在启动容器时注入,值与上面不同,格式一致。)