2014-04-13 (Sun) Heartbleed を tedu が分析 [長年日記]
_ また勝手訳。だって誰もこの件を取りあげてくれないんだもん。適当なので原文にあたってください。原文は色もついてて綺麗だし。
_ http://www.tedunangst.com/flak/post/heartbleed-vs-mallocconf (4/8)
heartbleed vs malloc.conf
約二年前に OpenSSL は新機能を導入しましたが、それは昨日まで皆さんが使ったことも聞いたこともなかったものでした。そう、プロセス内のメモリを読み出せるようにしてしまうバグが発見されるまでは。
heartbleed
そのバグ heartbleed のメインサイトには大量の情報がありますが、バグそのものの詳細な説明はありません。そちらは Diagnosis of the OpenSSL Heartbleed Bug をご覧ください。 ここにも参考のため擬似的なショートバージョンを載せておきます。
struct { unsigned short len; char payload[]; } *packet; packet = malloc(amt); read(s, packet, amt); buffer = malloc(packet->len); memcpy(buffer, packet->payload, packet->len); write(s, buffer, packet->len);packet はヒープのどこかにいて、我々はそこからユーザ指定の量だけ応答バッファにコピーしようとしています。そのユーザ指定のデータ長は 16 ビットだけですから安全ですし、書き込み先のバッファも常に確保されています。危険なのは、入力バッファが足りないかもしれないということです。バッファ以上に読み出せば、応答の中に本来あるはずのない情報が入ってしまいます。packet にいま雇われているメモリの前回の内容が interesting だったなら、応答の中身も interesting になってしまいます。
緩和方法
前回の内容が interesting でなければどうでしょう。たとえば再利用する前に malloc がメモリ内容を上書きしてくれていたら? まさに malloc.conf が J オプションで行なうとおりにです。そのオプションを付けていれば、攻撃しても 0xd0 を羅列したバッファしか得られませんから、明らかに uninteresting です。が、しかし……
物事には「しかし」がつきものです。libsslが OPENSSL_NO_BUF_FREELISTS オプション付きでコンパイルされていなければ (当時の OpenBSD では付いてなかった)、libssl は自前の freelist を管理し、malloc のあらゆる緩和策を無効にしてしまいます。そう、OpenSSL には自前の、攻撃緩和策の緩和策が組み込まれているのです。もちろん個人的にそのオプション付きで libssl をコンパイルすることはできます。が、しかし……
内部 freelist なしで libssl をビルドしてみたところ、それにリンクした nginx は、断続的かつ不規則に接続を拒否します。Firefox (nss) も ftp (libssl) もこのようなエラーを報告します:
1007048992:error:1409442E:SSL routines:SSL3_READ_BYTES:tlsv1 alert protocol version:libssl/src/ssl/s3_pkt.c:1255:SSL alert number 70ここで私はギブアップしました。 (そして……何が起こっているのかをあとで解明しました。)
入力パケットバッファの範囲を超えてデータをコピーしてしまうのは、防護ページを置く方法でも阻止できるはずです。マップされていないページを叩く → 即ドカーン。となるはずですが、まだドカーンを引き起こせていません; ということはlibssl のバッファはいつも十分に大きいように見えます。そう仮定するなら、読み出すメモリは必ず、以前に free されたメモリで、かつ利用中ではないメモリということになります。もちろん、free 済みメモリに大量の interesting なデータ (http ヘッダやフォームデータなど) があることは、お手軽なテストでも簡単にわかります。(libssl の入力パケットバッファが正確にどれほどの大きさなのかを確認するのは、やれば冥府の底より深くもぐることになるのでイヤです。挑戦者は心してかかるように。)
Posted 2014-04-08 18:36:16 by tedu Updated: 2014-04-10 13:52:22
_ http://www.tedunangst.com/flak/post/analysis-of-openssl-freelist-reuse (4/10)
openssl 内 freelist 再利用の分析
二日ほど前、Heartbleed を緩和する方法を探して OpenSSL をつついて回っていたところ、まずデフォルト設定の中に攻撃緩和策ブレイカが入っていることに気づきました。さらに、その邪魔なオプションを無効にしたところ OpenSSL は機能を完全に停止しました。とてもひどい状況ですが、そのときはもう我慢の限界でしたので、昨晩になって犯行現場に戻りました。
freelist
OpenSSL は接続バッファに独自の freelist を使っています。これは遠い昔、はるか彼方の malloc 速度が遅かったことに由来します。ユーザに自分でもっと良い malloc を探せと言うかわりに、OpenSSL は手作りの LIFO freelist を取り入れました。もうわかりますね。OpenSSL はその LIFO freelist を誤用しています。じつは、いまから説明するバグが存在し、また気づかれずにいる原因は、まさに freelist が LIFO であるというそのことにあるのです。
OpenSSL は接続からのデータを一時バッファに読み出しますが、バッファは必要に応じて新規に取得します。ソースは ssl/s3_pkt.c の関数 ssl3_read_n と ssl3_read_bytes を参照のこと。その際 record バッファ s->s3->rrec と read バッファ s->s3->rbuf の違いで混乱しないよう気をつけましょう。バッファの setup および release 関数本体は ssl/s3_both.c にあります。
1059 行目では、ヘッダを読み終わって ssl3_release_read_buffer を呼んでいます。これでバッファを free することになります。
if (type == rr->type) /* SSL3_RT_APPLICATION_DATA or SSL3_RT_HANDSHAKE */ { [...] if (!peek) { rr->length-=n; rr->off+=n; if (rr->length == 0) { s->rstate=SSL_ST_READ_HEADER; rr->off=0; if (s->mode & SSL_MODE_RELEASE_BUFFERS) ssl3_release_read_buffer(s); } }ちょっとした問題がひとつあります。このバッファはまだ使い終わっておらず、あとで読みたいデータが中に残っているのです。さいわい、LIFO freelist に言えばすぐ返してもらえるのですから、ほんの小さな問題ですね! 数ミリ秒もない一瞬だけ freelist で休んだら、すぐ ssl3_read_n が呼ばれて、そこから setup が呼ばれ、先程のところから続行です。同じバッファの、同じ中身で。
rb = &(s->s3->rbuf); if (rb->buf == NULL) if (!ssl3_setup_read_buffer(s)) return -1; left = rb->left;ただし、もちろんこれは freelist がない場合や release が本当にバッファをリリースする場合(!)を除いての話です。つまり OPENSSL_NO_BUF_FREELIST を付けてコンパイルすると動きません。最初のバッファは永遠に失われてしまい、まったく別のバッファを読み出し始めることになります。この新しいバッファが、前のバッファと同じデータを持っていることはあまり起きそうにありません。OpenSSL は、思っていたのと違うデータが来て混乱し、接続を強制終了するというわけです。
(謎: rb->left の値はなーんだ)
パッチ
解決策はとても簡単です。使い終わっていないならリリースしないことです。この毛玉を梳く方法はおそらく多数あるでしょう; そのひとつがこちらです:
diff -u -p -r1.20 s3_pkt.c --- s3_pkt.c 27 Feb 2014 21:04:57 -0000 1.20 +++ s3_pkt.c 10 Apr 2014 03:31:18 -0000 @@ -1054,8 +1054,6 @@ start: { s->rstate=SSL_ST_READ_HEADER; rr->off=0; - if (s->mode & SSL_MODE_RELEASE_BUFFERS) - ssl3_release_read_buffer(s); } } return(n);分析
もし OpenSSL 開発陣が面倒がらずにふつうの malloc (セキュリティ特化型 malloc でなくても、毎回ちゃんとメモリを free するもの) でテストしていたなら、このバグはまったく明白だったことでしょう。事実はその反対、私が心臓出血加速式アロケータをオフにする方法を探そうとするまで、何年も目覚めることなく横たわり続けたのです。
攻撃緩和策を構築するのは簡単なことではありません。それが難しいのは攻撃者たちが容赦なく狡猾だからです。それがイラッとするのは、攻撃を受けていないときでさえ正しく動作しない駄目ソフトがあまりにたくさんあって、多くの緩和策を完全には有効にできないからです。しかしセキュリティに関わる重要ソフトウェアの開発者が、世界で最も攻撃しやすいアロケーション手段を使ってこうした努力を妨害しておきながら、それを無効にできるかどうかのテストすらしないでいるときには、マジおこぷんぷん丸ですよ。
Update: ここにぶち当たったのは私が最初ではありませんでした。4年たつバグレポート があります。あともうひとつも。Piotr 教えてくれてありがとう!
Posted 2014-04-10 13:04:41 by tedu Updated: 2014-04-10 19:05:28
だから問題は、まず malloc に手をつけようと思った時点で「これは(セキュリティ的に)危険な作業だ」と思わなかったこと。freelist デザインの時点で「これって何かあったら危険なヤツだ」と思わなかったこと。freelist 無効での動作をテストしなかったこと。捨てたはずのメモリを freelist から拾ってこようと思った時点で「これ変だ」と思わなかったこと。この組み合わせだと思います。
- http://b.hatena.ne.jp/entrylis... ×9 : 1, 1, 1, 1, 1, 1, 1, 1, 1
- http://reader.livedoor.com/rea... ×5
- http://b.hatena.ne.jp/entry/ta... ×2
- http://b.hatena.ne.jp/rgfx/rss... ×2
- http://profile.hatena.ne.jp/hy... ×1
- http://profile.hatena.ne.jp/am... ×1
- http://profile.hatena.ne.jp/su... ×1
- http://t.co/e8kROR0lgS ×176
- http://slashdot.jp/submission/... ×154
- http://t.co/LjNPBTzUqD ×144
- http://slashdot.jp/ ×63
- http://t.co/BzIjv15GmZ ×32
- http://t.co/Cuos10nNoJ ×31
- http://opensource.slashdot.jp/... ×26
- http://slashdot.jp/submission/... ×19
- http://opensource.slashdot.jp/... ×16
- https://www.facebook.com/ ×10
- http://t.co/RNzJpL2XEw ×8
- http://t.co/6LXMakx8ZD ×7
- http://www.crowy.net/ ×5
- http://slashdot.jp/recent ×4
- http://pipes.yahoo.com/pipes/p... ×4
- http://it.slashdot.jp/submissi... ×4
- http://feedly.com/index.html ×4
- https://www.google.co.jp/ ×2
- http://htn.to/GnbEs6 ×2
- http://b.hatena.ne.jp/ya--mada... ×2
- http://b.hatena.ne.jp/tacchini... ×2
- http://b.hatena.ne.jp/ockeghem... ×2
- http://b.hatena.ne.jp/keyword/... ×2
- http://b.hatena.ne.jp/kjw_juni... ×1
- http://twipple.jp/ ×1
- http://ttr.zamanen.net/ ×1
- http://t.co/4ttMWGsRo0 ×1
- http://slashdot.jp/submission/... ×1
- http://slashdot.jp/submission/... ×1
- http://slashdot.jp/stories ×1
- http://slashdot.jp/index2.pl?f... ×1
- http://opensource.slashdot.jp/... ×1
- http://my.yahoo.co.jp/p/3.html... ×1
- http://inagist.com/all/4533445... ×1
- http://htn.to/RpJzVd ×1
- http://feedly.com/ ×1
- http://b.hatena.ne.jp/yiizuka/... ×1
- http://b.hatena.ne.jp/tacchini... ×1
- http://b.hatena.ne.jp/peppers_... ×1
- http://b.hatena.ne.jp/payato2/... ×1
- http://b.hatena.ne.jp/omron/fa... ×1
- http://b.hatena.ne.jp/ockeghem... ×1
- http://b.hatena.ne.jp/nYtvlllo... ×1
- http://b.hatena.ne.jp/mkouhei/... ×1
- http://b.hatena.ne.jp/mikihosh... ×1
- http://b.hatena.ne.jp/mikihosh... ×1
- http://b.hatena.ne.jp/medtoolz... ×1
- http://b.hatena.ne.jp/mayuki/f... ×1
- http://b.hatena.ne.jp/mayuki/f... ×1
- http://twtr.jp/home?max_id=456... ×1
- http://b.hatena.ne.jp/keyword/... ×1
- http://b.hatena.ne.jp/kanose/f... ×1
- http://b.hatena.ne.jp/kadoppe/... ×1
- http://b.hatena.ne.jp/crayzic/... ×1
- http://b.hatena.ne.jp/convivia... ×1
- http://b.hatena.ne.jp/coldcup/... ×1
- http://b.hatena.ne.jp/asihuret... ×1
- http://b.hatena.ne.jp/amdgRCC/... ×1
- http://b.hatena.ne.jp/Naruhodi... ×1
- http://b.hatena.ne.jp/Kamekiti... ×1
- http://b.hatena.ne.jp/ ×1
- http://app-mgng-local.rhcloud.... ×1
- http://api.twitter.com/1/statu... ×1
- http://api.twitter.com/1/statu... ×1
- http://api.twitter.com/1/statu... ×1
- http://api.twitter.com/1/statu... ×1
- はてなダイアリー[hoshikuzu] ×190 : 182, 5, 2, 1
- はてなダイアリー[next49] ×18 : 16, 1, 1
- はてなダイアリー[optical_frog] ×9 : 6, 2, 1
- はてなダイアリー[xenoth] ×6 : 5, 1
- はてなダイアリー[iww] ×4
- はてなダイアリー[thalion] ×2
- はてなダイアリー[nekoruri] ×2 : 1, 1
- http://reader.livedoor.com/rea... ×12
- http://rssc.dokoda.jp/r/f85e51... ×1
- http://t.co/k4nbg6N?tw_i=30022... ×1
- http://t.co/k4nbg6N?tw_i=29811... ×1
- tDiary.Net[tdiary2] ×1
- http://profile.hatena.ne.jp/am... ×1
- http://getpocket.com/a/read/48... ×1
- http://b.hatena.ne.jp/iww/rss ×1
- http://b.hatena.ne.jp/entry/ta... ×1
- http://practical-scheme.net/wi... ×605
- http://dic.nicovideo.jp/b/v/sm... ×170
- https://www.google.co.jp/ ×162
- http://mojix.org/2008/04/13/di... ×48
- http://kjunichi.cocolog-nifty.... ×45
- http://emasaka.blog65.fc2.com/... ×44
- https://www.google.com/ ×19
- http://www.google.com/search ×15
- http://security.slashdot.jp/st... ×13
- http://valvallow.blogspot.jp/2... ×10
- http://it.slashdot.jp/story/12... ×9
- http://www.kt.rim.or.jp/~kbk/z... ×8
- http://platform.twitter.com/wi... ×7
- http://dev.mutt.org/trac/wiki/... ×7
- http://blog.livedoor.jp/lionfa... ×7
- http://blog.livedoor.jp/lionfa... ×7
- http://www5.ocn.ne.jp/~roy21/ ×6
- http://www.kt.rim.or.jp/~kbk/z... ×6
- http://t.co/k4nbg6N ×6
- http://practical-scheme.net/wi... ×6
- http://www.kt.rim.or.jp/~kbk/z... ×5
- http://practical-scheme.net/wi... ×5
- http://dic.nicovideo.jp/v/sm19... ×5
- http://affilinews.info/ ×5
- http://www.google.com/gwt/x?gl... ×4
- http://www.comprare-acquistare... ×4
- http://valvallow.blogspot.jp/2... ×4
- http://ugo2.dip.jp/2013/10/23/... ×4
- http://practical-scheme.net/wi... ×4
- http://orera.g.hatena.ne.jp/ed... ×4
- http://www.infotop.jp/click.ph... ×3
- http://www.hi-matic.org/diary/... ×3
- http://www.addebitocartadicred... ×3
- http://twitcasting.tv/keiki22 ×3
- http://t.co/oXaOxVwgUU ×3
- http://search.seesaa.jp/SJIS 文... ×3
- http://muranoserena.blog91.fc2... ×3
- http://cloud.feedly.com/ ×3
- http://blog.search.yahoo.co.jp... ×3
- http://blog.livedoor.jp/flatli... ×3
- http://www.venditafarmacionlin... ×2
- http://www.infotop.jp/click.ph... ×2
- http://www.infotop.jp/click.ph... ×2
- http://www.google.co.jp/ ×2
- http://www.farmaciaonlines.com... ×2
- http://www.babynene.com/ ×2
- http://word.collect777.com/b/s... ×2
- http://ugo2.dip.jp/ ×2
- http://twilog.org/ts7i/date-10... ×2
- http://togetter.com/li/44088 ×2
- http://my.opera.com/community/... ×2
- http://j.mp/w0xkrG ×2
- http://hs4500.seesaa.net/ ×2
- http://blog.livedoor.jp/lionfa... ×2
- http://b.hatena.ne.jp/kitmkr/b... ×2
- https://lakura.net/jp/lakura-h... ×1
- http://www.x-tec.de/typo3conf/... ×1
- http://www.rkcorp.co.jp/ ×1
- http://www.lakura.net/jp/domai... ×1
- http://www.infotop.jp/click.ph... ×1
- http://www.infotop.jp/click.ph... ×1
- http://www.infotop.jp/click.ph... ×1
- http://www.infotop.jp/click.ph... ×1
- http://www.houndo-k.com/ ×1
- http://www.google.com/gwt/x?gl... ×1
- http://www.google.com/ ×1
- http://www.google.co.jp/gwt/x?... ×1
- http://www.genericotadalafi.co... ×1
- http://www.ee-nara.com/ ×1
- http://www.drugs.com/answers/w... ×1
- http://www.crowy.net/ ×1
- http://www.cozmixng.org/~rwiki... ×1
- http://www.annunci-net.com/ ×1
- http://webcache.googleusercont... ×1
- http://webcache.googleusercont... ×1
- http://togetter.com/li/54458 ×1
- http://togetter.com/li/41525?p... ×1
- http://togetter.com/li/284503 ×1
- http://togetter.com/li/17919 ×1
- http://t.co/wHjFYNGgXR ×1
- http://t.co/heQOkbX4c1 ×1
- http://t.co/VGCwDzJ6 ×1
- http://t.co/6Hh3J0QH ×1
- http://sp-search.auone.jp/sear... ×1
- http://smile510.com/gentleman/... ×1
- http://slashdot.jp/~aoppana ×1
- http://slashdot.jp/comments.pl... ×1
- http://search.seesaa.jp/ドライヤーホ... ×1
- http://search.seesaa.jp/ シャコ万力... ×1
- http://search.mobile.yahoo.co.... ×1
- http://search.mobile.yahoo.co.... ×1
- http://search.mobile.yahoo.co.... ×1
- http://search.mobile.yahoo.co.... ×1
- http://search.mobile.yahoo.co.... ×1
- http://search.mobile.yahoo.co.... ×1
- http://search.mobile.yahoo.co.... ×1
- http://search.mobile.yahoo.co.... ×1
- http://search.mobile.yahoo.co.... ×1
- http://search.mobile.yahoo.co.... ×1
- http://search.mobile.yahoo.co.... ×1
- 眠り姫問題 ×30 / 大岡裁判官 うなぎ ×5 / defining property ×4 / パスツレラ症 喘息 入院の可能性 ×3 / ECC演算 楕円 ×3 / デュララジジャケット ×3 / youtubeだけ遅い ×3 / The Hardest Logic Puzzle Ever ×3 / opera プラグインの起動に失敗 ×3 / libeskk ×2 / obsd 日本語 ×2 / youtubeだけ 遅い ×2 / mb_len_max ×2 / 大岡裁判官 うなぎ屋 ×2 / xubuntu pae 非対応 アップグレード ×2 / 楕円曲線 グラフ ×2 / 32bit 64bit 混在 ×2 / opera オートリダイレクト ×2 / pae非対応 ×2 / fno-delete-null-pointer-checks ×2 / pae 非対応 ×2 / あかぷろラジオ ×2 / mouse-processor ×2 / sylpheed smime ×2 / lubuntu 13.10 PAE 対応てなに? ×1 / w3m tamo.tdiary.net ×1 / w3m ×1 / w3m キーマップ Shift ×1 / tooltip "IME.ahk" ×1 / w3m 記号 ×1 / skk 特殊見出し文字 ×1 / openbsd cups ×1 / ncursesw ×1 / mutts �ǂݕ� ×1 / 貧乏な学生とうなぎやさん ×1 / linux-2.6.30 ×1 / libskk config ×1 / habit is ten times nature ×1 / chrom で google カレンダ 動かない ×1 / CVE-2008-1483 Redhat ×1 / 眠り姫 問題 ×1 / 森の射手問題 ×1 / 大岡裁き うなぎの匂い ×1 / ヴォイド・シェイパ ×1 / フレッツ youtube 遅い ×1 / アプリケーション ビットネス ×1 / "gpg handle plaintext failed" ×1 / S/MIME sylpheed ×1 / w3m keymap backspace ×1 / 大岡越前 鰻のにおい ×1 / OPERA Shockwave Flash プラグインの起動に失敗しました ×1 / 眠り姫問題 答え ×1 / よくわかる楕円曲線暗号 ×1 / desagreeを訳す ×1 / IME_GetConvMode() ×1 / 大岡裁判長 うなぎ ×1 / ARB3450 ×1 / libskk ×1 / iconv libc freebsd ×1 / fake-pae ×1 / The Hardest Logic Puzzle Ever 神様 ×1 / ポール グレアム 異論の階層 ×1 / tdiary 翻訳 ×1 / youtube遅い ×1 / w3m shift-down ×1 / urlview w3m ×1 / sendmail ログ stat=Sent (Message received ×1 / roxterm ×1 / Wheel Ball ahk ×1 / fsck_ffs ×1 / pae非対応カーネル 最新 ×1 / pae非対応を対応させる ×1 / lenovo premium club ×1 / mouse-processor win7 ×1 / marble mouse ボタン設定 ×1 / xmodmap Pointer_EnableKeys ×1 / linksys BEFSR41C-JP ファームウェア 1.19JP ×1 / gvim 背景 ×1 / gtk+3 移行 ×1 / defining 訳語 ×1 / dabo python ×1 / TrackScroll windows7 ×1 / TrackScroll ×1 / TrackScroll win7 ×1 / ROXTerm終了方法 ×1 / PAE非対応 活用 ×1 / PAE非対応 ×1 / GOOGLE エラー414 ×1 / 64bit 32bit dll の並存 ×1 / pae非対応 linux ×1 / 非pae ×1 / 眠り 主観確率 ×1 / 楕円曲線 Android 実装 ×1 / 楕円曲線 暗号 ×1 / PageUp w3m ×1 / 大岡 うなぎ屋 におい 学生 ×1 / 大岡越前 名裁き うなぎのにおい ×1 / ブラッド・スクーパ 人物 ×1 / デュララジ 花 フル ×1 / グラハム 不同意のヒエラルキー ×1
最近のツッコミ: