gpt4 book ai didi

c - Format String 漏洞困扰

转载 作者:太空宇宙 更新时间:2023-11-04 00:09:05 25 4
gpt4 key购买 nike

所以我有这个功能:

void print_usage(char* arg) 
{
char buffer[640];
sprintf(buffer, "Usage: %s [options]\n"
"Randomly generates a password, optionally writes it to /etc/shadow\n"
"\n"
"Options:\n"
"-s, --salt <salt> Specify custom salt, default is random\n"
"-e, --seed [file] Specify custom seed from file, default is from stdin\n"
"-t, --type <type> Specify different encryption method\n"
"-v, --version Show version\n"
"-h, --help Show this usage message\n"
"\n"
"Encryption types:\n"
" 0 - DES (default)\n"
" 1 - MD5\n"
" 2 - Blowfish\n"
" 3 - SHA-256\n"
" 4 - SHA-512\n", arg);
printf(buffer);
}

我想利用格式化字符串漏洞攻击(我的任务)。这是我的尝试:

我有一个利用 noops 和 shell 代码填充缓冲区的漏洞利用程序(我用这个程序来缓冲区溢出相同的函数,所以我知道它的好处)。现在,我对文件进行了对象转储以找到 .dtors_list 地址,我得到了 0x0804a20c,添加 4 个字节以得到 0x804a210。

接下来,我使用 gdb 查找在运行我的程序时我的 noops 开始的地址。使用这个我得到了 0xffbfdbb8。

到目前为止,我觉得我是对的,现在我知道我想使用格式字符串将 noop 地址复制到我的 .dtors_end 地址中。这是我想出的字符串(这是我作为用户输入提供给函数的字符串):

"\x10\xa2\x04\x08\x11\xa2\x04\x08\x12\xa2\x04\x08\x13\xa2\x04\x08%%.168u%%1$n%%.51u% %2$n%%.228u%%3$n%%.64u%%4$n"

这对我不起作用。程序运行正常,%s被我输入的字符串替换(减去前面的小端内存地址,由于某些原因,两个百分号现在变成了一个百分号)。

无论如何,我在这里有点难过,任何帮助将不胜感激。

最佳答案

免责声明:我不是专家。

您正在传递 "\x10\xa2\x04\x08\x11\xa2\x04\x08\x12\xa2\x04\x08\x13\xa2\x04\x08%%.168u%%1 $n%%.51u%%2$n%%.228u%%3$n%%.64u%%4$n" 作为 arg 的值?这意味着 buffer 将包含

"用法:\x20\x10\xa2\x04\x08\x11\xa2\x04\x08\x12\xa2\x04\x08\x13\xa2\x04\x08%.168u%1$n %.51u%2$n%.228u%3$n%.64u%4$n [选项]\x0aRandomly..."

现在让我们进一步假设您在 x86-32 目标上(如果您在 x86-64 上,这将不起作用),并且您正在使用不放置任何内容的优化级别进行编译在 print_usage 的栈帧中,除了 640 字节的 buffer 数组。

然后 printf(buffer) 将按顺序执行以下操作:

  • 压入 4 字节地址 &buffer
  • 推送一个 4 字节的返回地址。
  • 调用printf...
  • 打印出 "Usage:\x20\x10\xa2\x04\x08\x11\xa2\x04\x08\x12\xa2\x04\x08\x13\xa2\x04\x08" (23 个字节的序列)。
  • %.168u:将 printf 的下一个参数解释为 unsigned int 并将其打印在宽度为 168 的字段中。由于 printf没有下一个参数,这实际上是打印堆栈上的下一个东西;即buffer的前四个字节;即 “Usag” (0x67617355)。
  • %1$n:将 printf 的第二个参数解释为指向 int 的指针,并将 23+168 存储在该位置。这会将 0x000000bf 存储在位置 0x67617355 中。所以这是您的主要问题:您应该使用 %2$n 而不是 %1$n 并在 arg< 的前面添加一个垃圾字节。 (顺便说一句,请注意 GNU 说 "If any of the formats has a specification for the parameter position all of them in the format string shall have one. Otherwise the behavior is undefined." 所以为了安全起见,你应该仔细检查并将 1$ 添加到你所有的 %u 中。)
  • %.51u:打印另外 51 个字节的垃圾。
  • %2$n:将 printf 的第三个参数解释为指向 int 的指针,并将 0x000000f2 存储在该垃圾位置。如上,这应该是 %3$n
  • ……等等等等……

所以,这里的主要错误是您忘记考虑 "Usage: " 前缀。

我假设您正在尝试将四个字节 0xffbfdbb8 存储到地址 0x804a210 中。假设你已经让它工作了。但是你的下一步是什么?如何让程序将 0x804a210 处的四字节数字视为函数指针并跳过它?

利用此代码的传统方法是利用 sprintf 中的缓冲区溢出,而不是利用 printf< 中更复杂的 "%n" 漏洞。您只需要使 arg 的长度大约为 640 个字符,并确保它对应于 print_usage 的返回地址的 4 个字节包含您的 NOP sled 的地址。

不过,即使是那个部分也很棘手。您可能会遇到与 ASLR 相关的问题:仅仅因为您的 sled 在一次运行中存在于地址 0xffbfdbb8 并不意味着它会在下一次运行中存在于同一地址。

这有帮助吗?

关于c - Format String 漏洞困扰,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10740308/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com