《深入理解计算机系统》3.38题解——缓冲区溢出攻击实例(续1)

本博客(http://blog.csdn.net/livelylittlefish)贴出作者(三二一@小鱼)相关研究、学习内容所做的笔记,欢迎广大朋友指正!

 

 

《深入理解计算机系统》3.38题解——缓冲区溢出攻击实例(续1)

  •  

    1. 问题描述

     

    http://blog.csdn.net/livelylittlefish/archive/2009/12/27/5087640.aspx

     

    2. 目标分析与题解

     

    看源程序可以发现,好像无论输入什么数据,其返回结果都是1,打印出来的都是0x1,似乎无从下手。另外,我们攻击的目标只是让其返回0xdeadbeef,不干别的。

     

    实验环境:Winxp + cygwin + gcc(3.4.4)

     

    2.1 修改源程序?

     

    这是题目不允许的。题目的要求是输入一些数据,使其输出为0xdeadbeef。输入什么样的数字串?这就是本题要求解的。

     

    2.2 如何得到这个数字串?

     

    如果了解程序的编译、链接、执行的过程即可知道,此题不是无解。

    由《过程调用与栈帧》一文可知,过程调用时要将参数和返回地址压入栈中,然后进入被调过程执行,待从被调过程返回时,弹出返回地址,将该地址存入%eip寄存器,并转到该地址开始执行。入栈和出栈均是对%esp指向的内存操作,其基地址为%ebp

     

    假设,如果我们输入的是机器码,存放于该缓冲区中,注意到程序中的缓冲区只有12字节,利用缓冲区溢出,将本应存放test调用getbuf的返回地址的内存单元修改为存放可执行的机器码的地址,而这个地址就是我们的缓冲区地址,那么在调用完getbuf后会返回到缓冲区地址处执行我们输入的机器码,在机器码中让程序输出oxdeadbeef,并正确返回继续执行。这样会不会达到目标?

     

    这句话有些拗口,总结来讲,就是将存放test调用getbuf的返回地址的内存单元的内容修改为buf缓冲区的地址。

    不对源程序进行编译、汇编,我们先手工画出test调用getbuf的栈帧结构。

     

     

                      stack bottom

     high address |=================|<----+

                  |                 |     |

                  |                 |     |

                  |                 |     |

                  |                 |  'main' stack frame

                  |                 |     |

                  |                 |     |

                  |                 |     |

                  |=================|<----+

         %ebp'->  |    ...          |     |

                  |                 |     |

                  |    ...          |  'test' stack frame

                  |                 |     |

                  |-----------------|     |

              +4  |     retAddr     |     |  //retAddr is the address of 'printf' at line 13

                  |=================|<----+

          %ebp->  |     %ebp'       |     |  //this saved %ebp' for test stack frame

                  |-----------------|     |

                  |    ...          |     |

                  |                 |     |

                  |-----------------|     |

            ^     |                 |     |

            |     |                 |     |

            |     |                 |   'getbuf' stack frame

           buf->  |                 |     |

                  |-----------------|     |

                  |    ...          |     |

                  |-----------------|     |

                  |   buf addr      |     |  //this is parameter to getxs

                  |-----------------|     |

          %esp->  |     retAddr'    |     |  //retAddr' is the address of 'return' at line 5

                  |=================|<----+

                  |                 |     |

                  |                 |     |

                  |    ...          |  'getxs' stack frame

                  |                 |     |

                  |                 |     |

      low address |-----------------|<----+

                      stack top

     

    其中,

    'main','test','getbuf','getxs'均为函数名

    %ebp'即为'test'栈帧的基地址

    %ebp保存'getbuf'栈帧的基地址

    %ebp+4保存test调用'getbuf'的返回地址,即retAddr

    %esp指向'getbuf'栈帧的栈顶,其中存放retAddr'

    retAddrtest调用getbuf后的返回地址,即程序第13printf函数的地址

    retAddr'getbuf调用getxs

     

    我们输入的数据存放在buf指向的一段内存中,且数据由低地址到高地址存放(图中向上箭头所示)。

    如果输入的数据不覆盖%ebp+4指向的内存,即buf不溢出,getbuf将永远返回1

     

    如果输入的数据覆盖%ebp+4指向的内存呢?即buf缓冲区溢出,会出现什么样的情况?

     

    不能覆盖%ebp指向的内存,即其中的%ebp'不能被修改,如果被修改,程序将不能正确返回,甚至崩溃。

    如果%ebp+4指向的内存被修改为newAddr,即retAddr被覆盖而存入newAddr,则test调用getbuf后将返回到newAddr处执行,newAddr要存放一段可执行的代码。

     

    这个newAddr是谁?

    如果新填入%ebp+4newAddrbuf缓冲区的起始地址,是否能达到目标?即test调用getbuf后将返回到buf的起始地址处执行。如果newAddr是别的地址,这个地址无从得知,程序也变得不可控。因此,newAddr就是buf的起始地址。

     

    到此,基本可以确定如下内容:

     

    a. 输入的数据大致内容

     

    可执行机器码

    %ebp'

    newAddr

     

    其中%ebp'必须还是存放在%ebp指向的内存中,newAddr存放在%ebp+4指向的内存中,newAddr=buf

     

    b. 输入数据的长度

    %ebp+8-buf

    其中,可执行机器码的长度为%ebp-buf;接下来的任务就是获得这段可执行的机器码。

     

    2.3 如何获得可执行机器码?

     

    首先,我们应该确定可执行机器码的功能:

    a. 让程序返回0xdeadbeef

    b. 返回到%ebp+4指向的返回地址

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值