吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 38192|回复: 124
收起左侧

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

    [复制链接]
giantbranch 发表于 2019-10-16 10:06

漏洞简述

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

实验环境

win 7 32位 旗舰版

漏洞分析

发送POC

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函数,我们看看这个函数,通过这个我们知道channelname是在0x94偏移

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

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

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

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

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

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

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

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

1569749155914.jpg

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

1569749347361.jpg

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

1569749381652.jpg

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

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

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了两次

FreeChannel Addresss: 0x88f6e1a8 
FreeChannel Addresss: 0x88f6e1a8 

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

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

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

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

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

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

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

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操作

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

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(由于多次调试,下面的跟上面的地址会不一样)

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的时候向上回溯

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有虚函数调用,可以从这劫持控制流

1569823907606.jpg

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

1569823974741.jpg

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

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

1569824031639.jpg

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

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

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

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

1569825804868.jpg

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

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..

参考

https://github.com/n1xbyte/CVE-2019-0708

https://www.malwaretech.com/2019/05/analysis-of-cve-2019-0708-bluekeep.html

https://www.malwaretech.com/2019/09/bluekeep-a-journey-from-dos-to-rce-cve-2019-0708.html

补充资料

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

免费评分

参与人数 53吾爱币 +54 热心值 +49 收起 理由
190309JC + 1 + 1 我很赞同!
芯河斑斓 + 1 + 1 牛逼 就完事
monkey1314 + 1 + 1 我很赞同!
我好菜啊啊啊 + 1 + 1 我很赞同!
章三内 + 1 + 1 谢谢@Thanks!
大灰尾巴狼 + 1 + 1 谢谢@Thanks!
Liu0827 + 1 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
bricher9988 + 1 + 1 用心讨论,共获提升!
asylm + 1 + 1 我很赞同!
nigacat + 1 + 1 谢谢@Thanks!
一枝梨花 + 1 <font style="vertical-align: inherit;"><font style=
1394926200 + 1 + 1 谢谢@Thanks!
dazhige + 1 + 1 鼓励转贴优秀软件安全工具和文档!
cat_mist + 1 用心讨论,共获提升!
warren_520 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
18889646651 + 1 + 1 我很赞同!
大塘程序员 + 1 + 1 热心回复!
guohsm + 1 谢谢@Thanks!
Yennfer_ + 1 + 1 谢谢@Thanks!
也一样约约越 + 1 + 1 虽然看不懂,但是好像很牛逼的样子
lemon__star + 1 + 1 我很赞同!
hikansakuratan + 1 + 1 谢谢@Thanks!
L.KH + 1 + 1 热心回复!
果汁分妳一半 + 1 + 1 谢谢@Thanks!
守望者warden + 1 + 1 用心讨论,共获提升!
mjyxxxxx + 1 我很赞同!
yixi + 1 + 1 谢谢@Thanks!
PGdcJco + 1 + 1 用心讨论,共获提升!
lsrh2000 + 1 + 1 热心回复!
luzhiyao + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
test_for_jiao + 1 + 1 热心回复!
大大怪 + 1 + 1 tql
wmslecz + 1 + 1 谢谢@Thanks!
wmsuper + 3 + 1 谢谢@Thanks!
poisonbcat + 1 + 1 我很赞同!
greatwall001 + 1 谢谢@Thanks!
E147852 + 1 + 1 热心回复!
独行风云 + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
N0LL + 1 + 1 谢谢@Thanks!
siuhoapdou + 1 + 1 谢谢@Thanks!
爱拍阴天 + 1 + 1 我很赞同!
tztt3033 + 1 + 1 用心讨论,共获提升!
Terco + 1 谢谢@Thanks!
iBristlecone + 1 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
qn542231788 + 2 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
为海尔而战 + 2 + 1 我很赞同!
gaosld + 1 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
莫流云 + 1 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
抄经大弟子 + 1 + 1 热心回复!
40m41h42t + 1 用心讨论,共获提升!
a1142099496 + 2 + 1 欢迎分析讨论交流,吾爱破解论坛有你更精彩!
爱吃西柚的狼 + 1 + 1 <font style="vertical-align: inherit;"><font style=
韩老师长得帅 + 1 + 1 用心讨论,共获提升!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

Danger_Robot 发表于 2019-10-16 13:24
你字多,我一句也看不懂,我也不会用
xssc 发表于 2019-10-16 14:28
爱新觉罗罹江 发表于 2019-10-16 13:50
167023ab 发表于 2019-10-16 13:45
我能够看懂的部分也就只有多线程部分,向优秀的人学习
coolcalf 发表于 2019-10-16 11:14
然后呢? 能进入不?
wsb0626 发表于 2019-10-16 10:58
小白表示 看的头晕眼花 收藏下 等我混好了 再来
落神 发表于 2019-10-16 10:50
属实看不懂 膜拜大佬
Monitor 发表于 2019-10-16 10:43
这个我目前水平还看不懂,让大神们相互交流吧,先做个记号。
Quan 发表于 2019-11-4 14:57
大概看了一下,归根到底就是因为巨硬在这里忘了做检查 给入侵者留下机会 造成堆内存破坏 进而执行任意代码,大概就是那版RDP协议中,在初始化连接序列的时候,安全机制还没有启用。
然后这个时候系统要建立信道(初始化的一部分),在那一版的RDP协议中,定义了两种信道,一个是SVC(静态虚拟信道),另一个是DVC(动态虚拟信道);前者(SVC)是静态的且数量受限,在会话初始化的时候创建,直到会话结束才由系统释放,后者(DVC)是根据用户需求来动态创建释放的。
前面提到了,初始化的时候系统要建立信道,所以服务端会创建一个名为MS_T120,索引值为31的信道,这个MS_T120是属于SVC的,所以只会在内部使用,客户看不到,而且只有会话结束了,他才会被系统释放。忽略一些后续过程,只看关键:但是这个时候,问题就来了,入侵者可以通过设置另一个也叫MS_T120但是索引值不是31的SVC。
这个时候MS_T120指针就会有了两个引用了,问题就来了,当最后关闭连接的时候,当初入侵者自己绑定的MS_T120就会被free掉一次,系统在会话结束的时候会对这个MS_T120进行释放,等于说又free了一次,同一个指针free了两次,最后的结果就是free了个寂寞:二次释放导致堆内存被破坏,进而使得入侵者能够执行任意代码。
这就是这个漏洞大概的原理,这个漏洞其实也挺好修复,只要加一层检测代码,确保MS_T120和索引值31始终绑定就好了。

免费评分

参与人数 3吾爱币 +3 热心值 +3 收起 理由
rosemaryzed + 1 + 1 好厉害
seed + 1 + 1 通俗易懂
zycode + 1 + 1 谢谢@Thanks!

查看全部评分

墓后煮屎者 发表于 2019-10-16 14:26
技术含量太高。。欢迎大神们来讨论。
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2024-12-22 10:20

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表