問題のソースコードがあるのでDLして表示してみると中身は以下のcコード
#include <stdio.h>
int main() {
char buf[1024];
char secret1[64];
char flag[64];
char secret2[64];
// Read in first secret menu item
FILE *fd = fopen("secret-menu-item-1.txt", "r");
if (fd == NULL){
printf("'secret-menu-item-1.txt' file not found, aborting.\n");
return 1;
}
fgets(secret1, 64, fd);
// Read in the flag
fd = fopen("flag.txt", "r");
if (fd == NULL){
printf("'flag.txt' file not found, aborting.\n");
return 1;
}
fgets(flag, 64, fd);
// Read in second secret menu item
fd = fopen("secret-menu-item-2.txt", "r");
if (fd == NULL){
printf("'secret-menu-item-2.txt' file not found, aborting.\n");
return 1;
}
fgets(secret2, 64, fd);
printf("Give me your order and I'll read it back to you:\n");
fflush(stdout);
scanf("%1024s", buf);
printf("Here's your order: ");
printf(buf);
printf("\n");
fflush(stdout);
printf("Bye!\n");
fflush(stdout);
return 0;
}
bufに読み込んだ値を書式指定しないでprintfで表示している箇所がある。
scanf("%1024s", buf);
printf("Here's your order: ");
printf(buf);
これはformat string bug (fsb)と呼ばれる脆弱性で、printfなど書式指定を扱う関数において攻撃者は書式指定文字列を入力することでプログラム内部のスタック上の値を読み取ったり、任意のアドレスに書き込みを行うことができる。
今回はローカル変数flagの値を知りたいので%pでスタック上の値を読み取ることを試みる
%14$p
あたりを指定するとフラグらしき文字列(をエンコードした値)があらわあれるので%15$p、%16$p、…と値を読んでデコードするとフラグが得られる