packetgen-plugin-smb 0.6.3 → 0.7.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.
- checksums.yaml +4 -4
- data/.github/workflows/specs.yml +7 -3
- data/.rubocop.yml +5 -5
- data/Gemfile +7 -7
- data/README.md +8 -4
- data/examples/llmnr-responder +2 -2
- data/examples/smb-responder +8 -8
- data/lib/packetgen/plugin/gssapi.rb +7 -5
- data/lib/packetgen/plugin/netbios/datagram.rb +25 -27
- data/lib/packetgen/plugin/netbios/name.rb +3 -3
- data/lib/packetgen/plugin/netbios/session.rb +3 -3
- data/lib/packetgen/plugin/netbios.rb +0 -2
- data/lib/packetgen/plugin/ntlm/authenticate.rb +7 -7
- data/lib/packetgen/plugin/ntlm/av_pair.rb +17 -17
- data/lib/packetgen/plugin/ntlm/challenge.rb +4 -4
- data/lib/packetgen/plugin/ntlm/negotiate.rb +6 -6
- data/lib/packetgen/plugin/ntlm/ntlmv2_response.rb +10 -10
- data/lib/packetgen/plugin/ntlm.rb +21 -22
- data/lib/packetgen/plugin/smb/blocks.rb +8 -8
- data/lib/packetgen/plugin/smb/browser/domain_announcement.rb +1 -1
- data/lib/packetgen/plugin/smb/browser/host_announcement.rb +12 -12
- data/lib/packetgen/plugin/smb/browser/local_master_announcement.rb +1 -1
- data/lib/packetgen/plugin/smb/browser.rb +5 -5
- data/lib/packetgen/plugin/smb/close/request.rb +4 -4
- data/lib/packetgen/plugin/smb/close/response.rb +3 -3
- data/lib/packetgen/plugin/smb/filetime.rb +4 -6
- data/lib/packetgen/plugin/smb/negotiate/dialect.rb +5 -5
- data/lib/packetgen/plugin/smb/negotiate/request.rb +4 -4
- data/lib/packetgen/plugin/smb/ntcreateandx/request.rb +23 -23
- data/lib/packetgen/plugin/smb/ntcreateandx/response.rb +21 -21
- data/lib/packetgen/plugin/smb/string.rb +1 -1
- data/lib/packetgen/plugin/smb/trans/request.rb +24 -23
- data/lib/packetgen/plugin/smb/trans/response.rb +18 -17
- data/lib/packetgen/plugin/smb.rb +52 -62
- data/lib/packetgen/plugin/smb2/base.rb +4 -4
- data/lib/packetgen/plugin/smb2/error.rb +6 -6
- data/lib/packetgen/plugin/smb2/guid.rb +12 -12
- data/lib/packetgen/plugin/smb2/negotiate/context.rb +19 -19
- data/lib/packetgen/plugin/smb2/negotiate/request.rb +27 -27
- data/lib/packetgen/plugin/smb2/negotiate/response.rb +31 -26
- data/lib/packetgen/plugin/smb2/session_setup/request.rb +9 -11
- data/lib/packetgen/plugin/smb2/session_setup/response.rb +5 -6
- data/lib/packetgen/plugin/smb2.rb +49 -55
- data/lib/packetgen/plugin/smb_version.rb +1 -1
- data/packetgen-plugin-smb.gemspec +3 -3
- metadata +12 -37
@@ -8,7 +8,7 @@
|
|
8
8
|
module PacketGen::Plugin
|
9
9
|
# Base class for NTLM authentication protocol.
|
10
10
|
# @author Sylvain Daubert
|
11
|
-
class NTLM <
|
11
|
+
class NTLM < BinStruct::Struct
|
12
12
|
# NTLM message types
|
13
13
|
TYPES = {
|
14
14
|
'negotiate' => 1,
|
@@ -26,16 +26,16 @@ module PacketGen::Plugin
|
|
26
26
|
# @!attribute signature
|
27
27
|
# 8-byte NTLM signature
|
28
28
|
# @return [String]
|
29
|
-
|
29
|
+
define_attr :signature, BinStruct::String, static_length: 8, default: SIGNATURE
|
30
30
|
# @!attribute type
|
31
31
|
# 4-byte message type
|
32
32
|
# @return [Integer]
|
33
|
-
|
33
|
+
define_attr :type, BinStruct::Int32leEnum, enum: TYPES
|
34
34
|
# @!attribute payload
|
35
35
|
# @return [String]
|
36
|
-
|
36
|
+
define_attr :payload, BinStruct::String
|
37
37
|
|
38
|
-
class <<self
|
38
|
+
class << self
|
39
39
|
# @api private
|
40
40
|
# Return fields defined in payload one.
|
41
41
|
# @return [Hash]
|
@@ -55,16 +55,15 @@ module PacketGen::Plugin
|
|
55
55
|
|
56
56
|
# Define a flags field.
|
57
57
|
# @return [void]
|
58
|
-
def define_negotiate_flags
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
:flags_b, :flags_a
|
58
|
+
def define_negotiate_flags # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
|
59
|
+
define_bit_attr_before :payload, :flags, endian: :little, flags_w: 1, flags_v: 1, flags_u: 1, flags_r13: 3,
|
60
|
+
flags_t: 1, flags_r4: 1, flags_s: 1, flags_r: 1,
|
61
|
+
flags_r5: 1, flags_q: 1, flags_p: 1, flags_r6: 1,
|
62
|
+
flags_o: 1, flags_n: 1, flags_m: 1, flags_r7: 1,
|
63
|
+
flags_l: 1, flags_k: 1, flags_j: 1, flags_r8: 1,
|
64
|
+
flags_h: 1, flags_r9: 1, flags_g: 1, flags_f: 1,
|
65
|
+
flags_e: 1, flags_d: 1, flags_r10: 1, flags_c: 1,
|
66
|
+
flags_b: 1, flags_a: 1
|
68
67
|
alias_method :nego56?, :flags_w?
|
69
68
|
alias_method :key_exch?, :flags_v?
|
70
69
|
alias_method :nego128?, :flags_u?
|
@@ -93,7 +92,7 @@ module PacketGen::Plugin
|
|
93
92
|
class_eval do
|
94
93
|
def flags_a=(value)
|
95
94
|
self.old_flags_a = value
|
96
|
-
self.class.payload_fields.
|
95
|
+
self.class.payload_fields.each_key do |name|
|
97
96
|
attr = send(name)
|
98
97
|
attr.unicode = value if attr.respond_to?(:unicode=)
|
99
98
|
end
|
@@ -118,9 +117,9 @@ module PacketGen::Plugin
|
|
118
117
|
@payload_fields ||= {}
|
119
118
|
@payload_fields[name] = [type, options]
|
120
119
|
|
121
|
-
|
122
|
-
|
123
|
-
|
120
|
+
define_attr_before :payload, :"#{name}_len", BinStruct::Int16le
|
121
|
+
define_attr_before :payload, :"#{name}_maxlen", BinStruct::Int16le
|
122
|
+
define_attr_before :payload, :"#{name}_offset", BinStruct::Int32le
|
124
123
|
|
125
124
|
attr_accessor name
|
126
125
|
end
|
@@ -146,7 +145,7 @@ module PacketGen::Plugin
|
|
146
145
|
# Populate object from a binary string
|
147
146
|
# @param [String] str
|
148
147
|
# @return [self]
|
149
|
-
def read(str)
|
148
|
+
def read(str) # rubocop:disable Metrics/AbcSize
|
150
149
|
super
|
151
150
|
return self if self.class.payload_fields.nil?
|
152
151
|
|
@@ -174,7 +173,7 @@ module PacketGen::Plugin
|
|
174
173
|
return self if self.class.payload_fields.nil?
|
175
174
|
|
176
175
|
previous_len = 0
|
177
|
-
self.class.payload_fields.
|
176
|
+
self.class.payload_fields.each_key do |name|
|
178
177
|
send(:"#{name}_len=", 0)
|
179
178
|
send(:"#{name}_offset=", offset_of(:payload) + previous_len)
|
180
179
|
|
@@ -194,7 +193,7 @@ module PacketGen::Plugin
|
|
194
193
|
s = super
|
195
194
|
return s if self.class.payload_fields.nil?
|
196
195
|
|
197
|
-
self.class.payload_fields.
|
196
|
+
self.class.payload_fields.each_key do |name|
|
198
197
|
attr = send(name)
|
199
198
|
attr.unicode = unicode? if attr.respond_to?(:unicode=)
|
200
199
|
s << attr.to_s unless attr.nil? || send("#{name}_len").zero?
|
@@ -12,28 +12,28 @@ module PacketGen::Plugin
|
|
12
12
|
# {Blocks} handles parameter block and data block. Parameter block is
|
13
13
|
# composed of:
|
14
14
|
# * a 8-bit {#word_count} field,
|
15
|
-
# * a {#words} field, an array of +
|
15
|
+
# * a {#words} field, an array of +BinStruct::Int16le+.
|
16
16
|
# Data block is composed of:
|
17
17
|
# * a little endian 16-bit {#byte_count} field,
|
18
|
-
# * a {#bytes} field, an array of +
|
18
|
+
# * a {#bytes} field, an array of +BinStruct::Int8+.
|
19
19
|
# @author Sylvain Daubert
|
20
20
|
class Blocks < PacketGen::Header::Base
|
21
21
|
# @!attribute word_count
|
22
22
|
# The size, in 2-byte words, of the {#words} field.
|
23
23
|
# @return [Integer]
|
24
|
-
|
24
|
+
define_attr :word_count, BinStruct::Int8
|
25
25
|
# @!attribute words
|
26
26
|
# The message-specific parameters structure.
|
27
|
-
# @return [
|
28
|
-
|
27
|
+
# @return [BinStruct::ArrayOfInt16le]
|
28
|
+
define_attr :words, BinStruct::ArrayOfInt16le, builder: ->(h, t) { t.new(counter: h[:word_count]) }
|
29
29
|
# @!attribute byte_count
|
30
30
|
# The size, in bytes, of the {#bytes} field.
|
31
31
|
# @return [Integer]
|
32
|
-
|
32
|
+
define_attr :byte_count, BinStruct::Int16le
|
33
33
|
# @!attribute bytes
|
34
34
|
# The message-specific data structure.
|
35
|
-
# @return [
|
36
|
-
|
35
|
+
# @return [BinStruct::ArrayOfInt8]
|
36
|
+
define_attr :bytes, BinStruct::ArrayOfInt8, builder: ->(h, t) { t.new(counter: h[:byte_count]) }
|
37
37
|
|
38
38
|
# Give protocol name for this class
|
39
39
|
# @return [String]
|
@@ -14,7 +14,7 @@ module PacketGen::Plugin
|
|
14
14
|
# announce the machine group it serves.
|
15
15
|
# @author Sylvain Daubert
|
16
16
|
class DomainAnnouncement < HostAnnouncement
|
17
|
-
|
17
|
+
update_attr :opcode, default: 12
|
18
18
|
|
19
19
|
alias browser_conf_ver_maj os_ver_maj
|
20
20
|
alias browser_conf_ver_min os_ver_min
|
@@ -22,50 +22,50 @@ module PacketGen::Plugin
|
|
22
22
|
@protocol_name = "SMB::Browser::#{basename}"
|
23
23
|
end
|
24
24
|
|
25
|
-
|
26
|
-
|
25
|
+
remove_attr :body
|
26
|
+
update_attr :opcode, default: 1
|
27
27
|
# @!attribute update_count
|
28
28
|
# 8-bit integer. Not used. Should be 0
|
29
29
|
# @return [Integer]
|
30
|
-
|
30
|
+
define_attr :update_count, BinStruct::Int8, default: 0
|
31
31
|
# @!attribute periodicity
|
32
32
|
# 32-bit integer that must be the announcement frequency of the
|
33
33
|
# server in milliseconds.
|
34
34
|
# @return [Integer]
|
35
|
-
|
35
|
+
define_attr :periodicity, BinStruct::Int32le
|
36
36
|
# @!attribute server_name
|
37
37
|
# Null-terminated ASCII string of 16-byte length. Used to identify
|
38
38
|
# server.
|
39
39
|
# @return [String]
|
40
|
-
|
40
|
+
define_attr :server_name, BinStruct::CString, static_length: 16
|
41
41
|
# @!attribute os_ver_maj
|
42
42
|
# 8-bit integer indicating the OS major version number
|
43
43
|
# @return [Integer]
|
44
|
-
|
44
|
+
define_attr :os_ver_maj, BinStruct::Int8
|
45
45
|
# @!attribute os_ver_min
|
46
46
|
# 8-bit integer indicating the OS minor version number
|
47
47
|
# @return [Integer]
|
48
|
-
|
48
|
+
define_attr :os_ver_min, BinStruct::Int8
|
49
49
|
# @!attribute server_type
|
50
50
|
# 32-bit integer indicating the type of the server
|
51
51
|
# @return [Integer]
|
52
|
-
|
52
|
+
define_attr :server_type, BinStruct::Int32le
|
53
53
|
# @!attribute browser_ver_maj
|
54
54
|
# 8-bit Browser protocol major version number. Should be 15.
|
55
55
|
# @return [Integer]
|
56
|
-
|
56
|
+
define_attr :browser_ver_maj, BinStruct::Int8, default: 15
|
57
57
|
# @!attribute browser_ver_min
|
58
58
|
# 8-bit Browser protocol minor version number. Should be 1.
|
59
59
|
# @return [Integer]
|
60
|
-
|
60
|
+
define_attr :browser_ver_min, BinStruct::Int8, default: 1
|
61
61
|
# @!attribute signature
|
62
62
|
# 16-bit sinature integer. Should be 0xAA55.
|
63
63
|
# @return [Integer]
|
64
|
-
|
64
|
+
define_attr :signature, BinStruct::Int16le, default: 0xaa55
|
65
65
|
# @!attribute comment
|
66
66
|
# Null-terminated ASCII string.
|
67
67
|
# @return [String]
|
68
|
-
|
68
|
+
define_attr :comment, BinStruct::CString
|
69
69
|
end
|
70
70
|
PacketGen::Header.add_class HostAnnouncement
|
71
71
|
SMB::Trans::Request.bind HostAnnouncement, name: '\\MAILSLOT\\BROWSE', body: ->(v) { v[0] == OPCODES['HostAnnouncement'] }
|
@@ -14,7 +14,7 @@ module PacketGen::Plugin
|
|
14
14
|
# advertise its presence.
|
15
15
|
# @author Sylvain Daubert
|
16
16
|
class LocalMasterAnnouncement < HostAnnouncement
|
17
|
-
|
17
|
+
update_attr :opcode, default: 15
|
18
18
|
end
|
19
19
|
PacketGen::Header.add_class LocalMasterAnnouncement
|
20
20
|
SMB::Trans::Request.bind LocalMasterAnnouncement, name: '\\MAILSLOT\\BROWSE', body: ->(v) { v[0] == OPCODES['LocalMasterAnnouncement'] }
|
@@ -33,10 +33,10 @@ module PacketGen::Plugin
|
|
33
33
|
# @!attribute opcode
|
34
34
|
# 8-bit opcode
|
35
35
|
# @return [Integer]
|
36
|
-
|
36
|
+
define_attr :opcode, BinStruct::Int8Enum, enum: OPCODES
|
37
37
|
# @!attribute body
|
38
38
|
# @return [String]
|
39
|
-
|
39
|
+
define_attr :body, BinStruct::String
|
40
40
|
|
41
41
|
alias old_read read
|
42
42
|
private :old_read
|
@@ -46,10 +46,10 @@ module PacketGen::Plugin
|
|
46
46
|
# @return [Browser] may return a subclass object if a more specific class
|
47
47
|
# may be determined
|
48
48
|
def read(str)
|
49
|
-
if self.
|
49
|
+
if self.instance_of?(Browser)
|
50
50
|
return self if str.nil?
|
51
51
|
|
52
|
-
|
52
|
+
str = str.b
|
53
53
|
self[:opcode].read str[0]
|
54
54
|
|
55
55
|
opcode_klass = Browser.const_get(self[:opcode].to_human) if Browser.const_defined?(self[:opcode].to_human)
|
@@ -71,7 +71,7 @@ module PacketGen::Plugin
|
|
71
71
|
def added_to_packet(packet)
|
72
72
|
return if packet.respond_to? :smb_browser
|
73
73
|
|
74
|
-
packet.instance_eval("def smb_browser(arg=nil); header(#{self.class}, arg); end")
|
74
|
+
packet.instance_eval("def smb_browser(arg=nil); header(#{self.class}, arg); end") # def smb_browser(arg=nil); header(Browser, arg); end
|
75
75
|
end
|
76
76
|
|
77
77
|
private
|
@@ -16,11 +16,11 @@ module PacketGen::Plugin
|
|
16
16
|
# The size, in 2-byte words, of the SMB command parameters. It should
|
17
17
|
# be +3+.
|
18
18
|
# @return [Integer]
|
19
|
-
|
19
|
+
define_attr :word_count, BinStruct::Int8, default: 3
|
20
20
|
# @!attribute fid
|
21
21
|
# 16-bit FID of the object to close
|
22
22
|
# @return [Integer]
|
23
|
-
|
23
|
+
define_attr :fid, BinStruct::Int16le, default: 3
|
24
24
|
# @!attribute last_modified
|
25
25
|
# 32-bit time value encoded as the number of seconds since January
|
26
26
|
# 1, 1970 00:00:00.0. The client can request that the last modification
|
@@ -28,11 +28,11 @@ module PacketGen::Plugin
|
|
28
28
|
# or +0xFFFFFFFF+ results in the server not updating the last modification
|
29
29
|
# time.
|
30
30
|
# @return [Integer]
|
31
|
-
|
31
|
+
define_attr :last_modified, BinStruct::Int32le
|
32
32
|
# @!attribute byte_count
|
33
33
|
# Should be 0.
|
34
34
|
# @return [Integer]
|
35
|
-
|
35
|
+
define_attr :byte_count, BinStruct::Int16le, default: 0
|
36
36
|
|
37
37
|
# Give protocol name for this class
|
38
38
|
# @return [String]
|
@@ -18,12 +18,12 @@ module PacketGen::Plugin
|
|
18
18
|
# The size, in 2-byte words, of the SMB command parameters. It should
|
19
19
|
# be +0+.
|
20
20
|
# @return [Integer]
|
21
|
-
|
22
|
-
|
21
|
+
define_attr :word_count, BinStruct::Int8, default: 3
|
22
|
+
define_attr :last_modified, BinStruct::Int32le
|
23
23
|
# @!attribute byte_count
|
24
24
|
# Should be 0.
|
25
25
|
# @return [Integer]
|
26
|
-
|
26
|
+
define_attr :byte_count, BinStruct::Int16le, default: 0
|
27
27
|
|
28
28
|
# Give protocol name for this class
|
29
29
|
# @return [String]
|
@@ -10,7 +10,7 @@ module PacketGen::Plugin
|
|
10
10
|
# SMB FILETIME.
|
11
11
|
# @author Sylvain Daubert
|
12
12
|
class Filetime
|
13
|
-
include
|
13
|
+
include BinStruct::Structable
|
14
14
|
|
15
15
|
# Base time for SMB FILETIME.
|
16
16
|
# This value also indicate no time.
|
@@ -35,11 +35,9 @@ module PacketGen::Plugin
|
|
35
35
|
# @option options [Time] :time
|
36
36
|
# @raise [ArgumentError] if +:time+ and +:filetime+ are both given.
|
37
37
|
def initialize(options={})
|
38
|
-
if
|
39
|
-
raise ArgumentError, ':time and :filetime options are both given'
|
40
|
-
end
|
38
|
+
raise ArgumentError, ':time and :filetime options are both given' if options.key?(:time) && options.key?(:filetime)
|
41
39
|
|
42
|
-
@int =
|
40
|
+
@int = BinStruct::SInt64le.new(value: options[:filetime])
|
43
41
|
if options[:time]
|
44
42
|
@time = options[:time].getgm
|
45
43
|
@int.value = time2filetime
|
@@ -123,7 +121,7 @@ module PacketGen::Plugin
|
|
123
121
|
def time2filetime
|
124
122
|
# Time#to_f then #to_r is more precise than Time#to_r
|
125
123
|
# (ie Time#to_r sometimes does a rounding error).
|
126
|
-
(@time.to_i - NO_TIME.to_i) * ONE_SEC + ((@time.to_f.to_r * ONE_SEC) % ONE_SEC).to_i
|
124
|
+
((@time.to_i - NO_TIME.to_i) * ONE_SEC) + ((@time.to_f.to_r * ONE_SEC) % ONE_SEC).to_i
|
127
125
|
end
|
128
126
|
end
|
129
127
|
end
|
@@ -12,16 +12,16 @@ module PacketGen::Plugin
|
|
12
12
|
# * a 8-bit {#format} field, which should be set to 0x02,
|
13
13
|
# * a null-terminated string identifying a SMB dialect.
|
14
14
|
# @author Sylvain Daubert
|
15
|
-
class Dialect <
|
15
|
+
class Dialect < BinStruct::Struct
|
16
16
|
# @!attribute format
|
17
17
|
# 8-bit format. Should be +2+ to indicate a null-terminated string for
|
18
18
|
# {#dialect} field.
|
19
19
|
# @return [Integer]
|
20
|
-
|
20
|
+
define_attr :format, BinStruct::Int8, default: 2
|
21
21
|
# @!attribute dialect
|
22
22
|
# Null-terminated string identifying a SMB dialect.
|
23
23
|
# @return [String]
|
24
|
-
|
24
|
+
define_attr :dialect, BinStruct::CString
|
25
25
|
|
26
26
|
# @return [String]
|
27
27
|
def to_human
|
@@ -29,9 +29,9 @@ module PacketGen::Plugin
|
|
29
29
|
end
|
30
30
|
end
|
31
31
|
|
32
|
-
# Specialized {
|
32
|
+
# Specialized {BinStruct::Array} to embed {Dialect Dialects}.
|
33
33
|
# @author Sylvain Daubert
|
34
|
-
class ArrayOfDialect <
|
34
|
+
class ArrayOfDialect < BinStruct::Array
|
35
35
|
set_of Dialect
|
36
36
|
end
|
37
37
|
end
|
@@ -18,13 +18,13 @@ module PacketGen::Plugin
|
|
18
18
|
# The size, in 2-byte words, of the SMB command parameters. It should
|
19
19
|
# be +0+ setup_count+.
|
20
20
|
# @return [Integer]
|
21
|
-
|
21
|
+
define_attr :word_count, BinStruct::Int8, default: 0
|
22
22
|
# @!attribute byte_count
|
23
23
|
# @return [Integer]
|
24
|
-
|
24
|
+
define_attr :byte_count, BinStruct::Int16le
|
25
25
|
# @!attribute dialects
|
26
26
|
# @return [ArrayOfDialect]
|
27
|
-
|
27
|
+
define_attr :dialects, ArrayOfDialect
|
28
28
|
|
29
29
|
def self.protocol_name
|
30
30
|
'SMB::Negotiate::Request'
|
@@ -32,4 +32,4 @@ module PacketGen::Plugin
|
|
32
32
|
end
|
33
33
|
end
|
34
34
|
end
|
35
|
-
end
|
35
|
+
end
|
@@ -24,7 +24,7 @@ module PacketGen::Plugin
|
|
24
24
|
# * {#root_dir_fid} (+Int32le+),
|
25
25
|
# * {#access_mask} (+Int32le+),
|
26
26
|
# * {#alloc_size} (+Int64le+),
|
27
|
-
# * {#
|
27
|
+
# * {#fattributes} (+Int32le+),
|
28
28
|
# * {#share_access} (+Int32le+),
|
29
29
|
# * {#disposition} (+Int32le+),
|
30
30
|
# * {#options} (+Int32le+),
|
@@ -51,93 +51,93 @@ module PacketGen::Plugin
|
|
51
51
|
# @!attribute word_count
|
52
52
|
# The size, in 2-byte words, of the SMB parameters.
|
53
53
|
# @return [Integer]
|
54
|
-
|
54
|
+
define_attr :word_count, BinStruct::Int8, default: 24
|
55
55
|
# @!attribute and_xcommand
|
56
56
|
# 8-bit command code for the next SMB command in the
|
57
57
|
# packet.
|
58
58
|
# @return [Integer]
|
59
|
-
|
59
|
+
define_attr :and_xcommand, BinStruct::Int8Enum, enum: COMMANDS
|
60
60
|
# @!attribute rsv1
|
61
61
|
# 8-bit reserved field.
|
62
62
|
# @return [Integer]
|
63
|
-
|
63
|
+
define_attr :rsv1, BinStruct::Int8, default: 0
|
64
64
|
# @!attribute and_xoffset
|
65
65
|
# 16-bit offset from the start of SMB header to the start of
|
66
66
|
# the {#word_count} field in the next SMB command in this
|
67
67
|
# packet.
|
68
68
|
# @return [Integer]
|
69
|
-
|
69
|
+
define_attr :and_xoffset, BinStruct::Int16le, default: 0
|
70
70
|
# @!attribute rsv2
|
71
71
|
# 8-bit reserved field.
|
72
72
|
# @return [Integer]
|
73
|
-
|
73
|
+
define_attr :rsv2, BinStruct::Int8, default: 0
|
74
74
|
# @!attribute filename_len
|
75
75
|
# 16-bit length of the {#filename} field.
|
76
76
|
# @return [Integer]
|
77
|
-
|
77
|
+
define_attr :filename_len, BinStruct::Int16le
|
78
78
|
alias filename_length filename_len
|
79
79
|
alias filename_length= filename_len=
|
80
80
|
# @!attribute flags
|
81
81
|
# 32-bit flags word
|
82
82
|
# @return [Integer]
|
83
|
-
|
83
|
+
define_attr :flags, BinStruct::Int32le
|
84
84
|
# @!attribute root_dir_fid
|
85
85
|
# 32-bit file ID of an opened root directory.
|
86
86
|
# @return [Integer]
|
87
|
-
|
87
|
+
define_attr :root_dir_fid, BinStruct::Int32le
|
88
88
|
# @!attribute access_mask
|
89
89
|
# 32-bit flags that indicate access rights.
|
90
90
|
# @return [Integer]
|
91
|
-
|
91
|
+
define_attr :access_mask, BinStruct::Int32le
|
92
92
|
# @!attribute alloc_size
|
93
93
|
# 64-bit initial allocation size.
|
94
94
|
# @return [Integer]
|
95
|
-
|
96
|
-
# @!attribute
|
95
|
+
define_attr :alloc_size, BinStruct::Int64le
|
96
|
+
# @!attribute fattributes
|
97
97
|
# 32-bit extended file attributes.
|
98
98
|
# @return [Integer]
|
99
|
-
|
99
|
+
define_attr :fattributes, BinStruct::Int32le
|
100
100
|
# @!attribute share_access
|
101
101
|
# 32-bit field that specifies how the file should be shared.
|
102
102
|
# @return [Integer]
|
103
|
-
|
103
|
+
define_attr :share_access, BinStruct::Int32le
|
104
104
|
# @!attribute disposition
|
105
105
|
# 32-bit value that represents the action to take if the file
|
106
106
|
# already exists or if the file is a new file and does not already
|
107
107
|
# exist.
|
108
108
|
# @return [Integer]
|
109
|
-
|
109
|
+
define_attr :disposition, BinStruct::Int32le
|
110
110
|
# @!attribute options
|
111
111
|
# 32-bit field containing flag options to use if creating the file
|
112
112
|
# or the directory.
|
113
113
|
# @return [Integer]
|
114
|
-
|
114
|
+
define_attr :options, BinStruct::Int32le
|
115
115
|
# @!attribute impersonation
|
116
116
|
# 32-bit field specifying the impersonation level requested by
|
117
117
|
# the application.
|
118
118
|
# @return [Integer]
|
119
|
-
|
119
|
+
define_attr :impersonation, BinStruct::Int32le
|
120
120
|
# @!attribute sec_flags
|
121
121
|
# 8-bit security flags.
|
122
|
-
|
122
|
+
define_attr :sec_flags, BinStruct::Int8
|
123
123
|
# @!attribute byte_count
|
124
124
|
# The size, in bytes, of the SMB data.
|
125
125
|
# @return [Integer]
|
126
|
-
|
126
|
+
define_attr :byte_count, BinStruct::Int16le
|
127
127
|
# @!attribute pad1
|
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
|
-
|
131
|
+
define_attr :pad1, BinStruct::Int8, optional: ->(h) { h&.packet&.smb&.flags2_unicode? } # rubocop:disable Style/SafeNavigationChainLength
|
132
132
|
# @!attribute filename
|
133
133
|
# A string that represents the fully qualified name of the file
|
134
134
|
# relative to the supplied TID
|
135
135
|
# @return [String]
|
136
|
-
|
136
|
+
define_attr :filename, SMB::String, builder: ->(h, t) { t.new(unicode: !h.packet || h.packet.smb.flags2_unicode?) }
|
137
137
|
# @!attribute extra_bytes
|
138
138
|
# @return [Integer]
|
139
|
-
|
140
|
-
|
139
|
+
define_attr :extra_bytes, BinStruct::String,
|
140
|
+
builder: ->(h, t) { t.new(length_from: -> { h.byte_count - (h.present?(:pad1) ? 1 : 0) - h[:filename].sz }) }
|
141
141
|
|
142
142
|
# Give protocol name for this class
|
143
143
|
# @return [String]
|
@@ -23,81 +23,81 @@ module PacketGen::Plugin
|
|
23
23
|
# @!attribute word_count
|
24
24
|
# The size, in 2-byte words, of the SMB parameters.
|
25
25
|
# @return [Integer]
|
26
|
-
|
26
|
+
define_attr :word_count, BinStruct::Int8, default: 34
|
27
27
|
# @!attribute and_xcommand
|
28
28
|
# 8-bit command code for the next SMB command in the
|
29
29
|
# packet.
|
30
30
|
# @return [Integer]
|
31
|
-
|
31
|
+
define_attr :and_xcommand, BinStruct::Int8Enum, enum: Request::COMMANDS
|
32
32
|
# @!attribute rsv1
|
33
33
|
# 8-bit reserved field.
|
34
34
|
# @return [Integer]
|
35
|
-
|
35
|
+
define_attr :rsv1, BinStruct::Int8, default: 0
|
36
36
|
# @!attribute and_xoffset
|
37
37
|
# 16-bit offset from the start of SMB header to the start of
|
38
38
|
# the {#word_count} field in the next SMB command in this
|
39
39
|
# packet.
|
40
40
|
# @return [Integer]
|
41
|
-
|
41
|
+
define_attr :and_xoffset, BinStruct::Int16le, default: 0
|
42
42
|
# @!attribute oplock_level
|
43
43
|
# 8-bit OpLock level.
|
44
44
|
# @return [Integer]
|
45
|
-
|
45
|
+
define_attr :oplock_level, BinStruct::Int8Enum, enum: OP_LOCK_LEVELS
|
46
46
|
# @!attribute fid
|
47
47
|
# 16-bit FID.
|
48
48
|
# @return [Integer]
|
49
|
-
|
49
|
+
define_attr :fid, BinStruct::Int16le
|
50
50
|
# @!attribute disposition
|
51
51
|
# 32-bit value that represents the action to take if the file
|
52
52
|
# already exists or if the file is a new file and does not already
|
53
53
|
# exist.
|
54
54
|
# @return [Integer]
|
55
|
-
|
55
|
+
define_attr :disposition, BinStruct::Int32le
|
56
56
|
# @!attribute create_time
|
57
57
|
# 64-bit integer representing the time that the file was created.
|
58
58
|
# @return [Integer]
|
59
|
-
|
59
|
+
define_attr :create_time, SMB::Filetime
|
60
60
|
# @!attribute access_time
|
61
61
|
# 64-bit integer representing the time that the file was last accessed.
|
62
62
|
# @return [Integer]
|
63
|
-
|
63
|
+
define_attr :access_time, SMB::Filetime
|
64
64
|
# @!attribute write_time
|
65
65
|
# 64-bit integer representing the time that the file was last writen.
|
66
66
|
# @return [Integer]
|
67
|
-
|
67
|
+
define_attr :write_time, SMB::Filetime
|
68
68
|
# @!attribute change_time
|
69
69
|
# 64-bit integer representing the time that the file was last changed.
|
70
70
|
# @return [Integer]
|
71
|
-
|
72
|
-
# @!attribute
|
71
|
+
define_attr :change_time, SMB::Filetime
|
72
|
+
# @!attribute fattributes
|
73
73
|
# 32-bit extended file attributes.
|
74
74
|
# @return [Integer]
|
75
|
-
|
75
|
+
define_attr :fattributes, BinStruct::Int32le
|
76
76
|
# @!attribute alloc_size
|
77
77
|
# 64-bit integer representing the number of bytes allocated to the file.
|
78
78
|
# @return [Integer]
|
79
|
-
|
79
|
+
define_attr :alloc_size, BinStruct::Int64le
|
80
80
|
# @!attribute end_of_file
|
81
81
|
# 64-bit integer representing the end of file offset.
|
82
82
|
# @return [Integer]
|
83
|
-
|
83
|
+
define_attr :end_of_file, BinStruct::Int64le
|
84
84
|
# @!attribute res_type
|
85
85
|
# 16-bit file type.
|
86
86
|
# @return [Integer]
|
87
|
-
|
87
|
+
define_attr :res_type, BinStruct::Int16le
|
88
88
|
# @!attribute pipe_status
|
89
89
|
# 16-bit field that shows the status of the named pipe (if opened resource
|
90
90
|
# is a named pipe).
|
91
91
|
# @return [Integer]
|
92
|
-
|
92
|
+
define_attr :pipe_status, BinStruct::Int16le
|
93
93
|
# @!attribute directory
|
94
94
|
# 8-bit field indicating is the FID represents a directory.
|
95
95
|
# @return [Integer]
|
96
|
-
|
96
|
+
define_attr :directory, BinStruct::Int8
|
97
97
|
# @!attribute byte_count
|
98
98
|
# The size, in bytes, of the SMB data. Should be zero.
|
99
99
|
# @return [Integer]
|
100
|
-
|
100
|
+
define_attr :byte_count, BinStruct::Int16le, default: 0
|
101
101
|
|
102
102
|
# Give protocol name for this class
|
103
103
|
# @return [String]
|
@@ -108,7 +108,7 @@ module PacketGen::Plugin
|
|
108
108
|
# Say if FID is a directory
|
109
109
|
# @return [Boolean]
|
110
110
|
def directory?
|
111
|
-
self.directory
|
111
|
+
self.directory.positive?
|
112
112
|
end
|
113
113
|
|
114
114
|
# @!method human_create_time
|
@@ -120,7 +120,7 @@ module PacketGen::Plugin
|
|
120
120
|
# @!method human_change_time
|
121
121
|
# @return [String]
|
122
122
|
%i[create access write change].each do |type|
|
123
|
-
class_eval "def human_#{type}_time; self[:#{type}_time].to_human; end"
|
123
|
+
class_eval "def human_#{type}_time; self[:#{type}_time].to_human; end" # def human_create_time; self[:create_time].to_human; end
|
124
124
|
end
|
125
125
|
end
|
126
126
|
end
|
@@ -13,7 +13,7 @@ module PacketGen::Plugin
|
|
13
13
|
# @author Sylvain Daubert
|
14
14
|
class String
|
15
15
|
extend Forwardable
|
16
|
-
include
|
16
|
+
include BinStruct::Structable
|
17
17
|
|
18
18
|
def_delegators :@string, :[], :length, :size, :inspect, :==, :<<,
|
19
19
|
:unpack, :force_encoding, :encoding, :index, :empty?,
|