packetgen-plugin-smb 0.5.0 → 0.6.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/specs.yml +28 -0
- data/.rubocop.yml +26 -2
- data/Gemfile +15 -0
- data/README.md +51 -12
- data/Rakefile +10 -4
- data/examples/llmnr-responder +110 -0
- data/examples/smb-responder +233 -0
- data/lib/packetgen/plugin/gssapi.rb +16 -10
- data/lib/packetgen/plugin/llmnr.rb +4 -4
- data/lib/packetgen/plugin/netbios/datagram.rb +3 -3
- data/lib/packetgen/plugin/netbios/name.rb +4 -4
- data/lib/packetgen/plugin/netbios/session.rb +5 -5
- data/lib/packetgen/plugin/netbios.rb +2 -0
- data/lib/packetgen/plugin/ntlm/authenticate.rb +197 -0
- data/lib/packetgen/plugin/ntlm/av_pair.rb +115 -0
- data/lib/packetgen/plugin/ntlm/challenge.rb +140 -0
- data/lib/packetgen/plugin/ntlm/negotiate.rb +127 -0
- data/lib/packetgen/plugin/ntlm/ntlmv2_response.rb +59 -0
- data/lib/packetgen/plugin/ntlm.rb +211 -0
- data/lib/packetgen/plugin/smb/blocks.rb +2 -2
- data/lib/packetgen/plugin/smb/browser/domain_announcement.rb +2 -2
- data/lib/packetgen/plugin/smb/browser/host_announcement.rb +2 -2
- data/lib/packetgen/plugin/smb/browser/local_master_announcement.rb +2 -2
- data/lib/packetgen/plugin/smb/browser.rb +2 -2
- data/lib/packetgen/plugin/smb/close/request.rb +2 -2
- data/lib/packetgen/plugin/smb/close/response.rb +2 -2
- data/lib/packetgen/plugin/smb/close.rb +2 -2
- data/lib/packetgen/plugin/smb/filetime.rb +10 -2
- data/lib/packetgen/plugin/smb/negotiate/dialect.rb +7 -0
- data/lib/packetgen/plugin/smb/negotiate/request.rb +7 -0
- data/lib/packetgen/plugin/smb/negotiate/response.rb +9 -3
- data/lib/packetgen/plugin/smb/negotiate.rb +2 -2
- data/lib/packetgen/plugin/smb/nt_create_and_x.rb +2 -2
- data/lib/packetgen/plugin/smb/ntcreateandx/request.rb +4 -4
- data/lib/packetgen/plugin/smb/ntcreateandx/response.rb +2 -2
- data/lib/packetgen/plugin/smb/string.rb +60 -23
- data/lib/packetgen/plugin/smb/trans/request.rb +3 -3
- data/lib/packetgen/plugin/smb/trans/response.rb +2 -2
- data/lib/packetgen/plugin/smb/trans.rb +2 -2
- data/lib/packetgen/plugin/smb.rb +12 -12
- data/lib/packetgen/plugin/smb2/base.rb +3 -3
- data/lib/packetgen/plugin/smb2/error.rb +3 -4
- data/lib/packetgen/plugin/smb2/guid.rb +4 -3
- data/lib/packetgen/plugin/smb2/negotiate/context.rb +3 -3
- data/lib/packetgen/plugin/smb2/negotiate/request.rb +3 -5
- data/lib/packetgen/plugin/smb2/negotiate/response.rb +9 -7
- data/lib/packetgen/plugin/smb2/negotiate.rb +2 -2
- data/lib/packetgen/plugin/smb2/session_setup/request.rb +9 -5
- data/lib/packetgen/plugin/smb2/session_setup/response.rb +10 -6
- data/lib/packetgen/plugin/smb2/session_setup.rb +2 -2
- data/lib/packetgen/plugin/smb2.rb +3 -3
- data/lib/packetgen/plugin/smb_version.rb +3 -1
- data/lib/packetgen-plugin-smb.rb +3 -2
- data/packetgen-plugin-smb.gemspec +8 -10
- metadata +21 -84
- data/.travis.yml +0 -12
@@ -0,0 +1,211 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# This file is part of packetgen-plugin-smb.
|
4
|
+
# See https://github.com/sdaubert/packetgen-plugin-smb for more informations
|
5
|
+
# Copyright (C) 2018 Sylvain Daubert <sylvain.daubert@laposte.net>
|
6
|
+
# This program is published under MIT license.
|
7
|
+
|
8
|
+
module PacketGen::Plugin
|
9
|
+
# Base class for NTLM authentication protocol.
|
10
|
+
# @author Sylvain Daubert
|
11
|
+
class NTLM < PacketGen::Types::Fields
|
12
|
+
# NTLM message types
|
13
|
+
TYPES = {
|
14
|
+
'negotiate' => 1,
|
15
|
+
'challenge' => 2,
|
16
|
+
'authenticate' => 3
|
17
|
+
}.freeze
|
18
|
+
|
19
|
+
# NTLM signature
|
20
|
+
SIGNATURE = "NTLMSSP\0"
|
21
|
+
|
22
|
+
# void version
|
23
|
+
VOID_VERSION = [0].pack('q').freeze
|
24
|
+
VOID_CHALLENGE = VOID_VERSION
|
25
|
+
|
26
|
+
# @!attribute signature
|
27
|
+
# 8-byte NTLM signature
|
28
|
+
# @return [String]
|
29
|
+
define_field :signature, PacketGen::Types::String, static_length: 8, default: SIGNATURE
|
30
|
+
# @!attribute type
|
31
|
+
# 4-byte message type
|
32
|
+
# @return [Integer]
|
33
|
+
define_field :type, PacketGen::Types::Int32leEnum, enum: TYPES
|
34
|
+
# @!attribute payload
|
35
|
+
# @return [String]
|
36
|
+
define_field :payload, PacketGen::Types::String
|
37
|
+
|
38
|
+
class <<self
|
39
|
+
# @api private
|
40
|
+
# Return fields defined in payload one.
|
41
|
+
# @return [Hash]
|
42
|
+
attr_accessor :payload_fields
|
43
|
+
|
44
|
+
# Create a NTLM object from a binary string
|
45
|
+
# @param [String] str
|
46
|
+
# @return [NTLM]
|
47
|
+
def read(str)
|
48
|
+
ntlm = self.new.read(str)
|
49
|
+
type = TYPES.key(ntlm.type)
|
50
|
+
return ntlm if type.nil?
|
51
|
+
|
52
|
+
klass = NTLM.const_get(type.capitalize)
|
53
|
+
klass.new.read(str)
|
54
|
+
end
|
55
|
+
|
56
|
+
# Define a flags field.
|
57
|
+
# @return [void]
|
58
|
+
def define_negotiate_flags
|
59
|
+
define_field_before :payload, :flags, PacketGen::Types::Int32le
|
60
|
+
define_bit_fields_on :flags, :flags_w, :flags_v, :flags_u, :flags_r13, 3,
|
61
|
+
:flags_t, :flags_r4, :flags_s, :flags_r,
|
62
|
+
:flags_r5, :flags_q, :flags_p, :flags_r6,
|
63
|
+
:flags_o, :flags_n, :flags_m, :flags_r7,
|
64
|
+
:flags_l, :flags_k, :flags_j, :flags_r8,
|
65
|
+
:flags_h, :flags_r9, :flags_g, :flags_f,
|
66
|
+
:flags_e, :flags_d, :flags_r10, :flags_c,
|
67
|
+
:flags_b, :flags_a
|
68
|
+
alias_method :nego56?, :flags_w?
|
69
|
+
alias_method :key_exch?, :flags_v?
|
70
|
+
alias_method :nego128?, :flags_u?
|
71
|
+
alias_method :version?, :flags_t?
|
72
|
+
alias_method :target_info?, :flags_s?
|
73
|
+
alias_method :non_nt_session_key?, :flags_r?
|
74
|
+
alias_method :identify?, :flags_q?
|
75
|
+
alias_method :ext_session_security?, :flags_p?
|
76
|
+
alias_method :target_type_server?, :flags_o?
|
77
|
+
alias_method :target_type_domain?, :flags_n?
|
78
|
+
alias_method :always_sign?, :flags_m?
|
79
|
+
alias_method :oem_workstation_supplied?, :flags_l?
|
80
|
+
alias_method :oem_domain_supplied?, :flags_k?
|
81
|
+
alias_method :anonymous?, :flags_j?
|
82
|
+
alias_method :ntlm?, :flags_h?
|
83
|
+
alias_method :lm_key?, :flags_g?
|
84
|
+
alias_method :datagram?, :flags_f?
|
85
|
+
alias_method :seal?, :flags_e?
|
86
|
+
alias_method :sign?, :flags_d?
|
87
|
+
alias_method :request_target?, :flags_c?
|
88
|
+
alias_method :oem?, :flags_b?
|
89
|
+
alias_method :unicode?, :flags_a?
|
90
|
+
alias_method :old_flags_a=, :flags_a=
|
91
|
+
alias_method :old_flags=, :flags=
|
92
|
+
|
93
|
+
class_eval do
|
94
|
+
def flags_a=(value)
|
95
|
+
self.old_flags_a = value
|
96
|
+
self.class.payload_fields.each do |name, _|
|
97
|
+
attr = send(name)
|
98
|
+
attr.unicode = value if attr.respond_to?(:unicode=)
|
99
|
+
end
|
100
|
+
|
101
|
+
value
|
102
|
+
end
|
103
|
+
|
104
|
+
def flags=(value)
|
105
|
+
self.old_flags = value
|
106
|
+
self.flags_a = value & 1
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
|
111
|
+
# Define a field in payload. Also add +name_len+, +name_maxlen+ and
|
112
|
+
# +name_offset+ fields.
|
113
|
+
# @param [Symbol] name name of field.
|
114
|
+
# @param [Class,nil] type type of +name+ field.
|
115
|
+
# @param [Hash] options type's options needed at build time
|
116
|
+
# @return [void]
|
117
|
+
def define_in_payload(name, type=SMB::String, options={})
|
118
|
+
@payload_fields ||= {}
|
119
|
+
@payload_fields[name] = [type, options]
|
120
|
+
|
121
|
+
define_field_before :payload, :"#{name}_len", PacketGen::Types::Int16le
|
122
|
+
define_field_before :payload, :"#{name}_maxlen", PacketGen::Types::Int16le
|
123
|
+
define_field_before :payload, :"#{name}_offset", PacketGen::Types::Int32le
|
124
|
+
|
125
|
+
attr_accessor name
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
# @abstract This method is meaningful for {NTLM} subclasses only.
|
130
|
+
def initialize(options={})
|
131
|
+
super
|
132
|
+
return if self.class.payload_fields.nil?
|
133
|
+
|
134
|
+
self.class.payload_fields.each do |name, type_and_opt|
|
135
|
+
type, options = type_and_opt
|
136
|
+
content = if type.new.respond_to?(:unicode?)
|
137
|
+
type.new(options.merge(unicode: unicode?))
|
138
|
+
else
|
139
|
+
type.new(options)
|
140
|
+
end
|
141
|
+
send(:"#{name}=", content)
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
# @abstract This class is meaningful for {NTLM} subclasses only.
|
146
|
+
# Populate object from a binary string
|
147
|
+
# @param [String] str
|
148
|
+
# @return [self]
|
149
|
+
def read(str)
|
150
|
+
super
|
151
|
+
return self if self.class.payload_fields.nil?
|
152
|
+
|
153
|
+
self.class.payload_fields.each do |name, type_and_opt|
|
154
|
+
type, options = type_and_opt
|
155
|
+
offset_in_payload = send(:"#{name}_offset") - offset_of(:payload)
|
156
|
+
length = send(:"#{name}_len")
|
157
|
+
content = if type.new.respond_to?(:unicode?)
|
158
|
+
type.new(options.merge(unicode: unicode?))
|
159
|
+
else
|
160
|
+
type.new(options)
|
161
|
+
end
|
162
|
+
content.read(payload[offset_in_payload, length]) if length.positive?
|
163
|
+
send(:"#{name}=", content)
|
164
|
+
end
|
165
|
+
|
166
|
+
self
|
167
|
+
end
|
168
|
+
|
169
|
+
# @abstract This class is meaningful for {NTLM} subclasses only.
|
170
|
+
# Calculate and set +len+, +maxlen+ and +offset+ fields defined for
|
171
|
+
# fields in {#payload}.
|
172
|
+
# @return [void]
|
173
|
+
def calc_length
|
174
|
+
return self if self.class.payload_fields.nil?
|
175
|
+
|
176
|
+
previous_len = 0
|
177
|
+
self.class.payload_fields.each do |name, _type_and_opt|
|
178
|
+
send(:"#{name}_len=", 0)
|
179
|
+
send(:"#{name}_offset=", offset_of(:payload) + previous_len)
|
180
|
+
|
181
|
+
field = send(name)
|
182
|
+
next unless field && !field.empty?
|
183
|
+
|
184
|
+
length = field.respond_to?(:sz) ? field.sz : field.size
|
185
|
+
send(:"#{name}_len=", length)
|
186
|
+
send(:"#{name}_maxlen=", length)
|
187
|
+
previous_len = length
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
# @abstract This class is meaningful for {NTLM} subclasses only.
|
192
|
+
# @return [String]
|
193
|
+
def to_s
|
194
|
+
s = super
|
195
|
+
return s if self.class.payload_fields.nil?
|
196
|
+
|
197
|
+
self.class.payload_fields.each do |name, _type_and_opt|
|
198
|
+
attr = send(name)
|
199
|
+
attr.unicode = unicode? if attr.respond_to?(:unicode=)
|
200
|
+
s << attr.to_s unless attr.nil? || send("#{name}_len").zero?
|
201
|
+
end
|
202
|
+
s
|
203
|
+
end
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
require_relative 'ntlm/av_pair'
|
208
|
+
require_relative 'ntlm/ntlmv2_response'
|
209
|
+
require_relative 'ntlm/negotiate'
|
210
|
+
require_relative 'ntlm/challenge'
|
211
|
+
require_relative 'ntlm/authenticate'
|
@@ -1,10 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# This file is part of packetgen-plugin-smb.
|
2
4
|
# See https://github.com/sdaubert/packetgen-plugin-smb for more informations
|
3
5
|
# Copyright (C) 2018 Sylvain Daubert <sylvain.daubert@laposte.net>
|
4
6
|
# This program is published under MIT license.
|
5
7
|
|
6
|
-
# frozen_string_literal: true
|
7
|
-
|
8
8
|
module PacketGen::Plugin
|
9
9
|
class SMB
|
10
10
|
# Common blocks used for unsupported SMB messages.
|
@@ -1,10 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# This file is part of packetgen-plugin-smb.
|
2
4
|
# See https://github.com/sdaubert/packetgen-plugin-smb for more informations
|
3
5
|
# Copyright (C) 2018 Sylvain Daubert <sylvain.daubert@laposte.net>
|
4
6
|
# This program is published under MIT license.
|
5
7
|
|
6
|
-
# frozen_string_literal: true
|
7
|
-
|
8
8
|
module PacketGen::Plugin
|
9
9
|
class SMB
|
10
10
|
class Browser
|
@@ -1,10 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# This file is part of packetgen-plugin-smb.
|
2
4
|
# See https://github.com/sdaubert/packetgen-plugin-smb for more informations
|
3
5
|
# Copyright (C) 2018 Sylvain Daubert <sylvain.daubert@laposte.net>
|
4
6
|
# This program is published under MIT license.
|
5
7
|
|
6
|
-
# frozen_string_literal: true
|
7
|
-
|
8
8
|
module PacketGen::Plugin
|
9
9
|
class SMB
|
10
10
|
class Browser
|
@@ -1,10 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# This file is part of packetgen-plugin-smb.
|
2
4
|
# See https://github.com/sdaubert/packetgen-plugin-smb for more informations
|
3
5
|
# Copyright (C) 2018 Sylvain Daubert <sylvain.daubert@laposte.net>
|
4
6
|
# This program is published under MIT license.
|
5
7
|
|
6
|
-
# frozen_string_literal: true
|
7
|
-
|
8
8
|
module PacketGen::Plugin
|
9
9
|
class SMB
|
10
10
|
class Browser
|
@@ -1,10 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# This file is part of packetgen-plugin-smb.
|
2
4
|
# See https://github.com/sdaubert/packetgen-plugin-smb for more informations
|
3
5
|
# Copyright (C) 2018 Sylvain Daubert <sylvain.daubert@laposte.net>
|
4
6
|
# This program is published under MIT license.
|
5
7
|
|
6
|
-
# frozen_string_literal: true
|
7
|
-
|
8
8
|
module PacketGen::Plugin
|
9
9
|
class SMB
|
10
10
|
# Browser Trans sub-protocol.
|
@@ -1,10 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# This file is part of packetgen-plugin-smb.
|
2
4
|
# See https://github.com/sdaubert/packetgen-plugin-smb for more informations
|
3
5
|
# Copyright (C) 2018 Sylvain Daubert <sylvain.daubert@laposte.net>
|
4
6
|
# This program is published under MIT license.
|
5
7
|
|
6
|
-
# frozen_string_literal: true
|
7
|
-
|
8
8
|
module PacketGen::Plugin
|
9
9
|
class SMB
|
10
10
|
module Close
|
@@ -1,10 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# This file is part of packetgen-plugin-smb.
|
2
4
|
# See https://github.com/sdaubert/packetgen-plugin-smb for more informations
|
3
5
|
# Copyright (C) 2018 Sylvain Daubert <sylvain.daubert@laposte.net>
|
4
6
|
# This program is published under MIT license.
|
5
7
|
|
6
|
-
# frozen_string_literal: true
|
7
|
-
|
8
8
|
module PacketGen::Plugin
|
9
9
|
class SMB
|
10
10
|
module Close
|
@@ -1,10 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# This file is part of packetgen-plugin-smb.
|
2
4
|
# See https://github.com/sdaubert/packetgen-plugin-smb for more informations
|
3
5
|
# Copyright (C) 2018 Sylvain Daubert <sylvain.daubert@laposte.net>
|
4
6
|
# This program is published under MIT license.
|
5
7
|
|
6
|
-
# frozen_string_literal: true
|
7
|
-
|
8
8
|
module PacketGen::Plugin
|
9
9
|
class SMB
|
10
10
|
# Namespace for CLOSE related classes
|
@@ -1,15 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# This file is part of packetgen-plugin-smb.
|
2
4
|
# See https://github.com/sdaubert/packetgen-plugin-smb for more informations
|
3
5
|
# Copyright (C) 2018 Sylvain Daubert <sylvain.daubert@laposte.net>
|
4
6
|
# This program is published under MIT license.
|
5
7
|
|
6
|
-
# frozen_string_literal: true
|
7
|
-
|
8
8
|
module PacketGen::Plugin
|
9
9
|
class SMB
|
10
10
|
# SMB FILETIME.
|
11
11
|
# @author Sylvain Daubert
|
12
12
|
class Filetime
|
13
|
+
include PacketGen::Types::Fieldable
|
14
|
+
|
13
15
|
# Base time for SMB FILETIME.
|
14
16
|
# This value also indicate no time.
|
15
17
|
NO_TIME = Time.utc(1601).freeze
|
@@ -22,6 +24,12 @@ module PacketGen::Plugin
|
|
22
24
|
# String to parse time
|
23
25
|
PARSE_TIME_STR = '%Y-%m-%d %H:%M:%S.%N %Z'
|
24
26
|
|
27
|
+
# Return a new Filetime object initialized to current time.
|
28
|
+
# @return [Filetime]
|
29
|
+
def self.now
|
30
|
+
new(time: Time.now.utc)
|
31
|
+
end
|
32
|
+
|
25
33
|
# @param [Hash] options
|
26
34
|
# @option options [Integer] :filetime
|
27
35
|
# @option options [Time] :time
|
@@ -1,3 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# This file is part of packetgen-plugin-smb.
|
4
|
+
# See https://github.com/sdaubert/packetgen-plugin-smb for more informations
|
5
|
+
# Copyright (C) 2018 Sylvain Daubert <sylvain.daubert@laposte.net>
|
6
|
+
# This program is published under MIT license.
|
7
|
+
|
1
8
|
module PacketGen::Plugin
|
2
9
|
class SMB
|
3
10
|
module Negotiate
|
@@ -1,3 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# This file is part of packetgen-plugin-smb.
|
4
|
+
# See https://github.com/sdaubert/packetgen-plugin-smb for more informations
|
5
|
+
# Copyright (C) 2018 Sylvain Daubert <sylvain.daubert@laposte.net>
|
6
|
+
# This program is published under MIT license.
|
7
|
+
|
1
8
|
module PacketGen::Plugin
|
2
9
|
class SMB
|
3
10
|
module Negotiate
|
@@ -1,13 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# This file is part of packetgen-plugin-smb.
|
4
|
+
# See https://github.com/sdaubert/packetgen-plugin-smb for more informations
|
5
|
+
# Copyright (C) 2018 Sylvain Daubert <sylvain.daubert@laposte.net>
|
6
|
+
# This program is published under MIT license.
|
7
|
+
|
1
8
|
module PacketGen::Plugin
|
2
9
|
class SMB
|
3
10
|
module Negotiate
|
4
11
|
# SMB Negotiation Response header.
|
5
12
|
#
|
6
|
-
# See also {Blocks}, as {Negotiate::
|
13
|
+
# See also {Blocks}, as {Negotiate::Response} is a specialization of {Blocks#words}
|
7
14
|
# and {Blocks#bytes}.
|
8
15
|
# @author Sylvain Daubert
|
9
16
|
class Response < Blocks
|
10
|
-
|
11
17
|
# Get index of the dialect selected by the server from the list presented in the request.
|
12
18
|
# @return [Integer]
|
13
19
|
def dialect_index
|
@@ -20,4 +26,4 @@ module PacketGen::Plugin
|
|
20
26
|
end
|
21
27
|
end
|
22
28
|
end
|
23
|
-
end
|
29
|
+
end
|
@@ -1,10 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# This file is part of packetgen-plugin-smb.
|
2
4
|
# See https://github.com/sdaubert/packetgen-plugin-smb for more informations
|
3
5
|
# Copyright (C) 2018 Sylvain Daubert <sylvain.daubert@laposte.net>
|
4
6
|
# This program is published under MIT license.
|
5
7
|
|
6
|
-
# frozen_string_literal: true
|
7
|
-
|
8
8
|
module PacketGen::Plugin
|
9
9
|
class SMB
|
10
10
|
# Namespace for NEGOTIATE related classes
|
@@ -1,10 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# This file is part of packetgen-plugin-smb.
|
2
4
|
# See https://github.com/sdaubert/packetgen-plugin-smb for more informations
|
3
5
|
# Copyright (C) 2018 Sylvain Daubert <sylvain.daubert@laposte.net>
|
4
6
|
# This program is published under MIT license.
|
5
7
|
|
6
|
-
# frozen_string_literal: true
|
7
|
-
|
8
8
|
module PacketGen::Plugin
|
9
9
|
class SMB
|
10
10
|
# Namespace for NT_CREATE_ANDX related classes
|
@@ -1,10 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# This file is part of packetgen-plugin-smb.
|
2
4
|
# See https://github.com/sdaubert/packetgen-plugin-smb for more informations
|
3
5
|
# Copyright (C) 2018 Sylvain Daubert <sylvain.daubert@laposte.net>
|
4
6
|
# This program is published under MIT license.
|
5
7
|
|
6
|
-
# frozen_string_literal: true
|
7
|
-
|
8
8
|
module PacketGen::Plugin
|
9
9
|
class SMB
|
10
10
|
# Namespace for NT_CREATE_ANDX related classes
|
@@ -128,7 +128,7 @@ module PacketGen::Plugin
|
|
128
128
|
# Padding before {#filename} to align it on 16-bit boundary. Only present
|
129
129
|
# if {SMB#flags2_unicode?} is +true+.
|
130
130
|
# @return [Integer]
|
131
|
-
define_field :pad1, PacketGen::Types::Int8, optional: ->(h) { h
|
131
|
+
define_field :pad1, PacketGen::Types::Int8, optional: ->(h) { h&.packet&.smb&.flags2_unicode? }
|
132
132
|
# @!attribute filename
|
133
133
|
# A string that represents the fully qualified name of the file
|
134
134
|
# relative to the supplied TID
|
@@ -154,6 +154,6 @@ module PacketGen::Plugin
|
|
154
154
|
self.byte_count = bcount
|
155
155
|
end
|
156
156
|
end
|
157
|
-
|
157
|
+
end
|
158
158
|
end
|
159
159
|
end
|
@@ -1,10 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# This file is part of packetgen-plugin-smb.
|
2
4
|
# See https://github.com/sdaubert/packetgen-plugin-smb for more informations
|
3
5
|
# Copyright (C) 2018 Sylvain Daubert <sylvain.daubert@laposte.net>
|
4
6
|
# This program is published under MIT license.
|
5
7
|
|
6
|
-
# frozen_string_literal: true
|
7
|
-
|
8
8
|
module PacketGen::Plugin
|
9
9
|
class SMB
|
10
10
|
# Namespace for NT_CREATE_ANDX related classes
|
@@ -1,28 +1,39 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# This file is part of packetgen-plugin-smb.
|
2
4
|
# See https://github.com/sdaubert/packetgen-plugin-smb for more informations
|
3
5
|
# Copyright (C) 2018 Sylvain Daubert <sylvain.daubert@laposte.net>
|
4
6
|
# This program is published under MIT license.
|
5
7
|
|
6
|
-
|
8
|
+
require 'forwardable'
|
7
9
|
|
8
10
|
module PacketGen::Plugin
|
9
11
|
class SMB
|
10
|
-
# SMB strings (UTF-16 little-endian).
|
12
|
+
# SMB strings (UTF-16 little-endian or OEM).
|
11
13
|
# @author Sylvain Daubert
|
12
|
-
class String
|
13
|
-
|
14
|
+
class String
|
15
|
+
extend Forwardable
|
16
|
+
include PacketGen::Types::Fieldable
|
17
|
+
|
18
|
+
def_delegators :@string, :[], :length, :size, :inspect, :==, :<<,
|
19
|
+
:unpack, :force_encoding, :encoding, :index, :empty?,
|
20
|
+
:encode
|
21
|
+
|
22
|
+
# @return [::String]
|
23
|
+
attr_reader :string
|
24
|
+
# @param [Boolean] null_terminated
|
14
25
|
# @return [Boolean]
|
15
|
-
attr_writer :
|
26
|
+
attr_writer :null_terminated
|
16
27
|
|
17
28
|
# @param [Hash] options
|
18
|
-
# @option options [Integer] :static_length set a static length for this string
|
19
29
|
# @option options [Boolean] :unicode If +true+, string is encoded as a UTF-16
|
20
30
|
# unicode string. If +false+, string is encode in ASCII. Defaults to +true+.
|
31
|
+
# @option options [Boolean] :null_terminated If +true+, string is null-terminated.
|
32
|
+
# If +false+, string is not null-terminated. Defaults to +true+.
|
21
33
|
def initialize(options={})
|
22
|
-
super
|
23
34
|
@unicode = options.key?(:unicode) ? options[:unicode] : true
|
24
|
-
|
25
|
-
|
35
|
+
@null_terminated = options.key?(:null_terminated) ? options[:null_terminated] : true
|
36
|
+
@string = +''.encode(self_encoding)
|
26
37
|
end
|
27
38
|
|
28
39
|
# @return [Boolean]
|
@@ -30,6 +41,19 @@ module PacketGen::Plugin
|
|
30
41
|
@unicode
|
31
42
|
end
|
32
43
|
|
44
|
+
# @param [Boolean] bool
|
45
|
+
# @return [Boolean]
|
46
|
+
def unicode=(bool)
|
47
|
+
@unicode = bool
|
48
|
+
@string.force_encoding(self_encoding)
|
49
|
+
bool
|
50
|
+
end
|
51
|
+
|
52
|
+
# @return [Boolean]
|
53
|
+
def null_terminated?
|
54
|
+
@null_terminated
|
55
|
+
end
|
56
|
+
|
33
57
|
# @param [::String] str
|
34
58
|
# @return [String] self
|
35
59
|
def read(str)
|
@@ -37,34 +61,47 @@ module PacketGen::Plugin
|
|
37
61
|
|
38
62
|
str2 = case str.encoding
|
39
63
|
when Encoding::BINARY
|
40
|
-
|
41
|
-
0.step(to: str.size, by: 2) do |i|
|
42
|
-
binidx = i if str[i, 2] == binary_terminator
|
43
|
-
end
|
44
|
-
s = if binidx.nil?
|
45
|
-
str
|
46
|
-
else
|
47
|
-
str[0, binidx]
|
48
|
-
end
|
49
|
-
s.force_encoding(self_encoding)
|
64
|
+
str.dup.force_encoding(self_encoding)
|
50
65
|
else
|
51
66
|
str.encode(self_encoding)
|
52
67
|
end
|
53
|
-
str2 = str2[0, @static_length / 2] if @static_length.is_a? Integer
|
54
68
|
idx = str2.index(+"\x00".encode(self_encoding))
|
55
69
|
str2 = str2[0, idx] unless idx.nil?
|
56
|
-
|
70
|
+
@string = str2
|
57
71
|
self
|
58
72
|
end
|
59
73
|
|
74
|
+
# @return [String]
|
75
|
+
def to_s
|
76
|
+
str = string.dup.force_encoding('BINARY')
|
77
|
+
return str unless null_terminated?
|
78
|
+
|
79
|
+
str << binary_terminator.force_encoding('BINARY')
|
80
|
+
end
|
81
|
+
|
82
|
+
# Populate String from a human readable (ie UTF-8) string
|
83
|
+
# @param [String] str
|
84
|
+
# @return [self]
|
85
|
+
def from_human(str)
|
86
|
+
return self if str.nil?
|
87
|
+
|
88
|
+
@string = str.encode(self_encoding)
|
89
|
+
self
|
90
|
+
end
|
91
|
+
|
92
|
+
# @return [String]
|
93
|
+
def to_human
|
94
|
+
string.encode('UTF-8')
|
95
|
+
end
|
96
|
+
|
60
97
|
private
|
61
98
|
|
62
99
|
def self_encoding
|
63
|
-
@unicode ? Encoding::UTF_16LE : Encoding::
|
100
|
+
@unicode ? Encoding::UTF_16LE : Encoding::ASCII_8BIT
|
64
101
|
end
|
65
102
|
|
66
103
|
def binary_terminator
|
67
|
-
|
104
|
+
[0].pack('C').encode(self_encoding)
|
68
105
|
end
|
69
106
|
end
|
70
107
|
end
|
@@ -1,10 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# This file is part of packetgen-plugin-smb.
|
2
4
|
# See https://github.com/sdaubert/packetgen-plugin-smb for more informations
|
3
5
|
# Copyright (C) 2018 Sylvain Daubert <sylvain.daubert@laposte.net>
|
4
6
|
# This program is published under MIT license.
|
5
7
|
|
6
|
-
# frozen_string_literal: true
|
7
|
-
|
8
8
|
module PacketGen::Plugin
|
9
9
|
class SMB
|
10
10
|
module Trans
|
@@ -96,7 +96,7 @@ module PacketGen::Plugin
|
|
96
96
|
# 8-bit optional padding to align {#name} on a 2-byte boundary. Only present
|
97
97
|
# if {SMB#flags2_unicode?} is +true+.
|
98
98
|
# @return [Integer]
|
99
|
-
define_field :padname, PacketGen::Types::Int8, optional: ->(h) { h
|
99
|
+
define_field :padname, PacketGen::Types::Int8, optional: ->(h) { h&.packet&.smb&.flags2_unicode? }
|
100
100
|
# @!attribute name
|
101
101
|
# Pathname of the mailslot or named pipe.
|
102
102
|
# @return [String]
|
@@ -1,10 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# This file is part of packetgen-plugin-smb.
|
2
4
|
# See https://github.com/sdaubert/packetgen-plugin-smb for more informations
|
3
5
|
# Copyright (C) 2018 Sylvain Daubert <sylvain.daubert@laposte.net>
|
4
6
|
# This program is published under MIT license.
|
5
7
|
|
6
|
-
# frozen_string_literal: true
|
7
|
-
|
8
8
|
module PacketGen::Plugin
|
9
9
|
class SMB
|
10
10
|
module Trans
|
@@ -1,10 +1,10 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
# This file is part of packetgen-plugin-smb.
|
2
4
|
# See https://github.com/sdaubert/packetgen-plugin-smb for more informations
|
3
5
|
# Copyright (C) 2018 Sylvain Daubert <sylvain.daubert@laposte.net>
|
4
6
|
# This program is published under MIT license.
|
5
7
|
|
6
|
-
# frozen_string_literal: true
|
7
|
-
|
8
8
|
module PacketGen::Plugin
|
9
9
|
class SMB
|
10
10
|
# Namespace for TRANS related classes
|