如何转换永恒之蓝(Eternalblue)的POC

栏目: Ruby · 发布时间: 7年前

内容简介:如何转换永恒之蓝(Eternalblue)的POC

这个POC价值20个F币(20F币=300人民币)。最近写了一些POC在FOFA平台拿了点零花钱,不过我更喜欢帮助其他小伙伴,大家一起分享。大牛们写文章越来越少,小牛们只能报团取暖。

刚好,一些客户没有从勒索病毒“永恒之蓝”的阴影中走出来,看FOFA上还没有此POC,我准备写一个。

一开始以为FOFA只支持Web应用层的POC,不能支持网络层的。研究后发现FOFA是支持 Ruby 的POC,Ruby能做Web编程和系统编程。于是我给自己定了目标:将MS17010的POC录进FOFA里面。

研究 Python 的shellcode

经过一翻研究,我决定将巡风的POC转成Ruby的POC,FOFA只支持Ruby,不支持Python,这个跟seebug相反。

在t00ls有哥们说我本末倒置了:巡风的POC就是从MSF的EXP转的,而MSF的EXP是Ruby写的,囧。那我还转个啥?

当然不是这样!不是我不能用MSF的shellcode,而是刚学习Ruby,暂时没有这个能力读懂MSF框架的代码,二来巡风的也是将MS17010的exp整合的很好。而其他的Python版本的POC都是按Windows操作系统分类的,要么就是调用方程式黑客武器的那个XML和EXE文件实现的。

而巡风的Python脚本是支持所有Windows操作系统的。

代码如下:(ps:不想看的老司机们用力一划,就下去了)

#-*- coding: UTF-8 -*-
import binascii
import socket

FOFAquery = 'protocol=smb&& banner="windows"'
defget_tree_connect_request(ip, tree_id):
ipc = "005c5c" + binascii.hexlify(ip) + "5c49504324003f3f3f3f3f00"
ipc_len_hex = hex(len(ipc) / 2).replace("0x", "")
smb = "ff534d4275000000001801280000000000000000000000000000729c" + binascii.hexlify(
tree_id) + "c4e104ff00000000000100" + ipc_len_hex + "00" + ipc
    tree = "000000" + hex(len(smb) / 2).replace("0x", "") + smb
tree_connect_request = binascii.unhexlify(tree)
return tree_connect_request
defcheck(ip, port, timeout):
negotiate_protocol_request = binascii.unhexlify(
"shellcode区域")
session_setup_request = binascii.unhexlify(
"shellcode区域")
try:
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.settimeout(timeout)
s.connect((str(ip), int(port)))
s.send(negotiate_protocol_request)
s.recv(1024)
s.send(session_setup_request)
        data = s.recv(1024)
user_id = data[32:34]
        session_setup_request_2 = binascii.unhexlify(
"00000150ff534d4273000000001801280000000000000000000000000000729c" + binascii.hexlify(
user_id) + "shellcode区域")
s.send(session_setup_request_2)
s.recv(1024)
        session_setup_request_3 = binascii.unhexlify(
"shellcode区域")
s.send(session_setup_request_3)
        data = s.recv(1024)
tree_id = data[32:34]
smb = get_tree_connect_request(ip, tree_id)
s.send(smb)
s.recv(1024)
POC = binascii.unhexlify(
"0000004aff534d422500000000180128000000000000000000000000" + binascii.hexlify(
user_id) + "729c" + binascii.hexlify(
tree_id) + "shellcode区域")
s.send(POC)
        data = s.recv(1024)
if "\x05\x02\x00\xc0" in data:
return True
return False
s.close()
except Exception,e:
#print str(e)
return False
defverify(hostinfo):
ip,port = hostinfo.split(":")
    result = check(ip,port,5)
return result
if __name__ == '__main__':
print verify("8.8.8.8.230:445")

转为Ruby的shellcode

我根据其思路,将其中的shellcode转化为Ruby语言就达到我的目的了。

FOFA客户端的框架比其他的框架简单,一会我就准备好了代码,可是发现运行的时候卡在这边,百思不得骑姐???

加了begin和rescue..end也没有爆出什么异常。

按Ctrl+c发现连接被重置,但是不科学呀?shellcode完全和Python的一模一样啊。

如何转换永恒之蓝(Eternalblue)的POC

检查了几遍程序发现没有语法问题,也没有逻辑问题。

可是之前没有出现这个问题啊,扫描的时候能扫出没有补丁的还有关闭445端口的,但是扫到有漏洞的时候总是卡死在一个界面。

小伙伴看到说:小伙子啊,你这样不给力啊T T。

心怀不惩的我去吃饭,神秘大牛将最后一口饭吃下去之后,抿了下嘴巴,说半小时搞不定来找我。

半小时后,我只能去找他了。

定位问题

下面是他表演的时刻,文笔有限,尽量还原当时的情景。

首先,我将环境给他看了下,他说肯定是你shellcode哪些字符出问题。

我:不可能啊,都是复制粘贴进去的。

他:你能保证你发的包出去就是对的?

我:…

他:来,环境搞好。

我汹汹打开虚拟机

如何转换永恒之蓝(Eternalblue)的POC

多么精致的2003R2啊,可惜我就是没有把POC弄好。

首先确认IP地址。很多次我搞错IP,有同感的举手:)。

先用Python检测确定这个系统存在漏洞POC。

如何转换永恒之蓝(Eternalblue)的POC

提示True,说明存在漏洞。(值得一提的一点是先发送错误的payload会让之后正确的payload也利用失败,这个时候请重启系统)

那么这时候我们开启Wireshark抓包再次利用一下。

