从CVE-2024-6387中产生的思考
Linux 中 glibc 的攻击面 —— 从CVE-2024-6387中产生的思考
CVE-2024-6387简介
OpenSSH是SSH(Secure Shell)协议的开源实现,它支持在两个主机之间提供安全的加密通信,广泛用于Linux等系统,通常用于安全远程登录、远程文件传输和其它网络服务。
2024年7月1日,OpenSSH Server中存在的一个远程代码执行漏洞(CVE-2024-6387,又被称为regreSSHion)细节被公开,该漏洞影响基于glibc的Linux系统上的OpenSSH Server (sshd)。
默认配置下的OpenSSH Server (sshd)中存在信号处理程序竞争条件漏洞,如果客户端未在LoginGraceTime内(默认情况下为120秒,旧版OpenSSH中为600秒)进行身份验证,则sshd的SIGALRM处理程序将被异步调用,但该信号处理程序会调用非异步信号安全的函数,最终造成Double-Free内存管理问题。威胁者可利用该漏洞在基于glibc的Linux系统上以root身份实现未经身份验证的远程代码执行。根据已公开技术细节中的描述,在开启ASLR的i386设备上,利用该漏洞大约需要6-8小时获取root shell,在开启ASLR的amd64设备上则可能需要约一周左右。
CVE-2024-6387的攻击方式
攻击手段
- 利用glibc中malloc()和free()函数在signal信号量中断下不同步的性质进行条件竞争
- 使得代码只进行一部分,另一部分在没进行时就被信号截断了
- 信号截断后openssh会进行一系列函数,从而控制程序运行
它的前身CVE-2006-5051的攻击路径
- 利用signal中断攻击chunk_free函数,使得chunk堆块处于修改完inuse状态但是没有进行unlink的过程
- 然后会调用中断后执行的packet_close()函数,进行free,从而实现unsafe unlink的攻击
- 攻击__free_hook指针,从而实现控制程序运行的目的
它的攻击路径
- 利用signal中断攻击malloc()函数,使得它拆分了堆块,但是另一个堆块的大小还没改变
- 修改另一个堆块的大小,使其和下面的堆块重叠
- 调用syslog()函数,会使用open创建,申请出一个IO_file,而这一块会恰好和上面一块有一部分重叠
- 控制IO_file,应用House Of Apple2,控制程序流运行
很明显的是,这个漏洞是在不知道glibc基址的情况下进行的爆破攻击,并且想要产生竞争的条件苛刻,实际利用价值不高
linux中的程序攻击方式
程序本身elf文件的攻击
- 栈溢出从而控制程序流
- 格式化字符串导致任意地址读写
glibc相关攻击
堆漏洞攻击
- 任意地址读写
- 限制地址读写
IO块攻击
- 虚表攻击
针对内核的攻击
- 内核栈溢出
- 内核堆slab,slub的uaf攻击
glibc中的堆结构和bin结构
堆结构
linux在glibc中的堆分配策略
- 申请一页可读写的地址作为堆地址(页对齐)
- 创建一个叫做top chunk的空闲堆
- 每次在malloc等函数申请堆的时候都切割top chunk
堆的数据结构
struct malloc_chunk{ INTERNAL_SIZE_T prev_size; INTERNAL_SIZE_T size; struct malloc_chunk *fd; struct malloc_chunk *bk; struct malloc_chunk *fd_nextsize; struct malloc_chunk *bk_nextsize; }
glibc的堆回收策略
- 在glibc中,当堆使用完成后,通常会利用free()函数回收这个堆
- 但是有可能回收的堆会被马上用到,并且堆可能是不连续的
- 回收策略是建立bin来实现缓存快速使用
- 在一开始建立了4个bin:fast bin, unsorted bin, small bin, large bin,在glibc2.27之后引入了tcache bin
- 但是这样的bin策略就会产生安全隐患
各个bin的特性
- 单链表链接的bin:fast bin(栈模式), tcache bin
- 双链表链接的bin:unsorted bin, small bin, large bin
针对堆的攻击
堆漏洞从大方向可以分为两类
overflow
- 溢出,产生的原因是堆写入的长度控制不当形成的
- 溢出很多位(8位就会产生堆重叠的大问题)
- off by one
- off by none
use after free
- 通常情况下产生原因是free之后的指针没有清空造成的
- 野指针利用
针对bin的攻击
针对fastbin
- double free
- fastbin consolidate(来自scanf的攻击)
针对tcache bin
- double free(后期被修复了)
- tcache stashing unlink attack
针对small bin 和 large bin
- unsafe unlink
- small bin attack
- large bin attack
- 只能任意地址写堆地址
针对堆的攻击链
- house of 系列
针对hook的攻击
__malloc_hook
__realloc_hook
__free_hook
针对栈的攻击
environ
指向栈
针对IO的攻击
- house of orange
house of apple
- 主要是攻击
_wide_data
的vtable - 造成虚表函数可控
- 从而在程序exit或者报错退出时,在释放IO的时候调用某虚表函数
- 而后造成程序运行控制
- 主要是攻击