douphp20190711 code audit and vulnerability recurrence

douphp20190711 code audit and vulnerability recurrence

Download link http://down.douco.com/DouPHP_1.5_Release_20190711.rar

1. The parameter control is not strict when installing getshell

1.1 Audit process

During the audit, I directly used passive plus active scanning, installed douphp, and conducted routine tests. When I had no clue, I looked at the scan log and found code execution. Check the vulnerability at /install/index.php 161-173 Line, because the incoming parameters are not strictly filtered, and the written parameters are wrapped in double quotes, resulting in the incoming parameters will be directly executed as a function

Insert picture description here

1.2 Analysis vulnerability

First check whether the data / install.lock file exists, if it does not exist, proceed to the next step

The incoming parameters are filtered globally, and addlashes are used for processing. However, no other parameters are filtered. After the file is directly written and included, the code execution results can be viewed.

<?php
$dbpass   = "${@eval(phpinfo())};";
?>

Directly writing the following code will also produce such a vulnerability

Fixed this problem in the new version, replacing single quotes with double quotes

Insert picture description here

However, an installation vulnerability is generally more tasteless, if there is no arbitrary file deletion, it will have no effect, so the digging of arbitrary file deletion vulnerability is started next

2. Delete any files in the background

Take a look at the official changelog

Insert picture description here

Fix background security problems, check the update code

Insert picture description here

It is found that the deleted file name is regularly filtered, and the search is continued to search for the filtered parameter, and the value value taken from the mobile_logo of the database

Insert picture description here

We continue to check whether the value is controllable, and find related operations on this field.

The act operation parameter here is clear_logo. Through our observation of the background parameter transfer, we found that there is a delete logo operation under admin / mobile.php, which caused our idea to view the transfer parameters, track the code, and upload a file when it is found. Operation, try to modify the file name to upload, but the background parameters are always logo.png View background code

The core code is 62-69 lines under mobile.php

Insert picture description here

When viewing the code, pass the key value and key name assignment from the post, and then pass the update to enter the database storage, and do not operate on the file name, so view the data packet and modify it

Insert picture description here

Found that you can successfully modify the contents of the database, continue to view the image upload directory under the \ m \ theme \ default \ images directory, directly construct the payload "... / ... / ... / ... / data / install.lock", save it in the database, and perform the clrea_logo operation, After successfully deleting the data / install.lock file, we can brave the above installation vulnerability to write the shell.

3. The pits encountered

3.1 Audit of file upload

    function upload($file_field, $file_name = '') {
        if ($GLOBALS['dou']->check_read_write($this->full_file_dir) != 'write') {
            $GLOBALS['dou']->dou_msg($GLOBALS['_LANG']['file_dir_wrong']);
        }
        
        // 没有命名规则默认以时间作为文件名
        if (empty($file_name))
            $file_name = $GLOBALS['dou']->create_rand_string('number', 6, time()); // 设定当前时间为图片名称
        
        if (@ empty($_FILES[$file_field]['name']))
            $GLOBALS['dou']->dou_msg($GLOBALS['_LANG']['file_empty']);

        $name = explode(".", $_FILES[$file_field]["name"]); // 将上传前的文件以“.”分开取得文件类型
        $img_count = count($name); // 获得截取的数量
        $img_type = $name[$img_count - 1]; // 取得文件的类型
        if (stripos($this->file_type, $img_type) === false) {
            $GLOBALS['dou']->dou_msg($GLOBALS['_LANG']['file_support'] . $this->file_type . $GLOBALS['_LANG']['file_support_no'] . $img_type);
        }
        $full_file_name = $file_name . "." . $img_type; // 写入数据库的文件名
        $file_address = $this->full_file_dir . $full_file_name; // 上传后的文件名称
        $file_ok = move_uploaded_file($_FILES[$file_field]["tmp_name"], $file_address);
        if ($file_ok) {
            $img_size = $_FILES[$file_field]["size"];
            $img_size_kb = round($img_size / 1024);
            if ($img_size_kb > $this->file_size_max) {
                @unlink($file_address);
                $GLOBALS['dou']->dou_msg($GLOBALS['_LANG']['file_out_size'] . $this->file_size_max . "KB");
            } else {
                return $full_file_name;
            }
        } else {
            $GLOBALS['_LANG']['file_wrong'] = preg_replace('/d%/Ums', $this->file_size_max, $GLOBALS['_LANG']['file_wrong']);
            $GLOBALS['dou']->dou_msg($GLOBALS['_LANG']['file_wrong']);
        }
    }

The audit of the upload function found that the whitelist mode was used, and only the image file could be written. If the suffix of the image file exists in the whitelist, the obtained file suffix is ​​directly used as the file suffix and written. Through% 00 truncation and other methods have no effect, if there is no file contains and other vulnerabilities, there is no way to use

3.2 Speculation on whether the recorded IP of the account login can be injected

When we log in to the background, we can find that the system records the operation ip. If the ip is obtained in the wrong way, it can cause forgery, and the http header parameter is not in the get post cookie parameter, and it has not been globally filtered. A better injection point, we view the login page code

Get_ip () function on line 77 under admin / login.php, follow up the function

    function get_ip() {
        static $ip;
        if (isset($_SERVER)) {
            if (isset($_SERVER["HTTP_X_FORWARDED_FOR"])) {
                $ip = $_SERVER["HTTP_X_FORWARDED_FOR"];
            } else if (isset($_SERVER["HTTP_CLIENT_IP"])) {
                $ip = $_SERVER["HTTP_CLIENT_IP"];
            } else {
                $ip = $_SERVER["REMOTE_ADDR"];
            }
        } else {
            if (getenv("HTTP_X_FORWARDED_FOR")) {
                $ip = getenv("HTTP_X_FORWARDED_FOR");
            } else if (getenv("HTTP_CLIENT_IP")) {
                $ip = getenv("HTTP_CLIENT_IP");
            } else {
                $ip = getenv("REMOTE_ADDR");
            }
        }
        
        if (preg_match('/^(([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([1-9]?[0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$/', $ip)) {
            return $ip;
        } else {
            return '127.0.0.1';
        }
    }

Looking at the source code, I was very happy. Both of the above parameters can be forged, so I eagerly forged it, but found that the background did not have a chance of success. Instead, the IP became 127.0.0.1. So we continued to view the source code and found the following There is a regular match for ip ,,,,,

I'm sorry I haven't seen this point before injecting ip, I'm just a rookie.

4. Summary

Looking at the source code, I was very happy. Both of the above parameters can be forged, so I eagerly forged it, but found that the background did not have a chance of success. Instead, the IP became 127.0.0.1. So we continued to view the source code and found the following There is a regular match for ip ,,,,,

I'm sorry I haven't seen this point before injecting ip, I'm just a rookie.

4. Summary

For this cms, I only found the background getshell and the characteristics are particularly obvious. Delete the file and reset it. For practical operation, once this method is used, it is difficult. If the operation is improper, it will be easily invited by the uncle of the police to drink tea. It has been fixed in the new version of cms. Due to the poor personal level, I have not found a method of front-end SQL injection. If there is a front-end SQL injection, or with admin888 or information leakage, you can enter the background, reinstall the website, and repair the data after getshell. The problem is still not big. of.

Published 14 original articles · praised 0 · visits 13

Guess you like

Origin blog.csdn.net/qq_43645782/article/details/105468310