Macintoshでバッファオーバーフローを見つける


 と言うわけで、ここでは、Macintosh上でバッファオーバーフローが起きたとき、どうやって確認すればいいか、そして、そのオーバーフローが、セキュリティホールとして利用可能かどうか簡便に判断する方法、についてメモしておきます。全然詳しくないけど:-P

 このような記事を書く発端は、2001/12月に公表したOutlook express for Macintoshのバッファオーバーフロー脆弱性について、「実はISPは知っていたけど、セキュリティホールになり得ることに気づいていなかった」と言う事実(もしくは可能性)を知ったからです。

 さらに言えば、その昔、某ソフト(まだ公開していないので内緒)のバッファオーバーフローをチェックしたとき、ShadowPenguinSecurityのUNYUNさんに教えてもらった様な内容を日本語で探すのってけっこうつらそう、と感じたからです。

 この情報が、マカーな方々の役に立てばいいな、と考えています。あ、MacOSXは範疇外です。念のため。


 で、用意するものは、MacOSの入ったMacintoshとMacsBugです。

 入手方法ですが、まず、Macintoshはお店に売っています。MacsBugはAppleのサイトからダウンロードします。で、MacsBugをsystem Folder直下にコピーしてリスタートすれば準備完了です。

 ちなみに、MacsBugを入れると不安定になる場合がありますが、多くの場合、元々不安定な状態だったのを知らずにいれて、不安定な事実が発覚する、というパターンのようです。

 後は、いつもの通り使い続けます。そのうち、何かの拍子でMacintoshの画面が壊れ、中央に白わくが現れ、テキストが表示されます。ここで、「stdlog(リターン)」と入力するとテキストが出力されます。そのテキストはこんな感じです。


  MacsBug 6.6.1, Copyright Apple Computer, Inc. 1981-2000

PowerPC unmapped memory exception at 4F505150

 4-Oct-2001 7:18:25 PM (since boot = 12 minutes)
 Current application is ふがほげ
 Machine = #68 (PowerMac7500), System $0810, sysu = $01008000
 ROM version $077D, $28F2, $0001 (ROMBase $FFC00000)
 VM is on; paging is currently safe (and it probably isn't VM's fault)
 NIL^ = $FFC10000
 Stack space used = +77270178
Address 4F505150 is not in RAM or ROM
PowerPC 604 Registers
             CR0 CR1 CR2 CR3 CR4 CR5 CR6 CR7
 PC = 4F505150   CR 1000 0010 0000 0000 0000 0000 0100 0010
 LR = 4F505152     <>=O XEVO
 CTR = 001EB4E4
 MSR = 00000000     SOC Compare Count
 Int = 0      XER 000  00   00           MQ = 65666768

 R0 = 4F505152   R8 = 000000AB   R16 = 00000000   R24 = 61626364
 SP = 032AA230   R9 = 00000001   R17 = 00000000   R25 = 20656667
 TOC = 0323CDA0   R10 = 00000000   R18 = 00000000   R26 = 68696A6B
 R3 = 00000001   R11 = 0028F53C   R19 = 00000000   R27 = 6C6D6E6F
 R4 = FFFFFFFF   R12 = 05326EA8   R20 = 00000016   R28 = 70717273
 R5 = 00000000   R13 = 00000000   R21 = 00000000   R29 = 74757677
 R6 = 00000000   R14 = 00000000   R22 = 33343536   R30 = 78797A41
 R7 = 00000000   R15 = 00000000   R23 = 37383930   R31 = 42434445
Unable to access that address

