Affected指定されているけどPoCが無いフ
レームワークで再現試験をした話
2016/8/16 一ノ瀬 太樹
自己紹介
名前:
一ノ瀬 太樹
Twitter:
@mahoyaya
所属:
HASHコンサルティング株式会社
OWASP Japan プロモーションチーム
OWASP ZAP ユーザーグループ
脆弱性診断研究会(管理者その3)
http://blog.hash-c.co.jp/2016/07/httpoxyaffectedpoc.html
httpoxyは警視庁による注意喚起もされており、非常に注
目を集めています。
httpoxyの原因
httpoxyの根本的な原因はCGIの仕様と一般的に利用される環境
変数との名前空間の衝突
そのため、CGIやCGIライクな環境を利用している場合に
httpoxyの影響を受ける可能性がある
具体的な動作
CGIでは、クライアントが送信したHTTPリクエストヘッダの情報を環境変
数に設定する際の動作がRFC3875で規定されている
大文字に変換
ハイフン"-"をアンダースコア"_"に変換
名前の先頭に"HTTP_"を付与
例えば次のリクエストがあると
1 GET /index.php HTTP/1.1 2 Host: foo.example.com 3 Proxy: 10.0.0.1:8080CGIの動作により次の環境変数がセットされる
1 HTTP_PROXY=10.0.0.1:8080ただし、この動作だけで問題が発生するわけではない
HTTP_PROXYという環境変数は、一般的にCLIで利用されるコマン
ドベースのアプリケーションがProxyサーバを利用する際に参照す
るもの
この脆弱性が存在するWebサーバが環境変数を参照して外部通信
を行う場合に次の問題が発生する
内部サーバ宛てhttp通信の盗聴
外部サーバ宛てhttp通信の盗聴および改ざん(中間者攻撃)
本脆弱性への対処
PHPでは最新の5.5.38, 5.6.24, 7.0.9, 7.1.0-beta1にてgetenv関数にlocal_onlyの引数を持つこ
とが出来るようになる修正が含まれたことを確認。
今回利用しているフレームワークのArtaxでは2.0.4で修正されている。
回避策は大きく次の方法がある
•
HTTPリクエストヘッダを書き変える
• Apache HTTP Serverのmod_headersやNginxのfastcgi_paramなどが利用できる•
WAFでDropする
• Apache HTTP Serverのmod_rewriteなどが利用できる•
外部接続にHTTPSを利用する
• アプリケーションがHTTPS_PROXYを参照するようになり、原理的に影響を受けなくなるその他の回避策
httpoxy公式
https://httpoxy.org/
nginx公式の注意喚起
再現試験をした
httpoxyに関してはhttpoxy.orgによるPoCが既に公開されており、
ネタとしては面白くない。
なので、AffectedになっているがPoCは公開されていないPHPの
フレームワークであるArtax v2.0.3を利用して試験!
環境
本当の構成
Apache HTTP Server 2.2.15 + PHP 5.5.37
事象が再現したことを確認するためのPHPファイ
ル “httpoxy.php“を作る
# code
1 <?php
2 use Amp¥Artax¥Client;
3 require 'artax/vendor/autoload.php'; 4
5 echo "<h1>httpoxy exploit check</h1><br>¥n";
6 echo "<br>==============================================<br>¥n"; 7 echo "var_dump(¥$_SERVER['HTTP_PROXY']);¥n"; 8 var_dump($_SERVER['HTTP_PROXY']); 9 echo "<br>"; 10 echo "getenv('HTTP_PROXY');¥n"; 11 var_dump(getenv('HTTP_PROXY')); 環境変数を表示 環境変数を表示
# code
15
16 try {
17 $client = new Client;
18 $promise = $client->request('http://www.example.jp'); 19 $response = Amp¥wait($promise); 20 printf( 21 "¥nHTTP/%s %d %s¥n", 22 $response->getProtocol(), 23 $response->getStatus(), 24 $response->getReason() 25 );
26 } catch (Exception $error) { 27 echo $error;
外部通信を行う
環境変数にHTTP_PROXYをセットさせてみる
HTTPリクエストヘッダに“Proxy: 192.168.80.1:8080”などを設定してリクエストを送ると環
境変数をセットさせることが出来る。
“192.168.80.1”はWindows10のIPアドレスだが、ポート番号8080のアクセスは受け付けない
状態なので、「ARPは解決できるが、TCP接続は受け付けない状態」
curlを利用してリクエストを送信する
結果
# Response
6 var_dump($_SERVER['HTTP_PROXY']);
7 <pre class='xdebug-var-dump' dir='ltr'><small>string</small> <font color='#cc0000'>'192.168.80.1:8080'</font> <i>(length=17)</i>
8 </pre><br>getenv('HTTP_PROXY');
9 <pre class='xdebug-var-dump' dir='ltr'><small>string</small> <font color='#cc0000'>'192.168.80.1:8080'</font> <i>(length=17)</i> 10 </pre><br><br>============================================= =<br> 11 12 HTTP/1.1 200 OK 読み込まれてる 読み込まれてる
結果
# Response
6 var_dump($_SERVER['HTTP_PROXY']);
7 <pre class='xdebug-var-dump' dir='ltr'><small>string</small> <font color='#cc0000'>'192.168.80.1:8080'</font> <i>(length=17)</i>
8 </pre><br>getenv('HTTP_PROXY');
9 <pre class='xdebug-var-dump' dir='ltr'><small>string</small> <font color='#cc0000'>'192.168.80.1:8080'</font> <i>(length=17)</i>
10 </pre><br><br>============================================= =<br>
読み込まれてる
結果
# Response
Artaxのコードを確認した
1.ArtaxはProxyのパラメータを2つのオブジェクト(Client, HttpSocketPool)内に同じ
配列名かつ同じ変数名の“$options[self::OP_PROXY_HTTP]”で保持しており、
“getenv(‘http_proxy’)”で取得した値はHttpSocketPool側で保持している。
2.“new Client;”したタイミングでコンストラクタにより“new HttpSocketPool;”も実行
され、自動的に環境変数が読み込まれる。
※"self::OP_PROXY_HTTP"は双方共にHttpSocketPoolの定数を参照
3. 2つのオブジェクトが保持している配列のパラメータはリクエストを送信する際に
array_merge関数によってマージされるが、オブジェクトClientのパラメータで上書きさ
以下は、HttpSocketPool内のcheckout関数で利用されている実際のコード
$options にオブジェクトClientで設定されているパラメータが格納されている
# code
57 $options = $options ? array_merge($this->options, $options) : $this->options;
ProxyのパラメータはオブジェクトClientの初期化時に必ず空(‘’)で生成されるた
め上書きされてしまう
すごくモヤモヤする仕様だし、
脆弱性になっていない
コードを書き換えよう(ぇ
# code
57 //$options = $options ? array_merge($this->options, $options) : $this->options; 58 $options = $options ? array_merge($options, $this->options) : $this->options;
172.20.10.0/24 .3 .6 Fedora22(Server) Mac(Client) VM テザリング .1 稼働サービス Proxy: 8080 稼働サービス Httpd: 80 HASHのブログ
DEMO構成
172.20.10.0/24 .3 .6 Fedora22(Server) Mac(Client) VM テザリング .1 稼働サービス Proxy: 8080 稼働サービス Httpd: 80 HASHのブログ
通常通信
① ②172.20.10.0/24 .3 .6 Fedora22(Server) Mac(Client) VM テザリング .1 稼働サービス Proxy: 8080 稼働サービス Httpd: 80 HASHのブログ