摘要:24-37关,是sqli-labs Page-2(Adv Injections)
Less-23
- 单引号闭合,有错误回显,过滤了
--
和#
首先我们id=1,页面返回正常,试着加一个单引号,返回SQL语法错误;payload?id=1' and 1=1 --+
依然返回SQL错误,然后可以发现的是?id=1' and 1=1
与?id=1 and 1=1 --+
的报错返回没有任何不同,猜测注释符被过滤;改变思路,不再试图注释掉单引号,而是试着闭合它。
payload:
image?id=0' union select 1,@@version,3 and '1'='1
Less-24
- 二次注入
这一关是二次排序注入的范例,我们首先将可能造成SQL注入的字符串存入数据库中,再构造SQL语句调用这段字符串,引发SQL注入;
在本例子中,我们作为一个局外人,试图修改并登陆一个已注册的用户的账号;我们首先注册一个admin' #
的账号,然后登陆该账号修改密码,那么我们此时我们的SQL语句将变成了UPDATE users SET PASSWORD='$pass' where username='admin'#' and password='$curr_pass'
因此修改密码的操作实际上修改了admin用户的密码,接下来就使用admin的账号登陆了。
Less-25
- 单引号闭合,有数据库报错回显,有查询回显点过滤了and和or
因为有数据库的报错回显,可以使用报错注入;查询回显点也具有,因此也可以使用union联合查询注入,当然延时注入也是可以使用的,那么关键问题就在于如何绕过对and和or的过滤了;可以尝试以下方法:1.大小写绕过(如用And,Or来代替)2.双写绕过(anandd,oorr)3.编码,hex,urlencode等4.添加注释符(/*and*/)5.利用符号代替,and &&,or ||
image image在本例中,大小写绕过失效,符号,注释符也不能使用,只能使用双写来绕过;
Less-25a
- 无需闭合,无数据库回显报错,有查询回显点过滤了and和or
与25关类似,这里没有引号不需要闭合,没有了数据库报错的回显,报错注入不能生效,但是可以使用union联合查询注入和延时注入
Less-26
- 单引号闭合,有数据回显报错,有查询返回点,过滤了and、or和空格等
这一段是从源代码中拷下来的过滤规则
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;
}
可以看到过滤了and和or,无视大小写的过滤,过滤了注释符#、注释符--、以及多行注释/*、空格、以及斜杠反斜杠。对于and和or的过滤,依旧使用双写来绕过,不能使用注释符注释掉单引号,则可以利用'1'='1
来闭合掉单引号;对于空格的过滤,我们可以使用一些特殊字符的编码形式来代替空格,包括:
%09 TAB键(水平制表符)
%0a 新建一行
%0c 新建一页
%0d return 功能
%0b 垂直制表符
%a0 空格
可以采用报错注入,延时注入和union联合查询注入:
imageLess-26a
- 单引号+括弧闭合,其他同第26关
在本例中,基本与26关类同,需将闭合方式由单引号闭合改为单引号+括弧闭合。
Less-27
- 单引号闭合,在第26关的基础上过滤了union和select
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;
}
可以看到虽然过滤了select和union但是过滤并没有设置不区分大小写,给了我们可乘之机,因此对于“缺乏想象力”的黑名单,采用大小写混合的驼峰式结构可以绕过过滤,当然双写绕过也是可以的。preg_replace()
函数第一个参数匹配模式后的字母表示模式修饰符。
Less-27a
- 闭合方式改为双引号,与27关相同
在这里根据前面的经验,先测试出闭合方式后,修改了下27关的payload,直接可以使用
imageLess-28&Less-28a
- 单引号+括弧闭合、过滤了
union select
、注释符以及空格;有查询返回点无报错回显点;
Less-28
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+select/i',"", $id); //Strip out UNION & SELECT.
return $id;
}
Less-28a
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+select/i',"", $id); //Strip out spaces.
return $id;
}
分析黑名单过滤的源代码可以看到,Less-28将会过滤union select
(\s表示空白字元,也就是空格的意思);又因为这里过滤了太多,连空格也过滤掉了,我们根本就没用到空格,因此这里的体现并不明显;Less-28a的时候反而将过滤的条件放的更开,空格也不再过滤,因此我们可以试着用空格来代替%a0
来验证我们的猜想,结果没错,union select
被过滤掉了,在这里用Less-28的payload是完全可以的,毕竟Less-28的过滤条件是严格与Less-28a的,我们也可以使用更具Less-28a特色的payload:?id=0')%a0union selunion selectect%a01,2,3%a0||('1
,过滤是无视大小写的,双写可以顺利绕过。
image
image
Less-29&30&31
从页面上看,这三关应该是有waf的,应该过滤很严格,或是一不小心就会触发waf,但是利用常规的方法却确实可以成功注入;
imageimage
image
上网上查阅,发现很多博主也是很懵,但有的博主给出了正确的姿势,确实是绕过waf的,但不知道是更新还是什么原因,目录下并没有.jsp文件,暂扣,毕竟waf很广的,有机会看看原作者的视频,学习学习出个单篇的。
宽字节注入
原理:MySQL在使用GBK编码的时候,会认为两个字符为一个汉字,例如:%aa%5c就是一个汉字,(当前一个的ascii码大于128时才能到汉字的范围)
Less-32
- 输入会经过处理,单引号会被转义;关键在于如何使用单引号
addslashes()
函数——使用反斜线引用字符串;返回值为字符串,该字符串为了数据库查询语句等的需要在某些字符串前加上了反斜线。这些字符是单引号(')、双引号(")、反斜线(\)与NUL(NULL字符)。
因为我们的但因好前会自动加上反斜杠来转义,导致注入不能正常进行,因此必须要消灭掉这个转义;利用前面的宽字节注入的原理,添加%df来消灭掉\,因为urlencode('\)=%5c%27
,我们在前面添加%df,形成%df%5c%27
,因为MySQL在GBK编码时会将两个字节当做一个汉字,此时%df%5c就是一个汉字,%27作为一个单独的符号留在外面,也就达到了我们的目的。
这里的%df也不是特殊的,还记得前面说过需要前一个的ascii大于128时才能到汉字的范围吗?十六进制的80正好是十进制的128,当我们使用%81时,发现没毛病,与%df时效果一样,由此可见,%df并非特殊的一个值,只是大于128而已。
imageimage
Less-33
- 本关于32关基本类似
查看源代码我们可以发现Less-32的过滤思路:
function check_addslashes($string)
{
$string = preg_replace('/'. preg_quote('\\') .'/', "\\\\\\", $string); //escape any backslash
$string = preg_replace('/\'/i', '\\\'', $string); //escape single quote with a backslash
$string = preg_replace('/\"/', "\\\"", $string); //escape double quote with a backslash
return $string;
}
将'
转换为\'
,将"
转换为\"
,将\
转换为\\
,而第33关:
function check_addslashes($string)
{
$string= addslashes($string);
return $string;
}
addslashes()
函数与32关所实现的功能基本一致,返回在预定义字符之前添加反斜杠的字符串,预定义字符是:单引号、双引号、反斜杠;使用addslashes()
函数时,必须将mysql_query
设置为binary的方式,才能防御此漏洞mysql_query("SET character_set_connection=gbk,character_set_result=gbk,charater_set_client=binary",$conn);
Less-34
- post宽字节注入...
觉得有些文章……一大抄的感jio,并且在post不能使用编码来构造宽字节注入后的处理并没有讲太清,只是给出了一个可以复制粘贴的字符,�'or 1=1#,详细可以点击这篇文章——sqli-labs————Less-34(宽字节绕过、水平越权、盲注)
Less-35
- 同32关,get方式的宽字节注入,但是!这里并不需要引号闭合,也不在需要引号闭合,宽字节注入也就不存在了。(也是挺坑的)
Less-36
第36关,通过源代码,我们可以看到:
function check_quotes($string)
{
$string= mysql_real_escape_string($string);
return $string;
}
这里使用的是mysql_real_escape_string()
函数,函数的功能是——转义SQL语句中使用的字符串中的特殊字符,并考虑到连接的当前字符集,字PHP5.5.0时起已废弃,并在PHP7.0.0开始被移除;代替者mysqli_reql_escape_string()
这些字符均受影响:\x00、\n、\r、\、'、"、\x1a如果成功,则函数返回被转义的字符串,如果失败,则返回false。
使用该函数时,需要将字符集设置为GBK,如果没有设置为GBK字符集,则该函数仍旧可以被突破,方法是一样的。在使用mysqli_real_escape_string()
时,为了能够安全地防护这种问题,需要将MySQL设置为GBK即可;设置代码:mysql_set_charset('gbk','$conn')
Less-37
37关于前面34关是相似的,都是post传入数据,但是这里使用的不是addslashes()
函数,而是mysql_real_escape_string()
函数。
网友评论