rubyntlm 0.5.3 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +3 -3
- data/.rspec +2 -2
- data/.travis.yml +10 -11
- data/CHANGELOG.md +5 -5
- data/Gemfile +3 -3
- data/LICENSE +19 -19
- data/Rakefile +22 -22
- data/lib/net/ntlm.rb +266 -263
- data/lib/net/ntlm/blob.rb +28 -28
- data/lib/net/ntlm/channel_binding.rb +65 -0
- data/lib/net/ntlm/client.rb +65 -65
- data/lib/net/ntlm/client/session.rb +237 -223
- data/lib/net/ntlm/encode_util.rb +49 -49
- data/lib/net/ntlm/exceptions.rb +14 -0
- data/lib/net/ntlm/field.rb +34 -34
- data/lib/net/ntlm/field_set.rb +129 -129
- data/lib/net/ntlm/int16_le.rb +25 -25
- data/lib/net/ntlm/int32_le.rb +24 -24
- data/lib/net/ntlm/int64_le.rb +25 -25
- data/lib/net/ntlm/message.rb +129 -129
- data/lib/net/ntlm/message/type0.rb +16 -16
- data/lib/net/ntlm/message/type1.rb +18 -18
- data/lib/net/ntlm/message/type2.rb +102 -102
- data/lib/net/ntlm/message/type3.rb +131 -131
- data/lib/net/ntlm/security_buffer.rb +47 -47
- data/lib/net/ntlm/string.rb +34 -34
- data/lib/net/ntlm/target_info.rb +89 -0
- data/lib/net/ntlm/version.rb +11 -11
- data/rubyntlm.gemspec +28 -28
- data/spec/lib/net/ntlm/blob_spec.rb +16 -16
- data/spec/lib/net/ntlm/channel_binding_spec.rb +17 -0
- data/spec/lib/net/ntlm/client/session_spec.rb +68 -68
- data/spec/lib/net/ntlm/client_spec.rb +64 -64
- data/spec/lib/net/ntlm/encode_util_spec.rb +16 -16
- data/spec/lib/net/ntlm/field_set_spec.rb +33 -33
- data/spec/lib/net/ntlm/field_spec.rb +34 -34
- data/spec/lib/net/ntlm/int16_le_spec.rb +17 -17
- data/spec/lib/net/ntlm/int32_le_spec.rb +18 -18
- data/spec/lib/net/ntlm/int64_le_spec.rb +18 -18
- data/spec/lib/net/ntlm/message/type0_spec.rb +20 -20
- data/spec/lib/net/ntlm/message/type1_spec.rb +131 -131
- data/spec/lib/net/ntlm/message/type2_spec.rb +132 -132
- data/spec/lib/net/ntlm/message/type3_spec.rb +225 -225
- data/spec/lib/net/ntlm/message_spec.rb +16 -16
- data/spec/lib/net/ntlm/security_buffer_spec.rb +64 -64
- data/spec/lib/net/ntlm/string_spec.rb +72 -72
- data/spec/lib/net/ntlm/target_info_spec.rb +76 -0
- data/spec/lib/net/ntlm/version_spec.rb +27 -27
- data/spec/lib/net/ntlm_spec.rb +127 -127
- data/spec/spec_helper.rb +22 -22
- data/spec/support/certificates/sha_256_hash.pem +19 -0
- data/spec/support/shared/examples/net/ntlm/field_shared.rb +25 -25
- data/spec/support/shared/examples/net/ntlm/fieldset_shared.rb +239 -239
- data/spec/support/shared/examples/net/ntlm/int_shared.rb +43 -43
- data/spec/support/shared/examples/net/ntlm/message_shared.rb +35 -35
- metadata +12 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 96ed497ebb6619b61911e39777bf3d193909bc45
|
4
|
+
data.tar.gz: 4396365cd33577c1b52db0ae516d8c1353293877
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5959b911914ac4b71dc44296ee98345f874db4786da7630db08d016856bfa5555103e94310dd1bb0252211646c45ff87a3f94a9399be939e35ab0c8d32e067be
|
7
|
+
data.tar.gz: 1ab87702641e2e9946527ee504020fad142445ce6ac78206102b3fa378550a9c44ebb51795089f081e72b56329234dd772c8da7281f44badfe976d28dbc47c73
|
data/.gitignore
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
.yardoc
|
2
|
-
/doc
|
3
|
-
Gemfile.lock
|
1
|
+
.yardoc
|
2
|
+
/doc
|
3
|
+
Gemfile.lock
|
data/.rspec
CHANGED
@@ -1,2 +1,2 @@
|
|
1
|
-
--format documentation
|
2
|
-
--color
|
1
|
+
--format documentation
|
2
|
+
--color
|
data/.travis.yml
CHANGED
@@ -1,11 +1,10 @@
|
|
1
|
-
language: ruby
|
2
|
-
rvm:
|
3
|
-
- 1.9.3
|
4
|
-
- 1.9.2
|
5
|
-
-
|
6
|
-
-
|
7
|
-
- rbx-
|
8
|
-
-
|
9
|
-
|
10
|
-
|
11
|
-
- gem update bundler
|
1
|
+
language: ruby
|
2
|
+
rvm:
|
3
|
+
- 1.9.3
|
4
|
+
- 1.9.2
|
5
|
+
- 2.0.0
|
6
|
+
- rbx-19mode
|
7
|
+
- rbx-18mode
|
8
|
+
- jruby-19mode
|
9
|
+
before_install:
|
10
|
+
- gem update bundler
|
data/CHANGELOG.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
0.2.0 - Major changes to behavior!!!!
|
2
|
-
- Bug - Type 1 packets do not include a domain and workstation by defauly. Packet capture software will see this type of packet as malformed. All packets now include this information
|
3
|
-
- Bug - Type 3 packets do not include the calling workstation. This should be setup by default.
|
4
|
-
|
5
|
-
0.1.2
|
1
|
+
0.2.0 - Major changes to behavior!!!!
|
2
|
+
- Bug - Type 1 packets do not include a domain and workstation by defauly. Packet capture software will see this type of packet as malformed. All packets now include this information
|
3
|
+
- Bug - Type 3 packets do not include the calling workstation. This should be setup by default.
|
4
|
+
|
5
|
+
0.1.2
|
6
6
|
- Feature user can specify the target domain
|
data/Gemfile
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
source 'https://rubygems.org'
|
2
|
-
|
3
|
-
gemspec
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
|
3
|
+
gemspec
|
data/LICENSE
CHANGED
@@ -1,20 +1,20 @@
|
|
1
|
-
The MIT License (MIT)
|
2
|
-
|
3
|
-
Copyright (c) 2013 Paul Morton, Matt Zukowski, Kohei Kajimoto
|
4
|
-
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
6
|
-
this software and associated documentation files (the "Software"), to deal in
|
7
|
-
the Software without restriction, including without limitation the rights to
|
8
|
-
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
9
|
-
the Software, and to permit persons to whom the Software is furnished to do so,
|
10
|
-
subject to the following conditions:
|
11
|
-
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
13
|
-
copies or substantial portions of the Software.
|
14
|
-
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
17
|
-
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
18
|
-
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
19
|
-
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
1
|
+
The MIT License (MIT)
|
2
|
+
|
3
|
+
Copyright (c) 2013 Paul Morton, Matt Zukowski, Kohei Kajimoto
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of
|
6
|
+
this software and associated documentation files (the "Software"), to deal in
|
7
|
+
the Software without restriction, including without limitation the rights to
|
8
|
+
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
|
9
|
+
the Software, and to permit persons to whom the Software is furnished to do so,
|
10
|
+
subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
|
17
|
+
FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
|
18
|
+
COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
19
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
20
20
|
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
CHANGED
@@ -1,22 +1,22 @@
|
|
1
|
-
require "bundler/gem_tasks"
|
2
|
-
|
3
|
-
|
4
|
-
require 'rspec/core/rake_task'
|
5
|
-
RSpec::Core::RakeTask.new(:spec)
|
6
|
-
|
7
|
-
task :default => :spec
|
8
|
-
|
9
|
-
desc "Generate code coverage"
|
10
|
-
task :coverage do
|
11
|
-
ENV['COVERAGE'] = 'true'
|
12
|
-
Rake::Task["spec"].execute
|
13
|
-
end
|
14
|
-
|
15
|
-
desc "Open a Pry console for this library"
|
16
|
-
task :console do
|
17
|
-
require 'pry'
|
18
|
-
require 'net/ntlm'
|
19
|
-
ARGV.clear
|
20
|
-
Pry.start
|
21
|
-
end
|
22
|
-
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
|
3
|
+
|
4
|
+
require 'rspec/core/rake_task'
|
5
|
+
RSpec::Core::RakeTask.new(:spec)
|
6
|
+
|
7
|
+
task :default => :spec
|
8
|
+
|
9
|
+
desc "Generate code coverage"
|
10
|
+
task :coverage do
|
11
|
+
ENV['COVERAGE'] = 'true'
|
12
|
+
Rake::Task["spec"].execute
|
13
|
+
end
|
14
|
+
|
15
|
+
desc "Open a Pry console for this library"
|
16
|
+
task :console do
|
17
|
+
require 'pry'
|
18
|
+
require 'net/ntlm'
|
19
|
+
ARGV.clear
|
20
|
+
Pry.start
|
21
|
+
end
|
22
|
+
|
data/lib/net/ntlm.rb
CHANGED
@@ -1,263 +1,266 @@
|
|
1
|
-
# encoding: UTF-8
|
2
|
-
#
|
3
|
-
# = net/ntlm.rb
|
4
|
-
#
|
5
|
-
# An NTLM Authentication Library for Ruby
|
6
|
-
#
|
7
|
-
# This code is a derivative of "dbf2.rb" written by yrock
|
8
|
-
# and Minero Aoki. You can find original code here:
|
9
|
-
# http://jp.rubyist.net/magazine/?0013-CodeReview
|
10
|
-
# -------------------------------------------------------------
|
11
|
-
# Copyright (c) 2005,2006 yrock
|
12
|
-
#
|
13
|
-
#
|
14
|
-
# 2006-02-11 refactored by Minero Aoki
|
15
|
-
# -------------------------------------------------------------
|
16
|
-
#
|
17
|
-
# All protocol information used to write this code stems from
|
18
|
-
# "The NTLM Authentication Protocol" by Eric Glass. The author
|
19
|
-
# would thank to him for this tremendous work and making it
|
20
|
-
# available on the net.
|
21
|
-
# http://davenport.sourceforge.net/ntlm.html
|
22
|
-
# -------------------------------------------------------------
|
23
|
-
# Copyright (c) 2003 Eric Glass
|
24
|
-
#
|
25
|
-
# -------------------------------------------------------------
|
26
|
-
#
|
27
|
-
# The author also looked Mozilla-Firefox-1.0.7 source code,
|
28
|
-
# namely, security/manager/ssl/src/nsNTLMAuthModule.cpp and
|
29
|
-
# Jonathan Bastien-Filiatrault's libntlm-ruby.
|
30
|
-
# "http://x2a.org/websvn/filedetails.php?
|
31
|
-
# repname=libntlm-ruby&path=%2Ftrunk%2Fntlm.rb&sc=1"
|
32
|
-
# The latter has a minor bug in its separate_keys function.
|
33
|
-
# The third key has to begin from the 14th character of the
|
34
|
-
# input string instead of 13th:)
|
35
|
-
#--
|
36
|
-
# $Id: ntlm.rb,v 1.1 2006/10/05 01:36:52 koheik Exp $
|
37
|
-
#++
|
38
|
-
|
39
|
-
require 'base64'
|
40
|
-
require 'openssl'
|
41
|
-
require 'openssl/digest'
|
42
|
-
require 'socket'
|
43
|
-
|
44
|
-
# Load Order is important here
|
45
|
-
require 'net/ntlm/
|
46
|
-
require 'net/ntlm/
|
47
|
-
require 'net/ntlm/
|
48
|
-
require 'net/ntlm/
|
49
|
-
require 'net/ntlm/
|
50
|
-
|
51
|
-
|
52
|
-
require 'net/ntlm/
|
53
|
-
require 'net/ntlm/
|
54
|
-
require 'net/ntlm/
|
55
|
-
require 'net/ntlm/message
|
56
|
-
require 'net/ntlm/message/
|
57
|
-
require 'net/ntlm/message/
|
58
|
-
require 'net/ntlm/message/
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
#
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
151
|
-
|
152
|
-
#
|
153
|
-
# @
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
blob
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
|
221
|
-
|
222
|
-
|
223
|
-
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
231
|
-
|
232
|
-
|
233
|
-
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
|
240
|
-
|
241
|
-
|
242
|
-
|
243
|
-
|
244
|
-
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
|
262
|
-
|
263
|
-
end
|
1
|
+
# encoding: UTF-8
|
2
|
+
#
|
3
|
+
# = net/ntlm.rb
|
4
|
+
#
|
5
|
+
# An NTLM Authentication Library for Ruby
|
6
|
+
#
|
7
|
+
# This code is a derivative of "dbf2.rb" written by yrock
|
8
|
+
# and Minero Aoki. You can find original code here:
|
9
|
+
# http://jp.rubyist.net/magazine/?0013-CodeReview
|
10
|
+
# -------------------------------------------------------------
|
11
|
+
# Copyright (c) 2005,2006 yrock
|
12
|
+
#
|
13
|
+
#
|
14
|
+
# 2006-02-11 refactored by Minero Aoki
|
15
|
+
# -------------------------------------------------------------
|
16
|
+
#
|
17
|
+
# All protocol information used to write this code stems from
|
18
|
+
# "The NTLM Authentication Protocol" by Eric Glass. The author
|
19
|
+
# would thank to him for this tremendous work and making it
|
20
|
+
# available on the net.
|
21
|
+
# http://davenport.sourceforge.net/ntlm.html
|
22
|
+
# -------------------------------------------------------------
|
23
|
+
# Copyright (c) 2003 Eric Glass
|
24
|
+
#
|
25
|
+
# -------------------------------------------------------------
|
26
|
+
#
|
27
|
+
# The author also looked Mozilla-Firefox-1.0.7 source code,
|
28
|
+
# namely, security/manager/ssl/src/nsNTLMAuthModule.cpp and
|
29
|
+
# Jonathan Bastien-Filiatrault's libntlm-ruby.
|
30
|
+
# "http://x2a.org/websvn/filedetails.php?
|
31
|
+
# repname=libntlm-ruby&path=%2Ftrunk%2Fntlm.rb&sc=1"
|
32
|
+
# The latter has a minor bug in its separate_keys function.
|
33
|
+
# The third key has to begin from the 14th character of the
|
34
|
+
# input string instead of 13th:)
|
35
|
+
#--
|
36
|
+
# $Id: ntlm.rb,v 1.1 2006/10/05 01:36:52 koheik Exp $
|
37
|
+
#++
|
38
|
+
|
39
|
+
require 'base64'
|
40
|
+
require 'openssl'
|
41
|
+
require 'openssl/digest'
|
42
|
+
require 'socket'
|
43
|
+
|
44
|
+
# Load Order is important here
|
45
|
+
require 'net/ntlm/exceptions'
|
46
|
+
require 'net/ntlm/field'
|
47
|
+
require 'net/ntlm/int16_le'
|
48
|
+
require 'net/ntlm/int32_le'
|
49
|
+
require 'net/ntlm/int64_le'
|
50
|
+
require 'net/ntlm/string'
|
51
|
+
|
52
|
+
require 'net/ntlm/field_set'
|
53
|
+
require 'net/ntlm/blob'
|
54
|
+
require 'net/ntlm/security_buffer'
|
55
|
+
require 'net/ntlm/message'
|
56
|
+
require 'net/ntlm/message/type0'
|
57
|
+
require 'net/ntlm/message/type1'
|
58
|
+
require 'net/ntlm/message/type2'
|
59
|
+
require 'net/ntlm/message/type3'
|
60
|
+
|
61
|
+
require 'net/ntlm/encode_util'
|
62
|
+
|
63
|
+
require 'net/ntlm/client'
|
64
|
+
require 'net/ntlm/channel_binding'
|
65
|
+
require 'net/ntlm/target_info'
|
66
|
+
|
67
|
+
module Net
|
68
|
+
module NTLM
|
69
|
+
|
70
|
+
LM_MAGIC = "KGS!@\#$%"
|
71
|
+
TIME_OFFSET = 11644473600
|
72
|
+
MAX64 = 0xffffffffffffffff
|
73
|
+
|
74
|
+
|
75
|
+
class << self
|
76
|
+
|
77
|
+
# Valid format for LAN Manager hex digest portion: 32 hexadecimal characters.
|
78
|
+
LAN_MANAGER_HEX_DIGEST_REGEXP = /[0-9a-f]{32}/i
|
79
|
+
# Valid format for NT LAN Manager hex digest portion: 32 hexadecimal characters.
|
80
|
+
NT_LAN_MANAGER_HEX_DIGEST_REGEXP = /[0-9a-f]{32}/i
|
81
|
+
# Valid format for an NTLM hash composed of `'<LAN Manager hex digest>:<NT LAN Manager hex digest>'`.
|
82
|
+
DATA_REGEXP = /\A#{LAN_MANAGER_HEX_DIGEST_REGEXP}:#{NT_LAN_MANAGER_HEX_DIGEST_REGEXP}\z/
|
83
|
+
|
84
|
+
# Takes a string and determines whether it is a valid NTLM Hash
|
85
|
+
# @param [String] the string to validate
|
86
|
+
# @return [Boolean] whether or not the string is a valid NTLM hash
|
87
|
+
def is_ntlm_hash?(data)
|
88
|
+
decoded_data = data.dup
|
89
|
+
decoded_data = EncodeUtil.decode_utf16le(decoded_data)
|
90
|
+
if DATA_REGEXP.match(decoded_data)
|
91
|
+
true
|
92
|
+
else
|
93
|
+
false
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
# Conver the value to a 64-Bit Little Endian Int
|
98
|
+
# @param [String] val The string to convert
|
99
|
+
def pack_int64le(val)
|
100
|
+
[val & 0x00000000ffffffff, val >> 32].pack("V2")
|
101
|
+
end
|
102
|
+
|
103
|
+
# Builds an array of strings that are 7 characters long
|
104
|
+
# @param [String] str The string to split
|
105
|
+
# @api private
|
106
|
+
def split7(str)
|
107
|
+
s = str.dup
|
108
|
+
until s.empty?
|
109
|
+
(ret ||= []).push s.slice!(0, 7)
|
110
|
+
end
|
111
|
+
ret
|
112
|
+
end
|
113
|
+
|
114
|
+
# Not sure what this is doing
|
115
|
+
# @param [String] str String to generate keys for
|
116
|
+
# @api private
|
117
|
+
def gen_keys(str)
|
118
|
+
split7(str).map{ |str7|
|
119
|
+
bits = split7(str7.unpack("B*")[0]).inject('')\
|
120
|
+
{|ret, tkn| ret += tkn + (tkn.gsub('1', '').size % 2).to_s }
|
121
|
+
[bits].pack("B*")
|
122
|
+
}
|
123
|
+
end
|
124
|
+
|
125
|
+
def apply_des(plain, keys)
|
126
|
+
dec = OpenSSL::Cipher::Cipher.new("des-cbc")
|
127
|
+
dec.padding = 0
|
128
|
+
keys.map {|k|
|
129
|
+
dec.key = k
|
130
|
+
dec.encrypt.update(plain) + dec.final
|
131
|
+
}
|
132
|
+
end
|
133
|
+
|
134
|
+
# Generates a Lan Manager Hash
|
135
|
+
# @param [String] password The password to base the hash on
|
136
|
+
def lm_hash(password)
|
137
|
+
keys = gen_keys password.upcase.ljust(14, "\0")
|
138
|
+
apply_des(LM_MAGIC, keys).join
|
139
|
+
end
|
140
|
+
|
141
|
+
# Generate a NTLM Hash
|
142
|
+
# @param [String] password The password to base the hash on
|
143
|
+
# @option opt :unicode (false) Unicode encode the password
|
144
|
+
def ntlm_hash(password, opt = {})
|
145
|
+
pwd = password.dup
|
146
|
+
unless opt[:unicode]
|
147
|
+
pwd = EncodeUtil.encode_utf16le(pwd)
|
148
|
+
end
|
149
|
+
OpenSSL::Digest::MD4.digest pwd
|
150
|
+
end
|
151
|
+
|
152
|
+
# Generate a NTLMv2 Hash
|
153
|
+
# @param [String] user The username
|
154
|
+
# @param [String] password The password
|
155
|
+
# @param [String] target The domain or workstation to authenticate to
|
156
|
+
# @option opt :unicode (false) Unicode encode the domain
|
157
|
+
def ntlmv2_hash(user, password, target, opt={})
|
158
|
+
if is_ntlm_hash? password
|
159
|
+
decoded_password = EncodeUtil.decode_utf16le(password)
|
160
|
+
ntlmhash = [decoded_password.upcase[33,65]].pack('H32')
|
161
|
+
else
|
162
|
+
ntlmhash = ntlm_hash(password, opt)
|
163
|
+
end
|
164
|
+
userdomain = user.upcase + target
|
165
|
+
unless opt[:unicode]
|
166
|
+
userdomain = EncodeUtil.encode_utf16le(userdomain)
|
167
|
+
end
|
168
|
+
OpenSSL::HMAC.digest(OpenSSL::Digest::MD5.new, ntlmhash, userdomain)
|
169
|
+
end
|
170
|
+
|
171
|
+
def lm_response(arg)
|
172
|
+
begin
|
173
|
+
hash = arg[:lm_hash]
|
174
|
+
chal = arg[:challenge]
|
175
|
+
rescue
|
176
|
+
raise ArgumentError
|
177
|
+
end
|
178
|
+
chal = NTLM::pack_int64le(chal) if chal.is_a?(Integer)
|
179
|
+
keys = gen_keys hash.ljust(21, "\0")
|
180
|
+
apply_des(chal, keys).join
|
181
|
+
end
|
182
|
+
|
183
|
+
def ntlm_response(arg)
|
184
|
+
hash = arg[:ntlm_hash]
|
185
|
+
chal = arg[:challenge]
|
186
|
+
chal = NTLM::pack_int64le(chal) if chal.is_a?(Integer)
|
187
|
+
keys = gen_keys hash.ljust(21, "\0")
|
188
|
+
apply_des(chal, keys).join
|
189
|
+
end
|
190
|
+
|
191
|
+
def ntlmv2_response(arg, opt = {})
|
192
|
+
begin
|
193
|
+
key = arg[:ntlmv2_hash]
|
194
|
+
chal = arg[:challenge]
|
195
|
+
ti = arg[:target_info]
|
196
|
+
rescue
|
197
|
+
raise ArgumentError
|
198
|
+
end
|
199
|
+
chal = NTLM::pack_int64le(chal) if chal.is_a?(Integer)
|
200
|
+
|
201
|
+
if opt[:client_challenge]
|
202
|
+
cc = opt[:client_challenge]
|
203
|
+
else
|
204
|
+
cc = rand(MAX64)
|
205
|
+
end
|
206
|
+
cc = NTLM::pack_int64le(cc) if cc.is_a?(Integer)
|
207
|
+
|
208
|
+
if opt[:timestamp]
|
209
|
+
ts = opt[:timestamp]
|
210
|
+
else
|
211
|
+
ts = Time.now.to_i
|
212
|
+
end
|
213
|
+
# epoch -> milsec from Jan 1, 1601
|
214
|
+
ts = 10_000_000 * (ts + TIME_OFFSET)
|
215
|
+
|
216
|
+
blob = Blob.new
|
217
|
+
blob.timestamp = ts
|
218
|
+
blob.challenge = cc
|
219
|
+
blob.target_info = ti
|
220
|
+
|
221
|
+
bb = blob.serialize
|
222
|
+
|
223
|
+
OpenSSL::HMAC.digest(OpenSSL::Digest::MD5.new, key, chal + bb) + bb
|
224
|
+
end
|
225
|
+
|
226
|
+
def lmv2_response(arg, opt = {})
|
227
|
+
key = arg[:ntlmv2_hash]
|
228
|
+
chal = arg[:challenge]
|
229
|
+
|
230
|
+
chal = NTLM::pack_int64le(chal) if chal.is_a?(Integer)
|
231
|
+
|
232
|
+
if opt[:client_challenge]
|
233
|
+
cc = opt[:client_challenge]
|
234
|
+
else
|
235
|
+
cc = rand(MAX64)
|
236
|
+
end
|
237
|
+
cc = NTLM::pack_int64le(cc) if cc.is_a?(Integer)
|
238
|
+
|
239
|
+
OpenSSL::HMAC.digest(OpenSSL::Digest::MD5.new, key, chal + cc) + cc
|
240
|
+
end
|
241
|
+
|
242
|
+
def ntlm2_session(arg, opt = {})
|
243
|
+
begin
|
244
|
+
passwd_hash = arg[:ntlm_hash]
|
245
|
+
chal = arg[:challenge]
|
246
|
+
rescue
|
247
|
+
raise ArgumentError
|
248
|
+
end
|
249
|
+
chal = NTLM::pack_int64le(chal) if chal.is_a?(Integer)
|
250
|
+
|
251
|
+
if opt[:client_challenge]
|
252
|
+
cc = opt[:client_challenge]
|
253
|
+
else
|
254
|
+
cc = rand(MAX64)
|
255
|
+
end
|
256
|
+
cc = NTLM::pack_int64le(cc) if cc.is_a?(Integer)
|
257
|
+
|
258
|
+
keys = gen_keys(passwd_hash.ljust(21, "\0"))
|
259
|
+
session_hash = OpenSSL::Digest::MD5.digest(chal + cc).slice(0, 8)
|
260
|
+
response = apply_des(session_hash, keys).join
|
261
|
+
[cc.ljust(24, "\0"), response]
|
262
|
+
end
|
263
|
+
end
|
264
|
+
|
265
|
+
end
|
266
|
+
end
|