Libc Protections
块对齐强制
Malloc以8字节(32位)或16字节(64位)分组的方式分配内存。这意味着在32位系统中,块的末尾应该与0x8对齐,在64位系统中应该与0x0对齐。这项安全功能在使用来自bin的指针之前检查每个块是否在这些特定位置上正确对齐。
安全性益处
64位系统中块对齐的强制执行显著增强了Malloc的安全性,因为它将伪造块的放置限制为每16个地址中的1个。这使得利用变得更加复杂,特别是在用户对输入值的控制有限的情况下,攻击变得更加复杂且更难成功执行。
__malloc_hook上的Fastbin攻击
Malloc中的新对齐规则还阻止了涉及__malloc_hook
的经典攻击。以前,攻击者可以操纵块大小以覆盖此函数指针并获得代码执行。现在,严格的对齐要求确保这种操纵不再可行,关闭了一个常见的利用途径,增强了整体安全性。
快速bin和tcache上的指针混淆
指针混淆是一种用于保护内存管理操作中的fastbin和tcache Fd指针的安全增强技术。这种技术有助于防止某些类型的内存利用策略,特别是那些不需要泄漏内存信息或直接操纵相对已知位置的内存位置(相对覆写)。
这种技术的核心是一个混淆公式:
New_Ptr = (L >> 12) XOR P
L是指针的存储位置。
P是实际的fastbin/tcache Fd指针。
在进行XOR操作之前将存储位置(L)向右移12位的原因至关重要。这种操作解决了内存地址最不显著的12位的确定性特性,这些位通常由于系统架构约束而可预测。通过移动这些位,可预测的部分被排除在等式之外,增强了新的混淆指针的随机性,从而防范依赖这些位的可预测性的利用。
这个混淆指针利用了**地址空间布局随机化(ASLR)**提供的现有随机性,ASLR随机化程序使用的地址,使攻击者难以预测进程的内存布局。
解混淆指针以检索原始地址涉及使用相同的XOR操作。在这里,混淆指针被视为公式中的P,当与未更改的存储位置(L)进行XOR运算时,将显示原始指针。这种混淆和解混淆的对称性确保系统可以高效地对指针进行编码和解码,同时大大增加了对操纵内存指针的攻击的安全性。
安全性益处
指针混淆旨在防止堆管理中的部分和完整指针覆写,这是安全性的重大增强。这个特性在几个方面影响利用技术:
防止Byte Byte相对覆写:以前,攻击者可以更改指针的一部分,将堆块重定向到不同位置而无需知道确切地址,这种技术在无泄漏的House of Roman利用中明显。通过指针混淆,这种相对覆写现在需要堆泄漏来进行暴力破解,大大降低了成功的可能性。
增加Tcache Bin/Fastbin攻击的难度:通过操纵fastbin或tcache条目来覆盖函数指针(如
__malloc_hook
)的常见攻击受到阻碍。例如,一种攻击可能涉及泄漏LibC地址,将一个块释放到tcache bin,然后覆盖Fd指针以将其重定向到__malloc_hook
以进行任意代码执行。通过指针混淆,这些指针必须正确混淆,需要堆泄漏来进行准确操纵,从而提高了利用障碍。在非堆位置中需要堆泄漏:现在在非堆区域(如堆栈、.bss部分或PLT/GOT)中创建一个伪造块也需要堆泄漏,因为需要指针混淆。这增加了利用这些区域的复杂性,类似于操纵LibC地址的要求。
泄漏堆地址变得更具挑战性:指针混淆限制了fastbin和tcache bin中的Fd指针作为堆地址泄漏源的有用性。但是,未排序、小型和大型bin中的指针保持未混淆,因此仍可用于泄漏地址。这种转变推动攻击者探索这些bin以寻找可利用的信息,尽管一些技术仍可能允许在泄漏之前解混淆指针,尽管受到限制。
使用堆泄漏解混淆指针
有关该过程的更好解释,请从这里查看原始帖子。
算法概述
用于混淆和解混淆指针的公式是:
New_Ptr = (L >> 12) XOR P
其中L是存储位置,P是Fd指针。通过将L向右移动12位,可以获得P的最高12位,因为XOR的性质,当位与自身进行XOR运算时输出为0。
算法中的关键步骤:
最显著位的初始泄漏:通过将移位的L与P进行XOR运算,实际上可以获得P的前12位,因为L的移位部分将为零,使P的对应位保持不变。
恢复指针位:由于XOR是可逆的,知道结果和一个操作数允许您计算另一个操作数。这个属性用于通过连续XOR已知位组和混淆指针的部分来推断P的整个位集。
迭代解混淆:该过程重复进行,每次使用前一步中发现的P的新位来解码混淆指针的下一段,直到恢复所有位。
处理确定性位:由于移位,L的最后12位丢失,但它们是确定性的,可以在处理后重建。
您可以在这里找到此算法的实现:https://github.com/mdulin2/mangle
指针保护
指针保护是一种在glibc中使用的利用缓解技术,用于保护存储的函数指针,特别是那些由库调用(如atexit()
)注册的指针。该保护涉及将指针与存储在线程数据(fs:0x30
)中的秘密进行异或运算并应用位旋转来混淆指针。该机制旨在防止攻击者通过覆盖函数指针来劫持控制流。
通过泄漏绕过指针保护
理解指针保护操作: 指针的混淆是使用
PTR_MANGLE
宏完成的,该宏将指针与64位秘密进行异或运算,然后执行0x11位的左旋转。用于恢复原始指针的反向操作由PTR_DEMANGLE
处理。攻击策略: 攻击基于已知明文方法,攻击者需要知道指针的原始版本和混淆版本,以推断用于混淆的秘密。
利用已知明文:
识别固定函数指针: 通过检查glibc源代码或初始化的函数指针表(如
__libc_pthread_functions
),攻击者可以找到可预测的函数指针。计算秘密: 使用已知函数指针(如
__pthread_attr_destroy
)及其来自函数指针表的混淆版本,可以通过反向旋转(右旋转)混淆指针,然后将其与函数地址进行异或运算来计算秘密。
替代明文: 攻击者还可以尝试使用已知值(如0或-1)对指针进行混淆,以查看这些值是否在内存中产生可识别的模式,从而在内存转储中找到这些模式时可能揭示秘密。
实际应用: 计算出秘密后,攻击者可以以受控方式操纵指针,基本上绕过指针保护,在具有libc基址知识和能够读取任意内存位置的多线程应用程序中操作指针。
参考资料
Last updated