・・・・・・(等幅フォントで見た方がいいかと思います。)

 これが、典型的なバッファオーバーフローを起こした状態です。

 ちなみに、このような状態になったとき、キーボードが効けば、「es(リターン)」で何事もなかったようにMacOSに戻ります。気分が悪いなぁ、という場合には「rs(リターン)」で再起動を行うことができます。ほかにも当然いろいろなコマンドがありますが、上記2つだけは知っていた方がいいです。

 この画面になったときは、上下カーソルキー(使えない場合は完全に死んでます)でテキストを閲覧できますので、眺めてみてください。ここに、セキュリティホールとして悪用可能かどうかの情報があります。

 まず、「PowerPC unmapped memory exception at 4F505150」とありますが、これは「4F505150というメモリの場所に行こうとしたはいいが、そこにはメモリがないじゃん」、と言っています。つまり、プログラムがメモリがない場所に行こうとしてこけた、と言うことを示しています。

 なんでそんなところ(メモリのない場所)に行こうとしたか、と言うと、プログラムに「行け」と言われたからです。その証拠が、「PC = 4F505150」です。PCはプログラムカウンタ、つまり、CPUが今実行しようとしている命令の書かれた場所(番地)を保存しています。これが「4F505150」になっているので、プログラムはここに行け、とCPUに命令した、と言うことになります。

 本来なら、ここでバッファオーバーフローについてきちんと記述しなければならないのですが、決して分かりやすいものではないので、じわじわと説明しつつ、先に進みます。

 なぜ、プログラムはメモリがない様な場所(番地)に行ってしまったのでしょうか。

 それは、このような背後関係があるからです。

 (ざっくり言ってしまうと)プログラムは、メモリ上におかれますが、そのプログラムが実行されるとき、広いメモリ上のあっちに行ったり、こっちに行ったり、と非常にバラバラな場所で実行されます。上から順番に流れるように実行される場合はまれだと思って構いません。

 で、あっちいったあと、こっちに戻らなきゃならない場合も当然出てきます。この時、プログラムはあっちに行く前に、こっち(帰ってくるべき場所)がどこか、をメモリ上に保存しておきます。その保存領域をスタック、と呼びます。そのスタックのすぐとなりには、バッファ、と呼ばれる領域があります。バッファは、一次情報保管所の様なものです。

 この辺からややこしくなってくるんで、ゆっくりいきましょう。(^^)

 バッファは保管場所ですが、無限の大きさを保管できるわけではありません。大きさは有限で、基本的にプログラマーが「これだけ確保してね」と指定することで確保されます。これがバッファサイズです。

 たとえば、1から255まで数字のうち、どれか一つを保管する必要が生じた場合、1バイト(場合によって異なりますけど)必要となります。最大128文字(アルファベット)を保管したい場合、129バイト(128文字+文字の終端を表すNull文字1つ)確保する必要があります。

 さてここで問題です、上記の128文字保存のために確保したバッファに200文字保管させたらどうなるでしょうか?

 ちょっと考えると、「128文字しか保存できないんだから、『保存できません』っていわれるんじゃないの?」って思いますよね。そうだったらいいんですけど、実は、そんなこといわれなかったりします。

 何も考えず、200文字+終端のnull文字を保管します。そうすると、129文字のバッファからあふれますよね。これがバッファオーバーフローです。

 じゃぁ、あふれた分(この場合は200文字+Null文字−129文字分のバッファ=72文字)はどこに行ってしまうのでしょう。

 答えはお隣のスタック領域。つまり、プログラムが戻るためにわざわざ保管しておいた場所の情報を書き換えてしまうのです。

 そうなると、プログラムはたまったものではないですよね。全然違う場所の情報に書き換えられちゃうんですから。全然違う場所に戻ろうとして、たとえばメモリがないじゃん、といって落ちてしまう事になっちゃいます。

 さて、私はすでに「プログラムが戻るために保管した情報を書き換える」と書きました。また、バッファにはデータが保存されます。このデータは、多くの場合、ユーザの入力やファイルの入力などが入ります。

 じゃぁ、バッファにプログラムを入力してもいいんですよね。で、先ほどのプログラムの戻る場所、ってのをバッファの場所に書き換えてもよさそうです。そう言う入力をされてしまうと、どうなるか。

 バッファにはプログラムが入力され、バッファがあふれて、戻るための情報が書き換えられ、戻るところがバッファにためられたプログラムを指している、と言う状態ですから、戻った途端にバッファにおかれたプログラムが実行されることになります。

 もし、このプログラムが、「ファイルをみんな消去」ってものだったら・・・・・。これがバッファオーバーフローがセキュリティホールと呼ばれる所以です。

 さて、先に示したMacsBugの出力に戻りましょう。

 先に述べたとおり、PCが4F505150(本当は4F505152の予定なんですけどね)に書き変わっています。この時、バッファに送り込まれた文字列は、と言うと、以下のとおりです。

 1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJLMNOPQRSTUVWXYZ
 1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJLMNOPQRSTUVWXYZ
 1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJLMNOPQRSTUVWXYZ
 1234567890abcdefghijklmnopqrstuvwxyzABCDEFGHIJLMNOPQRSTUVWXYZ.tst(実際には一行)

 で、4F505152をascii文字列にすると、「OPQR」になります。上記文字列中には4ヶ所にこの文字列が存在していますので、この4ヶ所のうち、いずれかの場所をうまく書き換えてあげると、戻る場所を自由に選ぶことが可能となります。

 因みに、戻る場所を書き換えるためには入力の何文字目を書き換えなければならないか、と言うのを特定しなければならないのですが、これは入力をいろいろ変えて試してみると確認できます。

 また、MacsBugが出力するリストの最後の方を見ると、このような記述があります。

 Displaying memory from sp
 032AA230 4647 4849 4A4C 4D4E 4F50 5152 5354 5556 FGHIJLMNOPQRSTUV
 032AA240 5758 595A 3132 3334 3536 3738 3930 6162 WXYZ1234567890ab
 032AA250 6364 6566 6768 696A 6B6C 6D6E 6F70 7172 cdefghijklmnopqr
 032AA260 2073 7475 7677 7879 7A41 4243 4445 4647  stuvwxyzABCDEFG
 032AA270 4849 4A4C 4D4E 4F50 5152 5354 5556 5758 HIJLMNOPQRSTUVWX
 032AA280 595A 3132 3334 3536 3738 3930 6162 6364 YZ1234567890abcd
 032AA290 6566 6768 696A 6B6C 6D6E 6F70 7172 7374 efghijklmnopqrst
 032AA2A0 7576 7778 797A 4155 5657 5859 5A31 3233 uvwxyzAUVWXYZ123


 これは、スタックがどの様な文字列で埋められているか、を確認するためのメモリダンプ(メモリの中身をリストアップすること)、と呼ばれるものです。見ての通り、先に示した文字列で埋め尽くされていることが分かりますね。もしここにかかれているものが文字列ではなく、プログラムだったら、大変なことになってしまうわけです。

 因みに、上記ダンプの行の先頭(例:032AA230)はスタックの置き場所(番地)です。そのあとの8ブロックはスタックに保存されたデータのバイナリで最後のブロックはデータをascii文字に直したもの、となっています。

 と言うわけで、上記の状態の場合、1.戻る場所を変更可能、2.スタックに任意のプログラムを入力可能、という事になるので、セキュリティホールになりうる、という判断ができます。

 じゃぁ、だめな場合はどうか、と言うと、入力された文字列の一部がPCに反映されていない、という場合なのですが、実際問題、これがセキュリティホールになるかどうか判断が難しいところです。しいて言えば、プログラムに対するDoS攻撃が可能、というレベルでしょうか。

 ただし、これはあくまで可能性の問題です。つまり、セキュリティホールになる、と証明するためには実際にコードを書いて、事実を見せない限りはできると言いきれません。

 また、いくら文字列を入力可能、と言っても、使えない文字があるなどの制約条件がありますので、それを迂回するテクニックも必要となります。念のため。

 そういった制限事項があるとは言え、上記のように戻り場所を書き換えられる上、スタックにプログラムが置ける、というのはセキュリティホールの可能性が高い、と言うことは自明かと思います。


戻る


突っ込みはしかPまで。スパム、DMおことわり。