rubyntlm 0.5.3 → 0.6.0

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.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -3
  3. data/.rspec +2 -2
  4. data/.travis.yml +10 -11
  5. data/CHANGELOG.md +5 -5
  6. data/Gemfile +3 -3
  7. data/LICENSE +19 -19
  8. data/Rakefile +22 -22
  9. data/lib/net/ntlm.rb +266 -263
  10. data/lib/net/ntlm/blob.rb +28 -28
  11. data/lib/net/ntlm/channel_binding.rb +65 -0
  12. data/lib/net/ntlm/client.rb +65 -65
  13. data/lib/net/ntlm/client/session.rb +237 -223
  14. data/lib/net/ntlm/encode_util.rb +49 -49
  15. data/lib/net/ntlm/exceptions.rb +14 -0
  16. data/lib/net/ntlm/field.rb +34 -34
  17. data/lib/net/ntlm/field_set.rb +129 -129
  18. data/lib/net/ntlm/int16_le.rb +25 -25
  19. data/lib/net/ntlm/int32_le.rb +24 -24
  20. data/lib/net/ntlm/int64_le.rb +25 -25
  21. data/lib/net/ntlm/message.rb +129 -129
  22. data/lib/net/ntlm/message/type0.rb +16 -16
  23. data/lib/net/ntlm/message/type1.rb +18 -18
  24. data/lib/net/ntlm/message/type2.rb +102 -102
  25. data/lib/net/ntlm/message/type3.rb +131 -131
  26. data/lib/net/ntlm/security_buffer.rb +47 -47
  27. data/lib/net/ntlm/string.rb +34 -34
  28. data/lib/net/ntlm/target_info.rb +89 -0
  29. data/lib/net/ntlm/version.rb +11 -11
  30. data/rubyntlm.gemspec +28 -28
  31. data/spec/lib/net/ntlm/blob_spec.rb +16 -16
  32. data/spec/lib/net/ntlm/channel_binding_spec.rb +17 -0
  33. data/spec/lib/net/ntlm/client/session_spec.rb +68 -68
  34. data/spec/lib/net/ntlm/client_spec.rb +64 -64
  35. data/spec/lib/net/ntlm/encode_util_spec.rb +16 -16
  36. data/spec/lib/net/ntlm/field_set_spec.rb +33 -33
  37. data/spec/lib/net/ntlm/field_spec.rb +34 -34
  38. data/spec/lib/net/ntlm/int16_le_spec.rb +17 -17
  39. data/spec/lib/net/ntlm/int32_le_spec.rb +18 -18
  40. data/spec/lib/net/ntlm/int64_le_spec.rb +18 -18
  41. data/spec/lib/net/ntlm/message/type0_spec.rb +20 -20
  42. data/spec/lib/net/ntlm/message/type1_spec.rb +131 -131
  43. data/spec/lib/net/ntlm/message/type2_spec.rb +132 -132
  44. data/spec/lib/net/ntlm/message/type3_spec.rb +225 -225
  45. data/spec/lib/net/ntlm/message_spec.rb +16 -16
  46. data/spec/lib/net/ntlm/security_buffer_spec.rb +64 -64
  47. data/spec/lib/net/ntlm/string_spec.rb +72 -72
  48. data/spec/lib/net/ntlm/target_info_spec.rb +76 -0
  49. data/spec/lib/net/ntlm/version_spec.rb +27 -27
  50. data/spec/lib/net/ntlm_spec.rb +127 -127
  51. data/spec/spec_helper.rb +22 -22
  52. data/spec/support/certificates/sha_256_hash.pem +19 -0
  53. data/spec/support/shared/examples/net/ntlm/field_shared.rb +25 -25
  54. data/spec/support/shared/examples/net/ntlm/fieldset_shared.rb +239 -239
  55. data/spec/support/shared/examples/net/ntlm/int_shared.rb +43 -43
  56. data/spec/support/shared/examples/net/ntlm/message_shared.rb +35 -35
  57. metadata +12 -3
