20:55 *Defolos join (Defolos!Hamano@p1012-ipbf302osakakita.osaka.ocn.ne.jp) 20:55 *Names #lykeion: Defolos FCSAY be-be- kotto @minke 20:55 [Defolos] こんばんはー 20:55 [FCSAY] こんばんわ 20:55 [be-be-] こんばんは 20:55 [kotto] こんばんは 20:55 [minke] こんばんは。 20:55 *wahiko join (wahiko!~wahiko@softbank219021027026.bbtec.net) 20:55 [FCSAY] こんばんわ 20:56 [wahiko] こんばんわ 20:56 [be-be-] こんばんわ 20:56 [Defolos] こんばんは 20:58 *IPUSIRON join (IPUSIRON!~ipusiron@p17163-adsau16honb12-acca.tokyo.ocn.ne.jp) 20:58 [IPUSIRON] こんばんは 20:58 [FCSAY] こんばんわ 20:58 [Defolos] こんばんはー 20:59 [wahiko] こんばんは 21:00 [Defolos] 9時になりましたね 21:00 [Defolos] それでは始めましょうか 21:00 [FCSAY] はい 21:01 [Defolos] まずは資料をDLしてください 21:01 [Defolos] http://security2600.sakura.ne.jp/up/upload.php 21:01 [Defolos] からお願いします 21:01 [Defolos] えと、 21:02 [Defolos] 今日はテスト期間中で、ちょっと短く行きますね 21:02 [FCSAY] 了解です 21:02 [wahiko] はい 21:02 [kotto] はい 21:02 [Defolos] それでは、資料をお開きください 21:03 [Defolos] 今回はBOFの原理を使って、変数を書き換えることをやります 21:03 [Defolos] BOFで任意のコードを実行する前段階として 21:04 [Defolos] ローカル変数を書き換えて見ましょう 21:04 [Defolos] 今回のように、あるコードを実行するためのコードを挿入ベクターといいます 21:05 [Defolos] 挿入ベクターはペイロードを運ぶトラックの役割を果たします 21:05 [Defolos] 今日は実行までせず、変数の値を書き換えるだけですが 21:06 [Defolos] 次回はペイロードの実行まで行い間s 21:06 [Defolos] ペイロードと違って 21:06 [Defolos] 挿入ベクターはプログラム毎に作っていくので 21:06 [Defolos] 再利用性はあまり考慮されません 21:07 [Defolos] それでは、この挿入ベクターが利用する脆弱性について説明します 21:07 [Defolos] 今回はバッファオーバフローという脆弱性を利用します 21:08 [Defolos] 略してBOFといわれるやつですね 21:08 [Defolos] これを利用した攻撃が始めて公開されたのは、アメリカのハッカーWEBマガジン 21:08 [Defolos] フリークスで始めて公開されました 21:09 [Defolos] ただ、公開されたのはこの雑誌が初めてですが、 21:09 [Defolos] おそらくそれ以前にも散々利用されていたと予想されています 21:09 [Defolos] かなり昔からある古典的な脆弱性だと言えますね 21:10 [Defolos] それで、C言語で書いたプログラムはBOFの脆弱性が含まれることが多いです 21:11 [Defolos] これはC言語が細かい制御までできることと、文字列のサイズチェックを標準で行ってくれないことに起因しますが、 21:11 [Defolos] 詳しくは後述します 21:11 [Defolos] BOFのイメージとしては 21:12 [Defolos] 200ミリリットル入るコップを想像してください 21:13 [Defolos] このコップがバッファ=一時的にデータをためておく箱 だと思ってください 21:13 [Defolos] ここに、500ミリリットルの水を入れてみてください 21:13 [Defolos] 水がデータの代わりです 21:13 [Defolos] そうすると、300ミリリットルほどあふれてしまいますね 21:14 [Defolos] こういうことがコンピュータのメモリでも起こります 21:14 [Defolos] よくChar strings[10]みたいにバッファとして配列を用意しますが 21:15 [Defolos] ここに20バイトの文字を入れるみたいな感じです 21:16 [Defolos] あ、 21:16 [Defolos] ちょっと訂正いたします 21:16 [Defolos] アメリカのWEBマガジンなんですが 21:17 [Defolos] フリークスではなくフラックスのようです 21:17 [Defolos] phrackとつづるようです 21:17 [Defolos] イプシロンさんに教えていただきました 21:17 [Defolos] どうもありがとうございました 21:17 [IPUSIRON] フラックスじゃなくて多分フラックです 21:18 [Defolos] Σ 21:18 [Defolos] 本当ですね。Sついていませんね^^; 21:18 [Defolos] それでは、続けますね 21:19 [Defolos] えと 21:19 [Defolos] 具体例としては資料にあげたプログラムなのですが 21:19 [Defolos] Char型のcupという名前で200バイト分の配列を用意しています 21:20 [Defolos] ここに、cupのi番目の要素に1をいれていきます(iは1づつ加算します 21:21 [Defolos] 1というデータが水のようなイメージですね 21:21 [Defolos] で、iが200までのときはちゃんとCUPのなかに入ってくれるのですが 21:21 [Defolos] 201からはCUPからあふれてしまいますね 21:22 [Defolos] あふれたデータは消えるわけではなくて 21:23 [Defolos] 実はあふれたデータは隣接するメモリを上書きしてしまうのです 21:23 [Defolos] 水もこぼれたら、消えずに机の上にこぼれますよね 21:24 [Defolos] 図にもあるように、CUPの後ろ、つまり高位アドレスをどんどん上書きしていきます 21:25 [Defolos] こういうあふれがバッファオーバフローなのですが 21:25 [Defolos] これは実は大変重要な脆弱性となり得ます 21:26 [Defolos] 次回でそれを体感していただけるとは思います 21:26 [Defolos] 先ほど述べましたが、C言語はこの重大な脆弱性となるBOFが発生しやすいです 21:26 [Defolos] その理由を次に説明しますね 21:27 [Defolos] ここまでで質問などはありませんでしょうか 21:27 [FCSAY] えと、プログラムの部分なのですが 21:27 [Defolos] はい 21:27 [FCSAY] 0〜199までではないでしょうか 21:27 [Defolos] あ、申し訳ありません 21:28 [Defolos] C言語は配列が0から始まってますので 21:28 [Defolos] 0から199までの200個でした 21:28 [Defolos] ご指摘ありがとうございます 21:28 [FCSAY] いえ^^ 21:28 [Defolos] ほかにはございませんか? 21:28 [kotto] 特にないです 21:29 [FCSAY] 大丈夫です 21:29 [Defolos] それでは次に行きますね 21:29 [Defolos] 質問は適宜行っていただいて結構ですので〜 21:29 [Defolos] それで、ですね 21:30 [Defolos] C言語にはたくさんの文字列関数が用意されていますね 21:30 [Defolos] 例えばStrcpy()やGet()などですね 21:32 [Defolos] これらの文字列関数は出力先のバッファの長さをチェックしないので 21:33 [Defolos] 100バイトしか用意していないバッファに300バイトの文字をいれても、関数が感知してくれないということです 21:34 [Defolos] 例えば、サンプルコードの例では 21:34 [Defolos] str1という7バイトの配列を用意し、Hello!という文字を入れておきます 21:35 [Defolos] 次にstr2という5バイトの配列を用意します 21:35 [Defolos] 次にSTRCPY関数を使ってstr2にstr1をコピーします 21:36 [Defolos] プログラマーの感覚から言えば、コピー先に十分な領域がないならエラーにしてほしいのですが 21:36 [Defolos] C言語の関数は無理やりコピーしてくれます 21:37 [Defolos] Cで書いたプログラムにBOFのセキュリティホールが多いのはこのためです 21:38 [Defolos] で、一応こういうのを防ぐチェック機構を設けることができます 21:38 [Defolos] 一例としてはIFによるチェックです 21:40 [Defolos] コピーする前に、IF(SIZEOF(STR1) <= SIZEOF(STR2))で 21:40 [Defolos] STR1よりSTR2のほうが大きいときに限ってSTRCPYを実行するようにすればよいのです 21:41 [Defolos] ただ、このチェック方法はあらかじめコピー元とコピー先のサイズがわかってないとだめですよね 21:41 [Defolos] ユーザから文字を入力してもらうようなGET()はこの方法では防ぐことはできません 21:42 [Defolos] 実は本質的にGET()などのBOFを防ぐことができます 21:42 [Defolos] あ、できません。の間違いでした 21:43 [Defolos] ここまでは大丈夫でしょうか? 21:43 [FCSAY] 大丈夫です 21:43 [minke] えーと、関数名getじゃなくてgetsじゃないでしょうか 21:43 [Defolos] あ、gets()でした 21:43 [Defolos] ごめんなさいTT 21:44 [Defolos] ご指摘ありがとうございます 21:44 [Defolos] ほかはOKでしょうか 21:44 [FCSAY] OKです 21:44 [minke] はい、大丈夫です。 21:44 [Defolos] それでは、次に行きましょうか 21:45 [Defolos] 先ほどのBOFの隣接メモリを上書きしてしまうという性質を利用して、変数を書き換えることができてしまうのです 21:45 [Defolos] 今回はゲームの一部として、 21:46 [Defolos] ハイスコアを出したときのユーザ名入力の例を見ていきましょう 21:46 [Defolos] 始めにstarge,score,nameを宣言します 21:46 [Defolos] nameは12バイトだけ用意しています 21:47 [Defolos] で、GETSでnameに文字列を入れます 21:48 [Defolos] 後は名前とスコアを出力します 21:48 [Defolos] さて、名前入力用のバッファは12バイトしかないので 21:48 [Defolos] 13バイト以上を入れればBOFが発生しますね 21:49 [Defolos] それではあふれた文字はどこに入れられるのかを考えて見ましょう 21:50 [Defolos] これを知るには関数のメモリの取り方を知る必要があります 21:51 [Defolos] 関数は内部で使う変数をもっていますね 21:51 [Defolos] 今回の例ではScoreやNameです 21:51 [Defolos] あ、main関数も関数の一種ですので 21:52 [Defolos] これから説明する流れに準じます 21:52 [Defolos] えと、内部で変数を使いますので、どうにかして変数用にメモリを確保しておかないといけませんね 21:53 [Defolos] 関数呼び出しのときはスタックを使って変数用にメモリを確保します 21:53 [Defolos] まず、ソースコードではじめに出てくるStargeを確保します 21:53 [Defolos] これが一番高位メモリに確保されます 21:54 [Defolos] 次に、Scoreを確保しますが、スタックですので 21:54 [Defolos] 先ほどのStargeの直後に、低位に向かって確保します 21:54 [Defolos] 最後にNameを12バイト、低位に向かって確保します 21:55 [Defolos] もし、Stargeに4とかをいれたいとしたら、その図では0x00094というアドレスにいれます 21:56 [Defolos] Nameも同じように、0x00078に一文字目を0x00079に二文字目をいれます 21:56 [Defolos] 12文字目は0x00077にいれることになるのですが 21:57 [Defolos] STRCPYはこのようにメモリのアドレスでアクセスして文字列をコピーしています 21:57 [Defolos] 13文字目では0x00078にいれられることになるのですが 21:57 [Defolos] ここはすでにscoreが使ってますので 21:57 [Defolos] Scoreを無理やり上書きしてしまいます 21:58 [Defolos] このように、本来書き換えられると困る変数も書き換えられるのです 21:58 [Defolos] これがもし、Nameを最後にしていたら 21:58 [Defolos] メモリの上書きは低位から高位に行われるので 21:58 [Defolos] Scoreを書き換えられることはありません 21:59 [Defolos] 変数の宣言の仕方にも気を使わなければならないという例でもありますね 21:59 [Defolos] それでは、次の例題を見てください 21:59 [Defolos] これは宿題ということにします^^; 21:59 [Defolos] 先ほどのサンプルプログラムで 21:59 [Defolos] ユーザ名のところでaを17個入れます 22:00 [Defolos] aもコンピュータ内では41とか32とかの数値として扱われていますので 22:00 [Defolos] 数値として表示することもできるのです 22:00 [Defolos] それで、そのときにどういう表示になるのか考えてみてください 22:01 [Defolos] また、ラダーモデルを使って考えて見れくださいね 22:01 [Defolos] ラダーモデルとはハシゴのことなのですが 22:01 [Defolos] 先ほどのメモリの例で見てもらったような図のことです 22:01 [Defolos] ハシゴっぽいのでラダーモデルといわれます 22:02 [Defolos] さて、ここまでで何かご質問はありませんか? 22:03 [Defolos] ないようでしたら、ここまでで今日はおしまいにしたいと思いますが 22:03 [FCSAY] えと、資料では[ 22:03 [Defolos] はい 22:03 [FCSAY] 「13文字目は0x00090に格納される」って書いてあるのですが 22:03 [FCSAY] どっちが正しいのでしょうか 22:03 [Defolos] あ、ごめんなさい 22:03 [Defolos] 資料のミスです 22:04 [Defolos] 0x00078にいれられます 22:04 [Defolos] ほかにはございませんか? 22:05 [be-be-] OSやコンパイラーによっては余分にスタックが確保されるとかありますか? 22:06 [be-be-] たとえば、今回のcharの配列ですが12の領域をプログラマーが確保しようとしていますが 22:06 [Defolos] はい 22:06 [be-be-] コンパイラーもしくはOSの方で余分に確保して、あらかじめBOFを防ぐみたいなことは行っているのでしょうか? 22:07 [Defolos] えとですね 22:07 [Defolos] コンパイラやOSによって 22:07 [Defolos] メモリの摂り方に違いはあります 22:07 [Defolos] 例えば、Scoreを確保した後 22:08 [Defolos] 4バイトあけた後にNameを確保するというようなことをする可能性もあります 22:08 [Defolos] ただ、スタックを保護するのは 22:08 [Defolos] StackGuardなどの 22:08 [Defolos] プログラムが別途用意されています 22:08 [Defolos] 今回は 22:08 [Defolos] Linuxを前提にしておりまして 22:09 [Defolos] Linuxではメモリ領域を隣接して確保します 22:09 [Defolos] これで答えになってますでしょうか 22:10 [be-be-] ありがとうございました 22:10 [Defolos] ほかにはありますか? 22:11 [Defolos] なければ今日はここまでにしますが 22:11 [Defolos] OKでしょうか 22:12 [minke] はい。 22:12 [IPUSIRON] はい 22:12 [wahiko] はい 22:12 [be-be-] はい 22:12 [FCSAY] OKです 22:12 [Defolos] それでは、今日はお疲れ様でした 22:12 [be-be-] お疲れ様でした 22:12 [IPUSIRON] お疲れ様でした 22:12 [FCSAY] お疲れ様です。テストがんばってください 22:12 [minke] お疲れ様でした。 22:13 [wahiko] お疲れ様でした 22:13 [Defolos] また今日のところでわからないことがありましたら、SNSにお願いしますね 22:13 [kotto] お疲れさまでした 22:13 [Defolos] それではまた、次回お会いしましょう