网络安全参考 | UNIX参考 | GPS参考 | 无线参考 | 在线手册 | OSBUG.ORG | SUNNY-NETWORK.COM
网站地图 RSS订阅
高级搜索 收藏本站
Home | 业界动态 | 防火墙 | IDS/IPS | VPN | PKI | Honeypot | Hacker/Intruder | 黑客技术 | 破解技术 | 加密技术 | 病毒防护 | 木马 | 反垃圾邮件 | 反流氓软件 | 漏洞 | 无线安全 | UNIX | Windows | 安全编程 | 安全软件 | TPM/TCG | 数据恢复 | 企业信息安全 | 个人信息安全
 当前位置: Home > 安全编程 > 文章  
非安全编程演示之高级缓冲区溢出篇
文章来源: 华泰网安 文章作者: alert7 发布时间: 2006-07-10   字体: [ ]
 

  创建时间:2001-11-09
  文章属性:原创
  文章来源:http://xfocus.org/
  文章提交:alert7 (sztcww_at_sina.com)

  非安全编程演示之高级缓冲区溢出篇

  作者:alert7 <mailto: alert7@netguard.com.cn>
  主页: http://www.xfocus.org/  http://www.whitecell.org/
  公司:华泰网安 < http://www.netguard.com.cn >
  原文:http://community.core-sdi.com/~gera/InsecureProgramming/InsecureProgramming.tar.gz

  时间: 2001-11-9

  声明:文中的大部分演示程序来自qera <gera@core-sdi.com>,感谢qera为我们精心构造这些很能说明的演示程序。

  有些程序可能有不只一种的利用方法,而文中又没有提到的。如果您有好的idea,记得mailto:alert7@xfocus.org,不正确或者不当之处还请斧正。

  ★★ 一  高级缓冲区溢出篇

  ★ 1.1 演示一----盲目服从(blind obedience)

  定义的buf太小,需要copy的数据不足以容纳下。


/* abo1.c                                                   *
* specially crafted to feed your brain by
gera@core-sdi.com */

/* Dumb example to let you get introduced...                */

int main(int argc,char **argv) {
    char buf[256];

    strcpy(buf,argv[1]);
}


  这是个很好的例子程序,很能说明问题:该程序将拷贝argv[1]到buf中,使用了strcpy函数,没有做任何的边界检查。这就给了我们一个机会,传一个超长的argv[1]进去,覆盖到堆栈中buf后面的数据。你需要利用所有的工具来查看buf后面到底是什么重要的东西,然后才能构造出那些exploit需要的摸板。


  ★ 1.2 演示二----执行流程(execution flow)

  再来看看这个程序:

/* abo2.c                                                   *
* specially crafted to feed your brain by
gera@core-sdi.com */

/* This is a tricky example to make you think               *
* and give you some help on the next one                   */

int main(int argv,char **argc) {
    char buf[256];

    strcpy(buf,argc[1]);
    exit(1);
}

 

  正如我们看的那样,在这个例子中,加了个exit(). 发现了不同了吗?一般利用覆盖main的返回地址的方法已经行不通了。在这个例子中,windows下利用windows的异常机制可以成功的溢出这个程序,而在unix下就没有这种特性,暂时还不知道如何溢出这个程序?或者就根本不能利用。欢迎讨论,请mailto:alert7@xfocus.org :)


  ★ 1.3 演示三----覆盖函数指针


/* abo3.c                                                    *
* specially crafted to feed your brain by
gera@core-sdi.com */

/* This'll prepare you for The Next Step                     */

int main(int argv,char **argc) {
    extern system,puts;
    void (*fn)(char*)=(void(*)(char*))&system;
    char buf[256];

    fn=(void(*)(char*))&puts;
    strcpy(buf,argc[1]);
    fn(argc[2]);
    exit(1);
}


  可利用缓冲区溢出覆盖fn函数指针,达到攻击目的。


  ★ 1.4 演示四----覆盖指针,导致任意地址的覆盖

/* abo4.c                                                    *
* specially crafted to feed your brain by
gera@core-sdi.com */

/* After this one, the next is just an Eureka! away          */

extern system,puts;
void (*fn)(char*)=(void(*)(char*))&system;

int main(int argv,char **argc) {
    char *pbuf=malloc(strlen(argc[2])+1);
    char buf[256];

    fn=(void(*)(char*))&puts;
    strcpy(buf,argc[1]);
    strcpy(pbuf,argc[2]);
    fn(argc[3]);
    while(1);
}

  第一个strcpy时候,可覆盖到pbuf指针,可使pbuf指向fn地址,所以第二次strcpy的时候就会覆盖到fn指针,结果运行fn()函数的时候就可以执行任意函数调用,比如system();


  ★ 1.5 演示五----ch-ch-ch-changes


