缓冲区溢出属于非常有名的漏洞之一,其大体含义为:缓冲区溢出是超出程序内存设定范围,数据溢出后程序发生异常,黑客可以利用缓冲区溢出执行指定代码,重写栈中的返回地址()内容来执行任意操作。
本文从栈的介绍、代码示例、切入思路三个方面进行体系化介绍。
一、栈的介绍
栈是一种内存使用方式,采用LIFO(Last In,First Out,先进后出),像手枪的子弹夹一样。
示例代码
当调用func函数时,在跳转至函数起始地址的瞬间,栈的形式如下图:
栈的存储形式
基地址为内存高位,从后向前(向地址递减方向)增长, $1、$2、$3为方法变量地址,为main函数返回目标地址。
接下来 esp/rsp逐渐递减,为函数内部的局部变量分配内存空间,a&buff为方法内变量,存储形式如下图:
方法内变量存储
这时,如果数据溢出,超过了原本分配给buff数组的内存空间,数组后面的ebp、以及传递给函数的参数都会被溢出的数据覆盖掉,如下图:
内存溢出覆盖内容
一旦 ebp和被覆盖掉,将会引发严重的后果,存放的为main函数返回目标地址,也就是说,如果覆盖,攻击者就可以让程序跳转至任意地址,如果攻击者事前准备一段,然后让程序跳转至这段代码,也就相当于成功攻击了”可执行任意代码的漏洞“。
二、介绍
关于方面,简单的代码如下:
示例代码
该代码功能就是启动/bin/sh。通过该代码,我们可以将其转换为汇编语言,通过gdb方式对程序进行调试,gdb指令常用操作如下:
r:程序运行;
b:设置断点,加星号可传递地址;
c:在断点处中断后,继续运行程序;
x/[数字]i:对指定数量的指令进行反汇编;
x/[数字]x:显示指定长度数据;
x/[数字]s:以字符串形式显示指定长度数据;
set:向寄存器或内存写入;
q:退出;
通过对程序进行gdb调试,我们可清晰了解程序运行方式,如下图:
反汇编
上图0XVx:至558位置为方法的三个参数,倒序形式存放,我们在位置设置断点该位置为方法调用,当执行该方法时,我们通过r指令通过断点使用x/8x指令,确认rsp内容是否包含“/bin/sh”。
了解系统执行原理后,可通过汇编语句形成代码,代码如下:
汇编代码
具体代码解读如下:
xor eax,eax //清空寄存器;
push eax //入栈
push //sh
push //bin
mov al, 0x3b //0x3b表示其系统调用号的十六进制,十进制为59,本系统的系统调用编号为59。需要根据自身系统来确定。
将汇编转换成16进制
执行以下语句:
nasm -f elf .asm
ld -m -o .o
最终形成16进制code码,如下图:
汇编转16进制
将上图16进制代码整合后,形成执行文件,
执行文件
当我们执行该文件时,会出现段错误,是因为系统有保护机制,全局数据段不能被运行,即出现段错误。可安装,随后执行: -s 程序名,“故意”关掉 GCC 的堆栈段不可执行保护机制,便可执行成功,如下图:
执行成功
三、切入思路
通过第一章介绍,我们了解缓冲区溢出原理及如何利用该原理进行渗透。通过第二章我们实现了代码编写。如何利用缓冲区进行切入才是重重之重,一般我们不知道程序的返回地址,因此只能进行推测,我们可尽量在内存空间中填充NOP(0x90)指令(可通过gdb进行查看),然后将放在最后,这样就可以提高执行的概率。
本文源自我之前在其它博客所写文章,因之前内容不够详实,所以进行了再次编辑,通过本次再梳理使其内容更为丰富,具有更高的可读性。通过以上内存溢出原理和简单的,提供了一种代码切入思路,在具体实施过程中难度还是非常大的。
———END———
限 时 特 惠: 本站每日持续更新海量各大内部创业教程,永久会员只需109元,全站资源免费下载 点击查看详情
站 长 微 信: nanadh666