,我们因而在[VERSYM+(low_addr-SYMTAB)/8, VERSYM+(hi_addr-SYMTAB)/8]该区域寻找短零字节. 当找到了适合的verind后,还得检查如下这些: 1) 符号的地址不能够和伪造栈帧相交叉. 2) 符号的地址不能覆盖在任何内在的连接数据,比如strcpy的GOT全局偏移表入口) 3)须知道堆栈指针会被转移到静态的数据段.必须要有足够的空间来放置动态链接程序所在的栈帧栈.所以,最好,但不是必须的,在伪造栈帧后面放置符号"sym".
一个建议:寻找零短字节的方式,最好使用gdb,比通过命令"objdump -s" 输出分析要好一些.因为后者不能够显示出.rodata 后面的内存区域:)
实现代码icebreaker.c 是一个很简单的攻击pax.c程序. vuln.c和 pax.c唯一的不同是拷贝到静态缓冲的环境变量不同罢了.(注意看后面的代码:)
--[ 7 - 其他更多 ----[ 7.1 - 系统无关性 由于PaX是为linux系统设计的,所以在这篇文章中讨论的焦点也是对这种系统而言.然而 ,当今技术的发展和实现,趋向于系统的无关性.栈和栈帧指针,C函数调用的标准,ELF的描述,所有这些都在当今被广泛的使用和实现了.对dl-resolve.c 代码而言,我已经成功的在Solaris i386和 FreeBSD实现了. 不过mmap的第4个参数必须被调整,比如在BSD系统,MAP_ANON 的数值就不同的.在我实现的这两个系统,动态链接对符号版本影响不大,所以,不应该不容易实现:)
----[ 7.2 -其他类型的缺陷 对缓冲溢出而言,现有的技术是很基础的.返回某个地址的代码实现依靠的是不能更改堆栈%eip的单一的溢出,但是,在返回的函数地址,我们能够放置函数的参数在栈顶.
另外两个大的缺陷分类,malloc控制结构腐败和格式化字符串攻击.对前一个问题,我们用任意的数值覆盖其整型字节---非常的下,以至于逃脱了PaX的保护.后一个问题,我们通常改变任意字节的数目.如果我们能够覆盖%ebp和函数的%eip,我们不需要做其他的了.但是由于栈基是随机的地址,没有办法确定任何栈帧的地址.
通过改变一些 GOT全局偏移表 的入口,不过只能控制得到指令下一个的地址,对逃避Pax的保护还远不够.
不过,在这里有个开发实现代码的想法很可能能够实现.我们假设下面3个条件: 1)被攻击程序使用了-fomit-frame-pointer 编译选项. 2)一个f1的函数,它分配的堆栈缓冲区可以由我们来控制. 3)函数f2有一个格式话漏洞(或者错误使用free()),它被f1调用或者间接调用.
有缺陷的代码如下: void f2(char * buf) { printf(buf); // 格式化漏洞 some_libc_function(); } void f1(char * user_controlled) { char buf[1024]; buf[0] = 0; strncat(buf, user_controlled, sizeof(buf)-1); f2(buf); } 假设函数f1()正被调用,通过构造的格式化字符串,我们可以改变some_libc_function库函数的GOT全局偏移表入口地址,变成下面代码的入口地址.代码如下: addl $imm, %esp ret 这是个函数的结尾代码,这种情况,库函数被调用,通过"addl $imm, %esp"指令改变了堆栈指针.如果我们选择适当的$imm,让堆栈指针指向我们能够控制的堆栈缓冲里面.这样一来,就象一个堆栈的缓冲溢出,我们可以链接函数,返回链接技术等等溢出方式来实现.
另一种情况:单一字节的堆栈缓冲溢出.这种溢出控制栈帧指针最后的一个字节,在第二个函数返回的时候,攻击者有机会可以通过单一字节的溢出技术通过控制%esp,获得堆栈的整个控制权,改变弹出的%eip转到执行我们的实现代码,现有的所有技术已能够实现.
----[ 7.3 - 其他"不可执行"的解决方法 对此,我知道两个解决的方法,在Linux i386系统,让所有的数据段不可执行.第一个是RSX[见文10]. 由于,这种解决方法没有在堆栈中实现,也没有让库函数基址地址随机化,所以在3章中讲述了通过链接多个函数调用来实不可执行的突破.
如果我们要执行任意的代码,我们还需要额外的努力.比如在RSX系统,在保护模式可写的内存区域不能够放置执行代码.所以前面的mmap(...PROT_READ|PROT_WRITE|PROT_EXEC) 欺骗方法就不能够工作.但是任何不可执行的设计必须允许共享库函数里可以执行代码. 在RSX系统,通过这种办法,包含有shellcode的mmap(...PROT_READ|PROT_EXEC)达到了目的.远程利用的实现,其联结允许我们先创建这个文件。
第二种解决方法,和前一种类似的,是kNoX[见文11],不同的地方是对库函数进行了随机地址映射.其地址开始于0x00110000.(和Solar的补丁类似)在本文3.4节的末提及.这种保护仍然还不够:)
----[ 7.4 - 改进现有"不可执行"的设计 不知道是幸运还是不幸运,对保护者也许不幸运.呵呵,我没有见到可以让Pax更加牢固的方法以避免现有的技术攻击:)显然,由于 ELF 的标准描述过于详细的将其的某些对攻击者有用的技术细节公之于众,当然,一些现有的欺骗手段能够被得以制止.比如使用内核补丁.但不能够限制共享库函数在exploit技术中的实现.除非是对函数的联结来限制用法云云.
另一方面,如果正确的配置Pax,将会让现有的exploit技术的实现变得困难甚至是不能够实现.当Pax变得更加可靠的时候,应易于使用.呵呵,简单是另一种层次的防守:)
----[ 7.5 - 版本信息 所有代码均在以下补丁版本中测试: pax-linux-2.4.16.patch kNoX-2.2.20-pre6.tar.gz rsx.tar.gz for kernel 2.4.5 代码可以在任何2.4.x 内核版本的系统运行,但不能够在2.2.x的版本!
--[ 8 - 参考的出版物和工程项目 [1] Aleph One the article in phrack 49 that everybody quotes [2] Solar Designer "Getting around non-executable stack (and fix)" http://www.securityfocus.com/archive/1/7480 [3] Rafal Wojtczuk "Defeating Solar Designer non-executable stack patch" http://www.securityfocus.com/archive/1/8470 [4] John McDonald "Defeating Solaris/SPARC Non-Executable Stack Protection" http://www.securityfocus.com/archive/1/12734 [5] Tim Newsham "non-exec stack" http://www.securityfocus.com/archive/1/58864 [6] Gerardo Richarte, "Re: Future of buffer overflows ?" http://www.securityfocus.com/archive/1/142683 [7] PaX team PaX http://pageexec.virtualave.net [8] segvguard ftp://ftp.pl.openwall.com/misc/segvguard/ [9] ELF specification http://fileformat.virtualave.net/programm/elf11g.zip [10] Paul Starzetz Runtime addressSpace Extender http://www.ihaquer.com/software/rsx/ [11] Wojciech Purczynski kNoX http://cliph.linux.pl/knox [12] grugq "Cheating the ELF" http://hcunix.7350.org/grugq/doc/subversiveld.pdf
9- [ 附件:README.code <++>代码注解 准备好有缺陷的程序,进行编译。 $ gcc -o vuln.omit -fomit-frame-pointer vuln.c $ gcc -o vuln vuln.c $ gcc -o pax pax.c I. ex-move.c ~~~~~~~~~~~~ ex-move.c代码的前面部分预定义了一些象LIBC, STRCPY, MMAP, POPSTACK, POPNUM, PLAIN_RET, FRAMES 的常数,你可以根据系统的环境进行调整,注意:MMAP_START 不能改变
下面,我们来获得这些我们需要的在代码中预定义的常数。 1)LIBC [nergal@behemoth pax]$ ldd ./vuln.omit(*通过ldd,我们可以获得有缺陷函数vuln.omit调用的库函数及其地址) libc.so.6 => /lib/libc.so.6 (0x4001e000)<-yeah,这就是库函数的入口地址0x4001e000 /lib/ld-linux.so.2 => /lib/ld-linux.so.2 (0x40000000)
2) STRCPY [nergal@behemoth pax]$ objdump -T vuln.omit(*通过objdump的参数-T,我们可以得到vuln.omit的动态符号表( DST) vuln.omit: file format elf32-i386(显示文件格式)
动态符号表: 08048348 w DF *UND* 00000081 GLIBC_2.0 __register_frame_info 08048358 DF *UND* 0000010c GLIBC_2.0 getenv 08048368 w DF *UND* 000000ac GLIBC_2.0 __deregister_frame_info 08048378 DF *UND* 000000e0 GLIBC_2.0 __libc_start_main 08048388 w DF *UND* 00000091 GLIBC_2.1.3 __cxa_finalize 08048530 g DO .rodata 00000004 Base _IO_stdin_used 00000000 w D *UND* 00000000 __gmon_start__ 08048398 DF *UND* 00000030 GLIBC_2.0 strcpy <-------oh,yeah! ~~~~~~~~(得到调用strcpy函数的地址) 3) MMAP [nergal@behemoth pax]$ objdump -T /lib/libc.so.6 | grep mmap(*从库函数DST中找到mmap地址) 000daf10 w DF .text 0000003a GLIBC_2.0 mmap <-----yeah,中彩了。 000db050 w DF .text 000000a0 GLIBC_2.1 mmap64
4) POPSTACK/POPNUM/PLAIN_RET 我们必须找到"add $imm,%esp" 后面的"ret"指令。我们需要反汇编缺陷程序vuln.omit ,可以使用gdb的disas指令,也可以用objdump命令。这里使用"objdump --disassemble ./vuln.omit"。 [nergal@behemoth pax]$ objdump --disassemble ./vuln.omit |grep -B 1 ret(*找出反汇 上一页 [1] [2] [3] [4] [5] [6] [7] [8] [9] [10] ... 下一页 >> [办公软件]在sybase中插入图片、PDF、文本文件 [办公软件]安装Sybase ASE [办公软件]linux指令大全(完整篇) [办公软件]Linux新手入门常用命令大全 [办公软件]在RedHat Linux 9里安装gaim0.80 [办公软件]浅谈Linux 下Java 1.5 汉字方块问题解决方法 [办公软件]Linux程序员必读:中文化与GB18030标准 [办公软件]linux指令大全 [办公软件]制作Linux启动盘的四种方法 [办公软件]Linux文件系统的反删除方法
|