路由器——缓冲区溢出漏洞

路由器——缓冲区溢出漏洞

一. MIPS架构堆栈

栈操作:MIPS32架构堆栈与x86架构一样,都是向低地址增长的。但在MIPS32架构中没有EBP(栈底指针),进入一个函数时,需要将当前栈指针向下移动n比特,这个大小为n比特的存储空间就是此函数的Stack Frame的存储区域。此后,栈指针便不再移动,只能在函数返回时将栈指针加上这个偏移量恢复栈现场。由于不能随便移动栈指针,所以寄存器压栈和出栈时都必须指定偏移量。

调用:调用:如果函数A调用函数B,调用者函数(函数A)会在自己的栈顶预留一部分空间来保存被调用者(函数B)的参数,我们称之为调用参数空间。

参数传递:参数传递方式:前4个传入的参数通过 a 0   a0~ a0 a3传递。有些函数的参数可能会超过4个,此时,多余的参数会被放入调用参数空间。x86架构下的所有参数都是通过堆栈传递的。

返回地址:在x86架构中,使用call命令调用函数时,会先将当前执行位置压入堆栈,MIPS 的调用指令把函数的返回地址直接存入SRA寄存器而不是堆栈中。

二. 函数调用过程

  1. 在函数A执行到调用函数B的指令时,函数调用指令复制当前的 P C 寄存器的值到 PC寄存器的值到 PC寄存器的值到RA寄存器,即当前$RA的值就是当前函数执行结束的返回地址,然后跳转到函数B并执行。
  2. 程序跳转到函数B以后,如果函数B是非叶子函数,则函数B首先会把函数A的返回地址(此时返回函数A的地址存放在 R A 寄存器中 ) 存入堆栈,否则返回函数 A 的地址仍然在 RA寄存器中)存入堆栈,否则返回函数A的地址仍然在 RA寄存器中)存入堆栈,否则返回函数A的地址仍然在RA中。
  3. 函数返回时,如果函数B是叶子函数,则直接使用“jr r a ”指令返回函数 A ,这里的寄存器 ra”指令返回函数A,这里的寄存器 ra指令返回函数A,这里的寄存器RA指向返回地址。如果函数B是非叶子函数,返回过程相对来说复杂一点,函数B先从堆栈中取出被保存在堆栈上的返回地址,然后将返回地址存入寄存器 R A ,再使用“ j r RA,再使用“jr RA,再使用jrra”指令返回函数A。

三. MIPS架构下栈溢出的可行性

MIPS32架构下的函数调用指令不会把返回地址存入堆栈,而是直接存入寄存器$RA中。那么,在MIPS32架构下缓冲区溢出是否能够被利用?接下来我们就通过两个例子探讨在MIPS32架构下利用缓冲区溢出是否具有可行性。

1. 非叶子函数

案例1:非叶子函数has_stack()函数内调用了strcpy函数,因此,has_stack是非叶子函数,返回main()函数的地址会首先保存到寄存器ra中,进入has_stack()函数以后,has_stack会把返回main()函数的返回地址保存在has stack的堆栈中,在has stack()函数返回main()函数继续执行时,将保存在堆栈中的返回main()函数的返回地址写入ra并返回main()函数继续执行,代码如下。

image

image

has_stack()函数执行完第2条指令“swra,Ox38+saved_ra”后堆栈的情况如图6-7所示。虽然函数调用指令不再直接将返回main()函数的返回地址保存到堆栈中,而是将返回地址写入ra中,但由于has_stack()函数要调用sprintf函数,所以has_stack将返回main()函数的返回地址0x0040042C保存到has_stack栈帧底部(如代码中的0x00400394代码行)。当函数返回时,会先从堆栈中取出返回地址0x0040042C并将其存放到寄存器ra中(如代码中的0x004003E8代码行)。如果has_stack()函数的局部变量中国存在缓冲区溢出漏洞,就可能导致堆栈上返回main()函数的返回地址被覆盖,has_stack取出的返回main()函数的返回地址不再是0x0040042C,而是由攻击者精心构造的数据。因此,在这种情况下缓冲区溢出是可以被利用的。

image

2. 叶子函数

image

使用IDA加载subcall_nostack查看反汇编代码,其反汇编代码如图6-8所示。main()函数调用no_stack()函数时,返回main()函数的返回地址并不是直接存入堆栈中的,而是存储到寄

image

​但是,这并不代表叶子函数中的缓冲区溢出就完全无法利用。如果缓冲区溢出覆盖的区域足够大,no_stack()函数中的缓冲区溢出是有可能覆盖main()函数的栈帧的,这样就可能覆盖main()函数栈帧中存放的上层函数的返回地址。因此,当非叶子函数中存在缓冲区溢出漏洞时,程序的执行流程是存在被劫持的可能性的。​

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值