Buffer overflow

2,888 views

Published on

とっとるびー第9回の資料
基本的な事ばかり並べてみました。
詳細は、「HACKING:美しき策謀」や解説サイトを見た方が良いですよ!

Published in: Technology
0 Comments
5 Likes
Statistics
Notes
  • Be the first to comment

No Downloads
Views
Total views
2,888
On SlideShare
0
From Embeds
0
Number of Embeds
49
Actions
Shares
0
Downloads
22
Comments
0
Likes
5
Embeds 0
No embeds

No notes for slide

Buffer overflow

  1. 1. バッファオーバーフロー 〜そのとき何が起こった〜 とっとるびー第9回 @ionis_h
  2. 2. バッファオーバーフローとは?プログラムが確保したメモリサイズを越えて文字 列が入力され、領域を越えて溢れてしまう事 結果、予期せぬ動作が起きたりするIT 用語辞典 e-words http://e- words.jp/w/E38390E38383E38395E382A1E382AAE383BCE38390E383BCE38395E383A DE383BC.html 2/48
  3. 3. こんな感じ 3/48
  4. 4. 今回の内容は以下の本を参考にしています 「Hacking:美しき策謀 脆弱性攻撃の理論と実際」 4/48
  5. 5. サンプルコード (vuln.c)#include <string.h>int main (int arg, char* argv[]){ char buffer[500]; strcpy (buffer, argv[1]); return 0;} 5/48
  6. 6. サンプルコード (vuln.c)$ vi vuln.c$ gcc -o vuln vuln.c$ ./vuln test特に何も表示されません実行環境 gcc version 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.1.00) Mac OS X 10.6.8 6/48
  7. 7. サンプルコード (vuln.c)$ ./vuln `ruby -e "print a*500"`$ ./vuln `ruby -e "print a*501"`Abort trap確保していたbuffer配列よりも大きい文字列を入 れると、エラーメッセージが出てきました 7/48
  8. 8. サンプルコード (vuln.c)他の環境ではSegmentation faultと表示されたり するハズです ubuntu12.04ではそうでました余談: 「strcpyを使うのはダメだ」と言われる事が多いの は、プログラムが複雑になっていくと、なんらかの 結果、こういうミスを埋め込んでしまう事があるか らです strncpy等、 文字数制限を見る関数を使うようにしましょう 8/48
  9. 9. そもそも何がfaultなの?abort trapとかsegmentation faultとか 何がfaultなの?そのメモリアドレスが指し示すところを読み込ん だ際に、命令として解釈が出来ないので、fault なんです メモリアドレス、命令に関しては軽く後述 9/48
  10. 10. 質問突然ですが、今まで、一度も、 segmentation fault を発生させた事の無い方 いらっしゃいますか? 10/48
  11. 11. ですよねー。 11/48
  12. 12. ところでsegmentationって?メモリを使用目的に応じて区分けしたもの テキストセグメント(コードセグメント) データセグメント bssセグメント ヒープセグメント スタックセグメント 12/48
  13. 13. テキストセグメント (コードセグメント)マシン語で記述されたプログラムが格納される変数等が格納される事はない書き込みは禁止になっている 書き込みを試みると、警告を表示し、プログラムを停 止する 複数のプロセスでコードの共有が可能サイズは固定長 13/48
  14. 14. データセグメント bssセグメントグローバル変数や静的変数を格納するサイズは固定長データセグメント 初期化済みのものが格納されるbssセグメント 初期化されていないものが格納される Block Started by Symbol 14/48
  15. 15. ヒープセグメントプログラム中に動的に割り当てられる変数が格納 されるサイズは可変長拡張される場合、メモリアドレスの低位から高位 に向かって行われる 縮小の場合はその逆 15/48
  16. 16. スタックセグメント関数呼び出し時におけるコンテキストを格納する 関数呼び出し時の引数の値、復元する際のEIPの値等 を記憶しておく Extended Instruction Pointer: プロセッサ内にある記憶回路。レジスタの一種サイズは可変長拡張はヒープセグメントの逆で、高位から低位に 向かって行われる 16/48
  17. 17. segmentationまとめ低位アドレス テキストセグメント データセグメント bssセグメント ヒープセグメント スタックセグメント高位アドレス 17/48
  18. 18. では、バッファオーバーフロー・・・の前に。 18/48
  19. 19. 下準備プロセッサの大体の動作関数を呼び出した時の大体の動作 19/48
  20. 20. プロセッサの大体の動作EIPの値をアドレスと解釈し、そのアドレスのメ モリ内容を取得する該当命令のバイト長をEIPに加算 現在実行している命令に隣接している次の命令をEIに セットしている事になる最初に取得した命令を実行する1の手順に戻る 大体、以上を繰り返している EIP:現在実行している命令に隣接している次の命令を保持する 20/48
  21. 21. 関数を呼び出した時の大体の動作関数を呼び出すと、複数のデータをまとめて、ス タックセグメントに突っ込む 複数のデータ:スタックフレーム 関数に対する引数、関数内に定義してあるローカル変数 退避済フレームポインタ(SFP)、戻りアドレス Saved Frame Pointer: 関数終了時に、呼び出し前の状態に復元するのに使う スタックフレーム中の変数へのアクセスはEBPを利用 する(別名:FP, LB) 21/48
  22. 22. サンプルコードvoid function (int a, int b, int c, int d) { char flag; char buffer[10];}void main (void) { function(1, 2, 3, 4);} 22/48
  23. 23. main関数からfunctionを呼び出す時引数を逆順にスタックにプッシュcall命令 スタックに戻りアドレスがプッシュ 戻りアドレス:callを呼び、先に出て来た手順3の際の EIP(結果、隣接する命令のアドレス)現在のEBPをプッシュ(SFPと呼ぶ)現在のESPをEBPにコピー 23/48
  24. 24. 結果こんな感じになります低位アドレス buffer flag 退避済フレームポインタ(SFP) フレームポインタ 戻りアドレス (EBP) a b c d 復習: スタックセグメントは、 高位から低位に向かい、 拡張する高位アドレス 24/48
  25. 25. EIP, EBP, E...プロセッサ内にある特殊な記憶回路(レジスタ)EIP : Extended Instruction Pointer 次の命令が格納されているレジスタEBP : Extended Base Pointer スタックフレーム中の変数にアクセスするのに利用す るレジスタESP : Extended Stack Pointer スタックの末端アドレスを格納するレジスタ 25/48
  26. 26. もう少し詳しく知りたいです例えば、以下のサイトとか分かりやすいと思いま すスタック破りの楽しみと恩恵 http://www.asahi-net.or.jp/~vp5m-snd/sec/tech/Phrack49-14.html 26/48
  27. 27. 27/48
  28. 28. さて、本題ようやくバッファオーバーフローの本題です実際オーバーフローになると何が起きているの か? 例えば、先程の500文字分の配列に600文字ぐらい 突っ込んだらどうなるのか? 28/48
  29. 29. サンプルコード (vuln.c)#include <string.h>int main (int arg, char* argv[]){ char buffer[500]; strcpy (buffer, argv[1]); $ ./vuln `ruby -e "print A*600"` return 0; Abort trap} 29/48
  30. 30. $ ./vuln `ruby -e "print A*600"`buffer[500] bufferのサイズを越え、待避済フレームポインタ (SFP) "A”をドンドン埋めていく。 戻りアドレス(RET) 結果、ここのRETが 0x41,0x41,0x41... (Aの文字コード) で埋め尽くされている関数から戻る際には、EIPにRETの値を入れ、その値を命令として解釈し、0x41414141に制御を返してしまう。大体、こんな値は使えないので、不正だと判断され停止する 30/48
  31. 31. つまり?不正な命令だと解釈されないよう、実行可能な コードがあるアドレスでRETを埋めてあげれば OK 実行可能なコードに制御を返す事が大切 後は、適当にシェルコードを動かしてあげればOK 31/48
  32. 32. ところでシェルコードって何?セキュリティホールに流し込むペイロードとして 使うコード主にマシン語で記述されているシェルを起動する事が多いため、シェルコードと 呼ばれる wikipediaより http://ja.wikipedia.org/wiki/%E3%82%B7%E3%82%A7%E3%83%AB %E3%82%B3%E3%83%BC%E3%83%89 32/48
  33. 33. どうやるの?NOP sled シェルコードの先頭にNOPをいくつも置いておき、 シェルコードの先頭まで何も処理をしない命令をす る 戻りアドレス(RET)を、このNOP sledのどこか のアドレスで上書き出来るとシェルコードの実 行が確定するNOP: 何も処理をしないというマシン語命令 コンピュータの処理タイミングを調整する目的等で使う 33/48
  34. 34. つまりこんなデータを送り込むどんどん命令が消費されて、 ここの部分で元のRETシェルコードの先頭 を上書きするへ行く。NOP sled シェルコード 偽の戻りアドレス の繰返し 偽の戻りアドレス: NOP sledのどこかのアドレス 34/48
  35. 35. 偽の戻りアドレスどうするよ?現在のスタックポインタを参考に推測するvuln.cだと、bufferがスタックセグメントの一番 上に来るはずなので、偽の戻りアドレスはス タックポインタと一致している 結果、オフセットはほぼゼロ 35/48
  36. 36. 実際のコードは?大体こんな感じ http://d.hatena.ne.jp/tomitake_flash/20100411/127099 6605 36/48
  37. 37. とはいえ、この辺の話は5、6年前の話なのです 僕の手元にあるHACKING 美しき策謀は初版な ので2005年の話ですOSもコンパイラもずっと進化をし続けているの で、このような単純なオーバーフローでシェル が起動する事は、今は大体起きません 37/48
  38. 38. 防衛策NXビット (NoExecuteBit) データを配置した領域に印をつけておき、この領域の データを実行しないようにする 実行を試みるとエラーを発生させる AMDでの呼び名、IntelだとXDビットhttp://ja.wikipedia.org/wiki/NX%E3%83%93%E3%83%83%E3%83%88 38/48
  39. 39. 防衛策ASLR (Address Space Layout Randomization) アドレス空間をランダムにする データ領域やコード領域http://ja.wikipedia.org/wiki/%E3%82%A2%E3%83%89%E3%83%AC %E3%82%B9%E7%A9%BA%E9%96%93%E9%85%8D%E7%BD %AE%E3%81%AE %E3%83%A9%E3%83%B3%E3%83%80%E3%83%A0%E5%8C %96 39/48
  40. 40. 防衛策stack-protector gccコンパイラのオプション スタック上の変数が溢れた事による リターンアドレスの書き換えを検知する 40/48
  41. 41. 防衛策大体この3つが防衛策としてある NX/XDビット ASLR stack-protector第10章 著名な脆弱性対策バッファオーバーフロー: #5 運用環境における防御 http://www.ipa.go.jp/security/awareness/vendor/programmingv2/conte nts/c905.html 41/48
  42. 42. じゃあ、もうあんまり気にしなくて いい?segmentation faultで、 少なくともアプリは落ちることが多いですそれに簡単な手法だけでは、メリット(?)を体 感する事が出来なくなっただけで、実際には利 用されています 42/48
  43. 43. 例えばJailBreakとかPod2gがiOS5.1紐なし脱獄の情報を新たに公開!ついにASLRを 突破!(2012年4月22日) http://jailbreakers.info/iphone%E8%84%B1%E7%8D %84%E3%83%8B%E3%83%A5%E3%83%BC %E3%82%B9/pod2g %E3%81%8Cios5-1%E7%B4%90%E3%81%AA %E3%81%97%E8%84%B1%E7%8D%84%E3%81%AE %E6%83%85%E5%A0%B1%E3%82%92%E6%96%B0%E3%81 %9F%E3%81%AB%E5%85%AC%E9%96%8B%EF%BC %81%E3%81%A4%E3%81%84%E3%81%ABaslr%E3%82%92/ 43/48
  44. 44. 本も2版が出るぐらいだし2011年10月発売 ¥4410 http://books.rakuten.co.jp/rb/HACKING%EF%BC%9A%E7%BE%8E %E3%81%97%E3%81%8D%E7%AD%96%E8%AC %80%E7%AC%AC2%E7%89%88-%E8%84%86%E5%BC %B1%E6%80%A7%E6%94%BB%E6%92%83%E3%81%AE %E7%90%86%E8%AB%96%E3%81%A8%E5%AE%9F%E9%9A %9B-%E3%82%B8%E3%83%A7%E3%83%B3%E3%83%BB %E3%82%A8%E3%83%AA%E3%82%AF%E3%82%BD %E3%83%B3-9784873115146/item/11418036/ 44/48
  45. 45. それは置いといてもオーバーフローが起きないように コードを組んだ方が良いのは間違いないです 45/48
  46. 46. それは置いといてもオーバーフローが起きないように コードを組んだ方が良いのは間違いないです 46/48
  47. 47. 良いコーディングライフを XcodeとoverFlowは別に関係ないです。 日頃のアレを表示しただけです。 47/48
  48. 48. ご清聴ありがとうございます 48/48

×