alpaca_functions[choice]() には範囲による制約がないchoice = 5 は vuln() の直後をさす return address を指すことがわかるalpaca_functions[5]() を実行すれば vuln() の実行直後の行から実行できる問題のコードは以下である。
void win() {
asm volatile("mov $0,%spl");
puts("You Win! 🦙🦙🦙🦙🦙");
system("/bin/sh");
exit(0);
}
void vuln() {
void (*alpaca_functions[3])() = {
alpaca_function0,
alpaca_function1,
alpaca_function2};
unsigned int choice;
printf("Select an alpaca function index: ");
scanf("%u", &choice);
alpaca_functions[choice]();
exit(0);
}
int main() {
setvbuf(stdin, NULL, _IONBF, 0);
setvbuf(stdout, NULL, _IONBF, 0);
vuln();
win();
return 0;
}
choice はとくに入力する値の範囲に制約がないので、choice = 5 などを入れると配列の外を参照する(Cなので問題なく進む)。こうするとスタック上の隣の値を関数ポインタとして呼び出すことになるので、これを上手く使って win() を呼びたい。
実験として 1 とか 2 とか近い適当な数字を打ってもいいが、ちゃんと動き方を確認することにする。
vuln() を disassemble すると
objdump -d -Mintel ./chal