行业解决方案查看所有行业解决方案
IDA 用于解决软件行业的关键问题。
发布时间:2022-10-10 14: 14: 18
背景
2020年12月,DBAPPSecurity威胁情报中心发现了BITTER APT的新组件。对该组件的进一步分析使我们发现了win32kfull.sys中的一个零日漏洞。原始样本旨在针对当时最新的Windows10 1909 64位操作系统。该漏洞还影响并可能在最新的Windows10 20H2 64位操作系统上被利用。我们向MSRC报告了此漏洞,并在2021年2月的安全更新中将其修复为CVE-2021-1732。
到目前为止,我们检测到使用此漏洞的攻击数量非常有限,且受害者位于中国地区。
时间线
·2020/12/10:DBAPPSecurity威胁情报中心抓获BITTER APT新组件。
·2020/12/15:DBAPPSecurity威胁情报中心发现组件中存在未知的windows内核漏洞,并启动根本原因分析。
·2020/12/29:DBAPPSecurity威胁情报中心向MSRC报告了该漏洞。
·2020/12/29:MSRC确认已收到报告并为其立案。
·2020/12/31:MSRC确认该漏洞是零日漏洞并要求提供更多信息。
·2020/12/31:DBAPPSecurity向MSRC提供了更多细节。
·2021/01/06:MSRC感谢添加信息并开始修复漏洞。
·2021/02/09:MSRC将漏洞修复为CVE-2021-1732。
强调
根据我们的分析,野生零日有以下几个亮点:
1、针对最新版Windows10操作系统
1.1.野生样本针对最新版本的Windows10 1909 64位操作系统(样本编译于2020年5月)。
1.2.原始漏洞利用旨在针对多个Windows 10版本,从Windows10 1709到Windows10 1909。
1.3.只需稍加修改,即可在Windows10 20H2上利用原始漏洞。
2.漏洞质量高,利用复杂
2.1。原始漏洞利用漏洞功能绕过KASLR。
2.2.这不是UAF漏洞。整个利用过程不涉及堆喷射或内存重用。类型隔离缓解无法缓解此漏洞。Driver Verifier无法检测到,打开Driver Verifier后,野样本可以成功利用。很难通过沙盒猎取野外样本。
2.3.任意读取原语是通过漏洞功能结合GetMenuBarInfo实现的,令人印象深刻。
2.4.在实现任意读/写原语后,该漏洞利用使用仅数据攻击来执行权限提升,当前内核缓解措施无法缓解这种情况。
2.5.漏洞利用的成功率几乎是100%。
2.6.漏洞利用完成后,漏洞利用将恢复所有关键结构成员,利用后不会出现蓝屏。
3.攻击者谨慎使用
3.1。在利用之前,in-the-wild样本会检测特定的防病毒软件。
3.2.in-the-wild样本执行操作系统构建版本检查,如果当前构建版本低于16535(Windows10 1709),则永远不会调用exploit。
3.3.野生样本于2020年5月编制,2020年12月被我们捕获,至少存活了7个月。这间接反映了捕获这种隐身样本的难度。
技术分析
0x00触发效果
如果我们在最后的windows10 1909 64位环境中运行in-the-wild示例,我们可以观察到当前进程最初在中等完整性级别下运行。
漏洞利用代码执行后,我们可以观察到当前进程在系统完整性级别下运行。这表明当前进程的Token被替换为System进程的Token,这是利用内核提权漏洞的常用方法。
如果我们在上次的windows10 20H2 64位环境中运行in-the-wild示例,我们可以立即观察到BSOD。
0x01漏洞概述
该漏洞是由win32kfull!xxxCreateWindowEx中的xxxClientAllocWindowClassExtraBytes回调引起的。回调导致内核结构成员的设置及其对应的标志不同步。
当xxxCreateWindowEx创建一个有WndExtra区域的窗口时,会调用xxxClientAllocWindowClassExtraBytes触发回调,回调会返回用户态分配WndExtra区域。在自定义回调函数中,攻击者可以调用NtUserConsoleControl并传入当前窗口的句柄,这会将内核结构成员(指向WndExtra区域)更改为偏移量,并设置相应的标志来指示该成员现在是一个偏移量。之后,攻击者可以在回调中调用NtCallbackReturn并返回任意值。当回调结束并返回内核态时,返回值会覆盖之前的offset成员,但对应的flag不会被清除。之后,内核代码直接使用未经检查的偏移值进行堆内存寻址,导致越界访问。
0x02根本原因
我们对in-the-wild样本的漏洞利用代码进行了完全逆向,并构建了一个poc base。下图是我们poc的主要执行逻辑,我们将结合这张图说明漏洞触发逻辑。
在win32kfull!xxxCreateWindowEx中,默认会调用user32!_xxxClientAllocWindowClassExtraBytes回调函数来分配WndExtra的内存。回调的返回值是一个使用模式指针,然后将其保存到内核结构成员(WndExtra成员)。
如果我们在自定义_xxxClientAllocWindowClassExtraBytes回调中调用win32kfull!xxxConsoleControl并传入当前窗口的句柄,WndExtra成员将更改为偏移量,并设置相应的标志(|=0x800)。
poc在调用DestoryWindow时会触发蓝屏,win32kfull!xxxFreeWindow会检查上面的flag,如果已经设置,说明WndExtra成员是偏移量,xxxFreeWindow会调用RtlFreeHeap来释放WndExtra区域;如果不是,说明WndExtra成员是一个使用模式指针,xxxFreeWindow会调用xxxClientFreeWindowClassExtraBytes来释放WndExtra区域。
我们可以在自定义_xxxClientAllocWindowClassExtraBytes回调结束时调用NtCallbackReturn并返回任意值。当回调结束并返回内核态时,返回值会覆盖offset成员,但对应的flag不会被清除。
在poc中,我们返回一个用户模式堆地址,该地址将原始偏移量覆盖为用户模式堆地址(fake_offset)。这最终导致win32kfull!xxxFreeWindow在使用RtlFreeHeap释放内核堆时触发越界访问。
●RtlFreeHeap期望释放的是RtlHeapBase+offset
●RtlFreeHeap实际上免费的是RtlHeapBase+fake_offset
如果我们在这里调用RtlFreeHeap,它会触发BSOD。
0x03漏洞利用
野生样本是一个64位程序,它首先调用CreateToolhelp32Snapshot等函数枚举进程来检测“avp.exe”(avp.exe是卡巴斯基杀毒软件的一个进程)。
但是,当检测到“avp.exe”进程时,它只会将一些值保存到自定义结构中并且不会退出进程,仍然会调用完整的exploit函数。我们安装卡巴斯基反病毒产品并运行示例;它将像往常一样获得系统权限。
然后它调用IsWow64Process来检查当前环境是32位还是64位,并根据结果修复一些偏移量。这里代码开发者好像搞错了,根据下面的源码,g_x64应该理解为g_x86,但是后续调用表明这个变量代表的是64位环境。
但是,代码开发人员在初始化时强制g_x64为TRUE,对IsWow64Process的调用实际上可以在这里忽略。但这似乎意味着开发人员还开发了另一个32位版本的漏洞利用程序。
在修正了一些偏移量之后,它获得了RtlGetNtVersionNumbers、NtUserConsoleControl和NtCallbackReturn的地址。然后调用RtlGetNtVersionNumbers获取当前操作系统的build号,只有build号大于16535(Windows10 1709)时才会调用exploit函数,如果build号大于18204(Windows10 1903)会修复一些内核结构偏移量。这似乎意味着对这些版本的支持是后来添加的。
如果当前环境通过了检查,exploit将被野外样本调用。该漏洞首先搜索字节以获取HmValidateHandle的地址,并将USER32!_xxxClientAllocWindowClassExtraBytes挂钩到自定义回调函数。
然后,该漏洞利用注册了两种类型的windows类。一个类名为“magicClass”,用于创建漏洞窗口。另一个类的名称是“nomalClass”,它用于创建普通窗口,这将在以后辅助任意地址写入原语。
该漏洞利用normalClass创建10个窗口,并调用HmValidateHandle通过tagWND地址泄露每个窗口的用户态tagWND地址和每个窗口的偏移量。然后利用破坏最后8个窗口,只保留窗口0和窗口1。
如果当前程序是64位的,漏洞利用将调用NtUserConsoleControl并传递窗口1的句柄,这会将窗口0的WndExtra成员更改为偏移量。然后,该漏洞利用会泄露windows 0的内核tagWND偏移以供以后使用。
然后利用magicClass创建另一个窗口(windows 2),windows 2有一个之前生成的cbWndExtra值。在创建窗口2的过程中,会触发xxxClientAllocWindowClassExtraBytes回调,进入自定义回调函数。
在自定义回调函数中,漏洞利用首先检查当前窗口的cbWndExtra是否匹配某个值,然后检查当前进程是否为64位。如果两项检查都通过,则漏洞利用调用NtUserConsoleControl并传递窗口2的句柄,这会将窗口2的WndExtra更改为偏移量并设置相应的标志。然后exp调用NtCallbackReturn并传递windows 0的内核tagWND偏移量。当返回内核模式时,windows 2的内核WndExtra偏移量将变为windows 0的内核tagWND偏移量。这会导致后续对WndExtra区域的读/写窗口2对窗口0的内核tagWND结构的读/写。
创建窗口2后,漏洞利用通过设置窗口2的WndExtra区域获得写入窗口0的内核tagWND的原语。漏洞利用在窗口2上调用SetWindowLongW以测试该原语是否正常工作。
如果一切正常,漏洞利用调用SetWindowLongW将窗口0的cbWndExtra设置为0xfffffff,这为窗口0提供了OOB读/写原语。该漏洞利用OOB写入原语修改窗口1的样式(dwStyle|=WS_CHILD),然后利用伪造的spmenu替换窗口1的原始spmenu。
任意读取原语是通过假spmenu与GetMenuBarInfo一起使用来实现的。该漏洞利用tagMenuBarInfo.rcBar.left和tagMenuBarInfo.rcBar.top读取64位值。该方法之前并未公开使用过,但与《Windows 10 Anniversary Update上的LPE漏洞利用》(ZeroNight,2016)中的思路类似。
任意写入原语是通过窗口0和窗口1实现的,与SetWindowLongPtrA一起使用,见下文。
在实现任意读/写原语后,该漏洞利用从源spmemu泄漏内核地址,然后搜索它以找到当前进程的EPROCESS。
最后,漏洞利用遍历ActiveProcessLinks得到SYSTEM EPROCESS的Token和当前EPROCESS的Token区域地址,并将当前进程的Token值与SYSTEM Token交换。
实现提权后,漏洞利用任意写原语恢复窗口0、窗口1、窗口2的修改区域,如窗口1的origin spmenu和窗口2的flag,以确保不会导致BSOD。整个利用过程非常稳定。
0x04结论
该零日漏洞是由win32k回调引起的新漏洞,可用于在最新的Windows 10版本上逃出Microsoft IE浏览器或Adobe Reader的沙箱。这个漏洞的质量很高,并且利用很复杂。这种狂野的零日漏洞的使用体现了组织强大的漏洞储备能力。威胁组织可能已经招募了具有一定实力的成员,或者从漏洞经纪人那里购买。
概括
零日在网络空间中发挥着举足轻重的作用。通常作为威胁组织的战略储备,具有特殊的使命和战略意义。随着软/硬件的迭代和防御体系的完善,软/硬件零日漏洞的挖掘和利用成本越来越高和更高。
多年来,世界各地的供应商在检测APT攻击方面投入了大量资金。这使得APT组织在使用零日时更加谨慎。为了最大化它的价值,它只会用于极少数特定的目标。稍有不慎就会缩短零日的生命周期。同时,一些零日漏洞已经潜伏了很长时间才被曝光,最显着的例子是永恒之蓝使用的MS17-010,过去一年(2020年),全球公开了数十起0Day/1Day攻击,其中DBAPPSecurity威胁情报中心追踪到的攻击有3起。根据我们掌握的数据,我们预测2021年将有更多关于浏览器和权限升级的零日披露。
零日检测能力是APT对抗过程中需要不断改进的关键方面之一。除了端点攻击,对边界系统、关键设备和集中控制系统的攻击也值得注意。过去几年,这些地区也发生了几起安全事件。
未被发现并不意味着它不存在,它可能更多的是处于隐秘状态。高级威胁攻击的发现、检测和防御需要在博弈中不断迭代和强化。要多思考如何加强点、线、面的防御能力。网络安全任重道远,我们需要相互鼓励。
如何防御此类攻击
DBAPPSecurity APT攻击预警平台可以发现已知/未知威胁。该平台可以实时监控、捕获和分析恶意文件或程序的威胁,并可以对与电子邮件传递、漏洞利用、安装/植入和C2各个阶段相关的木马等恶意样本进行强大的监控。
同时,平台基于双向流量分析、智能机器学习、高效沙盒动态分析、丰富的特征库、全面的检测策略、海量威胁情报数据,对网络流量进行深度分析。检测能力完整覆盖整个APT攻击链,有效发现用户关心的APT攻击、未知威胁和网络安全事件。
雅拉规则
rule apt_bitter_win32k_0day{
meta:
author="dbappsecurity_lieying_lab"
data="01-01-2021"
strings:
$s1="NtUserConsoleControl"ascii wide
$s2="NtCallbackReturn"ascii wide
$s3="CreateWindowEx"ascii wide
$s4="SetWindowLong"ascii wide
$a1={48 C1 E8 02 48 C1 E9 02 C7 04 8A}
$a2={66 0F 1F 44 00 00 80 3C 01 E8 74 22 FF C2 48 FF C1}
$a3={48 63 05 CC 69 05 00 8B 0D C2 69 05 00 48 C1 E0 20 48 03 C1}
condition:
uint16(0)==0x5a4d and all of($s*)and 1 of($a*)
}
原文地址:https://ti.dbappsecurity.com.cn/blog/articles/2021/02/10/windows-kernel-zero-day-exploit-is-used-by-bitter-apt-in-targeted-attack/
展开阅读全文
︾
读者也喜欢这些内容:
IDA怎么修改字符串内容?IDA修改后怎么保存?
在软件开发和逆向工程领域,IDA Pro是一种极其强悍的工具,广泛用于程序剖析、调试和修改。它不仅支持多种处理器架构,还提供了大量的作用,以适应高档讲解的必须。本文将围绕ida怎么修改字符串内容,ida修改后怎么保存这一主题,详细描述怎样在IDA中更改字符串内容,及其修改后的存放方式。此外,我们还将探讨IDA转变的应用场景,帮助读者更深入地了解IDA的实际应用价值。...
阅读全文 >
APK反编译工具有哪些 ida怎么进行apk反编译
在移动应用程序开发和安全领域,APK反编译是一项不可或缺的任务。通过反编译,我们能够深入分析Android应用程序的内部结构、了解其工作原理,并进行安全审计。...
阅读全文 >
反汇编代码怎么看 ida如何反汇编成c语言
在计算机领域中,反汇编是一种将机器代码转换回更接近人类可理解的高级语言代码的过程。这在调试、逆向工程、病毒分析、漏洞挖掘等场景中具有重要的应用价值。而IDA作为最知名的反汇编工具,其功能强大、使用广泛。本文将围绕反汇编代码怎么看与IDA如何反汇编成C语言这两个主题进行深入探讨。...
阅读全文 >
IDA Pro模块列表(Module list)
...
阅读全文 >