PWN简单堆栈溢出漏洞利用(一)

2018年9月21日22:52:50 发表评论 18,781
摘要

本文将详细讲述PWN二进制漏洞中简单的堆栈利用,本文将从原理开始讲述,然后层层深入,让读者从理解到动手操作,能够跟着教程完成所有操作。

0x01 环境和程序准备

  • 安装有pwntools的kali Linux,安装教程可参考上一篇文章。
  • gdb-peda工具,这个是gdb的插件这个可以百度一下安装和使用教程。
  • IDA反汇编工具,可自行百度下载和学习使用方法,本文只做简单介绍。
  • 一个Linxu X86的含有漏洞的小程序pwn0,可在本文末尾下载链接处下载。

请在“/home/pwn/pwn0/"目录下建立flag文件,内容为flag{this_is_flag},此文件将是我们要利用pwn0读取的文件。

0x02 运行程序并反汇编分析

首先我们运行我们的程序,发现其就是一个简单的输入,然后输出的小程序,如下图:

PWN简单堆栈溢出漏洞利用(一)

我们把程序拉到IDA里面分析一下,发现函数foo(),getFlag(),在函数处按F5,将显示对应的C语言程序,如下:

PWN简单堆栈溢出漏洞利用(一)

main函数

从main函数中可以看到并没有什么,只是简单的输出一句话,然后调用了一下foo函数,但是这里给foo函数船了实参值为0x123456,这个后面我们用得到。下面我们看一下foo函数的结构:

PWN简单堆栈溢出漏洞利用(一)

foo函数

foo函数有一个参数a1,然后函数体内定义了两个变量,分别是result和s,从IDA分析看,result是一个寄存器变量,不占用内存。然后这个函数接收了我们的输入,然后进行显示,重要的是里面的if判断恒为false。所以这个getFlag()函数就是我们要解决的问题。

PWN简单堆栈溢出漏洞利用(一)

getFlag函数

我们发现main函数没有什么问题,主要函数在foo函数,getFlag函数便是我们要执行的函数,但是从现在的逻辑看,似乎这个getFlag()函数是不可能被执行的,因为a1的值为0x123456,但是if里面的判断却要求a1的值为0x61616161(转换为16进制查看),所以这个if是恒为false的。

分析一下流程发现,在foo函数里面声明的char s,但是使用了gets(&s),让我们为s赋值。gets()函数是不会检查你输入的字符串长度的,所以此处会有一个溢出漏洞,大部分简单的溢出漏洞都出现在让我们输入的地方。

foo函数中的第四行代码简单说一下:

IDA以及为我们分析出来了,这个s变量在内存中的位置距离栈顶有+Ch个字节,距离栈底有-1Ch个字节。注意这里的sp就是esp,bp就是ebp的意思,不明白的可看前面的函数栈分析文章。

分析到这里,我们简单画一下这个foo函数的栈结构图:

PWN简单堆栈溢出漏洞利用(一)

这里说一下啊reault变量是eax变量,没有往内存里面存,从IDA的标注可以看出来。有一个知识点也要注意一下,栈里面的数据在写的时候是从低地址往高地址写的,什么意思呢?就是从s开始写数据,一旦s的1字节被写满,就会继续往高地址的地方延申。

分析函数栈可知,我们的变量s只要内容够长,就可以不断的往下延申,最终覆盖掉EBP、EIP甚至a1,所以这里我们便有了利用思路,因为我们的而判断是判断a1和常量0x61616161是否相等,如果我们将s延申,覆盖掉a1,让a1的值恰好等于0x61616161那么if判断不就可以成立,然后执行getFlag()函数拿到flag。下面开始写Payload。

0x03 调试并分析Payload

我们先看一下foo函数的汇编代码:

我们在0x080485ab出下断点,可以看到变量s的地址就是eax的值,如下图:

PWN简单堆栈溢出漏洞利用(一)

此时eax的值为0xbffff1ac,EBP的值为0xbffff1c8正好相差0x1C,然后我们看下栈里面的情况:

PWN简单堆栈溢出漏洞利用(一)

我们发现我们的分析是正确的,a1在EIP下面,s和EBP相差0x1C,那么我们来计算一下s到a1的距离一共是:0x1C + 0x4(EBP) + 0x4(EIP) = 0x24 = 36 ,距离大概就是这样,那么我们测试一下,如果输入36个A和4个B会发生什么,输入完成后查看堆栈:

PWN简单堆栈溢出漏洞利用(一)

我们发现原来0xbffff1d0地址中存储的0x1231456被我们的BBBB给覆盖掉了。所以我们只需要将BBBB改为0x61616161就可以使if成立,但是这里要注意,我们输入的使字符串,和数字使不同的,我们需要将数字转化为字符串然后进行输入,这里我们使用Python中pwntools进行输入和输出。

到此位置我们可以编写Payload进行溢出利用了,下面开始编写脚本。

0x04 编写Payload利用脚本

基本的脚本利用如下:

看程序运行结果如下:

PWN简单堆栈溢出漏洞利用(一)

可以看到我们的getFlag函数以及成功运行,并且读取到了flag文件

0x05 补充

本文的程序比较简单,但是理解溢出漏洞练手的好程序,并且这个程序不止这个个利用方式,还有令该一个方式就是直接覆盖EIP然后跳转到getFlag()函数,下篇文章我们将讲述这种做法。

本文程序下载(密码akcz):

文件下载

  • A+
所属分类:CTF

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: