Guest User

Untitled

a guest
Jul 19th, 2018
88
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.43 KB | None | 0 0
  1. #!/usr/bin/python
  2. '''
  3.  
  4. This is a make-shift replacement for metasploit's auxiliary/scanner/smb_version for clients that have disabled/removed
  5. SMBv1. This grabs the hostname, domain name, and Windows version from the NTLMv2 challenge response
  6.  
  7. @Quickbreach
  8.  
  9. '''
  10. import argparse
  11. import struct
  12. from binascii import hexlify, unhexlify
  13. import socket
  14. import random
  15. import string
  16. from netaddr import IPNetwork
  17. from threading import Thread
  18. from multiprocessing import Queue
  19. from impacket.spnego import SPNEGO_NegTokenResp
  20. from impacket.ntlm import NTLMAuthChallenge, AV_PAIRS, NTLMSSP_AV_HOSTNAME
  21. from impacket.smb3structs import SMB2Packet, SMB2Negotiate, \
  22. SMB2SessionSetup_Response, SMB2_DIALECT_002, SMB2_DIALECT_21, \
  23. SMB2_DIALECT_30, SMB2_DIALECT_302
  24. import logging
  25. from impacket.examples import logger
  26. logger.init()
  27. logging.getLogger().setLevel(logging.INFO)
  28.  
  29.  
  30. class VChecker(Thread):
  31. def __init__(self, IPQueue, Timeout = 3):
  32. Thread.__init__(self)
  33. self.daemon = True
  34. self.IPQueue = IPQueue
  35. self.Timeout = 3
  36. self.suicide = False
  37. self.start()
  38.  
  39. def join(self, timeout):
  40. if(timeout == -1):
  41. return
  42. else:
  43. self.suicide = True
  44. super(VChecker, self).join(timeout)
  45.  
  46. def run(self):
  47. while True:
  48. if self.suicide: return
  49. nextIP = None # need this declared outside of the try/catch
  50. try:
  51. if not self.IPQueue.empty():
  52. nextIP = self.IPQueue.get()
  53. else:
  54. self.suicide = True
  55. return
  56. except Exception, e:
  57. return
  58.  
  59. if nextIP == None: return
  60. s = None
  61. try:
  62. s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  63. s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
  64. s.settimeout(self.Timeout)
  65. s.connect((nextIP, 445))
  66. except Exception, e:
  67. continue
  68. if(s == None):
  69. continue
  70.  
  71.  
  72. try:
  73. # Negotiate
  74. negProto = SMB2Negotiate(unhexlify("24000500010000007f000000cb78cd146438e7119168000c291232a370000000020000000202100200030203110300000100260000000000010020000100c8c31f28d43563c829b9070423e96a98701ac3ec788a3ac01573ee03d07d942600000200060000000000020002000100"))
  75. negProto['Dialects'] = [SMB2_DIALECT_002, SMB2_DIALECT_21, SMB2_DIALECT_30, SMB2_DIALECT_302, 0, 0]
  76. negProto['ClientGuid'] = ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(8))
  77. rawData = str(SMB2Packet()) + str(negProto)
  78. netbios = struct.pack('>i', len(str(rawData)))
  79. rpkt = str(netbios) + str(rawData)
  80. s.sendall(rpkt)
  81. data = s.recv(4096)
  82. negResp = SMB2Packet(data[4:])
  83.  
  84. # NTLMSSP Negotiate
  85. sessionSetup = unhexlify("000000a2fe534d42400001000000000001001f0000000000000000000200000000000000fffe00000000000000000000000000000000000000000000000000000000000019000001010000000000000058004a000000000000000000604806062b0601050502a03e303ca00e300c060a2b06010401823702020aa22a04284e544c4d5353500001000000978208e2000000000000000000000000000000000601b11d0000000f")
  86. test = SMB2Packet(sessionSetup[4:])
  87. test['Reserved'] = 0
  88. test['MessageID'] = 1
  89. netbios = str(struct.pack('>i', len(str(test))))
  90. s.sendall(netbios + str(test))
  91.  
  92.  
  93. # Get NTLMSSP challenge response
  94. data = s.recv(4096)
  95. s.close()
  96.  
  97. packet = SMB2Packet(data[4:])
  98. resp = SMB2SessionSetup_Response(packet['Data'])
  99. securityBlob = SPNEGO_NegTokenResp(resp['Buffer'])
  100. authData = NTLMAuthChallenge(securityBlob['ResponseToken'])
  101.  
  102. serverInfo = AV_PAIRS(authData['TargetInfoFields'])
  103. majorVersion = int(hexlify(struct.unpack('<c', str(authData['Version'])[0])[0]), 16)
  104. minorVersion = int(hexlify(struct.unpack('<c', str(authData['Version'])[1])[0]), 16)
  105. buildVersion = struct.unpack('<h', str(authData['Version'])[2:4])[0]
  106. hostname = serverInfo[NTLMSSP_AV_HOSTNAME][1].decode("utf-16-le").encode("utf-8")
  107. domain = authData['domain_name'].decode("utf-16-le").encode("utf-8")
  108. except Exception, e:
  109. logging.error("Failed to get data from " + nextIP + " (Does it support NTLM?)")
  110. logging.error(e)
  111. continue
  112.  
  113. OS = "(Unknown OS version)"
  114.  
  115. if majorVersion == 5:
  116. # Major 5, minor 1: Windows XP SP2
  117. if minorVersion == 1: OS = "Windows XP SP2"
  118. # Major 5, minor 2: Windows server 2003
  119. if minorVersion == 2: OS = "Windows Server 2003"
  120.  
  121. if majorVersion == 6:
  122. if minorVersion == 0: OS = "Windows Vista or Server 2008"
  123.  
  124. if minorVersion == 1: OS = "Windows 7 or Server 2008 R2"
  125.  
  126. if minorVersion == 2: OS = "Windows 8 or Server 2012"
  127.  
  128. if minorVersion == 3: OS = "Windows 8.1 or Server 2012 R2"
  129.  
  130. if majorVersion == 10:
  131. if minorVersion == 0: OS = "Windows 10 or Server 2016"
  132.  
  133. logging.info(nextIP + ":445\t" + OS + " (build:" + str(buildVersion) + ") (name:" + hostname + ") (Domain:" + domain + ")")
  134.  
  135.  
  136. if __name__ == "__main__":
  137. parser = argparse.ArgumentParser()
  138. parser._optionals.title = "Standard arguments"
  139. parser.add_argument('-t', type=str, help='Target IP or CIDR', required=True)
  140. parser.add_argument('--threads', default=1, type=int, help='Maximum number of concurrent threads (default: 1)', required=False)
  141. parser.add_argument('--timeout', default=1, type=int, help='Connection timeout in seconds (default: 1)', required=False)
  142. args = parser.parse_args()
  143.  
  144.  
  145. targetList = Queue()
  146. workers = []
  147.  
  148. for ip in IPNetwork(args.t):
  149. targetList.put(str(ip))
  150.  
  151. for x in range(0, args.threads):
  152. workers.append(VChecker(targetList, args.timeout))
  153.  
  154.  
  155. try:
  156. for worker in workers:
  157. while worker.isAlive():
  158. worker.join(-1)
  159. except KeyboardInterrupt:
  160. logging.error("Recieved interrupt - cleaning up...")
  161. for worker in workers:
  162. worker.join(0)
  163.  
  164. exit(0)
Add Comment
Please, Sign In to add comment