@@ -1,132 +1,132 @@
1
- # encoding: UTF-8
2
- require 'spec_helper'
3
-
4
- describe Net::NTLM::Message::Type2 do
5
-
6
- fields = [
7
- { :name => :sign, :class => Net::NTLM::String, :value => Net::NTLM::SSP_SIGN, :active => true },
8
- { :name => :type, :class => Net::NTLM::Int32LE, :value => 2, :active => true },
9
- { :name => :challenge, :class => Net::NTLM::Int64LE, :value => 0, :active => true },
10
- { :name => :context, :class => Net::NTLM::Int64LE, :value => 0, :active => false },
11
- { :name => :flag, :class => Net::NTLM::Int32LE, :value => Net::NTLM::DEFAULT_FLAGS[:TYPE2], :active => true },
12
- { :name => :target_name, :class => Net::NTLM::SecurityBuffer, :value => '', :active => true },
13
- { :name => :target_info, :class => Net::NTLM::SecurityBuffer, :value => '', :active => false },
14
- { :name => :os_version, :class => Net::NTLM::String, :value => '', :active => false },
15
- ]
16
- flags = [
17
- :UNICODE
18
- ]
19
- it_behaves_like 'a fieldset', fields
20
- it_behaves_like 'a message', flags
21
-
22
- let(:type2_packet) {"TlRMTVNTUAACAAAAHAAcADgAAAAFgooCJ+UA1//+ZM4AAAAAAAAAAJAAkABUAAAABgGxHQAAAA9WAEEARwBSAEEATgBUAC0AMgAwADAAOABSADIAAgAcAFYAQQBHAFIAQQBOAFQALQAyADAAMAA4AFIAMgABABwAVgBBAEcAUgBBAE4AVAAtADIAMAAwADgAUgAyAAQAHAB2AGEAZwByAGEAbgB0AC0AMgAwADAAOABSADIAAwAcAHYAYQBnAHIAYQBuAHQALQAyADAAMAA4AFIAMgAHAAgAZBMdFHQnzgEAAAAA"}
23
- let(:type3_packet) {"TlRMTVNTUAADAAAAGAAYAEQAAADAAMAAXAAAAAAAAAAcAQAADgAOABwBAAAUABQAKgEAAAAAAAA+AQAABYKKAgAAAADVS27TfQGmWxSSbXmolTUQyxJmD8ISQuBKKHFKC8GksUZISYc8Ps9RAQEAAAAAAAAANasTdCfOAcsSZg/CEkLgAAAAAAIAHABWAEEARwBSAEEATgBUAC0AMgAwADAAOABSADIAAQAcAFYAQQBHAFIAQQBOAFQALQAyADAAMAA4AFIAMgAEABwAdgBhAGcAcgBhAG4AdAAtADIAMAAwADgAUgAyAAMAHAB2AGEAZwByAGEAbgB0AC0AMgAwADAAOABSADIABwAIAGQTHRR0J84BAAAAAAAAAAB2AGEAZwByAGEAbgB0AGsAbwBiAGUALgBsAG8AYwBhAGwA"}
24
-
25
- it 'should deserialize' do
26
- t2 = Net::NTLM::Message.decode64(type2_packet)
27
- expect(t2.class).to eq(Net::NTLM::Message::Type2)
28
- expect(t2.challenge).to eq(14872292244261496103)
29
- expect(t2.context).to eq(0)
30
- expect(t2.flag).to eq(42631685)
31
- expect(t2.os_version).to eq(['0601b11d0000000f'].pack('H*'))
32
- expect(t2.sign).to eq("NTLMSSP\0")
33
-
34
- t2_target_info = Net::NTLM::EncodeUtil.decode_utf16le(t2.target_info)
35
- if RUBY_VERSION == "1.8.7"
36
- expect(t2_target_info).to eq("\x02\x1CVAGRANT-2008R2\x01\x1CVAGRANT-2008R2\x04\x1Cvagrant-2008R2\x03\x1Cvagrant-2008R2\a\b\e$(D+&\e(B\0\0")
37
- else
38
- expect(t2_target_info).to eq("\u0002\u001CVAGRANT-2008R2\u0001\u001CVAGRANT-2008R2\u0004\u001Cvagrant-2008R2\u0003\u001Cvagrant-2008R2\a\b፤ᐝ❴ǎ\0\0")
39
- end
40
-
41
- expect(Net::NTLM::EncodeUtil.decode_utf16le(t2.target_name)).to eq("VAGRANT-2008R2")
42
- expect(t2.type).to eq(2)
43
- end
44
-
45
- it 'should serialize' do
46
- source = Net::NTLM::Message.decode64(type2_packet)
47
-
48
- t2 = Net::NTLM::Message::Type2.new
49
- t2.challenge = source.challenge
50
- t2.context = source.context
51
- t2.flag = source.flag
52
- t2.os_version = source.os_version
53
- t2.sign = source.sign
54
- t2.target_info = source.target_info
55
- t2.target_name = source.target_name
56
- t2.type = source.type
57
- t2.enable(:context)
58
- t2.enable(:target_info)
59
- t2.enable(:os_version)
60
-
61
- expect(t2.encode64).to eq(type2_packet)
62
- end
63
-
64
- it 'should generate a type 3 response' do
65
- t2 = Net::NTLM::Message.decode64(type2_packet)
66
-
67
- type3_known = Net::NTLM::Message.decode64(type3_packet)
68
- type3_known.flag = 0x028a8205
69
- type3_known.enable(:session_key)
70
- type3_known.enable(:flag)
71
-
72
- t3 = t2.response({:user => 'vagrant', :password => 'vagrant', :domain => ''}, {:ntlmv2 => true, :workstation => 'kobe.local'})
73
- expect(t3.domain).to eq(type3_known.domain)
74
- expect(t3.flag).to eq(type3_known.flag)
75
- expect(t3.sign).to eq("NTLMSSP\0")
76
- expect(t3.workstation).to eq("k\0o\0b\0e\0.\0l\0o\0c\0a\0l\0")
77
- expect(t3.user).to eq("v\0a\0g\0r\0a\0n\0t\0")
78
- expect(t3.session_key).to eq('')
79
- end
80
-
81
- it 'should upcase domain when provided' do
82
- t2 = Net::NTLM::Message.decode64(type2_packet)
83
- t3 = t2.response({:user => 'vagrant', :password => 'vagrant', :domain => 'domain'}, {:ntlmv2 => true, :workstation => 'kobe.local'})
84
- expect(t3.domain).to eq("D\0O\0M\0A\0I\0N\0")
85
- end
86
-
87
- describe '.parse' do
88
- subject(:message) { described_class.parse(data) }
89
- # http://davenport.sourceforge.net/ntlm.html#appendixC7
90
- context 'NTLM2 Session Response Authentication; NTLM2 Signing and Sealing Using the 128-bit NTLM2 Session Response User Session Key With Key Exchange Negotiated' do
91
- let(:data) do
92
- [
93
- '4e544c4d53535000020000000c000c0030000000358289e0677f1c557a5ee96c' \
94
- '0000000000000000460046003c00000054004500530054004e00540002000c00' \
95
- '54004500530054004e00540001000c004d0045004d0042004500520003001e00' \
96
- '6d0065006d006200650072002e0074006500730074002e0063006f006d000000' \
97
- '0000'
98
- ].pack('H*')
99
- end
100
-
101
- it 'should set the magic' do
102
- expect(message.sign).to eql(Net::NTLM::SSP_SIGN)
103
- end
104
- it 'should set the type' do
105
- expect(message.type).to eq(2)
106
- end
107
- it 'should set the target name' do
108
- # TESTNT
109
- expect(message.target_name).to eq(["54004500530054004e005400"].pack('H*'))
110
- end
111
- it 'should set the flags' do
112
- expect(message.flag).to eq(0xe0898235)
113
- end
114
- it 'should set the challenge' do
115
- expect(message.challenge).to eq(0x6ce95e7a551c7f67)
116
- end
117
- it 'should set an empty context' do
118
- expect(message.context).to be_zero
119
- end
120
- it 'should set target info' do
121
- ti = [
122
- '02000c0054004500530054004e00540001000c004d0045004d00420045005200' \
123
- '03001e006d0065006d006200650072002e0074006500730074002e0063006f00' \
124
- '6d0000000000'
125
- ].pack('H*')
126
- expect(message.target_info).to eq(ti)
127
- end
128
-
129
- end
130
- end
131
-
132
- end
1
+ # encoding: UTF-8
2
+ require 'spec_helper'
3
+
4
+ describe Net::NTLM::Message::Type2 do
5
+
6
+ fields = [
7
+ { :name => :sign, :class => Net::NTLM::String, :value => Net::NTLM::SSP_SIGN, :active => true },
8
+ { :name => :type, :class => Net::NTLM::Int32LE, :value => 2, :active => true },
9
+ { :name => :challenge, :class => Net::NTLM::Int64LE, :value => 0, :active => true },
10
+ { :name => :context, :class => Net::NTLM::Int64LE, :value => 0, :active => false },
11
+ { :name => :flag, :class => Net::NTLM::Int32LE, :value => Net::NTLM::DEFAULT_FLAGS[:TYPE2], :active => true },
12
+ { :name => :target_name, :class => Net::NTLM::SecurityBuffer, :value => '', :active => true },
13
+ { :name => :target_info, :class => Net::NTLM::SecurityBuffer, :value => '', :active => false },
14
+ { :name => :os_version, :class => Net::NTLM::String, :value => '', :active => false },
15
+ ]
16
+ flags = [
17
+ :UNICODE
18
+ ]
19
+ it_behaves_like 'a fieldset', fields
20
+ it_behaves_like 'a message', flags
21
+
22
+ let(:type2_packet) {"TlRMTVNTUAACAAAAHAAcADgAAAAFgooCJ+UA1//+ZM4AAAAAAAAAAJAAkABUAAAABgGxHQAAAA9WAEEARwBSAEEATgBUAC0AMgAwADAAOABSADIAAgAcAFYAQQBHAFIAQQBOAFQALQAyADAAMAA4AFIAMgABABwAVgBBAEcAUgBBAE4AVAAtADIAMAAwADgAUgAyAAQAHAB2AGEAZwByAGEAbgB0AC0AMgAwADAAOABSADIAAwAcAHYAYQBnAHIAYQBuAHQALQAyADAAMAA4AFIAMgAHAAgAZBMdFHQnzgEAAAAA"}
23
+ let(:type3_packet) {"TlRMTVNTUAADAAAAGAAYAEQAAADAAMAAXAAAAAAAAAAcAQAADgAOABwBAAAUABQAKgEAAAAAAAA+AQAABYKKAgAAAADVS27TfQGmWxSSbXmolTUQyxJmD8ISQuBKKHFKC8GksUZISYc8Ps9RAQEAAAAAAAAANasTdCfOAcsSZg/CEkLgAAAAAAIAHABWAEEARwBSAEEATgBUAC0AMgAwADAAOABSADIAAQAcAFYAQQBHAFIAQQBOAFQALQAyADAAMAA4AFIAMgAEABwAdgBhAGcAcgBhAG4AdAAtADIAMAAwADgAUgAyAAMAHAB2AGEAZwByAGEAbgB0AC0AMgAwADAAOABSADIABwAIAGQTHRR0J84BAAAAAAAAAAB2AGEAZwByAGEAbgB0AGsAbwBiAGUALgBsAG8AYwBhAGwA"}
24
+
25
+ it 'should deserialize' do
26
+ t2 = Net::NTLM::Message.decode64(type2_packet)
27
+ expect(t2.class).to eq(Net::NTLM::Message::Type2)
28
+ expect(t2.challenge).to eq(14872292244261496103)
29
+ expect(t2.context).to eq(0)
30
+ expect(t2.flag).to eq(42631685)
31
+ expect(t2.os_version).to eq(['0601b11d0000000f'].pack('H*'))
32
+ expect(t2.sign).to eq("NTLMSSP\0")
33
+
34
+ t2_target_info = Net::NTLM::EncodeUtil.decode_utf16le(t2.target_info)
35
+ if RUBY_VERSION == "1.8.7"
36
+ expect(t2_target_info).to eq("\x02\x1CVAGRANT-2008R2\x01\x1CVAGRANT-2008R2\x04\x1Cvagrant-2008R2\x03\x1Cvagrant-2008R2\a\b\e$(D+&\e(B\0\0")
37
+ else
38
+ expect(t2_target_info).to eq("\u0002\u001CVAGRANT-2008R2\u0001\u001CVAGRANT-2008R2\u0004\u001Cvagrant-2008R2\u0003\u001Cvagrant-2008R2\a\b፤ᐝ❴ǎ\0\0")
39
+ end
40
+
41
+ expect(Net::NTLM::EncodeUtil.decode_utf16le(t2.target_name)).to eq("VAGRANT-2008R2")
42
+ expect(t2.type).to eq(2)
43
+ end
44
+
45
+ it 'should serialize' do
46
+ source = Net::NTLM::Message.decode64(type2_packet)
47
+
48
+ t2 = Net::NTLM::Message::Type2.new
49
+ t2.challenge = source.challenge
50
+ t2.context = source.context
51
+ t2.flag = source.flag
52
+ t2.os_version = source.os_version
53
+ t2.sign = source.sign
54
+ t2.target_info = source.target_info
55
+ t2.target_name = source.target_name
56
+ t2.type = source.type
57
+ t2.enable(:context)
58
+ t2.enable(:target_info)
59
+ t2.enable(:os_version)
60
+
61
+ expect(t2.encode64).to eq(type2_packet)
62
+ end
63
+
64
+ it 'should generate a type 3 response' do
65
+ t2 = Net::NTLM::Message.decode64(type2_packet)
66
+
67
+ type3_known = Net::NTLM::Message.decode64(type3_packet)
68
+ type3_known.flag = 0x028a8205
69
+ type3_known.enable(:session_key)
70
+ type3_known.enable(:flag)
71
+
72
+ t3 = t2.response({:user => 'vagrant', :password => 'vagrant', :domain => ''}, {:ntlmv2 => true, :workstation => 'kobe.local'})
73
+ expect(t3.domain).to eq(type3_known.domain)
74
+ expect(t3.flag).to eq(type3_known.flag)
75
+ expect(t3.sign).to eq("NTLMSSP\0")
76
+ expect(t3.workstation).to eq("k\0o\0b\0e\0.\0l\0o\0c\0a\0l\0")
77
+ expect(t3.user).to eq("v\0a\0g\0r\0a\0n\0t\0")
78
+ expect(t3.session_key).to eq('')
79
+ end
80
+
81
+ it 'should upcase domain when provided' do
82
+ t2 = Net::NTLM::Message.decode64(type2_packet)
83
+ t3 = t2.response({:user => 'vagrant', :password => 'vagrant', :domain => 'domain'}, {:ntlmv2 => true, :workstation => 'kobe.local'})
84
+ expect(t3.domain).to eq("D\0O\0M\0A\0I\0N\0")
85
+ end
86
+
87
+ describe '.parse' do
88
+ subject(:message) { described_class.parse(data) }
89
+ # http://davenport.sourceforge.net/ntlm.html#appendixC7
90
+ context 'NTLM2 Session Response Authentication; NTLM2 Signing and Sealing Using the 128-bit NTLM2 Session Response User Session Key With Key Exchange Negotiated' do
91
+ let(:data) do
92
+ [
93
+ '4e544c4d53535000020000000c000c0030000000358289e0677f1c557a5ee96c' \
94
+ '0000000000000000460046003c00000054004500530054004e00540002000c00' \
95
+ '54004500530054004e00540001000c004d0045004d0042004500520003001e00' \
96
+ '6d0065006d006200650072002e0074006500730074002e0063006f006d000000' \
97
+ '0000'
98
+ ].pack('H*')
99
+ end
100
+
101
+ it 'should set the magic' do
102
+ expect(message.sign).to eql(Net::NTLM::SSP_SIGN)
103
+ end
104
+ it 'should set the type' do
105
+ expect(message.type).to eq(2)
106
+ end
107
+ it 'should set the target name' do
108
+ # TESTNT
109
+ expect(message.target_name).to eq(["54004500530054004e005400"].pack('H*'))
110
+ end
111
+ it 'should set the flags' do
112
+ expect(message.flag).to eq(0xe0898235)
113
+ end
114
+ it 'should set the challenge' do
115
+ expect(message.challenge).to eq(0x6ce95e7a551c7f67)
116
+ end
117
+ it 'should set an empty context' do
118
+ expect(message.context).to be_zero
119
+ end
120
+ it 'should set target info' do
121
+ ti = [
122
+ '02000c0054004500530054004e00540001000c004d0045004d00420045005200' \
123
+ '03001e006d0065006d006200650072002e0074006500730074002e0063006f00' \
124
+ '6d0000000000'
125
+ ].pack('H*')
126
+ expect(message.target_info).to eq(ti)
127
+ end
128
+
129
+ end
130
+ end
131
+
132
+ end
@@ -1,225 +1,225 @@
1
- require 'spec_helper'
2
-
3
- describe Net::NTLM::Message::Type3 do
4
-
5
- fields = [
6
- { :name => :sign, :class => Net::NTLM::String, :value => Net::NTLM::SSP_SIGN, :active => true },
7
- { :name => :type, :class => Net::NTLM::Int32LE, :value => 3, :active => true },
8
- { :name => :lm_response, :class => Net::NTLM::SecurityBuffer, :value => '', :active => true },
9
- { :name => :ntlm_response, :class => Net::NTLM::SecurityBuffer, :value => '', :active => true },
10
- { :name => :domain, :class => Net::NTLM::SecurityBuffer, :value => '', :active => true },
11
- { :name => :user, :class => Net::NTLM::SecurityBuffer, :value => '', :active => true },
12
- { :name => :workstation, :class => Net::NTLM::SecurityBuffer, :value => '', :active => true },
13
- { :name => :session_key, :class => Net::NTLM::SecurityBuffer, :value => '', :active => false },
14
- { :name => :flag, :class => Net::NTLM::Int32LE, :value => 0, :active => false },
15
- ]
16
- flags = []
17
- it_behaves_like 'a fieldset', fields
18
- it_behaves_like 'a message', flags
19
-
20
- describe '.parse' do
21
- subject(:message) { described_class.parse(data) }
22
-
23
- context 'with NTLMv2 data' do
24
- let(:data) do
25
- # Captured NTLMSSP blob from smbclient with username 'administrator'
26
- # and a blank password, i.e.:
27
- # smbclient -U 'administrator%' -L //192.168.100.140/
28
- [
29
- '4e544c4d53535000030000001800180040000000c400c4005800000012001200' \
30
- '1c0100001a001a002e0100001a001a0048010000100010006201000015820860' \
31
- 'ced203d860b80c7350050754b238202a8c1c63134f0ae0f086a3fb147e8b2f9f' \
32
- 'de3ef1b1b43c83dc010100000000000080512dba020ed0011c5bc2c8339fd29a' \
33
- '0000000002001e00570049004e002d00420035004a004e003300520048004700' \
34
- '46003300310001001e00570049004e002d00420035004a004e00330052004800' \
35
- '470046003300310004001e00570049004e002d00420035004a004e0033005200' \
36
- '4800470046003300310003001e00570049004e002d00420035004a004e003300' \
37
- '52004800470046003300310007000800a209e5ba020ed0010000000057004f00' \
38
- '52004b00470052004f0055005000610064006d0069006e006900730074007200' \
39
- '610074006f0072004100550053002d004c004500450054002d00310030003300' \
40
- '31007036615cd6d9b19a685ded4312311cd7'
41
- ].pack('H*')
42
- end
43
-
44
- let(:server_challenge) { ['f588469dc96fe809'].pack('H*') }
45
-
46
- it 'should set the magic' do
47
- expect(message.sign).to eql(Net::NTLM::SSP_SIGN)
48
- end
49
- it 'should set the type' do
50
- expect(message.type).to eq(3)
51
- end
52
- it 'should set the LM response' do
53
- lm_response = ['ced203d860b80c7350050754b238202a8c1c63134f0ae0f0'].pack('H*')
54
- expect(message.lm_response).to eq(lm_response)
55
- end
56
- it 'should set the NTLM response' do
57
- ntlm_response = [
58
- '86a3fb147e8b2f9fde3ef1b1b43c83dc010100000000000080512dba020ed001' \
59
- '1c5bc2c8339fd29a0000000002001e00570049004e002d00420035004a004e00' \
60
- '330052004800470046003300310001001e00570049004e002d00420035004a00' \
61
- '4e00330052004800470046003300310004001e00570049004e002d0042003500' \
62
- '4a004e00330052004800470046003300310003001e00570049004e002d004200' \
63
- '35004a004e00330052004800470046003300310007000800a209e5ba020ed001' \
64
- '00000000'
65
- ].pack('H*')
66
- expect(message.ntlm_response).to eq(ntlm_response)
67
- end
68
- it 'should set the user' do
69
- # administrator
70
- user = ['610064006d0069006e006900730074007200610074006f007200'].pack('H*')
71
- expect(message.user).to eq(user)
72
- end
73
- it 'should set the domain' do
74
- # WORKGROUP
75
- domain = ['57004f0052004b00470052004f0055005000'].pack('H*')
76
- expect(message.domain).to eq(domain)
77
- end
78
- it 'should set the workstation' do
79
- # AUS-LEET-1031
80
- workstation = ['4100550053002d004c004500450054002d003100300033003100'].pack('H*')
81
- expect(message.workstation).to eq(workstation)
82
- end
83
- it 'should set the session key' do
84
- session_key = ['7036615cd6d9b19a685ded4312311cd7'].pack('H*')
85
- expect(message.session_key).to eq(session_key)
86
- end
87
-
88
- it 'should set the flags' do
89
- expect(message.flag).to eq(0x60088215)
90
- end
91
-
92
- it 'should NOT set the OS version structure' do
93
- expect(message.os_version).to be_nil
94
- end
95
-
96
- describe '#blank_password?' do
97
- it 'should be true' do
98
- expect(message.blank_password?(server_challenge)).to be true
99
- end
100
- end
101
-
102
- describe '#ntlm_version' do
103
- let(:ver) { message.ntlm_version }
104
- it 'should be :ntlmv2' do
105
- expect(ver).to eq(:ntlmv2)
106
- end
107
- end
108
-
109
- end
110
-
111
- # http://davenport.sourceforge.net/ntlm.html#appendixC7
112
- context 'NTLM2 Session Response Authentication; NTLM2 Signing and Sealing Using the 128-bit NTLM2 Session Response User Session Key With Key Exchange Negotiated' do
113
-
114
- let(:data) do
115
- [
116
- '4e544c4d5353500003000000180018006000000018001800780000000c000c00' \
117
- '40000000080008004c0000000c000c00540000001000100090000000358288e0' \
118
- '54004500530054004e00540074006500730074004d0045004d00420045005200' \
119
- '404d1b6f6915258000000000000000000000000000000000ea8cc49f24da157f' \
120
- '13436637f77693d8b992d619e584c7ee727a5240822ec7af4e9100c43e6fee7f'
121
- ].pack('H*')
122
- end
123
-
124
- it 'should set the LM response' do
125
- lm_response = ['404d1b6f6915258000000000000000000000000000000000'].pack('H*')
126
- expect(message.lm_response).to eq(lm_response)
127
- end
128
- it 'should set the NTLM response' do
129
- ntlm_response = [ 'ea8cc49f24da157f13436637f77693d8b992d619e584c7ee' ].pack('H*')
130
- expect(message.ntlm_response).to eq(ntlm_response)
131
- end
132
- it 'should set the domain' do
133
- # TESTNT
134
- domain = ['54004500530054004e005400'].pack('H*')
135
- expect(message.domain).to eq(domain)
136
- end
137
- it 'should set the user' do
138
- # test
139
- user = ['7400650073007400'].pack('H*')
140
- expect(message.user).to eq(user)
141
- end
142
- it 'should set the workstation' do
143
- # MEMBER
144
- workstation = ['4d0045004d00420045005200'].pack('H*')
145
- expect(message.workstation).to eq(workstation)
146
- end
147
- it 'should set the session key' do
148
- session_key = ['727a5240822ec7af4e9100c43e6fee7f'].pack('H*')
149
- expect(message.session_key).to eq(session_key)
150
- end
151
-
152
- let(:server_challenge) { ['677f1c557a5ee96c'].pack('H*') }
153
- describe '#password?' do
154
- it 'should be true for "test1234"' do
155
- expect(message.password?('test1234', server_challenge)).to be true
156
- end
157
- end
158
- describe '#blank_password?' do
159
- it 'should be false' do
160
- expect(message.blank_password?(server_challenge)).to be false
161
- end
162
- end
163
-
164
- describe '#ntlm_version' do
165
- let(:ver) { message.ntlm_version }
166
- it 'should be :ntlm2_session' do
167
- expect(ver).to eq(:ntlm2_session)
168
- end
169
- end
170
-
171
- end
172
-
173
- # http://davenport.sourceforge.net/ntlm.html#appendixC9
174
- context 'NTLMv2 Authentication; NTLM1 Signing and Sealing Using the 40-bit NTLMv2 User Session Key' do
175
- let(:data) do
176
- [
177
- '4e544c4d5353500003000000180018006000000076007600780000000c000c00' \
178
- '40000000080008004c0000000c000c005400000000000000ee00000035828000' \
179
- '54004500530054004e00540074006500730074004d0045004d00420045005200' \
180
- '5d55a02b60a40526ac9a1e4d15fa45a0f2e6329726c598e8f77c67dad00b9321' \
181
- '6242b197fe6addfa0101000000000000502db638677bc301f2e6329726c598e8' \
182
- '0000000002000c0054004500530054004e00540001000c004d0045004d004200' \
183
- '4500520003001e006d0065006d006200650072002e0074006500730074002e00' \
184
- '63006f006d000000000000000000'
185
- ].pack 'H*'
186
- end
187
-
188
- it 'should set the NTLM response' do
189
- ntlm_response = [
190
- 'f77c67dad00b93216242b197fe6addfa0101000000000000502db638677bc301' \
191
- 'f2e6329726c598e80000000002000c0054004500530054004e00540001000c00' \
192
- '4d0045004d0042004500520003001e006d0065006d006200650072002e007400' \
193
- '6500730074002e0063006f006d000000000000000000'
194
- ].pack 'H*'
195
- expect(message.ntlm_response).to eq(ntlm_response)
196
- end
197
-
198
- it 'should set the domain' do
199
- # TESTNT
200
- domain = ['54004500530054004e005400'].pack('H*')
201
- expect(message.domain).to eq(domain)
202
- end
203
- it 'should set the user' do
204
- # test
205
- user = ['7400650073007400'].pack('H*')
206
- expect(message.user).to eq(user)
207
- end
208
- it 'should set the workstation' do
209
- # MEMBER
210
- workstation = ['4d0045004d00420045005200'].pack('H*')
211
- expect(message.workstation).to eq(workstation)
212
- end
213
-
214
- describe '#ntlm_version' do
215
- let(:ver) { message.ntlm_version }
216
- it 'should be :ntlmv2' do
217
- expect(ver).to eq(:ntlmv2)
218
- end
219
- end
220
-
221
- end
222
-
223
- end
224
-
225
- end
1
+ require 'spec_helper'
2
+
3
+ describe Net::NTLM::Message::Type3 do
4
+
5
+ fields = [
6
+ { :name => :sign, :class => Net::NTLM::String, :value => Net::NTLM::SSP_SIGN, :active => true },
7
+ { :name => :type, :class => Net::NTLM::Int32LE, :value => 3, :active => true },
8
+ { :name => :lm_response, :class => Net::NTLM::SecurityBuffer, :value => '', :active => true },
9
+ { :name => :ntlm_response, :class => Net::NTLM::SecurityBuffer, :value => '', :active => true },
10
+ { :name => :domain, :class => Net::NTLM::SecurityBuffer, :value => '', :active => true },
11
+ { :name => :user, :class => Net::NTLM::SecurityBuffer, :value => '', :active => true },
12
+ { :name => :workstation, :class => Net::NTLM::SecurityBuffer, :value => '', :active => true },
13
+ { :name => :session_key, :class => Net::NTLM::SecurityBuffer, :value => '', :active => false },
14
+ { :name => :flag, :class => Net::NTLM::Int32LE, :value => 0, :active => false },
15
+ ]
16
+ flags = []
17
+ it_behaves_like 'a fieldset', fields
18
+ it_behaves_like 'a message', flags
19
+
20
+ describe '.parse' do
21
+ subject(:message) { described_class.parse(data) }
22
+
23
+ context 'with NTLMv2 data' do
24
+ let(:data) do
25
+ # Captured NTLMSSP blob from smbclient with username 'administrator'
26
+ # and a blank password, i.e.:
27
+ # smbclient -U 'administrator%' -L //192.168.100.140/
28
+ [
29
+ '4e544c4d53535000030000001800180040000000c400c4005800000012001200' \
30
+ '1c0100001a001a002e0100001a001a0048010000100010006201000015820860' \
31
+ 'ced203d860b80c7350050754b238202a8c1c63134f0ae0f086a3fb147e8b2f9f' \
32
+ 'de3ef1b1b43c83dc010100000000000080512dba020ed0011c5bc2c8339fd29a' \
33
+ '0000000002001e00570049004e002d00420035004a004e003300520048004700' \
34
+ '46003300310001001e00570049004e002d00420035004a004e00330052004800' \
35
+ '470046003300310004001e00570049004e002d00420035004a004e0033005200' \
36
+ '4800470046003300310003001e00570049004e002d00420035004a004e003300' \
37
+ '52004800470046003300310007000800a209e5ba020ed0010000000057004f00' \
38
+ '52004b00470052004f0055005000610064006d0069006e006900730074007200' \
39
+ '610074006f0072004100550053002d004c004500450054002d00310030003300' \
40
+ '31007036615cd6d9b19a685ded4312311cd7'
41
+ ].pack('H*')
42
+ end
43
+
44
+ let(:server_challenge) { ['f588469dc96fe809'].pack('H*') }
45
+
46
+ it 'should set the magic' do
47
+ expect(message.sign).to eql(Net::NTLM::SSP_SIGN)
48
+ end
49
+ it 'should set the type' do
50
+ expect(message.type).to eq(3)
51
+ end
52
+ it 'should set the LM response' do
53
+ lm_response = ['ced203d860b80c7350050754b238202a8c1c63134f0ae0f0'].pack('H*')
54
+ expect(message.lm_response).to eq(lm_response)
55
+ end
56
+ it 'should set the NTLM response' do
57
+ ntlm_response = [
58
+ '86a3fb147e8b2f9fde3ef1b1b43c83dc010100000000000080512dba020ed001' \
59
+ '1c5bc2c8339fd29a0000000002001e00570049004e002d00420035004a004e00' \
60
+ '330052004800470046003300310001001e00570049004e002d00420035004a00' \
61
+ '4e00330052004800470046003300310004001e00570049004e002d0042003500' \
62
+ '4a004e00330052004800470046003300310003001e00570049004e002d004200' \
63
+ '35004a004e00330052004800470046003300310007000800a209e5ba020ed001' \
64
+ '00000000'
65
+ ].pack('H*')
66
+ expect(message.ntlm_response).to eq(ntlm_response)
67
+ end
68
+ it 'should set the user' do
69
+ # administrator
70
+ user = ['610064006d0069006e006900730074007200610074006f007200'].pack('H*')
71
+ expect(message.user).to eq(user)
72
+ end
73
+ it 'should set the domain' do
74
+ # WORKGROUP
75
+ domain = ['57004f0052004b00470052004f0055005000'].pack('H*')
76
+ expect(message.domain).to eq(domain)
77
+ end
78
+ it 'should set the workstation' do
79
+ # AUS-LEET-1031
80
+ workstation = ['4100550053002d004c004500450054002d003100300033003100'].pack('H*')
81
+ expect(message.workstation).to eq(workstation)
82
+ end
83
+ it 'should set the session key' do
84
+ session_key = ['7036615cd6d9b19a685ded4312311cd7'].pack('H*')
85
+ expect(message.session_key).to eq(session_key)
86
+ end
87
+
88
+ it 'should set the flags' do
89
+ expect(message.flag).to eq(0x60088215)
90
+ end
91
+
92
+ it 'should NOT set the OS version structure' do
93
+ expect(message.os_version).to be_nil
94
+ end
95
+
96
+ describe '#blank_password?' do
97
+ it 'should be true' do
98
+ expect(message.blank_password?(server_challenge)).to be true
99
+ end
100
+ end
101
+
102
+ describe '#ntlm_version' do
103
+ let(:ver) { message.ntlm_version }
104
+ it 'should be :ntlmv2' do
105
+ expect(ver).to eq(:ntlmv2)
106
+ end
107
+ end
108
+
109
+ end
110
+
111
+ # http://davenport.sourceforge.net/ntlm.html#appendixC7
112
+ context 'NTLM2 Session Response Authentication; NTLM2 Signing and Sealing Using the 128-bit NTLM2 Session Response User Session Key With Key Exchange Negotiated' do
113
+
114
+ let(:data) do
115
+ [
116
+ '4e544c4d5353500003000000180018006000000018001800780000000c000c00' \
117
+ '40000000080008004c0000000c000c00540000001000100090000000358288e0' \
118
+ '54004500530054004e00540074006500730074004d0045004d00420045005200' \
119
+ '404d1b6f6915258000000000000000000000000000000000ea8cc49f24da157f' \
120
+ '13436637f77693d8b992d619e584c7ee727a5240822ec7af4e9100c43e6fee7f'
121
+ ].pack('H*')
122
+ end
123
+
124
+ it 'should set the LM response' do
125
+ lm_response = ['404d1b6f6915258000000000000000000000000000000000'].pack('H*')
126
+ expect(message.lm_response).to eq(lm_response)
127
+ end
128
+ it 'should set the NTLM response' do
129
+ ntlm_response = [ 'ea8cc49f24da157f13436637f77693d8b992d619e584c7ee' ].pack('H*')
130
+ expect(message.ntlm_response).to eq(ntlm_response)
131
+ end
132
+ it 'should set the domain' do
133
+ # TESTNT
134
+ domain = ['54004500530054004e005400'].pack('H*')
135
+ expect(message.domain).to eq(domain)
136
+ end
137
+ it 'should set the user' do
138
+ # test
139
+ user = ['7400650073007400'].pack('H*')
140
+ expect(message.user).to eq(user)
141
+ end
142
+ it 'should set the workstation' do
143
+ # MEMBER
144
+ workstation = ['4d0045004d00420045005200'].pack('H*')
145
+ expect(message.workstation).to eq(workstation)
146
+ end
147
+ it 'should set the session key' do
148
+ session_key = ['727a5240822ec7af4e9100c43e6fee7f'].pack('H*')
149
+ expect(message.session_key).to eq(session_key)
150
+ end
151
+
152
+ let(:server_challenge) { ['677f1c557a5ee96c'].pack('H*') }
153
+ describe '#password?' do
154
+ it 'should be true for "test1234"' do
155
+ expect(message.password?('test1234', server_challenge)).to be true
156
+ end
157
+ end
158
+ describe '#blank_password?' do
159
+ it 'should be false' do
160
+ expect(message.blank_password?(server_challenge)).to be false
161
+ end
162
+ end
163
+
164
+ describe '#ntlm_version' do
165
+ let(:ver) { message.ntlm_version }
166
+ it 'should be :ntlm2_session' do
167
+ expect(ver).to eq(:ntlm2_session)
168
+ end
169
+ end
170
+
171
+ end
172
+
173
+ # http://davenport.sourceforge.net/ntlm.html#appendixC9
174
+ context 'NTLMv2 Authentication; NTLM1 Signing and Sealing Using the 40-bit NTLMv2 User Session Key' do
175
+ let(:data) do
176
+ [
177
+ '4e544c4d5353500003000000180018006000000076007600780000000c000c00' \
178
+ '40000000080008004c0000000c000c005400000000000000ee00000035828000' \
179
+ '54004500530054004e00540074006500730074004d0045004d00420045005200' \
180
+ '5d55a02b60a40526ac9a1e4d15fa45a0f2e6329726c598e8f77c67dad00b9321' \
181
+ '6242b197fe6addfa0101000000000000502db638677bc301f2e6329726c598e8' \
182
+ '0000000002000c0054004500530054004e00540001000c004d0045004d004200' \
183
+ '4500520003001e006d0065006d006200650072002e0074006500730074002e00' \
184
+ '63006f006d000000000000000000'
185
+ ].pack 'H*'
186
+ end
187
+
188
+ it 'should set the NTLM response' do
189
+ ntlm_response = [
190
+ 'f77c67dad00b93216242b197fe6addfa0101000000000000502db638677bc301' \
191
+ 'f2e6329726c598e80000000002000c0054004500530054004e00540001000c00' \
192
+ '4d0045004d0042004500520003001e006d0065006d006200650072002e007400' \
193
+ '6500730074002e0063006f006d000000000000000000'
194
+ ].pack 'H*'
195
+ expect(message.ntlm_response).to eq(ntlm_response)
196
+ end
197
+
198
+ it 'should set the domain' do
199
+ # TESTNT
200
+ domain = ['54004500530054004e005400'].pack('H*')
201
+ expect(message.domain).to eq(domain)
202
+ end
203
+ it 'should set the user' do
204
+ # test
205
+ user = ['7400650073007400'].pack('H*')
206
+ expect(message.user).to eq(user)
207
+ end
208
+ it 'should set the workstation' do
209
+ # MEMBER
210
+ workstation = ['4d0045004d00420045005200'].pack('H*')
211
+ expect(message.workstation).to eq(workstation)
212
+ end
213
+
214
+ describe '#ntlm_version' do
215
+ let(:ver) { message.ntlm_version }
216
+ it 'should be :ntlmv2' do
217
+ expect(ver).to eq(:ntlmv2)
218
+ end
219
+ end
220
+
221
+ end
222
+
223
+ end
224
+
225
+ end