Share
## https://sploitus.com/exploit?id=1337DAY-ID-34704
######################################################################################################################
# Exploit Title: SMB12 information gathering
# SMB12 means it's capable of inspecting both SMB1 and SMB2 versions
# the utility will extract varios attributes from SMB protocol of the remote server such as
# OS version (only supported by SMB1 as per protocol definition)
# DNS computername, DNS domainname, NEtBIOS computername and NetBIOS domain name (SMB1 and SMB2)
# boot time and current time on the remote server (SMB1 and SMB2)
# Server's GUID (SMB1 and SMB2)
# Additional : NEtBIOS probe against UDP 137 (netbios session) to determine server roles such as
# -domain master browser
# -domain controller
# -server service
# Date: 11-July-2020
# Exploit Author: Ivica Stipovic
# Vendor Homepage: www.microsoft.com
# Software Link: intergrated as part of Windows OS
# Version: SMB1 and SMB2
# Tested on: Windows 7, Windows 10, Windows 2012 R2, Windows 2016, Windows 2019
# Domain setup: Some OS-es were setup as WORKGROUP members and some as DOMAIN
# Objective: enhance system info returned by SMB protocol in comparison to :
# nmap smb-system-info.nse and metasploit smb_version and smb2 modules
# Known Limitation: not designed for SAMBA implementations (Linux etc) - no reliable detection/exception possible
# Download link: https://github.com/adenosine-phosphatase/smb12info
###########################################################################################################
import socket
import sys
import time
from datetime import datetime, timedelta
from struct import *
TCP_PORT=445
netbios_check=(
"\x91\xe2" # Transaction ID
"\x00\x00" # Flags
"\x00\x01" # Questions=1
"\x00\x00" # Answer RRs
"\x00\x00" # Authority RRs
"\x00\x00" # Additional RRs
"\x20\x43\x4b\x41\x41\x41\x41\x41" # Queries MSHOME/Type NB, Class IN
"\x41\x41\x41\x41\x41\x41\x41\x41"
"\x41\x41\x41\x41\x41\x41\x41\x41"
"\x41\x41\x41\x41\x41\x41\x41\x41"
"\x41\x00"
"\x00\x21" # NBSTAT (33)
"\x00\x01") # Class IN(1)
smb_helper_message=(
"\x00" # NEtbios header - Message type 00
"\x00\x00\x54" # Length
"\xff\x53\x4d\x42" # SMB header-Server component
"\x72" # SMB command - negotiate protocol
"\x00" # NT Status - status_success
"\x00" # NT Status
"\x00\x00" # NT Status
"\x18" # Flags: 0x18
"\x01\x28" # Flags2
"\x00\x00" # Process ID High
"\x00\x00\x00\x00\x00\x00\x00\x00" # Signature
"\x00\x00" # Reserved
"\x00\x00" # Tree ID
"\x2e\x6f" # Process ID
"\x00\x00" # User ID
"\x7f\xe6" # Multiplex ID
"\x00" # Word Count
"\x31\x00" # Byte count
"\x02\x4c\x41\x4e\x4d\x41\x4e\x31\x2e\x30\x00" # Requested Dialects
"\x02\x4c\x4d\x31\x2e\x32\x58\x30\x30\x32\x00" # PC NETWORK PROGRAM 1.0
"\x02\x4e\x54\x20\x4c\x41\x4e\x4d\x41\x4e\x20" # MICROSOFT NETWORKS 1.03
"\x31\x2e\x30\x00"
"\x02\x4e\x54\x20\x4c\x4d\x20\x30\x2e\x31\x32\x00")
smb_enahanced_helper_message=(
"\x00" # NetBIOS header - message type
"\x00\x00\x45" # Length
"\xff\x53\x4d\x42" # Server Component -SMB2
"\x72" # Header Length
"\x00\x00\x00\x00" # NT STATUS - status success
"\x18" # Flags
"\x53\xc8" # Flags2
"\x00\x00" # Process ID High
"\x00\x00\x00\x00\x00\x00\x00\x00" # Signature=00000
"\x00\x00" # Reserved=0000
"\xff\xff" # Tree ID
"\xff\xfe" # Process ID
"\x00\x00" # User ID
"\x00\x00" # Multiplex ID
"\x00" # Word Count
"\x22\x00" # Byte count
"\x02\x4e\x54\x20\x4c\x4d\x20\x30\x2e\x31\x32\x00" # Requested dialects - this is
"\x02\x53\x4d\x42\x20\x32\x2e\x30\x30\x32\x00" # the main difference to initial SMB1
"\x02\x53\x4d\x42\x20\x32\x2e\x3f\x3f\x3f\x00") # request
smb2_helper_message=(
"\x00" # NetBIOS message type
"\x00\x00\xae" # Length
"\xfe\x53\x4d\x42" # SMB2 -Protocol ID
"\x40\x00" # Header Length
"\x00\x00" # Credit Charge
"\x00\x00" # Channel sequence
"\x00\x00" # Reserved
"\x00\x00" # Negotiate Protocol
"\x00\x00" # Credits requested
"\x00\x00\x00\x00" # Flags
"\x00\x00\x00\x00" # Chain offset
"\x01\x00\x00\x00\x00\x00\x00\x00" # Message ID - unknown=1
"\xff\xfe\x00\x00" # PRocess ID
"\x00\x00\x00\x00" # Tree ID
"\x00\x00\x00\x00\x00\x00\x00\x00" # Session ID
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" # Signature
"\x24\x00" # Structure size
"\x05\x00" # Dialect count
"\x01\x00" # Security mode / signing enabled
"\x00\x00" # Reserved
"\x7f\x00\x00\x00" # Capabilities
"\x86\xcc\xaa\x67\xca\xb6\xea\x11\x91\xb1\xfd\x77\x48\xa7\x6a\x3c" # Client GUID
"\x70\x00\x00\x00" # NegotiateContextOffset
"\x02\x00" # NEgotiateContextCount
"\x00\x00" # Reserved
"\x02\x02" # Dialect 1
"\x10\x02" # Dialect 2
"\x00\x03" # Dialect 3
"\x02\x03" # Dialect 4
"\x11\x03" # Dialect 5
"\x00\x00" # unknonw
"\x01\x00" # DataType SMB_PREAUTH
"\x26\x00" # Datalength
"\x00\x00\x00\x00" # Reserved
"\x01\x00" # Hash Algorithm
"\x20\x00" # salt length
"\x01\x00" # Hash algorithm SHA-512
"\xd3\x2f\xfe\xad\x6b\xc5\x32\xbb" # Salt (32 bytes)
"\x44\x29\x7d\x56\x33\x69\xcd\xe7"
"\x42\x1c\x20\x53\x85\x16\x97\xc5"
"\x01\xec\x80\x12\x6a\x9b\xbe\x2d"
"\x00\x00" # unknown
"\x02\x00" # SMB2_encryption_capabilities
"\x06\x00" # Datalength
"\x00\x00\x00\x00" # Reserved
"\x02\x00" # Cipher count
"\x02\x00" # Cipher ID
"\x01\x00") # Cipher ID
smb_helper_message_security_blob=(
"\x00" # NetBIOS message type
"\x00\x00\x8f" # Length
"\xff\x53\x4d\x42" # SMB1 Server Component
"\x73" # Session Setup AndX (0x73)
"\x00" # Error class=success
"\x00" # Reserved
"\x00\x00" # Error Code=no error
"\x18" # Flags
"\x01\x28" # Flags2
"\x00\x00" # Process ID High
"\x00\x00\x00\x00\x00\x00\x00\x00" # Signature
"\x00\x00" # Reserved
"\x00\x00" # Tree ID
"\x2e\x6f" # Process ID
"\x00\x00" # User ID
"\x7f\xe6" # Multiplex ID
"\x0c" # Word Count
"\xff" # AndX Command=no further commands
"\x00" # Reserved
"\x00\x00" # AndXOffset=0
"\xdf\xff" # Max Buffer
"\x02\x00" # Max Mpx Count
"\x01\x00" # VC Number
"\x00\x00\x00\x00" # Session Key
"\x31\x00" # Security Blob Length
"\x00\x00\x00\x00" # Reserved
"\xd4\x00\x00\x80" # Capabilities
"\x54\x00" # Byte Count
"\x4e\x54\x4c\x4d\x53\x53\x50\x00" # NTLMSSP identifier
"\x01\x00\x00\x00" # NTLM Message Type = NTLMSSP_NEGOTIATE
"\x05\x02\x88\xa2" # Negotiate flags
"\x01\x00\x01\x00\x20\x00\x00\x00\x10\x00\x10\x00\x21\x00\x00\x00" #Calling Wkst domain
"\x2e"
"\x32\x54\x64\x44\x36\x30\x77\x62\x4e\50\x36\47\x39\x61\x66\x76" # Calling wkst name
"\x57\x69\x6e\x64\x6f\x77\x73\x20\x32" # Native OS Win2000
"\x30\x30\x30\x20\x32\x31\x39\x35\x00" # Native LAN Manager
"\x57\x69\x6e\x64\x6f\x77\x73\x20\x32"
"\x30\x30\x30\x20\x35\x2e\x30\x00")
smb2_helper_ntlmssp_message= (
"\x00" # Netbios Message Type
"\x00\x00\xa2" # Length
"\xfe\x53\x4d\x42" # Server Component, ex: SMB2
"\x40\x00" # Header Length
"\x01\x00" # Credit Charge
"\x00\x00" # Channel sequence
"\x00\x00" # Reserved
"\x01\x00" # Session Setup
"\x21\x00" # Credits requested
"\x10\x00\x00\x00" # Flags
"\x00\x00\x00\x00" # Chain Offset
"\x02\x00\x00\x00\x00\x00\x00\x00" # Message ID
"\xff\xfe\x00\x00" # Process ID
"\x00\x00\x00\x00" # Tree ID
"\x00\x00\x00\x00\x00\x00\x00\x00" # Session ID
"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00" # Signature
"\x19\x00" # Structure size
"\x00" # Flags
"\x02" # Security mode
"\x01\x00\x00\x00" # Capabilities
"\x00\x00\x00\x00" # Channel
"\x58\x00" # Previous session ID
"\x4a\x00" # Blob length
"\x00\x00\x00\x00\x00\x00\x00\x00" # Previos Session ID
"\x60\x48\x06\x06\x2b\x06\x01\x05" # GSS-API Generic Security Service
"\x05\x02\xa0\x3e\x30\x3c\xa0\x0e" # Simple Protected NEgotiation
"\x30\x0c\x06\x0a\x2b\x06\x01\x04" # mechtypes + NTLM Secure Service Provider
"\x01\x82\x37\x02\x02\x0a\xa2\x2a"
"\x04\x28\x4e\x54\x4c\x4d\x53\x53"
"\x50\x00\x01\x00\x00\x00\x97\x82"
"\x08\xe2\x00\x00\x00\x00\x00\x00"
"\x00\x00\x00\x00\x00\x00\x00\x00"
"\x00\x00\x0a\x00\xee\x42\x00\x00"
"\x00\x0f")
def print_smb12_system_info (smb_type,data2):
netbios_header=4
if smb_type==1:
smb_header=32
else:
smb_header=64
blob_offset=netbios_header+smb_header
offset=0
index=0
size=len (data2)
pattern=0
security_blob="4e544c4d535350"
control=""
for t in data2[blob_offset:size-blob_offset]:
for x in data2[blob_offset+offset:blob_offset+offset+7]:
control=control+"{:02x}".format(ord(x),"x")
if security_blob==control:
index=blob_offset+offset
index=index+12
targetnamelen=int(ord(data2[index:index+1][::-1]))
index=index+28
index=index+16
targetname=data2[index:index+targetnamelen]
targetinfoitemlen=int(ord(data2[index+targetnamelen+2]))
netbiosname=data2[index+targetnamelen+4:index+targetnamelen+4+targetinfoitemlen]
netbioscomputernamelen=int(ord(data2[index+targetnamelen+4+targetinfoitemlen+2]))
index=index+targetnamelen+4+targetinfoitemlen+2
netbioscomputername=data2[index+2:index+2+netbioscomputernamelen]
dnsdomainnamelen=int(ord(data2[index+2+netbioscomputernamelen+2]))
index=index+2+netbioscomputernamelen+2
dnsdomainname=data2[index+2:index+2+dnsdomainnamelen]
dnscomputernamelen=int(ord(data2[index+2+dnsdomainnamelen+2]))
index=index+2+dnsdomainnamelen+2
dnscomputername=data2[index+2:index+2+dnscomputernamelen]
print "[+] Target Name:", targetname
print "[+] Netbios Domainname:",netbiosname
print "[+] Netbios Computername:", netbioscomputername
print "[+] DNS Domain Name:", dnsdomainname
print "[+] DNS Computer Name:", dnscomputername
index=index+2+dnscomputernamelen
# Check for DNS tree info item type - must be 5, anything else means not a domain member
if int(ord(data2[index]))==5:
dnstreelen=int(ord(data2[index+2]))
print "[+] DNS Tree Name:", data2[index+2:index+2+dnstreelen+1]
index=index+2+dnstreelen+2
# Skip over 16 bytes (timestamp=12 bytes + end-of-list=4 bytes
index=index+16
if size-index>0:
print "[+] OS info:",data2[index-2:size]
offset+=1
control=""
def netbios_fingerprint():
sockUDP=socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
try:
sockUDP.sendto(netbios_check,(TCP_IP,137))
sockUDP.settimeout(3)
dataUDP,addrUDP=sockUDP.recvfrom(1024)
number_of_names=int(ord(dataUDP[56]))
delta=0
names_offset=57
role=0
for x in range(number_of_names):
role=int(ord(dataUDP[names_offset+(x+1)*16-1+delta]))
if role==0:
print ("[+] NetBIOS Role: Workstation/Redirector")
elif role==32:
print ("[+] NetBIOS Role: Server Service")
elif role==28:
print ("[+] NetBIOS Role: Domain Controller")
elif role==27:
print ("[+] NetBIOS Role: Domain Master Browser")
delta+=2
except socket.timeout:
print "[-] No response from NetBIOS"
sockUDP.close()
def send_smb_request(message_type,sock_type):
sock_type.sendall(message_type)
resp,addr=sock_type.recvfrom(1024)
return resp
def print_smb1_guid(smb1_guid_data):
guidA_id=""
guidB_id=""
guidC_id=""
guidD_id=""
guidE_id=""
for x in temp_data[73:77]:
guidA_id=guidA_id+"{:02x}".format(ord(x),"x")
for x in temp_data[77:79]:
guidB_id=guidB_id+"{:02x}".format(ord(x),"x")
for x in temp_data[79:81]:
guidC_id=guidC_id+"{:02x}".format(ord(x),"x")
for x in temp_data[81:83]:
guidD_id=guidD_id+"{:02x}".format(ord(x),"x")
for x in temp_data[83:89]:
guidE_id=guidE_id+"{:02x}".format(ord(x),"x")
print "[+] Server GUID:" ,guidA_id+'-'+guidB_id+'-'+guidC_id+'-'+guidD_id+'-'+guidE_id
def print_system_time(start_time,end_time,time_type):
# time_type=0 then boot time
# time_type=1 then current time
dx=""
for y in temp_data[start_time:end_time][::-1]:
dx=dx+"{:02x}".format(ord(y),"x")
if dx!="0000000000000000":
us=int(dx,16) / 10.
if time_type==0:
print "[+] Boot time:",datetime(1601,1,1) + timedelta(microseconds=us)
else:
print "[+] Current time:", datetime(1601,1,1) + timedelta(microseconds=us)
else:
if time_type==0:
print "[-] Boot time not specified"
else:
print "[+] Current time not specified"
dx=""
if len(sys.argv)!=2:
print ("usage: python smbinject.py <ip address>")
sys.exit()
else:
TCP_IP=sys.argv[1]
#====================================
# Negotiate Protocol Request sequence
#=====================================
print ("[+] Trying NetBIOS fingerprint...")
netbios_fingerprint()
sock=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sock.connect((TCP_IP,TCP_PORT))
try:
print ("[+] Starting SMB1 check")
temp_data=send_smb_request(smb_helper_message,sock)
smb_dialect=temp_data[72:74]
current_time_start=60
current_time_stop=68
print_system_time(current_time_start,current_time_stop,1)
print_smb1_guid(temp_data)
print ("[+] SMB1 dialect detected")
time.sleep(1)
data=send_smb_request(smb_helper_message_security_blob,sock)
print ("[+] SMB response")
smb=1
print_smb12_system_info (smb,data)
except socket.error,ex:
print ("[-] Server reset SMB1 negotiation. Trying SMB2 ...")
sock2=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
sock2.connect((TCP_IP,TCP_PORT))
temp_data=send_smb_request(smb_enahanced_helper_message,sock2)
guid1_id=""
guid2_id=""
guid3_id=""
guid4_id=""
guid5_id=""
for x in temp_data[76:80][::-1]:
guid1_id=guid1_id+"{:02x}".format(ord(x),"x")
for x in temp_data[80:82][::-1]:
guid2_id=guid2_id+"{:02x}".format(ord(x),"x")
for x in temp_data[82:84][::-1]:
guid3_id=guid3_id+"{:02x}".format(ord(x),"x")
for x in temp_data[84:86]:
guid4_id=guid4_id+"{:02x}".format(ord(x),"x")
for x in temp_data[86:92]:
guid5_id=guid5_id+"{:02x}".format(ord(x),"x")
print "[+] Server GUID:" ,guid1_id+'-'+guid2_id+'-'+guid3_id+'-'+guid4_id+'-'+guid5_id
dt=""
current_time_start=108
current_time_stop=116
boot_time_start=116
boot_time_stop=124
print_system_time(current_time_start,current_time_stop,1)
print_system_time(boot_time_start,boot_time_stop,0)
time.sleep(2)
send_smb_request(smb2_helper_message,sock2)
time.sleep(1)
data2=send_smb_request(smb2_helper_ntlmssp_message,sock2)
smb=2
print_smb12_system_info (smb,data2)
sock2.close()
sock.close()