PHP code audit 3 - system reinstallation vulnerability

I. Introduction

1. Types of system reinstallation vulnerabilities

  • Automatically delete installation files

    常见的系统安装后,会生成一个lock文件来判断是否安装,如果系统会自动删除这一个文件的话,就会导致系统重装漏洞产生。
    
  • No installation result verification

    这种情况就是不会删除.lock文件,也不会生成.lock安装文件。
    
  • Installation detection can be bypassed

    这种情况就是,在安装过程中,系统安装检测是一个单独的页面,检测完成后302跳转到安装的情况。
    在这种情况下,我们就可以直接get请求安装页面来达到绕过检测的目的。
    
  • Variable override causes reload

    可以使用GET或者POST等方式提交一个变量名$lockFile,并为其赋空值,覆盖掉$lockFile,从而让file_existe()判断结果为false,达到绕过安装文件检测的目的。
    
  • After judging the lock file, there is no exit

    判断是否存在lock文件,如果lock文件存在则会跳转到某个页面,但是跳转后并没有exit检测程序。
    
  • There is a parsing vulnerability

    在安装完成后会将install.php重命名为install.php.bak,但是由于Apache的解析漏洞:如果无法识别到最后一个后缀的话,就会向上解析,那么就又变成了php了,然后结合安装时的变量覆盖又成重装了。
    

2. List of recent vulnerabilities

  • CNVD-2020-58513: ZZCMS 2020 version system reinstallation vulnerability
  • CNVD-2020-33196: Shield Spirit 1.0 system reinstallation vulnerability
  • CNVD-2020-31454: Heybbs micro-community install.php file reinstallation vulnerability
  • CNVD-2020-02229: Delivery 100 system reinstallation vulnerability
  • CNVD-2019-43815: s-cms enterprise website building system reinstallation vulnerability
  • CNVD-2018-05690: hpyun talent system version 4.5 reinstallation vulnerability

2. ZZCMS 2020 reinstallation vulnerability analysis and recurrence

1. Vulnerability analysis

First we see the vulnerable code: install/index.php.

On line 11 of the code, there is a $step variable whose value is passed in by the client.

6:include '../inc/config.php';
7:include 'conn.php';
8if($_POST) extract($_POST, EXTR_SKIP);//把数组中的键名直接注册为了变量。就像把$_POST[ai]直接注册为了$ai。
9:if($_GET) extract($_GET, EXTR_SKIP);
10:$submit = isset($_POST['submit']) ? true : false;
11:$step = isset($_POST['step']) ? $_POST['step'] : 1;

A ternary operator is used here to make a judgment. If the step parameter is not passed in, it will be assigned a value of 1 by default.

That is to say, when index.php is initially accessed, $step=1 will be assigned by default.

Next, let's focus on line 50:

