记一次通过劫持glibc2.35的tls_dtor_list实现流程控制

前言

最近碰到一道使用glibc 2.35版本的堆题,由于以前也没有真正接触过高版本glibc的堆利用,所以借着这次机会学习了如何通过控制tls_dtor_list来进行流程控制。

前置条件

1.任意地址写

2.堆基址泄露

3.pointer_guard泄露

4.exit函数退出

须知

劫持流程

exit
--->    
__run_exit_handlers
--->
__call_tls_dtors

__call_tls_dtors函数

void
__call_tls_dtors (void)
{
  while (tls_dtor_list)
    {
      struct dtor_list *cur = tls_dtor_list;
      dtor_func func = cur->func;
#ifdef PTR_DEMANGLE
      PTR_DEMANGLE (func);
#endif
 
      tls_dtor_list = tls_dtor_list->next;
      func (cur->obj);
      atomic_fetch_add_release (&cur->map->l_tls_dtor_count, -1);
      free (cur);
    }
}

tls_dtor结构

*(struct dtor_list*)fake_dtor = {
  func = 0x83485355fa1e0ff3,
  obj = 0x1ad48f1d8b4808ec,
  map = 0xed85482b8b486400,
  next = 0x441f0f664374
}

劫持tls_dtor_list原理

通过__call_tls_dtors源码可知,只要我们将tls_dtor_list改为可控区域,即可控制func(cur->obj)。

然而这里需要注意的是 PTR_DEMANGLE (func) 会将func解密,如下是 PTR_DEMANGLE 宏定义

#  define PTR_DEMANGLE(reg)	ror $2*LP_SIZE+1, reg;			      \
				xor %fs:POINTER_GUARD, reg

正常情况解密过程是先将reg循环右移0x11位,然后再将reg与pointer_guard进行异或得到最终的结果。

所以这里加密的过程也就很清晰了,只需要将我们真实地址先与pointer_guard进行异或,然后再循环左移0x11位即可。这也就是为什么我们需要泄露pointer_guard的原因。

其实tls的利用原理还是比较简单的,难的是实现任意地址写与目的地址泄露。

至于任意地址写与目的值泄露不在本博客讨论范围内,毕竟方法还是很多的。

这里还要提一点,就是在题目使用了沙盒,禁止掉execve要怎么办呢?

其实方法可以在hourse of emme中找到,我们也可以仿照emme手法中的栈迁移来实现orw

因为我这次做的题目就出现了这种情况,所以就在这里顺便说一说在能够利用tls_dtor_list劫持程序流程之后,如何进行栈迁移构造orw ROP链。

在讲解之前,首先要知道如下几个gadget

setcontext+61及setcontext+294

可以看到,在setcontext+61处可以通过[rdx+0xa0]来控制rsp的值,以实现栈迁移

那么如何实现控制rdx的值呢?在上述介绍tls劫持流程中我们知道,最后我们可以通过控制cur->obj来控制rdi,那么我们就可以通过[rdi-8]进而控制rdx,最后控制rsp到我们构造好的ROP链之中。

总结

高版本glibc的解题思路基本上都离不开对IO的利用,但是tls另辟蹊径,通过劫持tls_dtor_list来达成流程控制的目的,真的很不可思议(wwwww)。

若读者觉得本文描述的不够详细,可参考一下博客:

【精选】house of Emma-CSDN博客

house of emma利用手法详解(21湖湘杯实例解析) - FreeBuf网络安全行业门户

glibc 2.35 pwn——house of emma示例程序_ubuntu 22.04 glibc是多少-CSDN博客

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值