Windows Secure Channel RCE CVE-2024-38148的介绍
我之前看过一次secure channel, 在跟踪crypto处理时, 也发现了一个整数溢出(CVE-2024-29050), 可惜的是没找到远程无认证的攻击场景, 最后只能实现基于文件的远程代码执行. 在这个公告更新的时候, 也去分析了一下问题, 发现它并不是如微软官方定义的那样, 是一个dos的问题, 实际上, 它是一个uaf问题, 而且有利用的潜质, 合理的利用是非常可能被用于未认证的远程代码执行的, 鉴于它的危害性, 我就没有在补丁出来后公告, 而是现在才发文. 下面让我们一起了解一下吧.
Bug
首先, 通过补丁对比, 很容易就看到修补的位置, 在 CSsl3TlsContext::CSsl3TlsContext
函数内, 多了这么一段代码:
1 | if ( !(unsigned __int8)wil::details::FeatureImpl<__WilFeatureTraits_Feature_2612696381>::__private_IsEnabled(&`wil::Feature<__WilFeatureTraits_Feature_2612696381>::GetImpl'::`2'::impl) ) |
经过实际测试, 这个feature函数返回1, 因此补丁实际上是屏蔽了这个字段的赋值操作.
让我们来分析一下 472偏移的位置放了什么东西.
使用ida搜索binary:
筛选一下结果, 得到如下赋值操作:
在函数CSsl3TlsServerContext::ProcessRecord
内, 一段代码如下:
可以看到, 这里申请了一个新内存(记作M1), 并将它赋值给472(hex: 1D8h)的字段.
查看函数CTlsMessageFragment::Initialize
:
1 | void __fastcall CTlsMessageFragment::Initialize(CTlsMessageFragment *this, struct CSsl3TlsContext *a2) |
可以看到, 它把a2赋值给了M1的第一个8字节的字段.
那么我们大概可以得出一个结论, 那就是在CSsl3TlsContext::CSsl3TlsContext
内, 虽然赋值操作将a2结构体的472字段置零了, 但是, 没有更新M1的第一个字段, 导致它还是指向了a2, 所以, 可能在后续的释放流程里, 原始的a2结构体被先释放了, 然后接着在新的结构体里引用了M1的第一个字段, 从而导致了UAF问题.
接下来我们看一下其它引用了该字段且是free或者clean的操作:
查看函数CTls13ServerContext::CleanupConnectedState
从这可以看到, 它在释放流程里引用了该字段.v12
是M1结构体, *v12
就是被释放的结构体.
最后经过实际测试, 也确实是这个位置存在uaf问题. 从使用的位置也可以看出, 它会使用到结构体的虚表, 如果占位得当, 就可以直接控制rip, 配合合理的gadgets, 就可以实现远程代码执行.
感想
漏掉它, 还是在于我经验不足, 没有深入allocate函数去看它的实现中是否错误地引用了字段, 另一个, 我当时的重点放在了字节码解析上, 所以没有重点考虑uaf的问题. 经过此次学习, 也是提醒我看代码要尽量有耐心, 多关注字段的赋值.