web-dev-qa-db-ja.com

戻りアドレスの上書きに関する問題(バッファオーバーフロー)

次のコードをバッファオーバーフローで悪用し、オーバーフローした関数を実行しようとしています。

#include <string.h>
#include <stdio.h>

    void overflowed() {
        printf("%s\n", "Execution Hijacked");
    }

    void function(char *str){
        char buffer[5];
        strcpy(buffer, str); 
    } 
    void main(int argc, char *argv[])
    {
        function(argv[1]);
        printf("%s\n", "Executed normally");
    }

私は16 Aと4 Bでプログラムをファズしようとしましたが、RBPをBで正常に上書きしました。

ss#1

ss#2

次に、プログラムにオーバーフローした関数を実行させます。

ss#3

次のコマンドでRBPを上書きしようとしました。

r $(python -c 'print "A" * 16 + "\x44\x05\x40\x00")

ss#4

RBPを上書きしたと思いますが、プログラムを実行し続けると、以下のエラーが発生します。

ss#5

ご質問

  • 0x7fffを0x0000で上書きする必要がある問題はありますか?
  • どうすればいいですか?

注:プラットフォームはUbuntu 12.04 32ビットです。

2
user1758952

それはあなたが制御しなければならないのはrbpではなく、命令ポインタの裂け目です。関数が戻ると、ret命令はスタックの一番上にあるものをすべて受け取り、そこに実行を送信します。したがって、最後の2つの命令pop rbpとretに注意してください。最初のものは、その時点でスタックの一番上に残っているものをすべて取り、それをrbpに格納します。 2番目は、スタックの一番上に残っているものをすべて取り、rip、つまり命令ポインターに格納します。

基本的に、実行がそのret命令に達したときに、スタックの最上部(rspが指す場所)でターゲットアドレスが表示されていることを確認する必要があります。有効なアドレスをripにポップできなかった場合、プロセッサが無効な(つまり、マップされていない)場所から命令を読み取ろうとしたときに、セグメンテーション違反が発生します。または、ゴミ箱の値でrbpを上書きしても、実行が妨げられない(つまり、実際の戻りアドレスは変更されないままにする)場合は、プログラムが、無効なメモリ位置への読み取りまたは書き込みを試みて、セグメンテーション違反が発生するように設定できます。だからあなたはそれを説明する必要があります。

また、64ビットのアドレスとレジスタは8バイトの長さであることに注意してください。エクスプロイトが機能するためには、(リトルエンディアンの)戻りアドレスを置き換える必要があります。

0x44 0x05 0x40 0x00 0x00 0x00 0x00 0x00

したがって、ret命令は値0x0000000000400544を命令ポインタにポップし、実行パスを制御できるようにします。

ただし、strcpyのみを使用する場合、これらのnullバイトの処理に実際に問題が発生する可能性があります。ご覧のとおり、strcpy演習は32ビット時代からかなり古いものです。今日、x64では、ターゲットアドレスを上書きしようとするときに、不正なnullバイトが実際の面倒になる可能性があります。幸いにも(実際にはそうではありませんが)、strcpyの誤用は、物事を台無しにする唯一の方法ではありません。 memcpyを使用したり、ファイルまたはソケットから読み込んだり、範囲外の配列アクセスの偽のインデックスを取得したり、攻撃者が制御可能なブレーク条件でループするように、例を調整することができます。物事を台無しにする新しい創造的な方法を考え出すことは、実際にあなたの搾取スキルを練習するための良い方法です。

1
user25972