/* abo5.c                                                    *
* specially crafted to feed your brain by
gera@core-sdi.com */

/* You take the blue pill, you wake up in your bed,          *
*     and you believe what you want to believe              *
* You take the red pill,                                    *
*     and I'll show you how deep goes the rabbit hole       */

int main(int argv,char **argc) {
    char *pbuf=malloc(strlen(argc[2])+1);
    char buf[256];

    strcpy(buf,argc[1]);
    for (;*pbuf++=*(argc[2]++););
    exit(1);
}


  第一个strcpy时候,可覆盖到pbuf指针,可使pbuf指向exit的GOT或者.dotrs地址+4,从而可以覆盖到那些部分,获得控制权。

  ★ 1.6 演示六

/* abo6.c                                                   *
/* specially crafted to feed your brain by
gera@core-sdi.com */

/* wwwhat'u talkin' about? */

int main(int argv,char **argc) {
    char *pbuf=malloc(strlen(argc[2])+1);
    char buf[256];

    strcpy(buf,argc[1]);
    strcpy(pbuf,argc[2]);
    while(1);
}

  第一个strcpy时候,可覆盖到pbuf指针,可使pbuf指向第二个strcpy函数的返回地址,从而可以覆盖到该地址,第二个strcpy一返回就可以获得控制权。

  ★ 1.7 演示七

/* abo7.c                                                   *
* specially crafted to feed your brain by
gera@core-sdi.com */

/* sometimes you can,       *
* sometimes you don't      *
* that's what life's about */

char buf[256]={1};

int main(int argv,char **argc) {
    strcpy(buf,argc[1]);
}
[alert7@redhat]$ gcc -o test test.c -g
[alert7@redhat]$ gdb test -q
(gdb) l
1       char buf[256]={1};
2
3       int main(int argv,char **argc) {
4               strcpy(buf,argc[1]);
5       }
(gdb) b 4
Breakpoint 1 at 0x80483cb: file test.c, line 4.
(gdb) r 999
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/alert7/test 999

Breakpoint 1, main (argv=2, argc=0xbffffbc4) at test.c:4
4               strcpy(buf,argc[1]);
(gdb) p &buf
$1 = (char (*)[256]) 0x8049460

  buf的地址为0x8049460,也就是说如果0x8049460地址后有什么重要的话我们可以得到控制权的数据的话,那么我们就可以溢出成功。

  在这里:


[alert7@redhat]$ objdump -s -j .dtors test

test:     file format elf32-i386

Contents of section .dtors:
804956c ffffffff 00000000                    ........


  我们可以覆盖.dtors,达到获得控制权的目的。

  ★ 1.8 演示八

Don't stay static


/* abo8.c                                                    *
* specially crafted to feed your brain by
gera@core-sdi.com */

/* spot the difference */

 char buf[256];

int main(int argv,char **argc) {
    strcpy(buf,argc[1]);
}

[alert7@redhat]$ gcc -o  test test.c -g
[alert7@redhat]$ objdump --dynamic-reloc test

test:     file format elf32-i386

DYNAMIC RELOCATION RECORDS
OFFSET   TYPE              VALUE
0804947c R_386_GLOB_DAT    __gmon_start__
0804946c R_386_JUMP_SLOT   __register_frame_info
08049470 R_386_JUMP_SLOT   __deregister_frame_info
08049474 R_386_JUMP_SLOT   __libc_start_main
08049478 R_386_JUMP_SLOT   strcpy
[alert7@redhat]$ gdb test -q
(gdb) l
1
2       char buf[256];
3
4       int main(int argv,char **argc) {
5               strcpy(buf,argc[1]);
6       }
7
(gdb)  b 5
Breakpoint 1 at 0x80483cb: file test.c, line 5.
(gdb) r 11
Starting program: /home/alert7/test 11

Breakpoint 1, main (argv=2, argc=0xbffffbc4) at test.c:5
5               strcpy(buf,argc[1]);
(gdb) p & buf
$1 = (char (*)[256]) 0x8049540
(gdb) q
The program is running.  Exit anyway? (y or n) y
[alert7@redhat]$ objdump -s -j .dtors test

test:     file format elf32-i386

Contents of section .dtors:
8049458 ffffffff 00000000                    ........
[alert7@redhat]$ gcc -o  test test.c -g -static
[alert7@redhat]$ gdb test -q
(gdb) l
1
2       char buf[256];
3
4       int main(int argv,char **argc) {
5               strcpy(buf,argc[1]);
6       }
7
(gdb) b 5
Breakpoint 1 at 0x804819b: file test.c, line 5.
(gdb) r 11
Starting program: /home/alert7/test 11

