Home >Backend Development >PHP Tutorial >PHP backdoor composed of .user.ini file
0x00 Background
I guess many students looked at this with disdain and thought it was a piece of shit:
A PHP backdoor composed of .htaccess file
Then let me make a new one: .user.ini. It is more widely used than .htaccess. No matter it is nginx/apache/IIS, this method can be used as long as php running with fastcgi. All my nginx servers use fpm/fastcgi, all my IIS php5.3 and above use fastcgi/cgi, and my apache under win also uses fcgi. It can be said to be very broad, unlike .htaccess which has limitations.
0x01 .user.ini
So what is .user.ini?
This has to start with php.ini. php.ini is the default configuration file of PHP, which includes many PHP configurations. These configurations are divided into several types: PHP_INI_SYSTEM, PHP_INI_PERDIR, PHP_INI_ALL, PHP_INI_USER. You can view it here: http://php.net/manual/zh/ini.list.php What are the differences between these modes? Take a look at the official explanation:
enter image description here
It is mentioned that the configuration item with mode PHP_INI_USER can be set in the ini_set() function, set in the registry, and then set in .user.ini. .user.ini is mentioned here, so what configuration file is this? Then the official document explains here:
In addition to the main php.ini, PHP will also scan INI files in each directory, starting from the directory where the executed PHP file is located and going up to the web root directory ($_SERVER[ 'DOCUMENT_ROOT'] specified). If the PHP file being executed is outside the web root directory, only that directory will be scanned.
Only INI settings with PHP_INI_PERDIR and PHP_INI_USER modes are recognized in .user.ini style INI files.
It’s very clear here, .user.ini is actually a php.ini that can be “customized” by the user. The settings we can customize are the settings with the mode “PHP_INI_PERDIR, PHP_INI_USER”. (PHP_INI_PERDIR not mentioned in the above table can also be set in .user.ini)
In fact, modes other than PHP_INI_SYSTEM (including PHP_INI_ALL) can be set through .user.ini.
And, unlike php.ini, .user.ini is an ini file that can be loaded dynamically. That is to say, after I modify .user.ini, I don’t need to restart the server middleware. I only need to wait for the time set by user_ini.cache_ttl (default is 300 seconds) before it can be reloaded.
Then we saw the configuration items in php.ini. Unfortunately, I found to my dismay that all the slightly sensitive configuration items are in PHP_INI_SYSTEM mode (even php.ini only), including disable_functions, extension_dir, enable_dl, etc. However, we can easily construct a "backdoor" with the help of the .user.ini file.
There are two interesting items in the Php configuration items (the first and fourth in the picture below):
enter image description here
auto_append_file, auto_prepend_file, click to see what they mean:
enter image description here
Specify a file and automatically include it before the file to be executed, similar to calling the require() function before the file. Auto_append_file is similar, but included after the file. The usage is very simple, just write it directly in .user.ini:
auto_prepend_file=01.gif
01.gif is the file to be included.
So, we can use .user.ini to easily make all PHP files "automatically" include a certain file, and this file can be a normal PHP file or a webshell containing a sentence.
Test it, I tested on IIS6.0+Fastcgi+PHP5.3 and nginx+fpm+php5.3 respectively. The directory contains .user.ini, 01.gif containing webshell, and normal php file echo.php:
enter image description here
enter image description here
Visit echo.php to see the backdoor:
enter image description here
Same under Nginx:
enter image description here
enter image description here
So, we can think about it, in what situations can this gesture be used? For example, if a certain website restricts the uploading of .php files, you can upload a .user.ini, then upload an image horse, and include them for getshell. But the premise is that there needs to be a normal php file in the folder containing .user.ini, otherwise it cannot be included. For another example, if you just want to hide a backdoor, this method is the most convenient.