FASTCGI组件漏洞
CGI introduction
common gatewa interface/CGI describes a stardand for transferring data between server and client programs,allowing a client to request data from a program running on a network server via web browser
CGI is independent of any language,CGI program can be implemented using any scripting language or completely independent programming language,as long as this language can run on the system.(in fact,it is to process http request data parsed by the web server)
CGI workflow
the complete process is shown in follow figure.
specific process as follows:
1.user send a request package via browser to access server.
http://xx?user=1&passwd=1&age=11
2.server accquire the data and parse it
3.nginx don't know how to handle these login data and send them to the cgi program.the server then creates a CGI process to handle the data
4.CGI process execute
5.server send the cgi handle result to the client
CGI specific structure
the specific process of CGI process is as follows:
1. load the configuration,if neccessary,load the configuration to obtain data
2.connect to other server like database
3.perform logical processing
4.obtain the result and send it to server
5.exit
the drawbacks of CGI
when nginx send data to cig process,the server will create a cgi process.
frequent creation and destruction of processes are required when dealing with data,which leads to high server overhead and low efficiency.
therefore we can take a look at fastcgi
fastcgi
fast common gateway interface is an improvement over the CGI.fastcgi aims to reduce the overhead of interaction between web servers and cgi program,allowing server to handle more web request simultaneously.
unlike create a new process for each reqeust,fastcgi uses persistant processes to handle a serias of requests.
these processes are managed by fastcgi manager,rather than web server
different between fastcgi and cgi
FastCGI is a long-lived application program, while CGI is a short-lived application program. FastCGI is like a resident (long-live) CGI that can keep running without having to fork every time. In contrast, a regular CGI creates a new process for each request. FastCGI is a resident process and service, as can be seen from the following line of code.
while(FCGI_Accept()>=0)
The specific process is as follows:
1.The user accesses the server through a browser and sends a request with the following URL: http://localhost/login?user=zhang3&passwd=123456&age=12&sex=man
2.The server receives the data and parses it.
3. For some login data that it does not know how to handle, nginx sends the data to the fastcgi program through local sockets and network communication (via the socket interface).
4. FastCGI is started (not directly by the web server, but by a fastCGI process manager). The process includes loading configuration (optional), connecting to the server (database), and looping (if there is a request from the server, process it and send the processing result to the server; if there is no request, block).
5. The server sends the processing result of fastCGI to the client.
fastcgi usage
nginx cannot directly execute external executable programs like Apache, but it can act as a proxy server and forward requests to backend servers, which is one of its main functions. Among them, nginx supports FastCGI proxy, which receives client requests and then forwards them to the backend FastCGI process. Here's how to write CGI/FastCGI using C/C++ and deploy it to nginx. As mentioned earlier, FastCGI processes are managed by the FastCGI process manager, not nginx. This requires a FastCGI manager to manage our FastCGI program. We use spawn-fcgi as the FastCGI process manager. spawn-fcgi is a universal FastCGI process manager that is simple and compact. It was originally part of lighttpd, but later became a standalone project due to its widespread use. spawn-fcgi uses the pre-fork model, which mainly opens the listening port, binds the address, and then fork-and-exec to create our FastCGI application process, and exits to complete the work. The FastCGI application program initializes and then enters a loop to listen for socket connection requests.
php-fpm
PHP-FPM is a program that implements the FastCGI protocol. Its full name is FastCGI Process Manager. With PHP-FPM, web containers can send data in the format of the FastCGI protocol(the format is key-value), and PHP-FPM can execute the PHP file specified by the value of SCRIPT_FILENAME.
By default, PHP-FPM listens on port 9000. If this port is directly accessible, we can construct the FastCGI protocol ourselves and communicate with FPM.
For example, if we can control the content of this request packet, we can add 'PHP_ADMIN_VALUE': 'allow_url_include = On' to the request packet. Then the file requested in this request can use remote file inclusion.
loophole exploit
conditions
1 the absolute path of one php file on server
2. we can access php-fpm 9000 port
we can construct a malicious fastcgi format data to transfer with php-fpm,then we can make a rce
{ 'GATEWAY_INTERFACE': 'FastCGI/1.0', 'REQUEST_METHOD': 'GET', 'SCRIPT_FILENAME': '/var/www/html/index.php', 'SCRIPT_NAME': '/index.php', 'QUERY_STRING': '?a=1&b=2', 'REQUEST_URI': '/index.php?a=1&b=2', 'DOCUMENT_ROOT': '/var/www/html', 'SERVER_SOFTWARE': 'php/fcgiclient', 'REMOTE_ADDR': '127.0.0.1', 'REMOTE_PORT': '12345', 'SERVER_ADDR': '127.0.0.1', 'SERVER_PORT': '80', 'SERVER_NAME': "localhost", 'SERVER_PROTOCOL': 'HTTP/1.1' 'PHP_VALUE': 'auto_prepend_file = php://input', 'PHP_ADMIN_VALUE': 'allow_url_include = On' }
This request is to access index.php, and its absolute path on the server is /var/www/html/index.php. Knowledge of the absolute path of a file is necessary to exploit vulnerabilities.
auto_prepend_file tells PHP to include the file specified in auto_prepend_file before executing the target file; auto_append_file tells PHP to include the file specified in auto_append_file after executing the target file.
Now, suppose we set auto_prepend_file to php://input and enable allow_url_include by adding 'PHP_ADMIN_VALUE': 'allow_url_include = On' in the fastcgi data. In this case, index.php will first load the code we put in the post request body before loading, achieving remote code execution.