20145211《网络对抗》逆向及BOF基础实践

逆向及BOF基础实践——又是一年梅落时

一.实践目标

  • 本次实践的对象是一个名为pwn1的linux可执行文件。
  • 该程序正常执行流程是:main调用foo函数,foo函数会简单回显任何用户输入的字符串。

 

  • 该程序同时包含另外一个代码片断,getShell,会返回一个可用Shell。正常状况下这个代码是不会被运行的。咱们实践的目标就是想办法运行这个代码片断。
  • 咱们将学习两种方法
  1. 利用foo函数的Bof漏洞,构造一个攻击输入字符串,覆盖返回地址,触发getShell函数。
  2. 手工修改可执行文件,改变程序执行流程,直接跳转到getShell函数。

 

 二.实验原理

  缓冲区溢出(Buffer Overflow)是计算机安全领域内既经典而又古老的话题。随着计算机系统安全性的增强,传统的缓冲区溢出攻击方式可能变得再也不奏效,相应的介绍缓冲区溢出原理的资料也变得“大众化”起来。linux

  缓冲区溢出的含义是为缓冲区提供了多于其存储容量的数据,就像往杯子里倒入了过量的水同样。一般状况下,缓冲区溢出的数据只会破坏程序数据,形成意外终止。可是若是有人精心构造溢出数据的内容,那么就有可能得到系统的控制权!若是说用户(也多是黑客)提供了水——缓冲区溢出攻击的数据,那么系统提供了溢出的容器——缓冲区。vim

  缓冲区在系统中的表现形式是多样的,高级语言定义的变量、数组、结构体等在运行时能够说都是保存在缓冲区内的,所以所谓缓冲区能够更抽象地理解为一段可读写的内存区域,缓冲区攻击的最终目的就是但愿系统能执行这块可读写内存中已经被蓄意设定好的恶意代码。按照冯·诺依曼存储程序原理,程序代码是做为二进制数据存储在内存的,一样程序的数据也在内存中,所以直接从内存的二进制形式上是没法区分哪些是数据哪些是代码的,这也为缓冲区溢出攻击提供了可能。数组

 

 

 

进程地址空间分布安全

  图1是进程地址空间分布的简单表示。代码存储了用户程序的全部可执行代码,在程序正常执行的状况下,程序计数器(PC指针)只会在代码段和操做系统地址空间(内核态)内寻址。数据段内存储了用户程序的全局变量,文字池等。栈空间存储了用户程序的函数栈帧(包括参数、局部数据等),实现函数调用机制,它的数据增加方向是低地址方向。堆空间存储了程序运行时动态申请的内存数据等,数据增加方向是高地址方向。除了代码段和受操做系统保护的数据区域,其余的内存区域均可能做为缓冲区,所以缓冲区溢出的位置可能在数据段,也可能在堆、栈段。若是程序的代码有软件漏洞,恶意程序会“教唆”程序计数器从上述缓冲区内取指,执行恶意程序提供的数据代码!本文分析并实现栈溢出攻击方式。函数

  计算机程序通常都会使用到一些内存,这些内存或是程序内部使用,或是存放用户的输入数据,这样的内存通常称做缓冲区。溢出是指盛放的东西超出容器容量而溢出来了,在计算机程序中,就是数据使用到了被分配内存空间以外的内存空间。而缓冲区溢出,简单的说就是计算机对接收的输入数据没有进行有效的检测(理想的状况是程序检查数据长度并不容许输入超过缓冲区长度的字符),向缓冲区内填充数据时超过了缓冲区自己的容量,而致使数据溢出到被分配空间以外的内存空间,使得溢出的数据覆盖了其余内存空间的数据。学习

 

实践一:手工修改可执行文件

1.先cp一个一样的可执行文件,将本来的pwn1做为备份。spa

 

2.反汇编,了解程序的基本功能。用指令objdump反汇编20145211操作系统

   诚如刘老师上课讲的那样,第一列为内存地址,第二列为机器指令,第三列为汇编指令。3d

先看main函数反汇编的第4行,"call 8048491 "是汇编指令,是说这条指令将调用位于地址8048491处的foo函数;其对应机器指令为"e8 d7ffffff",e8即跳转之意。原本正常流程,此时此刻EIP的值应该是下条指令的地址,即80484ba,但一解释e8这条指令呢,CPU就会转而执行 "EIP + d7ffffff"这个位置的指令。"d7ffffff"是补码,表示-41,41=0x29,80484ba +d7ffffff= 80484ba-0x29正好是8048491这个值(foo函数调用入口)。main函数调用foo,对应机器指令为" e8 d7ffffff",那咱们想让它调用getShell,只要修改"d7ffffff"为,"getShell-80484ba"对应的补码就行。用Windows计算器,直接 47d-4ba就能获得补码,是c3ffffff。指针

  下面修改可执行文件,将其中的call指令的目标地址由d7ffffff变为c3ffffff。

3.vi20145211,并将其调成16进制显示,用指令“:%!xxd”

4.查询并修改e8 d7,用指令“/e8 d7”;a键进入编辑模式,将d7改成c3。

 

5.转成原格式保存退出,用指令“:%!xxd -r”,再次执行20145211

  能够发现咱们已经能够随心所欲,随心所欲,随心所欲……

6.再次反汇编验证机器指令

 

 

 

除了在vim中修改以外,还能够用wxhexeditor修改,如何安装再也不赘述。

简单介绍一下:

1.open file:20145211

2.search “e8”,so many;search "d7" instead,and substitute with "c3"

 

 

 

实践二:经过构造输入参数,形成BOF攻击,改变程序执行流程

1.再次cp一个20145211

2.进入gdb调试,输入一段神奇的字串1111111122222222333333334444444455555555

 ;观察一下各寄存器的值

 

 

3.此时eip寄存器中的值为0x35353535,即5555的ASCII码。eip寄存器的值是保存程序下一步所要执行指令的地址,此处咱们能够看出原本应返回到foo函数的返回地址已被"5555"覆盖

 

4.将输入字符串的“55555555”改为“12345678”,以便进一步观察修改的地方。

 

  此时寄存器eip的值,如上图“0x34333231 0x34333231”,换算成ASCⅡ码恰好是1234。也就是说若是输入字符串1111111122222222333333334444444412345678,那 1234 那四个数最终会覆盖到堆栈上的返回地址,进而CPU会尝试运行这个位置的代码。那只要把这四个字符替换为 getShell 的内存地址,输给20145211,20145211就会运行getShell。

 

5.获取机器字节序存储所采起的方式

  在输入字符串的地方0x804847d处设置断点,查其eip 0x804847d 0x804847d,能够发现是大端模式;因没法经过键盘输入\x7d\x84\x04\x08这样的16进制值,因此只能本身生成,并将输出重定向到input中,用“xxd input”检查是否操做成功;最后将input的输入,经过管道符“|”,做为pwn1的输入,执行获得结果

相关文章
相关标签/搜索