Breakpoint 1, main (argv=2, argc=0xbffffc14) at test.c:5
5               strcpy(buf,argc[1]);
(gdb) p &buf
$1 = (char (*)[256]) 0x807bb60
(gdb) p __exit_funcs
$2 = (struct exit_function_list *) 0x807b160
[alert7@redhat62 alert7]$ objdump -s -j .dtors test

test:     file format elf32-i386

Contents of section .dtors:
807b100 ffffffff 00000000                    ........


  buf的地址都比其他的地址要大,所以覆盖不到他们。
  这个例子还不知道如何得到控制权呢?用超长字符串覆盖main函数的返回地址是不现实的,并且在还没有覆盖到main函数返回地址之前就会Segmentation fault,原因是访问了一个没有映射的地址(地址映射是不连续的) 。
  这个演示程序让我郁闷了好久,在我的linux上还真的无法成功溢出这个程序,还是qera又一次专门为windows设计的!?(如果您有好的idea,记得mailto:alert7@xfocus.org)。在windows下成功溢出这个演示程序是没有问题的。

  ★ 1.9 演示九----两次free技术

/* abo9.c                                                  *
* specially crafted to feed your brain by
gera@core-sdi.com */

/* free(your mind) */

/* I'm not sure in what operating systems it can be done */

int main(int argv,char **argc) {
    char *pbuf1=(char*)malloc(256);
    char *pbuf2=(char*)malloc(256);

    gets(pbuf1);
    free(pbuf2);
    free(pbuf1);
}


  请参考waring3的<<一种新的Heap区溢出技术分析>>
  那片文章上已经讲的很明白了,不想多说,不想做重复的劳动:)

  ★ 1.10 演示十----一次free技术

/* abo10.c                                                  *
* specially crafted to feed your brain by
gera@core-sdi.com */

/* Deja-vu*/

char buf[256];

int main(int argv,char **argc) {
    char *pbuf=(char*)malloc(256);

    gets(buf);
    free(pbuf);
}
[alert7@redhat]$ gcc -o test test.c -g
/tmp/ccO6gW96.o: In function `main':
/home/alert7/test.c:6: the `gets' function is dangerous and should not be used.
[alert7@redhat]$ gdb test -q
(gdb) l
1       char buf[256];
2
3       int main(int argv,char **argc) {
4               char *pbuf=(char*)malloc(256);
5
6               gets(buf);
7               free(pbuf);
8       }
(gdb) b 6
Breakpoint 1 at 0x8048440: file test.c, line 6.
(gdb) r
Starting program: /home/alert7/test

Breakpoint 1, main (argv=1, argc=0xbffffbc4) at test.c:6
6               gets(buf);
(gdb) p &buf
$1 = (char (*)[256]) 0x80495c0
(gdb) p pbuf
$2 = 0x80496c8 ""


  可覆盖到pbuf的chunk块,利用一次free技术也可覆盖到.dotrs,main的返回地址等等。

  演示九和演示十都是由于缓冲区溢出而导致的内存管理函数处理出错,从而利用内存管理函数中的写操作,覆盖到自己想要覆盖的任何地址空间。

--
※ 链接: http://www.xfocus.net/articles/200111/298.html

 
推荐文章
·洪水攻击原理及代码实现全攻略(
·原始套接字透析之综合实例:网络
·原始套接字透析之实现IP地址欺骗
·原始套接字透析之ARP欺骗
·原始套接字透析之实现包分析
·原始套接字透析之实现sniffer
·原始套接字透析之实现路由欺骗
·原始套接字透析之ICMP拒绝服务攻
·原始套接字透析之实现Ping
·原始套接字透析之Raw Socket基础
·黑客之旅 -- 原始套接字透析之前
·QQ尾巴病毒的Visual C++实现探讨
·安全编程: 安全地调用组件
·安全编程: 验证输入
 
 
↑返回顶部   打印本页   关闭窗口↓  

Google
 
Web oldhand.org unixreference.net meshmea.org
热点文章
·原始套接字透析之Raw So
·原始套接字透析之ARP欺
·洪水攻击原理及代码实现
·原始套接字透析之综合实
·原始套接字透析之实现Pi
·黑客之旅 -- 原始套接字
·使用 OpenSSL API 进行
·安全编程: 警惕输入
相关分类
相关文章
·安全编程: 开发安全的程
·安全编程: 最小化特权
·安全编程: 警惕输入
·安全编程: 验证输入
·安全编程: 防止缓冲区溢
·安全编程: 安全地调用组
·使用 OpenSSL API 进行
·使用 OpenSSL API 进行
更多...
 
 

Copyright(c) 2001-2008 OLDHAND ORGANIZATION, All Rights reserved.
Power by DedeCms 织梦内容管理系统
$Id: article_article.html,v 1.3 2007/02/10 12:00:37 yjs Exp $