我有一个练习,我需要找到缓冲区的开始和结束地址(buf2
)。我无权编辑代码。
以下是代码:
(level2代码的密码是fsckmelogic)
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
int main(int argc, const char **argv) {
if (argc < 2) { printf("Fail. More Args...\n"); return 1; }
else {
setresuid(geteuid(),geteuid(),geteuid());
char buf2[4096];
char buf[16];
const char password[]="XXXXXXXXXXX";
strncpy(buf, argv[1], sizeof(buf) - 1);
if (strcmp(buf,password) != 0) {
printf("Wrong.\n");
return 1;
}
else {
strcpy(buf2,argv[2]);
printf("%s",buf2);
return 0;
}
}
}
答案 0 :(得分:3)
gcc level2.c -o so_test
现在我们想找出一些起始地址....所以让我们使用ltrace
(我希望它安装在系统上)我们得到:
ltrace ./so_test XXXXXXXXXXX ababaabaabab
__libc_start_main(0x4006f0, 3, 0x7fff291bddb8, 0x400800 <unfinished ...>
geteuid() = 1000
geteuid() = 1000
geteuid() = 1000
setresuid(1000, 1000, 1000, -1) = 0
strncpy(0x7fff291bdcb0, "XXXXXXXXXXX", 15) = 0x7fff291bdcb0
strcmp("XXXXXXXXXXX","XXXXXXXXXXX") = 0
strcpy(0x7fff291bcca0, "ababaabaabab") = 0x7fff291bcca0
printf("%s", "ababaabaabab") = 12
好的......那又怎么样?
请记住strncpy
返回指向目标字符串的指针,并从代码中返回
我们知道目的地为buf
,因此它的起始地址为0x7fff291bdcb0
(在我的机器上,您的号码会有所不同)。
strncpy
的第三个参数是要复制的字符数,在本例中为15.从代码中,我们可以看到strncpy
的第三个参数是{{ 1}}这意味着sizeof(buf) - 1
返回16.从此我们可以推断sizeof(buf)
的结束地址是0x7fff291bdcb1 + 0x10或ox7fff291bdcc1
我们还可以从buf
函数调用的结果中了解到buf2
的起始地址是0x7fff291bcca0。
我们可以知道,由于strcpy
函数调用的返回值,用户输入的字符串长度为12个字符。
所以现在剩下的就是找出buf2的终点。我们可以开始向它投掷输入,直到它炸毁我们。提示,如果您不想键入相同字符的长字符串,则可以执行以下操作:
printf
只需将1024更改为要输入buf2的字符数。在我的系统上,通过一些反复试验,我发现我可以输入的最大值是4151,推入4152 A导致分段错误(所以我们知道最大值) buf2的大小将小于此值。
希望这能为您提供一个开始,我不想为您完成整个挑战:)
答案 1 :(得分:0)
如果您无法修改代码,并且您的任务是获取buf2的开头和结尾ADDRESS,那么剩下的就是用调试器运行它,并从那里获取地址吗?
答案 2 :(得分:-1)
可以使用
查看缓冲区的起始地址 printf("%p", &buff2);
一旦得到地址的起点,就找到缓冲区的长度,即
len=strlen(buff2);
现在在指针中添加长度然后你得到buff2的结束地址,即
printf("%p %p", *buff2, *buff2+strlen(buff2));