Aquaboutic | Focus Security Research | Vulnerability Exploit | POC


on the security of open source web program background

Posted by zura at 2020-03-12

I. Preface

Somehow recently I miss campus life and the fried rice in the canteen. At that time, I would go to all kinds of security BBS to brush posts, like to see others' summary of security skills or experience; at that time, many articles on the BBS were titled: successfully infiltrate XXX, successfully win XXX. Here is an article about invading a university in the Philippines. Let's take a brief look at the process. The university website uses an open-source Web program called Joomla, (1) young people use a vulnerability that Joomla has already disclosed to enter the web background, (2) young people use Joomla to upload a web shell (3) the control host presents our national flag.

The original invasion of a host is so easy, the administrator decisively put a security patch on the web program. The administrator's work is over. As a security practitioner, I wonder if there is a problem that Joomla can upload webshell in the background. If Joomla can't upload webshell in the background, it can reduce the possibility and loss of intrusion. Let's go to the topic of this article: security of Web daemons.

Two, introduction

Many sites in China are built on open-source forums and CMS, such as discuz, phpwind, dedecms, etc. These programs are the best of the domestic open-source Web programs, and also pay more attention to security. Usually people pay more attention to SQL injection and XSS, which can directly steal user data. There are countless cases of weak password intrusion on the Internet. In addition, user data leakage incidents happen from time to time. The backstage that relies solely on password protection is broken through, and it is more and more likely to be social workers. After obtaining a management background password, combined with any code execution, file inclusion or command injection vulnerabilities of the background program to get a shell, it is not difficult to steal user information. At this time, the security of the background program becomes a short board.

Discuz is a popular forum program. The author takes its background program as an example to briefly analyze its security. Let's take a look at some vulnerability cases (the latest version of discuz has been patched, please upgrade to the latest version - Discuz! X3.1 r20140101).

3、 Case study tips: the $settingnew mentioned below is a variable for discuz to store form data in the background, which can be controlled by users in the background.

Case 1: improper filtering logic of user input data

Vulnerability file: x3 \ source \ admincp \ admincp _setting.php


//1. Alice modifies $settingnew ['extcredits'] non array

