Preface
原本是用docker装的sqlib靶场,但是后来发现看源码有点麻烦,干脆还是localhost本地弄了。然后本地是xampp一体的环境,PHP版本与sqlib有点不匹配,就是原本是mysql的函数要全部换成mysqli,此外自己还把输入的SQL语句打印了出来便于理解,所以显示有些差异。
此外,这篇文章更多的是依据现有的sqlib的writeup写的,前半段因为不熟悉,更多偏重于对别人的payload的理解,仅用于记录感想。
【】标记代表知识点模糊,暂时还不能给出合理让人信服的答案,也许以后会填坑=。=
Less-1
根据提示,用GET方法上传ID,发现存在注入点。用单引号测试报错。
可以尝试用union看当前库名,payload:?id=-1’ union select 1,2,database();–+
之所以使用-1,在根据源码或测试后可知,用mysqli_fetch_array()一次只返回一行数据【1】,故为了不挡住我们union想要的数据,于是将前面那个设为查不到结果的-1;
其次,union查询的要求即两个查询表的列相同,根据测试可得select 1,2,database()返回三行数据,恰好匹配;
后面跟着的–+,–是注释,+号是url中替代空格的字符。
单行注释可以使用–注释符,–注释符后需要加一个空格,注释才能生效。
至于#号为什么不行,暂时还不知道原因【2】
至此得出数据库名为security;那么怎么利用呢?我去看writeup了……
1 ?id=-1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database() --+
=。=,完全看不懂,导向另一个坑:mysql建立的information_schema数据库,学会了再继续~
information_schema是一个mysql自动维护的、只读的数据库,里面包含了mysql数据库内所有的信息,而我们只需要知道里面的两个表,一个是tables表,一个是columns表。这就是上面information_schema.tables的来源,下面也有information_schema.columns。
tables表:
字段 | 含义 |
---|---|
Table_schema | 数据表所属的数据库名称; |
table_name | 数据表名称; |
columns表:
字段 | 含义 |
---|---|
table_schema | 数据表所属的数据库名称; |
table_name | 数据表名称; |
column_name | 列名称; |
根据这些信息,我们就可以看懂上面那个writeup了,就是先找出security数据库中所有的表名,然后
1 ?id=0' union select 1,2,group_concat(column_name) from information_schema.columns where table_name='users' --+
根据users表爆出所有列名,然后根据列名爆数据
1 ?id=0' union select 1,2,group_concat(username,0x3a,password) from users--+
至此第一关结束。
Less-2
和第一关几乎一模一样。。。对比了源码,发现差异仅在于第一关的$id传入时用单引号封闭,第二关未做任何处理而已。
BUT!有人说这是整型注入……不知道这是啥的我自然又去查了字符型注入和整型注入的概念==
数字型注入/整形注入:查询参数为数字,传参进入时不需要引号,即?id=(int);
整形注入:查询参数为字符或字符串,?id=(string);
对于该题而言,也就是有无引号而判断出是否是整型注入;
Less-3
同上,对比源码发现查询语句在Less-1的基础上加了一对括号,payload也就是在?id=0’后再多加个括号即可
Less-4
同上,传入的$id用(“$id”)进行包括,改一下即可
- 本文作者: crlwebby
- 本文链接: https://crlwebby.github.io/security/CTF/sqli-page1/
- 版权声明: 本博客所有文章除特别声明外,均采用 MIT 许可协议。转载请注明出处!