[Zer0pts2020]phpNantokaAdmin
题目是一个sqlite的数据库管理工具,实现的功能只有table的创建,展示,record的插入
查看代码
1 |
|
我们发现flag在FLAG_TABLE表中,表名和列名是config.php中定义的常量,此外
1 |
|
这样限制了可以展示的表仅限于flag表之外用户创建的表
在index.php;中可以看出,创建表时的表名,列名,列类型可能存在sql注入
1 |
|
但是,参数使用了untils.php中定义的is_vaild函数进行了一次检查,禁用了一些特殊字符
1 |
|
首先我们fuzz一下能够通过is_vaild函数的字符
1 |
|
注意:[
和]
可以使用,在sqlite中,可以使用[
和]
代替反引号来包裹字符
此外:sqlite中可以使用create table ... as
这样的用法,从其它的表的内容来创建新的表
利用这些,在创建表时,table t as select sql[列名abc,列类型] from sqlite_master;
,这样拼接成功后的sql语句为:
1 | CREATE TABLE t AS SELECT sql [ (dummy1 TEXT, dummy2 TEXT, `abc` ]FROM sqlite_master;); |
等价于create table t as select sql from sqlite_master;
,(dummy1…
被解释为sql的别名。这样在展示表时可以获得插入flag时的语句,其中包括flag表名和列名
所以我们在创建表时post传
1 | table_name=[aaa] as select [sql][&columns[0][name]=]from sqlite_master;&columns[0][type]=2 |
得到了表名和字段名
然后我们用同样的方法查看flag(需要先把之前那个表删掉)
1 | table_name=[aaa] as select [flag_2a2d04c3][&columns[0][name]=]from flag_bf1811da;&columns[0][type]=2 |
得到flag
sqlite bypass技巧
select的时候,当列名用空白字符隔开时,sqlite只会把空格之前的字符当做列名,并且忽视空格后的字符