|
论文大纲,目录 |
关键词搜索:计算机应用论文 学术论文 |
# 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 ”,get_esp()); } 通常,进程运行时向堆栈中写入的数据不会超过数百个字节或数千个字节,有了这个起始地址,用简单的一个个尝试的方法也是可以攻击的。但显然这不是一种效率高的方法。解决的办法是在缓冲区前端填充几百字节NOP指令,只要猜测的地址落在NOP指令序列中,仍可以执行shellcode,从而成倍地增加猜中的机会。 (3) 攻击代码中字节代码为零的消除 Unix的程序中大量使用了strcpy函数,shellcode中含有0x00,由于通常是攻击一个字符缓冲区,如果攻击代码中含有0,则它会被当成字符串的结尾处理,于是攻击代码被截断。消除的方法是对代码做适当的变换,因此在这里需要使用一些汇编程序设计技巧,把shellcode转换成不含0x00的等价代码。 (4)被攻击的缓冲区很小的情况 当缓冲区太小,可能使NOP部分或shellcode部分覆盖返回地址ret,导致缓冲区起址到返回地址的距离不足以容纳shellcode,这样设定的跳转地址就没有用上,攻击代码不能被正确执行。 一个方法就是利用环境变量。当一个进程启动时,环境变量被映射到进程堆栈空间的顶端。这样就可以把攻击代码(NOP串+Shellcode)放到一个环境变两中,而在被溢出的缓冲区中填上攻击代码的地址。比如,可以把shellcode放在环境变量中,并把环境变量传入到要攻击的程序中,就可以对有缓冲区溢出漏洞的程序进行攻击。利用这样方法,还可以设计很大的攻击代码。 2.2缓冲区溢出攻击的类型 缓冲区溢出的目的在于扰乱具有某些特权运行程序的功能,这样就可以让攻击者取得程序的控制权,如果该程序具有足够的权限,那么整个主机甚至服务器就被控制了。一般而言,攻击者攻击root程序,然后执行类似“exec(sh)”的执行代无忧论文 【http://www.uklunwen.com】码来获得root的shell。但并不总是这样,为了达到这个目的,攻击者必须达到如下两个目标: l 在程序的地址空间里安排适当的代码 l 通过适当地初始化寄存器和存储器,让程序跳转到安排好的地址空间执行。 我们可以根据这两个目标来对缓冲区溢出攻击进行分类。 1.在程序的地址空间里安排适当的代码有两种在被攻击程序地址空间里安排攻击代码的方法: (1) 植入法: 攻击者向被攻击的程序输入一个字符串,程序会把这个字符串放到缓冲区里。这个字符串所包含的数据是可以在这个被攻击的硬件平台运行的指令流。在这里攻击者用被攻击程序的缓冲区来存放攻击代码,具体方式有以下两种差别: a.攻击者不必为达到此目的而溢出任何缓冲区,可以找到足够的空间来放置攻击代码; b.缓冲区可设在任何地方:堆栈(存放自动变量)、堆(动态分配区)和静态数据区(初始化或未初始化的数据)。 (2) 利用已经存在的代码 有时候攻击者所要的代码已经存在于被攻击的程序中了,攻击者所要做的只是对代码传递一些参数,然后使程序跳转到想要执行的代码那里。比如,共及代码要求执行“exec(‘bin/sh’)”,而在libc库中的代码执行“exec(arg)”,其中arg是一个指向字符串的指针参数,那么攻击者只要把传入的参数指针改向指向“/bin/sh”,然后调转到libc库中相应的指令序列即可。 2.控制程序转移到攻击代码的方法 所有这些方法都是在试图改变程序的执行流程,使之跳转到攻击代码。其基本特点就是给没有边界检查或有其他弱点的程序送出一个超长的缓冲区,以达到扰乱程序正常执行顺序的目的。通过溢出一个缓冲区,攻击者可以用几乎暴力的方法(穷尽法)改写相邻的程序空间面直接跳过系统的检查。 这里的分类基准是攻击者所寻求的缓冲区溢出的程序空间类型。原则上可以是任意的空间。比如起初的Morris Worm(莫尔斯蠕虫)就是使用了fingerd程序的缓冲区溢出,扰乱fingerd要执行的文件的名字。实际上许多的缓冲区溢出是用暴力的方法来寻求改变程序指针的。这类程序不同的地方就是程序空间的突破和内存空间的定位不同。一般来说,控制程序转移到攻击代码的方法有以下几种: (1) 函数返回地址 每当一个函数调用发生时,调用者会在堆栈中留下函数返回地址,它包含了函数结束时返回的地址。攻击者通过溢出这些自动变量,使这个返回地址指向攻击代码,这样就通过改变程序的返回地址,当函数调用结束时,程序跳转到攻击者设定的地址,而不是原先的地址。这类的缓冲区进出被称为“stack smashing attack”,是目前常用的缓冲区溢出攻击方式。(2) 函数指针 “Void(*foo)()”中声明了一个返回值为Void函数指针的变量foo。函数指针定位任何地址空间,所以攻击者只需在任何空间内的函数指针附近找到一个能够溢出的缓冲区,然后溢出来改变函数指针,当程序通过函数指针调用函数时,程序的流程就会发生改变而实现攻击者的目的。 (3) 长跳转缓冲区 在C语言中包含了一个简单的检验/恢复系统,称为“setjmp/longjmp”,意思是在检验点设定“setjmp(buffer)”,用longjmp(buffer)“来恢复检验点。然而,如果攻击时能够进入缓冲区的空间,那么“longjmp(buffer)”实际上是跳转到攻击者的代码。像函数指针一样,longjmp缓冲区能够指向任何地方,所以攻击者所要做的就是找到一个可供溢出的缓冲区。一个典型的例子就是Perl 5 |
|
|
第1页 第2页 第3页 第4页 第5页 第6页 第7页 |
|
|
| 上一篇:项目管理在软件中的应用下一篇:基于B/S体系结构开发应用系统
|
| 最新论文 |
最热门论文 |
|
|
|
|
|