我在 CTF 中遇到了打印格式漏洞挑战。我对这些漏洞一无所知,所以我正在研究来自exploit-db.com(https://www.exploit-db.com/docs/english/28476)的Saif El-Sherei格式字符串利用教程-linux-format-string-exploitation.pdf)。但是,我很早就陷入了困境。我希望有人能指出我哪里出错了。
这是我写的一些代码:
#include <stdio.h>
#include <stdlib.h>
void nicefunction()
{
printf("you are in the nice function!\n");
}
void notnicefunction()
{
printf("you are in the NOT nice function!\n");
}
int foo()
{
void (*fptr)() = &nicefunction;
char buf[100];
puts("Please enter a string. ");
fgets(buf,80,stdin);
puts("Here's your string");
printf(buf);
puts("\nNow we call the nice function");
(*fptr)();
return 0;
}
int main(int argc, char **argv)
{
foo();
}
我的目标是制作一个输入字符串,我可以用它来将 fptr 更改为指向 notnicefunction。我编译它:gcc -m32 -g test.c -fno-stack-protector -z execstack -o test
我在 gdb 下运行二进制文件并在断点前后添加。当我输入字符串“AAAA”然后执行 x/20xw $esp 时,我看到堆栈中的 0x41414141 位于 0xffffd018。如果我重新运行并输入字符串“AAAA %6$x”,我会得到 AAAA 41414141。到目前为止一切顺利。
现在我想找到fptr的地址。使用 nm,我看到它应该包含 0x0804849b 的值(nicefunction 的地址)。我的目标是把它改成notnicefunction的地址0x080484b4。我用 AAAA 重新运行,然后检查堆栈,直到找到包含 0x0804849b 的地址。这是从 buf 开始的堆栈中更深的 0xffffd07c, 0x64 (100d) 个字。这是有道理的。
我想通过使用 %n 来控制 fptr 的内容。所以我制作了这个输入字符串:\x7c\xd0\xff\xff\xff\xffAAAA%5$x%n。我认为这应该将 0xffffd07c 的内容更改为 13d。但是我在 printf 中出现了段错误。
我哪里错了?
更新:我尝试将我的 fptr 地址写入缓冲区的开头,只是为了查看我是否正确写入了地址。但是当我在 gdb 中检查它时,它有 ASCII 表示:
(gdb) x/20xw $esp+8
0xffffd018: 0x6337785c 0x3064785c 0x6666785c 0x6666785c
所以问题是 bash 不喜欢我的十六进制文字。我想我可以通过从文件重定向来解决这个问题。但是,如果有人知道处理此问题的更清洁的方法,我很想知道。
MOAR 更新:Pawel 下面的评论让我克服了 how-do-I-get-hex-bytes-into-this-binary 障碍。但我仍然在我的 %n 上进行段错误。但是当我将 %5$x %n 更改为 %x %x %x %x %x %n 时,段错误就消失了。现在我能够(某种程度上)控制任意堆栈内存的内容。呜呼!