50:switch($step) {
    
    
51:	case '1'://协议
52:		include 'step_'.$step.'.php';
53:		break;
54:	case '2'://环境
55:		$pass = true;
56:		$PHP_VERSION = PHP_VERSION;
57:		if(version_compare($PHP_VERSION, '4.3.0', '<')) {
    
    
58:			$php_pass = $pass = false;
59:		} else {
    
    
60:			$php_pass = true;
61:		}

Here, a switch statement is used to determine $step. When $setp=1, the step_1.php file will be included. The function of this file is to determine whether our system has been installed by detecting the install.lock file. Its code is as follows:

if(file_exists("install.lock")){
    
    
	echo "<div style='padding:30px;'>安装向导已运行安装过,如需重安装,请删除 /install/install.lock 文件</div>";
}

And when the step is 2 or other, it will enter the system installation step, so when we capture the packet and modify the value of $step to 2 or 3, it will directly enter the system installation step, thereby bypassing the system installation detection.

2. Vulnerability recurrence

The following picture shows the system we have installed:
insert image description here

We visit /install/index.php, then use burpsuite to capture packets, construct step=2, and modify the parameter transfer method to POST submission, successfully bypassing the system installation detection and entering the system installation steps:

insert image description here

3. System Reinstall Vulnerability in Shield Spirit V.10

Note: The Dunling system includes the official account promotion system, news release system, information sharing system, etc. This time, the official account promotion system of Dunling is used for code audit.

1. Vulnerability analysis

First of all, we first visit your-IP/install/index.php. The effect is as follows. Two detection steps are provided, one is database connection detection, and the other is file write permission detection.

insert image description here

Then we turn our attention to the /install/index.php file. It is mainly some JS code, which uses jqurey's ajax request to send data to the back-end interface. It can be seen that from line 36 to line 42, ajax request is used to send database information to mysql.php.

36:     $.post("mysql.php",
37{
    
    
38:      mysqlip:mysqlip,
39:      mysqlusername:mysqlusername,
40:      mysqluserpass:mysqluserpass,
41:      mysqldb:mysqldb
42},

Then we followed the train of thought and looked at the mysql.php file, and found that the function of this file is to detect whether our database can be connected normally.

<?php
error_reporting(0);
header("Content-type: text/html; charset=utf-8");
$ip = $_POST['mysqlip'];
$username = $_POST['mysqlusername'];
$userpass = $_POST['mysqluserpass'];
$db = $_POST['mysqldb'];
$ok1 = mysql_connect($ip,$username,$userpass)or die("数据库连接错误,请检查账号或密码是否有误!");
$ok2 = mysql_select_db($db)or die("无法找到数据库,请检查数据库名称是否填写正确");
if($ok1 or $ok2){
    
    
    echo "ok";
}
?>

Then we follow the train of thought and look at the file read and write permission detection in the second step. In the /install/index.php file, ajax is also used to request the backend interface, but the requested file is is_writable.php, and the access The file parameter is config.php.

$("#install_2").click(function(){
    
    
    $.post("is_writable.php",{
    
    
        file:'config.php'
}

Then I found that the way if_writeable.php judges whether the file has read and write permissions is to use the is_writable() function to judge whether the config.php file is writable.

isset($_POST['file'])?$file = $_POST['file']:$file="config.php";
$is = is_writable($file);

When both detection items are detected successfully, the option to install the system immediately will pop up.

insert image description here

The execution result of this selection is to send the parameters related to connecting to the database to the backend "steup.php file" through ajax.

 $.post("setup.php",
    {
    
    
      mysqlip:mysqlip,
      mysqlusername:mysqlusername,
      mysqluserpass:mysqluserpass,
      mysqldb:mysqldb
    },

In setup.php, the parameters for connecting to the database are obtained first, and then it is checked again whether the database can be connected. If the database connection detection result is OK, the config.php file will be created. And insert the account number and password of the administrator. The password here is encrypted by MD5, but after the installation is successful, it will prompt that the password of the admin account is the first line of the English keyboard, so it is also a hard-coded password vulnerability.

And on line 29, we see that it renames the index.php file in the /install directory to the index.lock file.

16if($ok){
    
    
17$mysqlconfig = $ip.'@dunling@'.$username.'@dunling@'.$userpass.'@dunling@'.$db;
18$config_t = file_get_contents("mysql_config.dll");
19$config_a = array("@server@","@mysqlname@","@mysqlpass@","@mysqldb@");
20$config_b = array($ip,$username,$userpass,$db);:
21$mysqlconfig = str_replace($config_a,$config_b,$config_t);
22$fileok = file_put_contents("../config.php",$mysqlconfig);:
23if($fileok){
    
    
24echo "installok";
25$adminsql = "INSERT INTO `dunling_admin` VALUES ('1', 'admin', '90b9aa7e25f80cf4f64e990b78a9fc5ebd6cecad')";
26$configsql = "INSERT INTO `dunling_config` VALUES ('1', '盾灵微信加粉联盟系统', 'www.dunling.com', '1.00', '5000.00', '2.00', '10', '0.20', '0.00', '0','25')";
27mysql_query($configsql,$ok1);
28mysql_query($adminsql,$ok1);
29rename("index.php","index.lock");:
30}else{
    
    
31echo "installno";
32}

But through the previous analysis, we know that the installation system is actually carried out in the setup.php file, but the file has not been deleted or renamed, that is, if we directly construct the database connection parameter request setup.php , it will bypass the previous database detection and file permission detection, and directly reinstall the system.

But one thing worth noting is that when we construct the database connection parameters, the relevant parameters are not known, so we can only rely on social workers or other means to obtain them, which is still quite difficult to use.

2. Vulnerability recurrence

Note: Just mentioned that under normal circumstances we don't know the database connection parameters, but here we simulate that we have obtained relevant parameters for experiments.

First of all, we can see that the installed page looks like this:

insert image description here

Then we request the /install/setup.php file, and use burpsuite to capture packets, modify the request method to POST, and set the transmission data as database related parameters, send the request, and you can see the prompt of successful installation.

insert image description here
Finally, to sum up, as the two system reinstallation vulnerabilities that were discovered relatively recently, it can be seen that their vulnerability logic is due to the fact that the installation and detection are on different pages, so the installation detection can be bypassed. It can be seen that this is indeed a common problem in system installation and detection. For newcomers like me who want to dig out such vulnerabilities, you can try this idea more.

Guess you like

Origin blog.csdn.net/qq_45590334/article/details/125468741