librex 0.0.6 → 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
|