时间:2022-6-4来源:本站原创作者:佚名
前言

经过上一篇文章我们已经大概的了解sql注入去怎样审计了。但是在实际的网站中和用户的输入输出接口不可能想那样没有防御措施的。现在各大网站都在使用waf对网站或者APP的业务流量进行恶意特征识别及防护,避免网站服务器被恶意入侵。所以我们就需要绕过waf,这篇文章就用代码审计的方式给大家讲解一些sql的绕过技巧。

关键字过滤

部分waf会对关键字进行过滤,我们可以用大小写或者双写关键字来绕过。

源代码分析

?phprequiredb.php;header(Content-type:text/html;charset=utf8);$username=dl($_POST[username]);$password=dl($_POST[password]);$dl="SELECT*FROMxsWHEREusername=$usernameandpassword=$password";//登录界面后台处理$ck=mysqli_query($db,$dl);$row=mysqli_fetch_array($ck);if($_POST[login]){if($row){echo"你的密码".$row[username];}else{echo"登录失败";}}functiondl($gl){$gl=str_replace(array("union","UNION"),"","$gl");$gl=str_replace(array("select","SELECT"),"","$gl");$gl=str_replace(array("database","DATABASE"),"","$gl");$gl=str_replace(array("sleep","SLEEP"),"","$gl");$gl=str_replace(array("if","IF"),"","$gl");$gl=str_replace("--","","$gl");$gl=str_replace("order","","$gl");return$gl;}

分析一下代码,首先获取了数据,加载dl函数以后带入了数据库中执行,然后if判定是否有提交,是否登录成功,登录成功后回显用户的账号,这是一个非常简单的后台登录代码。往下看有一个自定义函数dl,函数内使用了str_replace(),str_replace()的作用是替换字符串,这里union,select,database,if这些常用的注入字符大小写都被替换成空。做了一个简单的危险字符过滤自定义函数。

关键字过滤注入方法

用大小写和双写关键字来尝试绕过,返回代码里有回显位所以可以union注入,dl函数把union,select这些字符替换成空但是mysql中是不不区分大小写的,所以可以大小写混写来绕过dl函数的过滤。比如SelectUnionDAtabase()这样的字符是可以执行的。也可以用双写的手法,比如seselectlect这样的语句,dl函数会把里面的select替换为空这样两边的字符凑在一起刚好又是一个select这样就起到了绕过的作用。

大小写绕过语句为

-1’unioNSelectdataBASE(),2#

双写关键字绕过语句为

-1’ununionionselecselecttdatabasdatabasee(),2#

都运行成功

orandxornot过滤

orandxornot像这样的逻辑运算也会被过滤袋掉那我们怎么绕过呢?

源代码分析

?phprequiredb.php;header(Content-type:text/html;charset=utf8);$username=dl($_POST[username]);$password=dl($_POST[password]);$zifu=/(and

or

xor

not)/i;if(preg_match("$zifu","$username$password")){echo"scriptalert(存在危险字符)/script";}$dl="SELECT*FROMxsWHEREusername=$usernameandpassword=$password";//登录界面后台处理$ck=mysqli_query($db,$dl);$row=mysqli_fetch_array($ck);if($_POST[login]){if($row){echo"登录成功";}else{echo"登录失败";}}functiondl($gl){$gl=str_replace(array("union","UNION"),"","$gl");$gl=str_replace(array("select","SELECT"),"","$gl");$gl=str_replace(array("database","DATABASE"),"","$gl");$gl=str_replace(array("sleep","SLEEP"),"","$gl");$gl=str_replace(array("if","IF"),"","$gl");$gl=str_replace("--","","$gl");$gl=str_replace("order","","$gl");return$gl;}?

阅读一遍代码发现在上一段的基础上面添加了一个preg_match函数,这个函数过滤了orandxornot关键字,需要注意的是preg_match会大小写都过滤,继续往下读回显位改成了成功或者失败所以我们只能采用盲注或者延时注入。

逻辑运算符绕过

先尝试大小写绕过,果然是失败的。

使用逻辑运算符尝试

and=or=

xor=

#异或not=!

使用代替and构造盲注语句1’length(DATAbase())=3#因为关键字过滤函数还在所以还同时需要大小写绕过。

注入成功

url编码绕过

在平常使用url提交数据时,web容器在接到url后会自动进行一次url编码解析,但是由于业务问题有些网站在web容器自动解析之后,通过编写程序对解析的参数进行再次url编码解析,就会出大问题。

源代码分析

?phprequiredb.php;header(Content-type:text/html;charset=utf8);$id1=$_GET[id];$gl="/and

or

not

xor

length

union

select

database

if

sleep

substr/i";if(preg_match($gl,$id1)){echo"scriptalert(存在危险字符)/script";}else{$id=urldecode($id1);$dl="SELECT*FROMxsWHEREid=$id";$result=mysqli_query($db,$dl);$row=mysqli_fetch_assoc($result);if($_GET[id]){if($row){echo"登录成功:".$row[username];}}}?

上来还是先看看代码,把客户端传入的get参数赋值进了$id1,用if加preg_match对变量$id1的值进行检索。如果客户端传入的参数有$gl里的值,那么就会返回前端代码进行警告。没有危险字符才会执行下面的代码,接着把$id1里的参数进行一次url解编码并赋值给$id。此时客户端传入的参数已经经过了两次url编码解析。最后过滤完成把id变量带入数据库中进行查询并返回用户的账号。

注入语句

分析代码时说到客户端传入的参数会进行两次url编码解析之后带入数据库,但危险过滤是在第一次解析之后第二次解析之前执行的。也就是说我们可以写入两次url编码过的语句绕过preg_match,比如and在过滤范围之中,对and一次url全编码后变为%61%6e%64%0,再进行一次编码为%25%36%31%25%36%65%25%36%34。把经过两次编码后的and提交数据会经过web容器解码后变为%61%6e%64,preg_match判定就不会触发。

构造尝试语句

把-1’unionselectdatabase(),2,3—+编码为-1’

%25%37%35%25%36%65%25%36%39%25%36%66%25%36%65%25%37%33%25%36%35%25%36%63%25%36%35%25%36%33%25%37%34%25%36%34%25%36%31%25%37%34%25%36%31%25%36%32%25%36%31%25%37%33%25%36%35(),2,3—+

成功绕过,代码执行带出了当前数据库。

精彩推荐

预览时标签不可点收录于话题#个上一篇下一篇
转载请注明原文网址:http://www.coolofsoul.com/phpfz/phpfz/24118.html
------分隔线----------------------------