if(is_array($settingnew['extcredits'])) {

foreach($settingnew['extcredits'] as $key => $value) {

//2. Pass phpinfo(); to $settingnew ['initcredits'] [1], non array bypass intval conversion

$settingnew['initcredits'][$i] = intval($settingnew['initcredits'][$i]);

... omit

for($i = 1; $i <= 8; $i++) {

//3. Phpinfo(); assigned to $initformula

$initformula = str_replace('extcredits'.$i, $settingnew['initcredits'][$i], $initformula);


//4. Phpinfo() is brought into Eval for execution

eval("\$_G['setting']['initcredits'] = round($initformula);");

Case 2: secondary injection

Briefly introduce the secondary injection. The malicious user Alice enters the malicious data at a and is stored in the database, which does not directly cause security problems at a; the data stored at a is referenced at B, which triggers security problems.

Vulnerability file: x3 \ source \ admincp \ admincp _setting.php


//1. Assume that Alice uploads a picture Trojan horse as 1. GIF; Alice sets the value of $settingnew ['seccodedata '] ['type'] as 1. Gif \ 0: XX (jump the appropriate directory according to the picture address); the value is not filtered and stored in the database

if($settingnew['seccodedata']['type'] == 0 || $settingnew['seccodedata']['type'] == 2) {

$seccoderoot = 'static/image/seccode/font/en/';

} elseif($settingnew['seccodedata']['type'] == 1) {

$seccoderoot = 'static/image/seccode/font/ch/';


Vulnerability file: source \ module \ misc \ misc_seccode.php

//2. The $_g ['setting '] ['seccodedata'] ['type '] value comes from the database, that is, the 1. Gif \ 0: XX passed in at 1

if(!is_numeric($_G['setting']['seccodedata']['type'])) {

$etype = explode(':', $_G['setting']['seccodedata']['type']);

if(count($etype) > 1) {

//3., \ 0 truncate to get $codeFile as the picture Pony (you can also use the method of multiple pathers to truncate it)

$codefile = DISCUZ_ROOT.'./source/plugin/'.$etype[0].'/seccode/seccode_'.$etype[1].'.php';

... omit

if(file_exists($codefile)) {

//4. The picture trojan is included to get webshell

@include_once $codefile;

Case 3: loopholes caused by new logic of program upgrade

Vulnerability file: x3 \ source \ admincp \ admincp_adv.php

//1. Suppose that Alice uploads a picture Trojan horse as 1.gif; the value of Alice's incoming type parameter is 1. Gif \ 0: XX (jump to the appropriate directory according to the picture address)

$type = $_GET['type'];


If ($type) {

//2. Get $etype of 1. Gif \ 0

$etype = explode(':', $type);

if(count($etype) > 1) {

//3. $advfile value is truncated by \ 0, which is the picture Trojan path 1.gif

$advfile = DISCUZ_ROOT.'./source/plugin/'.$etype[0].'/adv/adv_'.$etype[1].'.php';

$advclass = 'adv_'.$etype[1];


... omit

//4. Include picture Trojan to get webshell

if(file_exists($advfile)) {

require_once $advfile;

Compared with the logic of x2.5, the vulnerability here is completely caused by the new code.

$type = $_GET['type'];

$target = $_GET['target'];

$typeadd = '';

If ($type) {

$advfile = libfile('adv/'.$type, 'class');

if(file_exists($advfile)) {

require_once $advfile;

Case 4: imperfect bug repair

Vulnerability file: x3 \ API \ uc.php


//1. The content of config ﹣ ucenter.php is as follows: define ('uc ﹣ API ','http: / / localhost / BBS / UC ﹣ server');

$configfile = trim(file_get_contents(DISCUZ_ROOT.'./config/config_ucenter.php'));


//2. $UC ﹣ AP is externally controllable. Alice passes in the value of $UC ﹣ API as XYZ '); Eval ($﹣ post [CMD]; gets the value of $configFile as define ('uc ﹣ API','xyz \ '; Eval ($﹣ post [CMD];'); the quotation mark after XYZ is escaped.

$configfile=preg_replace("/define\('UC_API',\s*'.*?'\);/i","define('UC_API','".addslashes($UC_API)."');", $configfile);

//3. Write define ('uc_api ','xyz \'; Eval ($_post [CMD]; '); to the configuration file

if($fp = @fopen(DISCUZ_ROOT.'./config/config_ucenter.php', 'w')) {

       @fwrite($fp, trim($configfile));


}//4. Alice passes in the value of $uc_api as XYZ again, and the regular expression used by preg_replace is define \ ('uc_api ', \ s *'. *? '\);. *?' non greedy match, matching to the end of the first quotation mark, and the previous escape character is replaced by XYZ \ to XYZ, so as to get the value of $configFile as define ('uc_api ','xyz'); Eval ($_post [CMD]; '); write the configuration file to get webshell.

As early as 2010, this issue was publicized externally, and the official patch has been released in time

Four, summary

The above examples are mainly the summary of the author's practical experience, not necessarily comprehensive, hoping to expand some ideas for you; for example, the two injections mentioned above, the variable $settingnew['seccodedata']['type'] is not filtered, and other arrays of $settingnew may not be filtered, and there are many similar problems. You can try it yourself. There are two main directions about code auditing: (1) dangerous function tracking input upward; (2) tracking whether user input enters dangerous function; dangerous function here mainly includes code execution related: Eval, assert, file including, require, etc., command execution: system, exec, etc., write file fwrite, file "put" contents, etc;

Two articles are recommended for code audit:

Five, reflection

1. All inputs are harmful;

The user input of the background program mainly increases the data of the background form compared with the foreground. In addition, some background supports uploading files (such as the customized SQL of dz1.5), and the content of the uploaded files also belongs to the input; these inputs belong to the user scope. We must do strict control and filtration.

2. Safety awareness;

In fact, many loopholes are not caused by technical problems, but by our lack of security awareness and attention to security. In particular, the third and the fourth should not happen at all; they need to give security publicity and basic security training to developers.

3. Vulnerability review;

(1) After receiving the vulnerability, developers should summarize the causes of the vulnerability and review whether there are similar problems in the code. Sometimes developers just fix the vulnerability points provided by the security personnel or white hat. Another code has similar problems and continues to break the loopholes. This will bring more hidden dangers. Hackers are very willing and good at summarizing and reflecting. Each patch actually expands the thinking of hackers. If the patching is not complete, the consequences will be very serious.

(2) The security personnel need to test and confirm after the completion of the repair by the developers. The above case 4 is a distinct example. If possible, security personnel should sort out some common bug repair guidelines, which can also improve work efficiency.