1.此夜圆—— 一江春水何年尽,万古清光此夜圆
查看附件 index.php:

典型字符串逃逸,利用 15 个 Firebasky 转换后变成 Firebaskyup 来保持长度一致

最终 payload:$username=‘1FirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebaskyFirebasky”;s:8:“password”;s:5:“yu22x”;}#‘;
2.故人心—— 三五月中新月色,二千里外故人心

1.is numeric(a)<7 and a**2==0
a 要是数字,长度小于 7,平方后等于 0,利用浮点数 下溢,当小数点超过 161 位做平方运算时会被截断,同时长度需要小于 7,利用科学计数法
?a=1e-162
2.md2 碰撞,和 md 碰撞差不多
b)) && (c))
c 经过两次 md2 加密后要和自身相等
弱比较中 0e 被当作科学计数法返回 0,所以我们只需要另变量以 0e 开头并且经过加密后依旧以 0e 开头就能绕过
查看提示 robots.txt

提示告诉了我们两个变量的结尾,缩小了了查询的范围
构造脚本:

注意构造的c 要是纯数字字符串才能比较为 0,但是 md2 加密后的字符串可能含有字母,因此需要检验是否为纯数字字符串:is_numeric(b) && substr(b,0,2) ==“0e”

拿到 b,c 的值
if(filter_var($url[1],FILTER_VALIDATE_URL)){
url[1]);
print _r($host);
if(preg_match(/ctfshow.comhost[‘host’]){
print _r(file_get _contents($url[1]);
FILTER_VALIDATE_URL 检验参数是否为合法 url
url[1]);解析主机名,检验主机名是否为 ctfshow.com 结尾
经过多种绕过尝试无果,查找资料发现 file_get_contents 遇到未知协议时会把整个 url 当作本地路径处理,同时搭配目录穿越
url=a://ctfshow/../../../../../fl0g.txt
parse_url() 解析结果:
Array(
[scheme] => a
[host] => ctfshow.com // ← 满足正则 /ctfshow.com$/
[path] => /../../../../../fl0g.txt
)
3.莫负婵娟—— 皎洁一年惟此夜,莫教容易负婵娟

查看登录页面源码,泄露了用户名称与 sql 查询语句
SELECT T*FROM users whereusername like binary(‘password’)
先测试可用字符情况,发现过滤了 ’ ” () , # \ %
允许 _ 空格
过滤了单引号很难受,闭合不了前面的引号就把不能形成注入了,感觉是要利用 like,但是具体还是不知道怎么操作,查看题解才知道还可以利用 like 进行盲注
LIKE 语句支持%和 _ 两个通配符,此处可利用 _
使用 payload:_____,当下划线数量与密码数量一致时会触发回显,探测后发现密码数量为 32 位,大概率是哈希加密后的值

这样的话就可以一步步探测每位上的值是多少,构造脚本:

哈希后的值的范围在 0123456789abcdefABCDEF 中

得到密码:67815b0c009ee970fe4014abaa3Fa6A0

登录成功跳转到一个 ping 界面
经过测试过滤了小写字母,/
可用:大写字母 $ ; ? 空格
有点懵,小写字母全都过滤了怎么玩,linux 命令区分大小写,小写字母过滤了我怎么操作
查看题解发现一个很巧妙的方法,通过字串截取环境变量的输出拿到小写字母
本机上测试:


通过截取字符串拿到我们想要执行的命令

但是 flag 在 flag.php 中,通过环境变量拿不到 f,又陷入死胡同了,再次查看题解,居然用?通配符来替代字符,md 我怎么想不到

为什么我想不到?????