librex 0.0.6 → 0.0.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +3 -5
- data/Rakefile +26 -0
- data/lib/rex/compat.rb +1 -1
- data/lib/rex/exploitation/javascriptosdetect.rb +125 -62
- data/lib/rex/file.rb +15 -0
- data/lib/rex/io/stream.rb +1 -1
- data/lib/rex/parser/nmap_xml.rb +6 -0
- data/lib/rex/poly/block.rb +9 -0
- data/lib/rex/post/meterpreter/client.rb +0 -8
- data/lib/rex/post/meterpreter/extensions/priv/priv.rb +6 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/fs/file.rb +1 -1
- data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_advapi32.rb +49 -35
- data/lib/rex/post/meterpreter/extensions/stdapi/railgun/def/def_netapi32.rb +26 -0
- data/lib/rex/post/meterpreter/extensions/stdapi/railgun/railgun.rb +9 -2
- data/lib/rex/post/meterpreter/extensions/stdapi/railgun/util.rb +630 -0
- data/lib/rex/post/meterpreter/packet.rb +3 -1
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/core.rb +143 -57
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/fs.rb +6 -0
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/net.rb +9 -3
- data/lib/rex/post/meterpreter/ui/console/command_dispatcher/stdapi/sys.rb +6 -4
- data/lib/rex/proto.rb +1 -0
- data/lib/rex/proto/dhcp/server.rb +4 -2
- data/lib/rex/proto/http/packet.rb +5 -6
- data/lib/rex/proto/ntlm.rb +7 -0
- data/lib/rex/proto/ntlm.rb.ut.rb +177 -0
- data/lib/rex/proto/ntlm/base.rb +326 -0
- data/lib/rex/proto/ntlm/constants.rb +74 -0
- data/lib/rex/proto/ntlm/crypt.rb +340 -0
- data/lib/rex/proto/ntlm/exceptions.rb +9 -0
- data/lib/rex/proto/ntlm/message.rb +533 -0
- data/lib/rex/proto/ntlm/utils.rb +358 -0
- data/lib/rex/proto/smb/client.rb +548 -86
- data/lib/rex/proto/smb/client.rb.ut.rb +4 -4
- data/lib/rex/proto/smb/constants.rb +7 -24
- data/lib/rex/proto/smb/crypt.rb +12 -71
- data/lib/rex/proto/smb/exceptions.rb +12 -0
- data/lib/rex/proto/smb/simpleclient.rb +17 -5
- data/lib/rex/proto/smb/utils.rb +3 -460
- data/lib/rex/proto/tftp/server.rb +2 -2
- data/lib/rex/script/base.rb +2 -2
- data/lib/rex/socket.rb +12 -0
- data/lib/rex/socket.rb.ut.rb +31 -10
- data/lib/rex/socket/ssl_tcp_server.rb.ut.rb +15 -5
- data/lib/rex/text.rb +55 -4
- data/lib/rex/ui/output.rb +0 -2
- data/lib/rex/ui/text/dispatcher_shell.rb +95 -10
- data/lib/rex/ui/text/output/buffer.rb +0 -4
- data/lib/rex/ui/text/shell.rb +8 -0
- data/lib/rex/ui/text/table.rb +21 -1
- metadata +15 -19
- data/lib/rex/proto/smb/crypt.rb.ut.rb +0 -20
@@ -0,0 +1,358 @@
|
|
1
|
+
module Rex
|
2
|
+
module Proto
|
3
|
+
module NTLM
|
4
|
+
class Utils
|
5
|
+
|
6
|
+
#duplicate from lib/rex/proto/smb/utils cause we only need this fonction from Rex::Proto::SMB::Utils
|
7
|
+
# Convert a unix timestamp to a 64-bit signed server time
|
8
|
+
def self.time_unix_to_smb(unix_time)
|
9
|
+
t64 = (unix_time + 11644473600) * 10000000
|
10
|
+
thi = (t64 & 0xffffffff00000000) >> 32
|
11
|
+
tlo = (t64 & 0x00000000ffffffff)
|
12
|
+
return [thi, tlo]
|
13
|
+
end
|
14
|
+
|
15
|
+
#
|
16
|
+
# Prepends an ASN1 formatted length field to a piece of data
|
17
|
+
#
|
18
|
+
def self.asn1encode(str = '')
|
19
|
+
res = ''
|
20
|
+
|
21
|
+
# If the high bit of the first byte is 1, it contains the number of
|
22
|
+
# length bytes that follow
|
23
|
+
|
24
|
+
case str.length
|
25
|
+
when 0 .. 0x7F
|
26
|
+
res = [str.length].pack('C') + str
|
27
|
+
when 0x80 .. 0xFF
|
28
|
+
res = [0x81, str.length].pack('CC') + str
|
29
|
+
when 0x100 .. 0xFFFF
|
30
|
+
res = [0x82, str.length].pack('Cn') + str
|
31
|
+
when 0x10000 .. 0xffffff
|
32
|
+
res = [0x83, str.length >> 16, str.length & 0xFFFF].pack('CCn') + str
|
33
|
+
when 0x1000000 .. 0xffffffff
|
34
|
+
res = [0x84, str.length].pack('CN') + str
|
35
|
+
else
|
36
|
+
raise "ASN1 str too long"
|
37
|
+
end
|
38
|
+
return res
|
39
|
+
end
|
40
|
+
|
41
|
+
# GSS functions
|
42
|
+
|
43
|
+
# GSS BLOB usefull for SMB_NEGOCIATE_RESPONSE message
|
44
|
+
# mechTypes: 2 items :
|
45
|
+
# -MechType: 1.3.6.1.4.1.311.2.2.30 (SNMPv2-SMI::enterprises.311.2.2.30)
|
46
|
+
# -MechType: 1.3.6.1.4.1.311.2.2.10 (NTLMSSP - Microsoft NTLM Security Support Provider)
|
47
|
+
#
|
48
|
+
# this is the default on Win7
|
49
|
+
def self.make_simple_negotiate_secblob_resp
|
50
|
+
blob =
|
51
|
+
"\x60" + self.asn1encode(
|
52
|
+
"\x06" + self.asn1encode(
|
53
|
+
"\x2b\x06\x01\x05\x05\x02"
|
54
|
+
) +
|
55
|
+
"\xa0" + self.asn1encode(
|
56
|
+
"\x30" + self.asn1encode(
|
57
|
+
"\xa0" + self.asn1encode(
|
58
|
+
"\x30" + self.asn1encode(
|
59
|
+
"\x06" + self.asn1encode(
|
60
|
+
"\x2b\x06\x01\x04\x01\x82\x37\x02\x02\x0a"
|
61
|
+
)
|
62
|
+
)
|
63
|
+
)
|
64
|
+
)
|
65
|
+
)
|
66
|
+
)
|
67
|
+
|
68
|
+
return blob
|
69
|
+
end
|
70
|
+
|
71
|
+
# GSS BLOB usefull for SMB_NEGOCIATE_RESPONSE message
|
72
|
+
# mechTypes: 4 items :
|
73
|
+
# MechType: 1.2.840.48018.1.2.2 (MS KRB5 - Microsoft Kerberos 5)
|
74
|
+
# MechType: 1.2.840.113554.1.2.2 (KRB5 - Kerberos 5)
|
75
|
+
# MechType: 1.2.840.113554.1.2.2.3 (KRB5 - Kerberos 5 - User to User)
|
76
|
+
# MechType: 1.3.6.1.4.1.311.2.2.10 (NTLMSSP - Microsoft NTLM Security Support Provider)
|
77
|
+
# mechListMIC:
|
78
|
+
# principal: account@domain
|
79
|
+
def self.make_negotiate_secblob_resp(account, domain)
|
80
|
+
blob =
|
81
|
+
"\x60" + self.asn1encode(
|
82
|
+
"\x06" + self.asn1encode(
|
83
|
+
"\x2b\x06\x01\x05\x05\x02"
|
84
|
+
) +
|
85
|
+
"\xa0" + self.asn1encode(
|
86
|
+
"\x30" + self.asn1encode(
|
87
|
+
"\xa0" + self.asn1encode(
|
88
|
+
"\x30" + self.asn1encode(
|
89
|
+
"\x06" + self.asn1encode(
|
90
|
+
"\x2a\x86\x48\x82\xf7\x12\x01\x02\x02"
|
91
|
+
) +
|
92
|
+
"\x06" + self.asn1encode(
|
93
|
+
"\x2a\x86\x48\x86\xf7\x12\x01\x02\x02"
|
94
|
+
) +
|
95
|
+
"\x06" + self.asn1encode(
|
96
|
+
"\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x03"
|
97
|
+
) +
|
98
|
+
"\x06" + self.asn1encode(
|
99
|
+
"\x2b\x06\x01\x04\x01\x82\x37\x02\x02\x0a"
|
100
|
+
)
|
101
|
+
)
|
102
|
+
) +
|
103
|
+
"\xa3" + self.asn1encode(
|
104
|
+
"\x30" + self.asn1encode(
|
105
|
+
"\xa0" + self.asn1encode(
|
106
|
+
"\x1b" + self.asn1encode(
|
107
|
+
account + '@' + domain
|
108
|
+
)
|
109
|
+
)
|
110
|
+
)
|
111
|
+
)
|
112
|
+
)
|
113
|
+
)
|
114
|
+
)
|
115
|
+
|
116
|
+
return blob
|
117
|
+
end
|
118
|
+
|
119
|
+
|
120
|
+
# GSS BLOB usefull for ntlmssp type 1 message
|
121
|
+
def self.make_ntlmssp_secblob_init(domain = 'WORKGROUP', name = 'WORKSTATION', flags=0x80201)
|
122
|
+
blob =
|
123
|
+
"\x60" + self.asn1encode(
|
124
|
+
"\x06" + self.asn1encode(
|
125
|
+
"\x2b\x06\x01\x05\x05\x02"
|
126
|
+
) +
|
127
|
+
"\xa0" + self.asn1encode(
|
128
|
+
"\x30" + self.asn1encode(
|
129
|
+
"\xa0" + self.asn1encode(
|
130
|
+
"\x30" + self.asn1encode(
|
131
|
+
"\x06" + self.asn1encode(
|
132
|
+
"\x2b\x06\x01\x04\x01\x82\x37\x02\x02\x0a"
|
133
|
+
)
|
134
|
+
)
|
135
|
+
) +
|
136
|
+
"\xa2" + self.asn1encode(
|
137
|
+
"\x04" + self.asn1encode(
|
138
|
+
"NTLMSSP\x00" +
|
139
|
+
[1, flags].pack('VV') +
|
140
|
+
|
141
|
+
[
|
142
|
+
domain.length, #length
|
143
|
+
domain.length, #max length
|
144
|
+
32
|
145
|
+
].pack('vvV') +
|
146
|
+
|
147
|
+
[
|
148
|
+
name.length, #length
|
149
|
+
name.length, #max length
|
150
|
+
domain.length + 32
|
151
|
+
].pack('vvV') +
|
152
|
+
|
153
|
+
domain + name
|
154
|
+
)
|
155
|
+
)
|
156
|
+
)
|
157
|
+
)
|
158
|
+
)
|
159
|
+
|
160
|
+
return blob
|
161
|
+
end
|
162
|
+
|
163
|
+
|
164
|
+
# GSS BLOB usefull for ntlmssp type 2 message
|
165
|
+
def self.make_ntlmssp_secblob_chall(win_domain, win_name, dns_domain, dns_name, chall, flags)
|
166
|
+
|
167
|
+
blob =
|
168
|
+
"\xa1" + self.asn1encode(
|
169
|
+
"\x30" + self.asn1encode(
|
170
|
+
"\xa0" + self.asn1encode(
|
171
|
+
"\x0a" + self.asn1encode(
|
172
|
+
"\x01"
|
173
|
+
)
|
174
|
+
) +
|
175
|
+
"\xa1" + self.asn1encode(
|
176
|
+
"\x06" + self.asn1encode(
|
177
|
+
"\x2b\x06\x01\x04\x01\x82\x37\x02\x02\x0a"
|
178
|
+
)
|
179
|
+
) +
|
180
|
+
"\xa2" + self.asn1encode(
|
181
|
+
"\x04" + self.asn1encode(
|
182
|
+
make_ntlmssp_blob_chall(win_domain, win_name, dns_domain, dns_name, chall, flags)
|
183
|
+
)
|
184
|
+
)
|
185
|
+
)
|
186
|
+
)
|
187
|
+
|
188
|
+
return blob
|
189
|
+
end
|
190
|
+
|
191
|
+
# BLOB without GSS usefull for ntlm type 2 message
|
192
|
+
def self.make_ntlmssp_blob_chall(win_domain, win_name, dns_domain, dns_name, chall, flags)
|
193
|
+
|
194
|
+
addr_list = ''
|
195
|
+
addr_list << [2, win_domain.length].pack('vv') + win_domain
|
196
|
+
addr_list << [1, win_name.length].pack('vv') + win_name
|
197
|
+
addr_list << [4, dns_domain.length].pack('vv') + dns_domain
|
198
|
+
addr_list << [3, dns_name.length].pack('vv') + dns_name
|
199
|
+
addr_list << [0, 0].pack('vv')
|
200
|
+
|
201
|
+
ptr = 0
|
202
|
+
blob = "NTLMSSP\x00" +
|
203
|
+
[2].pack('V') +
|
204
|
+
[
|
205
|
+
win_domain.length, # length
|
206
|
+
win_domain.length, # max length
|
207
|
+
(ptr += 48) # offset
|
208
|
+
].pack('vvV') +
|
209
|
+
[ flags ].pack('V') +
|
210
|
+
chall +
|
211
|
+
"\x00\x00\x00\x00\x00\x00\x00\x00" +
|
212
|
+
[
|
213
|
+
addr_list.length, # length
|
214
|
+
addr_list.length, # max length
|
215
|
+
(ptr += win_domain.length)
|
216
|
+
].pack('vvV') +
|
217
|
+
win_domain +
|
218
|
+
addr_list
|
219
|
+
return blob
|
220
|
+
end
|
221
|
+
|
222
|
+
|
223
|
+
# GSS BLOB Usefull for ntlmssp type 3 message
|
224
|
+
def self.make_ntlmssp_secblob_auth(domain, name, user, lm, ntlm, enc_session_key, flags = 0x080201)
|
225
|
+
|
226
|
+
lm ||= "\x00" * 24
|
227
|
+
ntlm ||= "\x00" * 24
|
228
|
+
|
229
|
+
domain_uni = Rex::Text.to_unicode(domain)
|
230
|
+
user_uni = Rex::Text.to_unicode(user)
|
231
|
+
name_uni = Rex::Text.to_unicode(name)
|
232
|
+
session = enc_session_key
|
233
|
+
|
234
|
+
ptr = 64
|
235
|
+
blob =
|
236
|
+
"\xa1" + self.asn1encode(
|
237
|
+
"\x30" + self.asn1encode(
|
238
|
+
"\xa2" + self.asn1encode(
|
239
|
+
"\x04" + self.asn1encode(
|
240
|
+
|
241
|
+
"NTLMSSP\x00" +
|
242
|
+
[ 3 ].pack('V') +
|
243
|
+
|
244
|
+
[ # Lan Manager Response
|
245
|
+
lm.length,
|
246
|
+
lm.length,
|
247
|
+
(ptr)
|
248
|
+
].pack('vvV') +
|
249
|
+
|
250
|
+
[ # NTLM Manager Response
|
251
|
+
ntlm.length,
|
252
|
+
ntlm.length,
|
253
|
+
(ptr += lm.length)
|
254
|
+
].pack('vvV') +
|
255
|
+
|
256
|
+
[ # Domain Name
|
257
|
+
domain_uni.length,
|
258
|
+
domain_uni.length,
|
259
|
+
(ptr += ntlm.length)
|
260
|
+
].pack('vvV') +
|
261
|
+
|
262
|
+
[ # Username
|
263
|
+
user_uni.length,
|
264
|
+
user_uni.length,
|
265
|
+
(ptr += domain_uni.length)
|
266
|
+
].pack('vvV') +
|
267
|
+
|
268
|
+
[ # Hostname
|
269
|
+
name_uni.length,
|
270
|
+
name_uni.length,
|
271
|
+
(ptr += user_uni.length)
|
272
|
+
].pack('vvV') +
|
273
|
+
|
274
|
+
[ # Session Key (none)
|
275
|
+
session.length,
|
276
|
+
session.length,
|
277
|
+
(ptr += name_uni.length)
|
278
|
+
].pack('vvV') +
|
279
|
+
|
280
|
+
[ flags ].pack('V') +
|
281
|
+
|
282
|
+
lm +
|
283
|
+
ntlm +
|
284
|
+
domain_uni +
|
285
|
+
user_uni +
|
286
|
+
name_uni +
|
287
|
+
session + "\x00"
|
288
|
+
)
|
289
|
+
)
|
290
|
+
)
|
291
|
+
)
|
292
|
+
return blob
|
293
|
+
end
|
294
|
+
|
295
|
+
|
296
|
+
# GSS BLOB Usefull for SMB Success
|
297
|
+
def self.make_ntlmv2_secblob_success
|
298
|
+
blob =
|
299
|
+
"\xa1" + self.asn1encode(
|
300
|
+
"\x30" + self.asn1encode(
|
301
|
+
"\xa0" + self.asn1encode(
|
302
|
+
"\x0a" + self.asn1encode(
|
303
|
+
"\x00"
|
304
|
+
)
|
305
|
+
)
|
306
|
+
)
|
307
|
+
)
|
308
|
+
return blob
|
309
|
+
end
|
310
|
+
|
311
|
+
# This function return an ntlmv2 client challenge
|
312
|
+
def self.make_ntlmv2_clientchallenge(win_domain, win_name, dns_domain, dns_name, client_challenge = nil, chall_MsvAvTimestamp = nil)
|
313
|
+
|
314
|
+
client_challenge ||= Rex::Text.rand_text(8)
|
315
|
+
# We have to set the timestamps here to the one in the challenge message from server if present
|
316
|
+
# If we don't do that, recent server like seven will send a STATUS_INVALID_PARAMETER error packet
|
317
|
+
timestamp = chall_MsvAvTimestamp != nil ? chall_MsvAvTimestamp : self.time_unix_to_smb(Time.now.to_i).reverse.pack("VV")
|
318
|
+
# Make those values unicode as requested
|
319
|
+
win_domain = Rex::Text.to_unicode(win_domain)
|
320
|
+
win_name = Rex::Text.to_unicode(win_name)
|
321
|
+
dns_domain = Rex::Text.to_unicode(dns_domain)
|
322
|
+
dns_name = Rex::Text.to_unicode(dns_name)
|
323
|
+
# Make the AV_PAIRs
|
324
|
+
addr_list = ''
|
325
|
+
addr_list << [2, win_domain.length].pack('vv') + win_domain
|
326
|
+
addr_list << [1, win_name.length].pack('vv') + win_name
|
327
|
+
addr_list << [4, dns_domain.length].pack('vv') + dns_domain
|
328
|
+
addr_list << [3, dns_name.length].pack('vv') + dns_name
|
329
|
+
addr_list << [7, 8].pack('vv') + timestamp
|
330
|
+
|
331
|
+
# MAY BE USEFUL FOR FUTURE
|
332
|
+
# Seven (client) add at least one more av that is of type MsAvRestrictions (8)
|
333
|
+
# maybe this will be usefull with future windows OSs but has no use at all for the moment afaik
|
334
|
+
# restriction_encoding = [48,0,0,0].pack("VVV") + # Size, Z4, IntegrityLevel, SubjectIntegrityLevel
|
335
|
+
# Rex::Text.rand_text(32) # MachineId generated on startup on win7 and above
|
336
|
+
# addr_list << [8, restriction_encoding.length].pack('vv') + restriction_encoding
|
337
|
+
|
338
|
+
# Seven (client) and maybe others versions also add an av of type MsvChannelBindings (10) but the hash is "\x00" * 16
|
339
|
+
# addr_list << [10, 16].pack('vv') + "\x00" * 16
|
340
|
+
|
341
|
+
# Seven and maybe other versions also add an av of type MsvAvTargetName(9) with value cifs/target(_ip)
|
342
|
+
# implementing it will necessary require knowing the target here, todo... :-/
|
343
|
+
# spn= Rex::Text.to_unicode("cifs/RHOST")
|
344
|
+
# addr_list << [9, spn.length].pack('vv') + spn
|
345
|
+
|
346
|
+
addr_list << [0, 0].pack('vv')
|
347
|
+
ntlm_clientchallenge = [1,1,0,0].pack("CCvV") + #RespType, HiRespType, Reserved1, Reserved2
|
348
|
+
timestamp + #Timestamp
|
349
|
+
client_challenge + #clientchallenge
|
350
|
+
[0].pack("V") + #Reserved3
|
351
|
+
addr_list + "\x00" * 4
|
352
|
+
|
353
|
+
end
|
354
|
+
|
355
|
+
end
|
356
|
+
end
|
357
|
+
end
|
358
|
+
end
|
data/lib/rex/proto/smb/client.rb
CHANGED
@@ -8,8 +8,11 @@ require 'rex/struct2'
|
|
8
8
|
require 'rex/proto/smb/constants'
|
9
9
|
require 'rex/proto/smb/exceptions'
|
10
10
|
require 'rex/proto/smb/evasions'
|
11
|
-
require 'rex/proto/smb/crypt'
|
12
11
|
require 'rex/proto/smb/utils'
|
12
|
+
require 'rex/proto/smb/crypt'
|
13
|
+
require 'rex/proto/ntlm/crypt'
|
14
|
+
require 'rex/proto/ntlm/constants'
|
15
|
+
require 'rex/proto/ntlm/utils'
|
13
16
|
|
14
17
|
|
15
18
|
# Some short-hand class aliases
|
@@ -18,6 +21,9 @@ CRYPT = Rex::Proto::SMB::Crypt
|
|
18
21
|
UTILS = Rex::Proto::SMB::Utils
|
19
22
|
XCEPT = Rex::Proto::SMB::Exceptions
|
20
23
|
EVADE = Rex::Proto::SMB::Evasions
|
24
|
+
NTLM_CRYPT = Rex::Proto::NTLM::Crypt
|
25
|
+
NTLM_CONST = Rex::Proto::NTLM::Constants
|
26
|
+
NTLM_UTILS = Rex::Proto::NTLM::Utils
|
21
27
|
|
22
28
|
def initialize(socket)
|
23
29
|
self.socket = socket
|
@@ -30,15 +36,28 @@ EVADE = Rex::Proto::SMB::Evasions
|
|
30
36
|
self.read_timeout = 10
|
31
37
|
self.evasion_opts = {
|
32
38
|
|
33
|
-
|
34
|
-
|
39
|
+
# Padding is performed between packet headers and data
|
40
|
+
'pad_data' => EVADE::EVASION_NONE,
|
35
41
|
|
36
|
-
|
37
|
-
|
42
|
+
# File path padding is performed on all open/create calls
|
43
|
+
'pad_file' => EVADE::EVASION_NONE,
|
38
44
|
|
39
|
-
|
40
|
-
|
45
|
+
# Modify the \PIPE\ string in trans_named_pipe calls
|
46
|
+
'obscure_trans_pipe' => EVADE::EVASION_NONE,
|
41
47
|
}
|
48
|
+
|
49
|
+
self.verify_signature = false
|
50
|
+
self.use_ntlmv2 = false
|
51
|
+
self.usentlm2_session = true
|
52
|
+
self.send_lm = true
|
53
|
+
self.use_lanman_key = false
|
54
|
+
self.send_ntlm = true
|
55
|
+
|
56
|
+
# Signing
|
57
|
+
self.sequence_counter = 0
|
58
|
+
self.signing_key = ''
|
59
|
+
self.require_signing = false
|
60
|
+
|
42
61
|
end
|
43
62
|
|
44
63
|
# Read a SMB packet from the socket
|
@@ -73,7 +92,17 @@ EVADE = Rex::Proto::SMB::Evasions
|
|
73
92
|
data << buff
|
74
93
|
end
|
75
94
|
|
95
|
+
#signing
|
96
|
+
if self.require_signing && self.signing_key != ''
|
97
|
+
if self.verify_signature
|
98
|
+
raise XCEPT::IncorrectSigningError if not CRYPT::is_signature_correct?(self.signing_key,self.sequence_counter,data)
|
99
|
+
end
|
100
|
+
self.sequence_counter += 1
|
101
|
+
end
|
102
|
+
|
76
103
|
return data
|
104
|
+
|
105
|
+
|
77
106
|
end
|
78
107
|
|
79
108
|
# Send a SMB packet down the socket
|
@@ -85,6 +114,12 @@ EVADE = Rex::Proto::SMB::Evasions
|
|
85
114
|
size = 0
|
86
115
|
wait = 0
|
87
116
|
|
117
|
+
#signing
|
118
|
+
if self.require_signing && self.signing_key != ''
|
119
|
+
data = CRYPT::sign_smb_packet(self.signing_key, self.sequence_counter, data)
|
120
|
+
self.sequence_counter += 1
|
121
|
+
end
|
122
|
+
|
88
123
|
begin
|
89
124
|
# Just send the packet and return
|
90
125
|
if (size == 0 or size >= data.length)
|
@@ -121,7 +156,7 @@ EVADE = Rex::Proto::SMB::Evasions
|
|
121
156
|
pkt = CONST::SMB_BASE_PKT.make_struct
|
122
157
|
pkt.from_s(data)
|
123
158
|
res = pkt
|
124
|
-
|
159
|
+
|
125
160
|
begin
|
126
161
|
case pkt['Payload']['SMB'].v['Command']
|
127
162
|
|
@@ -219,14 +254,14 @@ EVADE = Rex::Proto::SMB::Evasions
|
|
219
254
|
|
220
255
|
# Process incoming SMB_COM_SESSION_SETUP_ANDX packets
|
221
256
|
def smb_parse_session_setup(pkt, data)
|
222
|
-
# Process
|
257
|
+
# Process NTLMSSP negotiate responses
|
223
258
|
if (pkt['Payload']['SMB'].v['WordCount'] == 4)
|
224
259
|
res = CONST::SMB_SETUP_NTLMV2_RES_PKT.make_struct
|
225
260
|
res.from_s(data)
|
226
261
|
return res
|
227
262
|
end
|
228
263
|
|
229
|
-
# Process
|
264
|
+
# Process LANMAN responses
|
230
265
|
if (pkt['Payload']['SMB'].v['WordCount'] == 3)
|
231
266
|
res = CONST::SMB_SETUP_RES_PKT.make_struct
|
232
267
|
res.from_s(data)
|
@@ -436,7 +471,7 @@ EVADE = Rex::Proto::SMB::Evasions
|
|
436
471
|
end
|
437
472
|
|
438
473
|
# Negotiate a SMB dialect
|
439
|
-
def negotiate(
|
474
|
+
def negotiate(smb_extended_security=true, do_recv = true)
|
440
475
|
|
441
476
|
dialects = ['LANMAN1.0', 'LM1.2X002' ]
|
442
477
|
|
@@ -452,7 +487,7 @@ EVADE = Rex::Proto::SMB::Evasions
|
|
452
487
|
pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_NEGOTIATE
|
453
488
|
pkt['Payload']['SMB'].v['Flags1'] = 0x18
|
454
489
|
|
455
|
-
if(
|
490
|
+
if(smb_extended_security)
|
456
491
|
pkt['Payload']['SMB'].v['Flags2'] = 0x2801
|
457
492
|
else
|
458
493
|
pkt['Payload']['SMB'].v['Flags2'] = 0xc001
|
@@ -460,7 +495,7 @@ EVADE = Rex::Proto::SMB::Evasions
|
|
460
495
|
|
461
496
|
pkt['Payload'].v['Payload'] = data
|
462
497
|
|
463
|
-
ret = self.smb_send(pkt.to_s)
|
498
|
+
ret = self.smb_send(pkt.to_s, EVADE::EVASION_NONE)
|
464
499
|
return ret if not do_recv
|
465
500
|
|
466
501
|
ack = self.smb_recv_parse(CONST::SMB_COM_NEGOTIATE)
|
@@ -483,6 +518,11 @@ EVADE = Rex::Proto::SMB::Evasions
|
|
483
518
|
# Set the security mode
|
484
519
|
self.security_mode = ack['Payload'].v['SecurityMode']
|
485
520
|
|
521
|
+
#set require_signing
|
522
|
+
if (ack['Payload'].v['SecurityMode'] & 0x08 != 0)
|
523
|
+
self.require_signing = true
|
524
|
+
end
|
525
|
+
|
486
526
|
# Set the challenge key
|
487
527
|
if (ack['Payload'].v['EncryptionKey'] != nil)
|
488
528
|
self.challenge_key = ack['Payload'].v['EncryptionKey']
|
@@ -530,15 +570,6 @@ EVADE = Rex::Proto::SMB::Evasions
|
|
530
570
|
end
|
531
571
|
self.system_zone = system_zone * 60
|
532
572
|
|
533
|
-
# XXX: this is being commented out because ruby prior to 1.9.2 doesn't
|
534
|
-
# seem to support representing non-utc or local times (eg, a time in
|
535
|
-
# another timezone) If you know a way to do it in pre-1.9.2 please
|
536
|
-
# tell us!
|
537
|
-
=begin
|
538
|
-
# Adjust the system_time object to reflect the remote timezone
|
539
|
-
self.system_time = self.system_time.utc.localtime(system_zone)
|
540
|
-
=end
|
541
|
-
|
542
573
|
return ack
|
543
574
|
end
|
544
575
|
|
@@ -547,15 +578,15 @@ EVADE = Rex::Proto::SMB::Evasions
|
|
547
578
|
def session_setup(*args)
|
548
579
|
|
549
580
|
if (self.dialect =~ /^(NT LANMAN 1.0|NT LM 0.12)$/)
|
550
|
-
|
551
|
-
|
581
|
+
|
552
582
|
if (self.challenge_key)
|
553
|
-
return self.
|
583
|
+
return self.session_setup_no_ntlmssp(*args)
|
554
584
|
end
|
555
585
|
|
556
586
|
if ( self.extended_security )
|
557
|
-
return self.
|
587
|
+
return self.session_setup_with_ntlmssp(*args)
|
558
588
|
end
|
589
|
+
|
559
590
|
end
|
560
591
|
|
561
592
|
return self.session_setup_clear(*args)
|
@@ -571,7 +602,14 @@ EVADE = Rex::Proto::SMB::Evasions
|
|
571
602
|
|
572
603
|
pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_SESSION_SETUP_ANDX
|
573
604
|
pkt['Payload']['SMB'].v['Flags1'] = 0x18
|
574
|
-
|
605
|
+
if self.require_signing
|
606
|
+
#ascii
|
607
|
+
pkt['Payload']['SMB'].v['Flags2'] = 0x2807
|
608
|
+
else
|
609
|
+
#ascii
|
610
|
+
pkt['Payload']['SMB'].v['Flags2'] = 0x2801
|
611
|
+
end
|
612
|
+
|
575
613
|
pkt['Payload']['SMB'].v['WordCount'] = 10
|
576
614
|
pkt['Payload'].v['AndX'] = 255
|
577
615
|
pkt['Payload'].v['MaxBuff'] = 0xffdf
|
@@ -601,17 +639,36 @@ EVADE = Rex::Proto::SMB::Evasions
|
|
601
639
|
return ack
|
602
640
|
end
|
603
641
|
|
604
|
-
# Authenticate
|
605
|
-
def
|
642
|
+
# Authenticate without NTLMSSP
|
643
|
+
def session_setup_no_ntlmssp(user = '', pass = '', domain = '', do_recv = true)
|
606
644
|
|
645
|
+
# Requires a challenge key to have been seen during negotiation
|
607
646
|
raise XCEPT::NTLM1MissingChallenge if not self.challenge_key
|
608
647
|
|
609
|
-
|
610
|
-
|
611
|
-
|
648
|
+
#
|
649
|
+
# We can not yet handle signing in this situation
|
650
|
+
# But instead of throwing an exception,we will disable signing, continue and hope for the best.
|
651
|
+
#
|
652
|
+
|
653
|
+
#raise XCEPT::SigningError if self.require_signing
|
654
|
+
self.require_signing = false if self.require_signing
|
655
|
+
|
656
|
+
|
657
|
+
if UTILS.is_pass_ntlm_hash?(pass)
|
658
|
+
arglm = {
|
659
|
+
:lm_hash => [ pass.upcase()[0,32] ].pack('H32'),
|
660
|
+
:challenge => self.challenge_key
|
661
|
+
}
|
662
|
+
hash_lm = NTLM_CRYPT::lm_response(arglm)
|
663
|
+
|
664
|
+
argntlm = {
|
665
|
+
:ntlm_hash => [ pass.upcase()[33,65] ].pack('H32'),
|
666
|
+
:challenge => self.challenge_key
|
667
|
+
}
|
668
|
+
hash_nt = NTLM_CRYPT::ntlm_response(argntlm)
|
612
669
|
else
|
613
|
-
hash_lm = pass.length > 0 ?
|
614
|
-
hash_nt = pass.length > 0 ?
|
670
|
+
hash_lm = pass.length > 0 ? NTLM_CRYPT.lanman_des(pass, self.challenge_key) : ''
|
671
|
+
hash_nt = pass.length > 0 ? NTLM_CRYPT.ntlm_md4(pass, self.challenge_key) : ''
|
615
672
|
end
|
616
673
|
|
617
674
|
data = ''
|
@@ -660,8 +717,10 @@ EVADE = Rex::Proto::SMB::Evasions
|
|
660
717
|
end
|
661
718
|
|
662
719
|
|
663
|
-
# Authenticate
|
664
|
-
def
|
720
|
+
# Authenticate without ntlmssp with a precomputed hash pair
|
721
|
+
def session_setup_no_ntlmssp_prehash(user, domain, hash_lm, hash_nt, do_recv = true)
|
722
|
+
|
723
|
+
raise XCEPT::NTLM2MissingChallenge if self.require_signing
|
665
724
|
|
666
725
|
data = ''
|
667
726
|
data << hash_lm
|
@@ -708,14 +767,40 @@ EVADE = Rex::Proto::SMB::Evasions
|
|
708
767
|
return ack
|
709
768
|
end
|
710
769
|
|
711
|
-
# Authenticate using extended security negotiation
|
712
|
-
def
|
770
|
+
# Authenticate using extended security negotiation
|
771
|
+
def session_setup_with_ntlmssp(user = '', pass = '', domain = '', name = nil, do_recv = true)
|
772
|
+
|
773
|
+
if require_signing
|
774
|
+
ntlmssp_flags = 0xe2088215
|
775
|
+
else
|
776
|
+
|
777
|
+
ntlmssp_flags = 0xa2080205
|
778
|
+
end
|
779
|
+
|
780
|
+
if self.usentlm2_session
|
781
|
+
if self.use_ntlmv2
|
782
|
+
#set Negotiate Target Info
|
783
|
+
ntlmssp_flags |= NTLM_CONST::NEGOTIATE_TARGET_INFO
|
784
|
+
end
|
785
|
+
|
786
|
+
else
|
787
|
+
#remove the ntlm2_session flag
|
788
|
+
ntlmssp_flags &= 0xfff7ffff
|
789
|
+
#set lanmanflag only when lm and ntlm are sent
|
790
|
+
if self.send_lm
|
791
|
+
ntlmssp_flags |= NTLM_CONST::NEGOTIATE_LMKEY if self.use_lanman_key
|
792
|
+
end
|
793
|
+
end
|
794
|
+
|
795
|
+
#we can also downgrade ntlm2_session when we send only lmv1
|
796
|
+
ntlmssp_flags &= 0xfff7ffff if self.usentlm2_session && (not self.use_ntlmv2) && (not self.send_ntlm)
|
797
|
+
|
713
798
|
|
714
799
|
if (name == nil)
|
715
800
|
name = Rex::Text.rand_text_alphanumeric(16)
|
716
801
|
end
|
717
802
|
|
718
|
-
blob =
|
803
|
+
blob = NTLM_UTILS.make_ntlmssp_secblob_init(domain, name, ntlmssp_flags)
|
719
804
|
|
720
805
|
native_data = ''
|
721
806
|
native_data << self.native_os + "\x00"
|
@@ -726,26 +811,33 @@ EVADE = Rex::Proto::SMB::Evasions
|
|
726
811
|
|
727
812
|
pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_SESSION_SETUP_ANDX
|
728
813
|
pkt['Payload']['SMB'].v['Flags1'] = 0x18
|
729
|
-
|
814
|
+
if require_signing
|
815
|
+
#ascii
|
816
|
+
pkt['Payload']['SMB'].v['Flags2'] = 0x2807
|
817
|
+
else
|
818
|
+
#ascii
|
819
|
+
pkt['Payload']['SMB'].v['Flags2'] = 0x2801
|
820
|
+
end
|
730
821
|
pkt['Payload']['SMB'].v['WordCount'] = 12
|
731
822
|
pkt['Payload'].v['AndX'] = 255
|
732
823
|
pkt['Payload'].v['MaxBuff'] = 0xffdf
|
733
824
|
pkt['Payload'].v['MaxMPX'] = 2
|
734
825
|
pkt['Payload'].v['VCNum'] = 1
|
735
826
|
pkt['Payload'].v['SecurityBlobLen'] = blob.length
|
736
|
-
pkt['Payload'].v['Capabilities'] =
|
827
|
+
pkt['Payload'].v['Capabilities'] = 0x800000d4
|
737
828
|
pkt['Payload'].v['SessionKey'] = self.session_id
|
738
829
|
pkt['Payload'].v['Payload'] = blob + native_data
|
739
830
|
|
740
831
|
ret = self.smb_send(pkt.to_s)
|
832
|
+
|
741
833
|
return ret if not do_recv
|
742
834
|
|
743
835
|
ack = self.smb_recv_parse(CONST::SMB_COM_SESSION_SETUP_ANDX, true)
|
744
836
|
|
745
837
|
|
746
|
-
# The server doesn't know about NTLM_NEGOTIATE
|
838
|
+
# The server doesn't know about NTLM_NEGOTIATE
|
747
839
|
if (ack['Payload']['SMB'].v['ErrorClass'] == 0x00020002)
|
748
|
-
return
|
840
|
+
return session_setup_no_ntlmssp(user, pass, domain)
|
749
841
|
end
|
750
842
|
|
751
843
|
# Make sure the error code tells us to continue processing
|
@@ -782,62 +874,326 @@ EVADE = Rex::Proto::SMB::Evasions
|
|
782
874
|
# Extract the address list from the blob
|
783
875
|
alist_len,alist_mlen,alist_off = blob[cidx + 40, 8].unpack("vvV")
|
784
876
|
alist_buf = blob[cidx + alist_off, alist_len]
|
785
|
-
|
877
|
+
chall_MsvAvTimestamp = nil
|
786
878
|
while(alist_buf.length > 0)
|
787
879
|
atype, alen = alist_buf.slice!(0,4).unpack('vv')
|
788
880
|
break if atype == 0x00
|
789
881
|
addr = alist_buf.slice!(0, alen)
|
790
882
|
case atype
|
791
883
|
when 1
|
884
|
+
#netbios name
|
792
885
|
self.default_name = addr.gsub("\x00", '')
|
793
886
|
when 2
|
887
|
+
#netbios domain
|
794
888
|
self.default_domain = addr.gsub("\x00", '')
|
795
889
|
when 3
|
890
|
+
#dns name
|
796
891
|
self.dns_host_name = addr.gsub("\x00", '')
|
797
892
|
when 4
|
893
|
+
#dns domain
|
798
894
|
self.dns_domain_name = addr.gsub("\x00", '')
|
799
895
|
when 5
|
800
|
-
#
|
896
|
+
#The FQDN of the forest.
|
897
|
+
when 6
|
898
|
+
#A 32-bit value indicating server or client configuration
|
801
899
|
when 7
|
802
|
-
#
|
900
|
+
#Client time
|
901
|
+
chall_MsvAvTimestamp = addr
|
902
|
+
when 8
|
903
|
+
#A Restriction_Encoding structure
|
904
|
+
when 9
|
905
|
+
#The SPN of the target server.
|
906
|
+
when 10
|
907
|
+
#A channel bindings hash.
|
803
908
|
end
|
804
909
|
end
|
910
|
+
|
911
|
+
#calculate the lm/ntlm response
|
912
|
+
resp_lm = "\x00" * 24
|
913
|
+
resp_ntlm = "\x00" * 24
|
805
914
|
|
806
|
-
|
807
|
-
# Generate a random client-side challenge
|
808
915
|
client_challenge = Rex::Text.rand_text(8)
|
916
|
+
ntlm_cli_challenge = ''
|
917
|
+
if self.send_ntlm #should be default
|
918
|
+
if self.usentlm2_session
|
919
|
+
|
920
|
+
if self.use_ntlmv2
|
921
|
+
# This is only a partial implementation, in some situation recent servers may send STATUS_INVALID_PARAMETER
|
922
|
+
# answer must then be somewhere in [MS-NLMP].pdf around 3.1.5.2.1 :-/
|
923
|
+
ntlm_cli_challenge = NTLM_UTILS::make_ntlmv2_clientchallenge(default_domain, default_name, dns_domain_name,
|
924
|
+
dns_host_name,client_challenge , chall_MsvAvTimestamp)
|
925
|
+
if UTILS.is_pass_ntlm_hash?(pass)
|
926
|
+
argntlm = {
|
927
|
+
:ntlmv2_hash => NTLM_CRYPT::ntlmv2_hash(
|
928
|
+
user,
|
929
|
+
[ pass.upcase()[33,65] ].pack('H32'),
|
930
|
+
domain,{:pass_is_hash => true}
|
931
|
+
),
|
932
|
+
:challenge => self.challenge_key
|
933
|
+
}
|
934
|
+
else
|
935
|
+
argntlm = {
|
936
|
+
:ntlmv2_hash => NTLM_CRYPT::ntlmv2_hash(user, pass, domain),
|
937
|
+
:challenge => self.challenge_key
|
938
|
+
}
|
939
|
+
end
|
940
|
+
|
941
|
+
optntlm = { :nt_client_challenge => ntlm_cli_challenge}
|
942
|
+
ntlmv2_response = NTLM_CRYPT::ntlmv2_response(argntlm,optntlm)
|
943
|
+
resp_ntlm = ntlmv2_response
|
944
|
+
|
945
|
+
if self.send_lm
|
946
|
+
if UTILS.is_pass_ntlm_hash?(pass)
|
947
|
+
arglm = {
|
948
|
+
:ntlmv2_hash => NTLM_CRYPT::ntlmv2_hash(
|
949
|
+
user,
|
950
|
+
[ pass.upcase()[33,65] ].pack('H32'),
|
951
|
+
domain,{:pass_is_hash => true}
|
952
|
+
),
|
953
|
+
:challenge => self.challenge_key
|
954
|
+
}
|
955
|
+
else
|
956
|
+
arglm = {
|
957
|
+
:ntlmv2_hash => NTLM_CRYPT::ntlmv2_hash(user,pass, domain),
|
958
|
+
:challenge => self.challenge_key
|
959
|
+
}
|
960
|
+
end
|
961
|
+
|
962
|
+
optlm = { :client_challenge => client_challenge }
|
963
|
+
resp_lm = NTLM_CRYPT::lmv2_response(arglm, optlm)
|
964
|
+
else
|
965
|
+
resp_lm = "\x00" * 24
|
966
|
+
end
|
967
|
+
|
968
|
+
else # ntlm2_session
|
969
|
+
if UTILS.is_pass_ntlm_hash?(pass)
|
970
|
+
argntlm = {
|
971
|
+
:ntlm_hash => [ pass.upcase()[33,65] ].pack('H32'),
|
972
|
+
:challenge => self.challenge_key
|
973
|
+
}
|
974
|
+
else
|
975
|
+
argntlm = {
|
976
|
+
:ntlm_hash => NTLM_CRYPT::ntlm_hash(pass),
|
977
|
+
:challenge => self.challenge_key
|
978
|
+
}
|
979
|
+
end
|
980
|
+
|
981
|
+
optntlm = { :client_challenge => client_challenge}
|
982
|
+
resp_ntlm = NTLM_CRYPT::ntlm2_session(argntlm,optntlm).join[24,24]
|
983
|
+
|
984
|
+
# Generate the fake LANMAN hash
|
985
|
+
resp_lm = client_challenge + ("\x00" * 16)
|
986
|
+
end
|
809
987
|
|
810
|
-
|
811
|
-
|
812
|
-
|
813
|
-
|
814
|
-
|
815
|
-
|
816
|
-
|
817
|
-
|
818
|
-
|
988
|
+
else # we use lmv1/ntlmv1
|
989
|
+
if UTILS.is_pass_ntlm_hash?(pass)
|
990
|
+
argntlm = {
|
991
|
+
:ntlm_hash => [ pass.upcase()[33,65] ].pack('H32'),
|
992
|
+
:challenge => self.challenge_key
|
993
|
+
}
|
994
|
+
else
|
995
|
+
argntlm = {
|
996
|
+
:ntlm_hash => NTLM_CRYPT::ntlm_hash(pass),
|
997
|
+
:challenge => self.challenge_key
|
998
|
+
}
|
999
|
+
end
|
1000
|
+
|
1001
|
+
resp_ntlm = NTLM_CRYPT::ntlm_response(argntlm)
|
1002
|
+
if self.send_lm
|
1003
|
+
if UTILS.is_pass_ntlm_hash?(pass)
|
1004
|
+
arglm = {
|
1005
|
+
:lm_hash => [ pass.upcase()[0,32] ].pack('H32'),
|
1006
|
+
:challenge => self.challenge_key
|
1007
|
+
}
|
1008
|
+
else
|
1009
|
+
arglm = {
|
1010
|
+
:lm_hash => NTLM_CRYPT::lm_hash(pass),
|
1011
|
+
:challenge => self.challenge_key
|
1012
|
+
}
|
1013
|
+
end
|
1014
|
+
resp_lm = NTLM_CRYPT::lm_response(arglm)
|
1015
|
+
else
|
1016
|
+
#when windows does not send lm in ntlmv1 type response,
|
1017
|
+
# it gives lm response the same value as ntlm response
|
1018
|
+
resp_lm = resp_ntlm
|
1019
|
+
end
|
1020
|
+
end
|
1021
|
+
else #send_ntlm = false
|
1022
|
+
#lmv2
|
1023
|
+
if self.usentlm2_session && self.use_ntlmv2
|
1024
|
+
if UTILS.is_pass_ntlm_hash?(pass)
|
1025
|
+
arglm = {
|
1026
|
+
:ntlmv2_hash => NTLM_CRYPT::ntlmv2_hash(
|
1027
|
+
user,
|
1028
|
+
[ pass.upcase()[33,65] ].pack('H32'),
|
1029
|
+
domain,{:pass_is_hash => true}
|
1030
|
+
),
|
1031
|
+
:challenge => self.challenge_key
|
1032
|
+
}
|
1033
|
+
else
|
1034
|
+
arglm = {
|
1035
|
+
:ntlmv2_hash => NTLM_CRYPT::ntlmv2_hash(user,pass, domain),
|
1036
|
+
:challenge => self.challenge_key
|
1037
|
+
}
|
1038
|
+
end
|
1039
|
+
optlm = { :client_challenge => client_challenge }
|
1040
|
+
resp_lm = NTLM_CRYPT::lmv2_response(arglm, optlm)
|
1041
|
+
else
|
1042
|
+
if UTILS.is_pass_ntlm_hash?(pass)
|
1043
|
+
arglm = {
|
1044
|
+
:lm_hash => [ pass.upcase()[0,32] ].pack('H32'),
|
1045
|
+
:challenge => self.challenge_key
|
1046
|
+
}
|
1047
|
+
else
|
1048
|
+
arglm = {
|
1049
|
+
:lm_hash => NTLM_CRYPT::lm_hash(pass),
|
1050
|
+
:challenge => self.challenge_key
|
1051
|
+
}
|
1052
|
+
end
|
1053
|
+
resp_lm = NTLM_CRYPT::lm_response(arglm)
|
1054
|
+
end
|
1055
|
+
resp_ntlm = ""
|
1056
|
+
end
|
1057
|
+
|
1058
|
+
|
1059
|
+
# Create the sessionkey (aka signing key, aka mackey) and encrypted session key
|
1060
|
+
# Server will decide for key_size and key_exchange
|
1061
|
+
enc_session_key = ''
|
1062
|
+
if self.require_signing
|
1063
|
+
|
1064
|
+
server_ntlmssp_flags = blob[cidx + 20, 4].unpack("V")[0]
|
1065
|
+
# Set default key size and key exchange values
|
1066
|
+
key_size = 40
|
1067
|
+
key_exchange = false
|
1068
|
+
# Remove ntlmssp.negotiate56
|
1069
|
+
ntlmssp_flags &= 0x7fffffff
|
1070
|
+
# Remove ntlmssp.negotiatekeyexch
|
1071
|
+
ntlmssp_flags &= 0xbfffffff
|
1072
|
+
# Remove ntlmssp.negotiate128
|
1073
|
+
ntlmssp_flags &= 0xdfffffff
|
1074
|
+
# Check the keyexchange
|
1075
|
+
if server_ntlmssp_flags & NTLM_CONST::NEGOTIATE_KEY_EXCH != 0 then
|
1076
|
+
key_exchange = true
|
1077
|
+
ntlmssp_flags |= NTLM_CONST::NEGOTIATE_KEY_EXCH
|
1078
|
+
end
|
1079
|
+
# Check 128bits
|
1080
|
+
if server_ntlmssp_flags & NTLM_CONST::NEGOTIATE_128 != 0 then
|
1081
|
+
key_size = 128
|
1082
|
+
ntlmssp_flags |= NTLM_CONST::NEGOTIATE_128
|
1083
|
+
ntlmssp_flags |= NTLM_CONST::NEGOTIATE_56
|
1084
|
+
# Check 56bits
|
1085
|
+
else
|
1086
|
+
if server_ntlmssp_flags & NTLM_CONST::NEGOTIATE_56 != 0 then
|
1087
|
+
key_size = 56
|
1088
|
+
ntlmssp_flags |= NTLM_CONST::NEGOTIATE_56
|
1089
|
+
end
|
1090
|
+
end
|
819
1091
|
|
820
|
-
|
821
|
-
|
1092
|
+
# Generate the user session key
|
1093
|
+
lanman_weak = false
|
1094
|
+
|
1095
|
+
if self.send_ntlm # Should be default
|
1096
|
+
if self.usentlm2_session
|
1097
|
+
if self.use_ntlmv2
|
1098
|
+
if UTILS.is_pass_ntlm_hash?(pass)
|
1099
|
+
user_session_key = NTLM_CRYPT::ntlmv2_user_session_key(user,
|
1100
|
+
[ pass.upcase()[33,65] ].pack('H32'),
|
1101
|
+
domain,
|
1102
|
+
self.challenge_key, ntlm_cli_challenge,
|
1103
|
+
{:pass_is_hash => true})
|
1104
|
+
else
|
1105
|
+
user_session_key = NTLM_CRYPT::ntlmv2_user_session_key(user, pass, domain,
|
1106
|
+
self.challenge_key, ntlm_cli_challenge)
|
1107
|
+
end
|
1108
|
+
else
|
1109
|
+
if UTILS.is_pass_ntlm_hash?(pass)
|
1110
|
+
user_session_key = NTLM_CRYPT::ntlm2_session_user_session_key([ pass.upcase()[33,65] ].pack('H32'),
|
1111
|
+
self.challenge_key,
|
1112
|
+
client_challenge,
|
1113
|
+
{:pass_is_hash => true})
|
1114
|
+
else
|
1115
|
+
user_session_key = NTLM_CRYPT::ntlm2_session_user_session_key(pass, self.challenge_key,
|
1116
|
+
client_challenge)
|
1117
|
+
end
|
1118
|
+
end
|
1119
|
+
else # lmv1/ntlmv1
|
1120
|
+
if self.send_lm
|
1121
|
+
if self.use_lanman_key
|
1122
|
+
if UTILS.is_pass_ntlm_hash?(pass)
|
1123
|
+
user_session_key = NTLM_CRYPT::lanman_session_key([ pass.upcase()[0,32] ].pack('H32'),
|
1124
|
+
self.challenge_key,
|
1125
|
+
{:pass_is_hash => true})
|
1126
|
+
else
|
1127
|
+
user_session_key = NTLM_CRYPT::lanman_session_key(pass, self.challenge_key)
|
1128
|
+
end
|
1129
|
+
lanman_weak = true
|
1130
|
+
else
|
1131
|
+
if UTILS.is_pass_ntlm_hash?(pass)
|
1132
|
+
user_session_key = NTLM_CRYPT::ntlmv1_user_session_key([ pass.upcase()[33,65] ].pack('H32'),
|
1133
|
+
{:pass_is_hash => true})
|
1134
|
+
else
|
1135
|
+
user_session_key = NTLM_CRYPT::ntlmv1_user_session_key(pass)
|
1136
|
+
end
|
1137
|
+
|
1138
|
+
end
|
1139
|
+
end
|
1140
|
+
end
|
1141
|
+
else
|
1142
|
+
if self.usentlm2_session && self.use_ntlmv2
|
1143
|
+
if UTILS.is_pass_ntlm_hash?(pass)
|
1144
|
+
user_session_key = NTLM_CRYPT::lmv2_user_session_key(user, [ pass.upcase()[33,65] ].pack('H32'),
|
1145
|
+
domain,
|
1146
|
+
self.challenge_key, client_challenge,
|
1147
|
+
{:pass_is_hash => true})
|
1148
|
+
else
|
1149
|
+
user_session_key = NTLM_CRYPT::lmv2_user_session_key(user, pass, domain,
|
1150
|
+
self.challenge_key, client_challenge)
|
1151
|
+
end
|
1152
|
+
else
|
1153
|
+
if UTILS.is_pass_ntlm_hash?(pass)
|
1154
|
+
user_session_key = NTLM_CRYPT::lmv1_user_session_key([ pass.upcase()[0,32] ].pack('H32'),
|
1155
|
+
{:pass_is_hash => true})
|
1156
|
+
else
|
1157
|
+
user_session_key = NTLM_CRYPT::lmv1_user_session_key(pass)
|
1158
|
+
end
|
1159
|
+
end
|
1160
|
+
end
|
822
1161
|
|
823
|
-
|
824
|
-
|
1162
|
+
user_session_key = NTLM_CRYPT::make_weak_sessionkey(user_session_key,key_size, lanman_weak)
|
1163
|
+
self.sequence_counter = 0
|
1164
|
+
# Sessionkey and encrypted session key
|
1165
|
+
if key_exchange
|
1166
|
+
self.signing_key = Rex::Text.rand_text(16)
|
1167
|
+
enc_session_key = NTLM_CRYPT::encrypt_sessionkey(self.signing_key, user_session_key)
|
1168
|
+
else
|
1169
|
+
self.signing_key = user_session_key
|
1170
|
+
end
|
1171
|
+
|
1172
|
+
end
|
1173
|
+
# Create the security blob data
|
1174
|
+
blob = NTLM_UTILS.make_ntlmssp_secblob_auth(domain, name, user, resp_lm, resp_ntlm, enc_session_key, ntlmssp_flags)
|
825
1175
|
|
826
1176
|
pkt = CONST::SMB_SETUP_NTLMV2_PKT.make_struct
|
827
1177
|
self.smb_defaults(pkt['Payload']['SMB'])
|
828
1178
|
|
829
1179
|
pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_SESSION_SETUP_ANDX
|
830
1180
|
pkt['Payload']['SMB'].v['Flags1'] = 0x18
|
831
|
-
|
1181
|
+
if self.require_signing
|
1182
|
+
#ascii
|
1183
|
+
pkt['Payload']['SMB'].v['Flags2'] = 0x2807
|
1184
|
+
else
|
1185
|
+
#ascii
|
1186
|
+
pkt['Payload']['SMB'].v['Flags2'] = 0x2801
|
1187
|
+
end
|
832
1188
|
pkt['Payload']['SMB'].v['WordCount'] = 12
|
833
1189
|
pkt['Payload']['SMB'].v['UserID'] = temp_user_id
|
834
1190
|
pkt['Payload'].v['AndX'] = 255
|
835
1191
|
pkt['Payload'].v['MaxBuff'] = 0xffdf
|
836
1192
|
pkt['Payload'].v['MaxMPX'] = 2
|
837
1193
|
pkt['Payload'].v['VCNum'] = 1
|
838
|
-
pkt['Payload'].v['SecurityBlobLen'] = blob.length
|
839
1194
|
pkt['Payload'].v['Capabilities'] = 0x8000d05c
|
840
1195
|
pkt['Payload'].v['SessionKey'] = self.session_id
|
1196
|
+
pkt['Payload'].v['SecurityBlobLen'] = blob.length
|
841
1197
|
pkt['Payload'].v['Payload'] = blob + native_data
|
842
1198
|
|
843
1199
|
# NOTE: if do_recv is set to false, we cant reach here...
|
@@ -847,8 +1203,13 @@ EVADE = Rex::Proto::SMB::Evasions
|
|
847
1203
|
|
848
1204
|
# Make sure that authentication succeeded
|
849
1205
|
if (ack['Payload']['SMB'].v['ErrorClass'] != 0)
|
1206
|
+
|
850
1207
|
if (user.length == 0)
|
851
|
-
|
1208
|
+
# Ensure that signing is disabled when we hit this corner case
|
1209
|
+
self.require_signing = false
|
1210
|
+
|
1211
|
+
# Fall back to the non-ntlmssp authentication method
|
1212
|
+
return self.session_setup_no_ntlmssp(user, pass, domain)
|
852
1213
|
end
|
853
1214
|
|
854
1215
|
failure = XCEPT::ErrorCode.new
|
@@ -869,7 +1230,7 @@ EVADE = Rex::Proto::SMB::Evasions
|
|
869
1230
|
|
870
1231
|
|
871
1232
|
# An exploit helper function for sending arbitrary SPNEGO blobs
|
872
|
-
def
|
1233
|
+
def session_setup_with_ntlmssp_blob(blob = '', do_recv = true)
|
873
1234
|
native_data = ''
|
874
1235
|
native_data << self.native_os + "\x00"
|
875
1236
|
native_data << self.native_lm + "\x00"
|
@@ -898,14 +1259,14 @@ EVADE = Rex::Proto::SMB::Evasions
|
|
898
1259
|
end
|
899
1260
|
|
900
1261
|
|
901
|
-
# Authenticate using extended security negotiation (
|
902
|
-
def
|
1262
|
+
# Authenticate using extended security negotiation (NTLMSSP), but stop half-way, using the temporary ID
|
1263
|
+
def session_setup_with_ntlmssp_temp(domain = '', name = nil, do_recv = true)
|
903
1264
|
|
904
1265
|
if (name == nil)
|
905
1266
|
name = Rex::Text.rand_text_alphanumeric(16)
|
906
1267
|
end
|
907
1268
|
|
908
|
-
blob =
|
1269
|
+
blob = NTLM_UTILS.make_ntlmssp_secblob_init(domain, name)
|
909
1270
|
|
910
1271
|
native_data = ''
|
911
1272
|
native_data << self.native_os + "\x00"
|
@@ -934,7 +1295,7 @@ EVADE = Rex::Proto::SMB::Evasions
|
|
934
1295
|
|
935
1296
|
# The server doesn't know about NTLM_NEGOTIATE, try ntlmv1
|
936
1297
|
if (ack['Payload']['SMB'].v['ErrorClass'] == 0x00020002)
|
937
|
-
return
|
1298
|
+
return session_setup_no_ntlmssp(user, pass, domain)
|
938
1299
|
end
|
939
1300
|
|
940
1301
|
# Make sure the error code tells us to continue processing
|
@@ -981,7 +1342,14 @@ EVADE = Rex::Proto::SMB::Evasions
|
|
981
1342
|
|
982
1343
|
pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_TREE_CONNECT_ANDX
|
983
1344
|
pkt['Payload']['SMB'].v['Flags1'] = 0x18
|
984
|
-
|
1345
|
+
if self.require_signing
|
1346
|
+
#ascii
|
1347
|
+
pkt['Payload']['SMB'].v['Flags2'] = 0x2807
|
1348
|
+
else
|
1349
|
+
#ascii
|
1350
|
+
pkt['Payload']['SMB'].v['Flags2'] = 0x2801
|
1351
|
+
end
|
1352
|
+
|
985
1353
|
pkt['Payload']['SMB'].v['WordCount'] = 4
|
986
1354
|
pkt['Payload'].v['AndX'] = 255
|
987
1355
|
pkt['Payload'].v['PasswordLen'] = pass.length + 1
|
@@ -1008,7 +1376,14 @@ EVADE = Rex::Proto::SMB::Evasions
|
|
1008
1376
|
|
1009
1377
|
pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_TREE_DISCONNECT
|
1010
1378
|
pkt['Payload']['SMB'].v['Flags1'] = 0x18
|
1011
|
-
|
1379
|
+
if self.require_signing
|
1380
|
+
#ascii
|
1381
|
+
pkt['Payload']['SMB'].v['Flags2'] = 0x2807
|
1382
|
+
else
|
1383
|
+
#ascii
|
1384
|
+
pkt['Payload']['SMB'].v['Flags2'] = 0x2801
|
1385
|
+
end
|
1386
|
+
|
1012
1387
|
pkt['Payload']['SMB'].v['WordCount'] = 0
|
1013
1388
|
pkt['Payload']['SMB'].v['TreeID'] = tree_id
|
1014
1389
|
|
@@ -1037,7 +1412,14 @@ EVADE = Rex::Proto::SMB::Evasions
|
|
1037
1412
|
|
1038
1413
|
pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_NT_CREATE_ANDX
|
1039
1414
|
pkt['Payload']['SMB'].v['Flags1'] = 0x18
|
1040
|
-
|
1415
|
+
if self.require_signing
|
1416
|
+
#ascii
|
1417
|
+
pkt['Payload']['SMB'].v['Flags2'] = 0x2807
|
1418
|
+
else
|
1419
|
+
#ascii
|
1420
|
+
pkt['Payload']['SMB'].v['Flags2'] = 0x2801
|
1421
|
+
end
|
1422
|
+
|
1041
1423
|
pkt['Payload']['SMB'].v['WordCount'] = 24
|
1042
1424
|
|
1043
1425
|
pkt['Payload'].v['AndX'] = 255
|
@@ -1071,7 +1453,14 @@ EVADE = Rex::Proto::SMB::Evasions
|
|
1071
1453
|
|
1072
1454
|
pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_DELETE
|
1073
1455
|
pkt['Payload']['SMB'].v['Flags1'] = 0x18
|
1074
|
-
|
1456
|
+
if self.require_signing
|
1457
|
+
#ascii
|
1458
|
+
pkt['Payload']['SMB'].v['Flags2'] = 0x2807
|
1459
|
+
else
|
1460
|
+
#ascii
|
1461
|
+
pkt['Payload']['SMB'].v['Flags2'] = 0x2801
|
1462
|
+
end
|
1463
|
+
|
1075
1464
|
pkt['Payload']['SMB'].v['TreeID'] = tree_id
|
1076
1465
|
pkt['Payload']['SMB'].v['WordCount'] = 1
|
1077
1466
|
|
@@ -1095,7 +1484,14 @@ EVADE = Rex::Proto::SMB::Evasions
|
|
1095
1484
|
|
1096
1485
|
pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_OPEN_ANDX
|
1097
1486
|
pkt['Payload']['SMB'].v['Flags1'] = 0x18
|
1098
|
-
|
1487
|
+
if self.require_signing
|
1488
|
+
#ascii
|
1489
|
+
pkt['Payload']['SMB'].v['Flags2'] = 0x2807
|
1490
|
+
else
|
1491
|
+
#ascii
|
1492
|
+
pkt['Payload']['SMB'].v['Flags2'] = 0x2801
|
1493
|
+
end
|
1494
|
+
|
1099
1495
|
pkt['Payload']['SMB'].v['WordCount'] = 15
|
1100
1496
|
|
1101
1497
|
pkt['Payload'].v['AndX'] = 255
|
@@ -1125,7 +1521,14 @@ EVADE = Rex::Proto::SMB::Evasions
|
|
1125
1521
|
|
1126
1522
|
pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_CLOSE
|
1127
1523
|
pkt['Payload']['SMB'].v['Flags1'] = 0x18
|
1128
|
-
|
1524
|
+
if self.require_signing
|
1525
|
+
#ascii
|
1526
|
+
pkt['Payload']['SMB'].v['Flags2'] = 0x2807
|
1527
|
+
else
|
1528
|
+
#ascii
|
1529
|
+
pkt['Payload']['SMB'].v['Flags2'] = 0x2801
|
1530
|
+
end
|
1531
|
+
|
1129
1532
|
pkt['Payload']['SMB'].v['TreeID'] = tree_id
|
1130
1533
|
pkt['Payload']['SMB'].v['WordCount'] = 3
|
1131
1534
|
|
@@ -1140,10 +1543,8 @@ EVADE = Rex::Proto::SMB::Evasions
|
|
1140
1543
|
return ack
|
1141
1544
|
end
|
1142
1545
|
|
1143
|
-
|
1144
1546
|
# Writes data to an open file handle
|
1145
1547
|
def write(file_id = self.last_file_id, offset = 0, data = '', do_recv = true)
|
1146
|
-
|
1147
1548
|
pkt = CONST::SMB_WRITE_PKT.make_struct
|
1148
1549
|
self.smb_defaults(pkt['Payload']['SMB'])
|
1149
1550
|
|
@@ -1153,7 +1554,14 @@ EVADE = Rex::Proto::SMB::Evasions
|
|
1153
1554
|
|
1154
1555
|
pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_WRITE_ANDX
|
1155
1556
|
pkt['Payload']['SMB'].v['Flags1'] = 0x18
|
1156
|
-
|
1557
|
+
if self.require_signing
|
1558
|
+
#ascii
|
1559
|
+
pkt['Payload']['SMB'].v['Flags2'] = 0x2805
|
1560
|
+
else
|
1561
|
+
#ascii
|
1562
|
+
pkt['Payload']['SMB'].v['Flags2'] = 0x2801
|
1563
|
+
end
|
1564
|
+
|
1157
1565
|
pkt['Payload']['SMB'].v['WordCount'] = 14
|
1158
1566
|
|
1159
1567
|
pkt['Payload'].v['AndX'] = 255
|
@@ -1184,7 +1592,14 @@ EVADE = Rex::Proto::SMB::Evasions
|
|
1184
1592
|
|
1185
1593
|
pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_READ_ANDX
|
1186
1594
|
pkt['Payload']['SMB'].v['Flags1'] = 0x18
|
1187
|
-
|
1595
|
+
if self.require_signing
|
1596
|
+
#ascii
|
1597
|
+
pkt['Payload']['SMB'].v['Flags2'] = 0x2807
|
1598
|
+
else
|
1599
|
+
#ascii
|
1600
|
+
pkt['Payload']['SMB'].v['Flags2'] = 0x2801
|
1601
|
+
end
|
1602
|
+
|
1188
1603
|
pkt['Payload']['SMB'].v['WordCount'] = 10
|
1189
1604
|
|
1190
1605
|
pkt['Payload'].v['AndX'] = 255
|
@@ -1272,7 +1687,14 @@ EVADE = Rex::Proto::SMB::Evasions
|
|
1272
1687
|
|
1273
1688
|
pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_TRANSACTION
|
1274
1689
|
pkt['Payload']['SMB'].v['Flags1'] = 0x18
|
1275
|
-
|
1690
|
+
if self.require_signing
|
1691
|
+
#ascii
|
1692
|
+
pkt['Payload']['SMB'].v['Flags2'] = 0x2807
|
1693
|
+
else
|
1694
|
+
#ascii
|
1695
|
+
pkt['Payload']['SMB'].v['Flags2'] = 0x2801
|
1696
|
+
end
|
1697
|
+
|
1276
1698
|
pkt['Payload']['SMB'].v['WordCount'] = 14 + setup_count
|
1277
1699
|
|
1278
1700
|
pkt['Payload'].v['ParamCountTotal'] = param.length
|
@@ -1343,7 +1765,14 @@ EVADE = Rex::Proto::SMB::Evasions
|
|
1343
1765
|
|
1344
1766
|
pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_TRANSACTION
|
1345
1767
|
pkt['Payload']['SMB'].v['Flags1'] = 0x18
|
1346
|
-
|
1768
|
+
if self.require_signing
|
1769
|
+
#ascii
|
1770
|
+
pkt['Payload']['SMB'].v['Flags2'] = 0x2807
|
1771
|
+
else
|
1772
|
+
#ascii
|
1773
|
+
pkt['Payload']['SMB'].v['Flags2'] = 0x2801
|
1774
|
+
end
|
1775
|
+
|
1347
1776
|
pkt['Payload']['SMB'].v['WordCount'] = 14 + setup_count
|
1348
1777
|
|
1349
1778
|
pkt['Payload'].v['ParamCountTotal'] = param.length
|
@@ -1406,7 +1835,14 @@ EVADE = Rex::Proto::SMB::Evasions
|
|
1406
1835
|
|
1407
1836
|
pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_TRANSACTION
|
1408
1837
|
pkt['Payload']['SMB'].v['Flags1'] = 0x18
|
1409
|
-
|
1838
|
+
if self.require_signing
|
1839
|
+
#ascii
|
1840
|
+
pkt['Payload']['SMB'].v['Flags2'] = 0x2807
|
1841
|
+
else
|
1842
|
+
#ascii
|
1843
|
+
pkt['Payload']['SMB'].v['Flags2'] = 0x2801
|
1844
|
+
end
|
1845
|
+
|
1410
1846
|
pkt['Payload']['SMB'].v['WordCount'] = 14 + setup_count
|
1411
1847
|
|
1412
1848
|
pkt['Payload'].v['ParamCountTotal'] = param.length
|
@@ -1449,7 +1885,14 @@ EVADE = Rex::Proto::SMB::Evasions
|
|
1449
1885
|
|
1450
1886
|
pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_TRANSACTION2
|
1451
1887
|
pkt['Payload']['SMB'].v['Flags1'] = 0x18
|
1452
|
-
|
1888
|
+
if self.require_signing
|
1889
|
+
#ascii
|
1890
|
+
pkt['Payload']['SMB'].v['Flags2'] = 0x2807
|
1891
|
+
else
|
1892
|
+
#ascii
|
1893
|
+
pkt['Payload']['SMB'].v['Flags2'] = 0x2801
|
1894
|
+
end
|
1895
|
+
|
1453
1896
|
pkt['Payload']['SMB'].v['WordCount'] = 14 + setup_count
|
1454
1897
|
|
1455
1898
|
pkt['Payload'].v['ParamCountTotal'] = param.length
|
@@ -1488,7 +1931,14 @@ EVADE = Rex::Proto::SMB::Evasions
|
|
1488
1931
|
|
1489
1932
|
pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_NT_TRANSACT
|
1490
1933
|
pkt['Payload']['SMB'].v['Flags1'] = 0x18
|
1491
|
-
|
1934
|
+
if self.require_signing
|
1935
|
+
#ascii
|
1936
|
+
pkt['Payload']['SMB'].v['Flags2'] = 0x2807
|
1937
|
+
else
|
1938
|
+
#ascii
|
1939
|
+
pkt['Payload']['SMB'].v['Flags2'] = 0x2801
|
1940
|
+
end
|
1941
|
+
|
1492
1942
|
pkt['Payload']['SMB'].v['WordCount'] = 19 + setup_count
|
1493
1943
|
|
1494
1944
|
pkt['Payload'].v['ParamCountTotal'] = param.length
|
@@ -1526,7 +1976,14 @@ EVADE = Rex::Proto::SMB::Evasions
|
|
1526
1976
|
|
1527
1977
|
pkt['Payload']['SMB'].v['Command'] = CONST::SMB_COM_NT_TRANSACT_SECONDARY
|
1528
1978
|
pkt['Payload']['SMB'].v['Flags1'] = 0x18
|
1529
|
-
|
1979
|
+
if self.require_signing
|
1980
|
+
#ascii
|
1981
|
+
pkt['Payload']['SMB'].v['Flags2'] = 0x2807
|
1982
|
+
else
|
1983
|
+
#ascii
|
1984
|
+
pkt['Payload']['SMB'].v['Flags2'] = 0x2801
|
1985
|
+
end
|
1986
|
+
|
1530
1987
|
pkt['Payload']['SMB'].v['WordCount'] = 18
|
1531
1988
|
|
1532
1989
|
pkt['Payload'].v['ParamCountTotal'] = param.length
|
@@ -1757,7 +2214,8 @@ EVADE = Rex::Proto::SMB::Evasions
|
|
1757
2214
|
|
1758
2215
|
# public read/write methods
|
1759
2216
|
attr_accessor :native_os, :native_lm, :encrypt_passwords, :extended_security, :read_timeout, :evasion_opts
|
1760
|
-
attr_accessor
|
2217
|
+
attr_accessor :verify_signature, :use_ntlmv2, :usentlm2_session, :send_lm, :use_lanman_key, :send_ntlm
|
2218
|
+
attr_accessor :system_time, :system_zone
|
1761
2219
|
|
1762
2220
|
# public read methods
|
1763
2221
|
attr_reader :dialect, :session_id, :challenge_key, :peer_native_lm, :peer_native_os
|
@@ -1765,6 +2223,8 @@ EVADE = Rex::Proto::SMB::Evasions
|
|
1765
2223
|
attr_reader :multiplex_id, :last_tree_id, :last_file_id, :process_id, :last_search_id
|
1766
2224
|
attr_reader :dns_host_name, :dns_domain_name
|
1767
2225
|
attr_reader :security_mode, :server_guid
|
2226
|
+
#signing related
|
2227
|
+
attr_reader :sequence_counter,:signing_key, :require_signing
|
1768
2228
|
|
1769
2229
|
# private methods
|
1770
2230
|
attr_writer :dialect, :session_id, :challenge_key, :peer_native_lm, :peer_native_os
|
@@ -1772,6 +2232,8 @@ EVADE = Rex::Proto::SMB::Evasions
|
|
1772
2232
|
attr_writer :dns_host_name, :dns_domain_name
|
1773
2233
|
attr_writer :multiplex_id, :last_tree_id, :last_file_id, :process_id, :last_search_id
|
1774
2234
|
attr_writer :security_mode, :server_guid
|
2235
|
+
#signing related
|
2236
|
+
attr_writer :sequence_counter,:signing_key, :require_signing
|
1775
2237
|
|
1776
2238
|
attr_accessor :socket
|
1777
2239
|
|