设定如下:

如何转换永恒之蓝(Eternalblue)的POC

将抓取到Python发送的数据包保存为230_Python.pcapng

用Ruby发包,抓取Ruby发送的数据包保存为230_Ruby.pcapng

如何转换永恒之蓝(Eternalblue)的POC

期中Ruby爆出的异常是:An existing connection was forcibly closed by remote host(被远程主机强制断开了,定位到46行。

按照出异常的经验,一般是前面数据包包的shellcode出现问题导致主机主动断开连接。然后我分析了三次数据包,发包和收包。

这个漏洞是基于445端口的SMB服务。

如何转换永恒之蓝(Eternalblue)的POC

图:由攻击者发送的第3个SMB包

下图右侧Ruby的POC发送第三个时显示红色Malformed Packet(恶意格式的数据包)

如何转换永恒之蓝(Eternalblue)的POC

图:Python和Ruby发送的第3个数据包,正常和异常效果对比

右边是Ruby的包,左边是Python的包。右边变红了,这个比股票变绿了可怕。

如何转换永恒之蓝(Eternalblue)的POC

选择第3个由客户端发送的SMB包,右键,Copy(复制)->Byte(位)->OffsetHex。复制出数据包的Hex值发现明显不相同(不相同处要标红)。相同的POCshellcode为何发送的数据包不一样呢?

如何转换永恒之蓝(Eternalblue)的POC

图:Python和Ruby发送的数据包内容不一样

而shellcode是一样的

code区域 :Python的MS17010利用shellcode

session_setup_request_2 = binascii.unhexlify(
"00000150ff534d4273000000001801280000000000000000000000000000729c" + binascii.hexlify(
user_id) + "c4e10cff000000dfff0200010000000000f200000000005cd0008015014e544c4d53535000030000001800180040000000780078005800000002000200d000000000000000d200000020002000d200000000000000f2000000050208a2ec893eacfc70bba9afefe94ef78908d37597e0202fd6177c0dfa65ed233b731faf86b02110137dc50101000000000000004724eed7b8d2017597e0202fd6177c0000000002000a0056004b002d005000430001000a0056004b002d005000430004000a0056004b002d005000430003000a0056004b002d00500043000700080036494bf1d7b8d20100000000000000002e003400310042006c007400410031004e005000590074006200490055004700300057696e646f7773203230303020323139350057696e646f7773203230303020352e3000")
s.send(session_setup_request_2)
s.recv(1024)

code区域 :Ruby的MS17010利用shellcode

buf3 = "00000150ff534d4273000000001801280000000000000000000000000000729c" + user_id.unpack(
'H*').first + "c4e10cff000000dfff0200010000000000f200000000005cd0008015014e544c4d53535000030000001800180040000000780078005800000002000200d000000000000000d200000020002000d200000000000000f2000000050208a2ec893eacfc70bba9afefe94ef78908d37597e0202fd6177c0dfa65ed233b731faf86b02110137dc50101000000000000004724eed7b8d2017597e0202fd6177c0000000002000a0056004b002d005000430001000a0056004b002d005000430004000a0056004b002d005000430003000a0056004b002d00500043000700080036494bf1d7b8d20100000000000000002e003400310042006c007400410031004e005000590074006200490055004700300057696e646f7773203230303020323139350057696e646f7773203230303020352e3000"
buf3 = [buf3].pack('H*')

找到答案

难道是Ruby的Hex解码和Python的Hex解码有差异? 相同的shellcode,不同语言,发送不同的数据包。

神秘大牛很确定得告诉我这个是不可能的!问题可能来自这2者语法不同

神秘大牛怀疑是:Python中的切片和Ruby中的字符串截取不一样。

s.send(session_setup_request)
data = s.recv(1024)
user_id = data[32:34]

打开Ruby的调试环境:irb

如何转换永恒之蓝(Eternalblue)的POC

定义一个变量a=’10086’

用a[2..4]做一个切片,我们从中可以看出a在内存的位置是从0算起的,共三位,2~4就是“086”

再看看Python

a = "10086"
print a[2:4]

运行结果:

如何转换永恒之蓝(Eternalblue)的POC

运行的结果居然是“08”。

Python的切片是最后一位属于界定位,不包含在内。

所以将Ruby中的切片改为:[32:33]就行了。

还有一个小坑:,

Ruby会自动对字符识别做转换,在Python不会,所以Ruby在转换的时候就会报错,解决的方法就是加一个编码转化回ascii。

Code区域:

ifdata.include? "\x05\x02\x00\xc0".force_encoding('ASCII-8BIT')

成就感

总结下,要使用一门语言还是要学习深入一点~

而Ruby我第一次用(/ □ \)

硬着头皮上了~重要的还是细心,一步步解决问题明显很迷人~~。然后放一下扫描的图片。

如何转换永恒之蓝(Eternalblue)的POC


以上所述就是小编给大家介绍的《如何转换永恒之蓝(Eternalblue)的POC》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

具体数学(英文版第2版)

具体数学(英文版第2版)

[美] Ronald L. Graham、Donald E. Knuth、Oren Patashnik / 机械工业出版社 / 2002-8 / 49.00元

This book introduces the mathematics that supports advanced computer Programming and the analysis of algorithms. The primary aim of its well-known authors is to provide a solid and relevant base of ma......一起来看看 《具体数学(英文版第2版)》 这本书的介绍吧!

CSS 压缩/解压工具
CSS 压缩/解压工具

在线压缩/解压 CSS 代码

XML、JSON 在线转换
XML、JSON 在线转换

在线XML、JSON转换工具