packetgen-plugin-smb 0.2.0 → 0.3.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/lib/packetgen-plugin-smb.rb +7 -5
- data/lib/packetgen/plugin/gssapi.rb +125 -0
- data/lib/packetgen/plugin/smb.rb +26 -32
- data/lib/packetgen/plugin/smb/blocks.rb +2 -2
- data/lib/packetgen/plugin/smb/browser.rb +3 -3
- data/lib/packetgen/plugin/smb/browser/domain_announcement.rb +3 -3
- data/lib/packetgen/plugin/smb/browser/host_announcement.rb +4 -4
- data/lib/packetgen/plugin/smb/browser/local_master_announcement.rb +3 -3
- data/lib/packetgen/plugin/smb/close.rb +9 -59
- data/lib/packetgen/plugin/smb/close/request.rb +45 -0
- data/lib/packetgen/plugin/smb/close/response.rb +36 -0
- data/lib/packetgen/plugin/smb/filetime.rb +10 -9
- data/lib/packetgen/plugin/smb/nt_create_and_x.rb +9 -264
- data/lib/packetgen/plugin/smb/ntcreateandx/request.rb +159 -0
- data/lib/packetgen/plugin/smb/ntcreateandx/response.rb +128 -0
- data/lib/packetgen/plugin/smb/string.rb +4 -4
- data/lib/packetgen/plugin/smb/trans.rb +9 -190
- data/lib/packetgen/plugin/smb/trans/request.rb +121 -0
- data/lib/packetgen/plugin/smb/trans/response.rb +94 -0
- data/lib/packetgen/plugin/smb2.rb +181 -0
- data/lib/packetgen/plugin/smb2/base.rb +31 -0
- data/lib/packetgen/plugin/smb2/error.rb +50 -0
- data/lib/packetgen/plugin/smb2/guid.rb +68 -0
- data/lib/packetgen/plugin/smb2/negotiate.rb +22 -0
- data/lib/packetgen/plugin/smb2/negotiate/context.rb +131 -0
- data/lib/packetgen/plugin/smb2/negotiate/request.rb +166 -0
- data/lib/packetgen/plugin/smb2/negotiate/response.rb +190 -0
- data/lib/packetgen/plugin/smb2/session_setup.rb +21 -0
- data/lib/packetgen/plugin/smb2/session_setup/request.rb +98 -0
- data/lib/packetgen/plugin/smb2/session_setup/response.rb +69 -0
- data/lib/packetgen/plugin/smb_version.rb +1 -1
- data/packetgen-plugin-smb.gemspec +2 -1
- metadata +42 -4
@@ -0,0 +1,94 @@
|
|
1
|
+
# This file is part of packetgen-plugin-smb.
|
2
|
+
# See https://github.com/sdaubert/packetgen-plugin-smb for more informations
|
3
|
+
# Copyright (C) 2018 Sylvain Daubert <sylvain.daubert@laposte.net>
|
4
|
+
# This program is published under MIT license.
|
5
|
+
|
6
|
+
# frozen_string_literal: true
|
7
|
+
|
8
|
+
module PacketGen::Plugin
|
9
|
+
class SMB
|
10
|
+
module Trans
|
11
|
+
# Transaction Response.
|
12
|
+
#
|
13
|
+
# See also {Blocks}, as {Response} is a specialization of {Blocks#words}
|
14
|
+
# and {Blocks#bytes}.
|
15
|
+
# @author Sylvain Daubert
|
16
|
+
class Response < PacketGen::Header::Base
|
17
|
+
# @!attribute word_count
|
18
|
+
# The size, in 2-byte words, of the SMB command parameters. It should
|
19
|
+
# be +14 + setup_count+.
|
20
|
+
# @return [Integer]
|
21
|
+
define_field :word_count, PacketGen::Types::Int8, default: 10
|
22
|
+
# @!attribute total_param_count
|
23
|
+
# The total number of transaction parameter bytes.
|
24
|
+
# @return [Integer]
|
25
|
+
define_field :total_param_count, PacketGen::Types::Int16le
|
26
|
+
# @!attribute total_data_count
|
27
|
+
# The total number of transaction data bytes.
|
28
|
+
# @return [Integer]
|
29
|
+
define_field :total_data_count, PacketGen::Types::Int16le
|
30
|
+
# @!attribute rsv1
|
31
|
+
# 16-bit reserved field
|
32
|
+
# @return [Integer]
|
33
|
+
define_field :rsv1, PacketGen::Types::Int16le, default: 0
|
34
|
+
# @!attribute param_count
|
35
|
+
# 16-bit number of transaction parameter bytes sent in this response.
|
36
|
+
# @return [Integer]
|
37
|
+
define_field :param_count, PacketGen::Types::Int16le
|
38
|
+
# @!attribute param_offset
|
39
|
+
# 16-bit offset (in bytes) from the start of the SMB header to the start of the
|
40
|
+
# transaction parameters.
|
41
|
+
# @return [Integer]
|
42
|
+
define_field :param_offset, PacketGen::Types::Int16le
|
43
|
+
# @!attribute param_displacement
|
44
|
+
# 16-bit offset (in bytes) relative to all of the transaction
|
45
|
+
# parameter bytes in this transaction response at which this block of
|
46
|
+
# parameter bytes SHOULD be placed.
|
47
|
+
# @return [Integer]
|
48
|
+
define_field :param_displacement, PacketGen::Types::Int16le
|
49
|
+
# @!attribute data_count
|
50
|
+
# 16-bit number of transaction data bytes sent in this response.
|
51
|
+
# @return [Integer]
|
52
|
+
define_field :data_count, PacketGen::Types::Int16le
|
53
|
+
# @!attribute data_offset
|
54
|
+
# 16-bit offset (in bytes) from the start of the SMB header to the start
|
55
|
+
# of the data field.
|
56
|
+
# @return [Integer]
|
57
|
+
define_field :data_offset, PacketGen::Types::Int16le
|
58
|
+
# @!attribute data_displacement
|
59
|
+
# 16-bit offset (in bytes) relative to all of the transaction data bytes in
|
60
|
+
# this transaction response at which this block of data bytes SHOULD be placed.
|
61
|
+
# @return [Integer]
|
62
|
+
define_field :data_displacement, PacketGen::Types::Int16le
|
63
|
+
# @!attribute setup_count
|
64
|
+
# 8-bit number of setup words (ie 16-bit words) contained in {#setup} field.
|
65
|
+
define_field :setup_count, PacketGen::Types::Int8
|
66
|
+
# @!attribute rsv3
|
67
|
+
# 8-bit reserved field
|
68
|
+
# @return [Integer]
|
69
|
+
define_field :rsv2, PacketGen::Types::Int8
|
70
|
+
# @!attribute setup
|
71
|
+
# Array of 2-byte words.
|
72
|
+
# @return [ArrayPacketGen::]
|
73
|
+
define_field :setup, PacketGen::Types::ArrayOfInt16le, builder: ->(h, t) { t.new(counter: h[:setup_count]) }
|
74
|
+
# @!attribute byte_count
|
75
|
+
# @return [Integer]
|
76
|
+
define_field :byte_count, PacketGen::Types::Int16le
|
77
|
+
# @!attribute pad1
|
78
|
+
# Padding before {#body} to align it on 32-bit boundary
|
79
|
+
# @return [Integer]
|
80
|
+
define_field :pad1, PacketGen::Types::String, default: "\0" * 4,
|
81
|
+
builder: ->(h, t) { t.new(length_from: -> { h.data_offset - SMB.new.sz - (h.offset_of(:byte_count) + h[:byte_count].sz) }) }
|
82
|
+
# @!attribute body
|
83
|
+
# @return [String]
|
84
|
+
define_field :body, PacketGen::Types::String
|
85
|
+
|
86
|
+
# Give protocol name for this class
|
87
|
+
# @return [String]
|
88
|
+
def protocol_name
|
89
|
+
'SMB::Trans::Response'
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
@@ -0,0 +1,181 @@
|
|
1
|
+
# This file is part of packetgen-plugin-smb.
|
2
|
+
# See https://github.com/sdaubert/packetgen-plugin-smb for more informations
|
3
|
+
# Copyright (C) 2018 Sylvain Daubert <sylvain.daubert@laposte.net>
|
4
|
+
# This program is published under MIT license.
|
5
|
+
|
6
|
+
# frozen_string_literal: true
|
7
|
+
|
8
|
+
module PacketGen::Plugin
|
9
|
+
# Server Message Block version 2 and 3 (SMB2) header.
|
10
|
+
# @author Sylvain Daubert
|
11
|
+
class SMB2 < PacketGen::Header::Base
|
12
|
+
# Known commands
|
13
|
+
COMMANDS = {
|
14
|
+
'negotiate' => 0,
|
15
|
+
'session_setup' => 1,
|
16
|
+
'logoff' => 2,
|
17
|
+
'tree_connect' => 3,
|
18
|
+
'tree_disconnect' => 4,
|
19
|
+
'create' => 5,
|
20
|
+
'close' => 6,
|
21
|
+
'flush' => 7,
|
22
|
+
'read' => 8,
|
23
|
+
'write' => 9,
|
24
|
+
'lock' => 10,
|
25
|
+
'ioctl' => 11,
|
26
|
+
'cancel' => 12,
|
27
|
+
'echo' => 13,
|
28
|
+
'query_directory' => 14,
|
29
|
+
'change_notify' => 15,
|
30
|
+
'query_info' => 16,
|
31
|
+
'set_info' => 17,
|
32
|
+
'oplock_break' => 18
|
33
|
+
}.freeze
|
34
|
+
|
35
|
+
# SMB marker, on start of header
|
36
|
+
MARKER = PacketGen.force_binary("\xfeSMB").freeze
|
37
|
+
|
38
|
+
# SMB2 header size
|
39
|
+
HEADER_SIZE = 64
|
40
|
+
|
41
|
+
# @!attribute protocol
|
42
|
+
# This field must contain {MARKER SMB2 marker}
|
43
|
+
# @return [String]
|
44
|
+
define_field :protocol, PacketGen::Types::String, static_length: 4, default: MARKER
|
45
|
+
# @!attribute structure_size
|
46
|
+
# 16-bit SMB2 header size. Should be 64.
|
47
|
+
# @return [Integer]
|
48
|
+
define_field :structure_size, PacketGen::Types::Int16le, default: HEADER_SIZE
|
49
|
+
# @!attribute credit charge
|
50
|
+
# 16-bit credit charge field. Must not be used and must be set to 0.
|
51
|
+
# @return [Integer]
|
52
|
+
define_field :credit_charge, PacketGen::Types::Int16le
|
53
|
+
# @!attribute status
|
54
|
+
# 32-bit status field (SMB 2 dialect only).
|
55
|
+
# @return [Integer]
|
56
|
+
define_field :status, PacketGen::Types::Int32le
|
57
|
+
# @!attribute command
|
58
|
+
# 16-bit command field
|
59
|
+
# @return [Integer]
|
60
|
+
define_field :command, PacketGen::Types::Int16leEnum, enum: COMMANDS
|
61
|
+
# @!attribute credit
|
62
|
+
# 16-bit credit field. This is the number of credits a client is requesting in
|
63
|
+
# a request, and the number of credits granted in a response.
|
64
|
+
# @return [Integer]
|
65
|
+
define_field :credit, PacketGen::Types::Int16le
|
66
|
+
# @!attribute flags
|
67
|
+
# 32-bit flags field
|
68
|
+
# @return [Integer]
|
69
|
+
define_field :flags, PacketGen::Types::Int32le
|
70
|
+
# @!attribute next_command
|
71
|
+
# 32-bit offset from the beginning of this SMB2 header to the start of the subsequent
|
72
|
+
# 8-byte aligned SMB2 header (only for compounded requests).
|
73
|
+
# @return [Integer]
|
74
|
+
define_field :next_command, PacketGen::Types::Int32le
|
75
|
+
# @!attribute message_id
|
76
|
+
# 64-bit alue that identifies a message request and response uniquely across all
|
77
|
+
# messages that are sent on the same SMB 2 Protocol transport connection.
|
78
|
+
# @return [Integer]
|
79
|
+
define_field :message_id, PacketGen::Types::Int64le
|
80
|
+
# @!attribute async_id
|
81
|
+
# 64-bit unique ID that is created by the server to handle operations
|
82
|
+
# asynchronously. Only present for asynchronous messages.
|
83
|
+
# @return [Integer]
|
84
|
+
define_field :async_id, PacketGen::Types::Int64le, optional: ->(h) { h.flags & 2 == 2}
|
85
|
+
# @!attribute reserved
|
86
|
+
# 32-bit reserved field.
|
87
|
+
# Only present for synchronous messages.
|
88
|
+
# @return [Integer]
|
89
|
+
define_field :reserved, PacketGen::Types::Int32le, optional: ->(h) { (h.flags & 2).zero? }
|
90
|
+
# @!attribute tree_id
|
91
|
+
# 32-bit integer that uniquely identifies the tree connect for the command.
|
92
|
+
# Only present for synchronous messages.
|
93
|
+
# @return [Integer]
|
94
|
+
define_field :tree_id, PacketGen::Types::Int32le, optional: ->(h) { (h.flags & 2).zero? }
|
95
|
+
# @!attribute session_id
|
96
|
+
# 64-bit integer that uniquely identifies the established session for the command.
|
97
|
+
# @return [Integer]
|
98
|
+
define_field :session_id, PacketGen::Types::Int64le
|
99
|
+
# @!attribute signature
|
100
|
+
# 16-byte message signature
|
101
|
+
# @return [String]
|
102
|
+
define_field :signature, PacketGen::Types::String, static_length: 16, default: [0, 0].pack('qq')
|
103
|
+
# @!attribute body
|
104
|
+
# @return [String]
|
105
|
+
define_field :body, PacketGen::Types::String
|
106
|
+
# @!attribute flags_rsv1
|
107
|
+
# 2-bit reserved field
|
108
|
+
# @return [Integer]
|
109
|
+
# @!attribute flags_smb3_replay_op?
|
110
|
+
# When set, the command is a replay operation (only SMB 3 dialect).
|
111
|
+
# @return [Boolean]
|
112
|
+
# @!attribute flags_dsf_op?
|
113
|
+
# When set, the command is a Distributed File System (DFS) operation..
|
114
|
+
# @return [Boolean]
|
115
|
+
# @!attribute flags_rsv2
|
116
|
+
# 21-bit reserved field
|
117
|
+
# @return [Integer]
|
118
|
+
# @!attribute flags_smb3_priority
|
119
|
+
# 3-bit value of I/O priority (only SMB 3 dialect).
|
120
|
+
# @return [Integer]
|
121
|
+
# @!attribute flags_signed?
|
122
|
+
# When set, the message is signed.
|
123
|
+
# @return [Boolean]
|
124
|
+
# @!attribute flags_related_op?
|
125
|
+
# When set, the message is a related operation in a compounded chain.
|
126
|
+
# @return [Boolean]
|
127
|
+
# @!attribute flags_async?
|
128
|
+
# When set, the message is a asynchronous.
|
129
|
+
# @return [Boolean]
|
130
|
+
# @!attribute flags_response?
|
131
|
+
# When set, the message is a response from server to client.
|
132
|
+
# @return [Boolean]
|
133
|
+
define_bit_fields_on :flags, :flags_rsv1, 2, :flags_smb3_replay_op, :flags_dfs_op,
|
134
|
+
:flags_rsv2, 21, :flags_smb3_priority, 3,
|
135
|
+
:flags_signed, :flags_related_op, :flags_async,
|
136
|
+
:flags_response
|
137
|
+
|
138
|
+
# Helper to bind a SMB2 command to {SMB2} header.
|
139
|
+
# @param [String] command name
|
140
|
+
# @return [void]
|
141
|
+
def self.bind_command(command)
|
142
|
+
contantized = command.capitalize.gsub(/_(\w)/) { $1.upcase }
|
143
|
+
krequest = self.const_get("#{contantized}::Request")
|
144
|
+
kresponse = self.const_get("#{contantized}::Response")
|
145
|
+
PacketGen::Header.add_class krequest
|
146
|
+
self.bind krequest, command: SMB2::COMMANDS[command], flags: ->(v) { v.nil? ? 0 : (v & 1).zero? }
|
147
|
+
PacketGen::Header.add_class kresponse
|
148
|
+
self.bind kresponse, command: SMB2::COMMANDS[command], flags: ->(v) { v.nil? ? 0 : (v & 1 == 1) }
|
149
|
+
end
|
150
|
+
|
151
|
+
# @return [String]
|
152
|
+
def inspect
|
153
|
+
super do |attr|
|
154
|
+
next unless attr == :flags
|
155
|
+
|
156
|
+
value = bits_on(attr).reject { |_, v| v > 1 }
|
157
|
+
.keys
|
158
|
+
.select { |b| send("#{b}?") }
|
159
|
+
.map(&:to_s)
|
160
|
+
.join(',')
|
161
|
+
.gsub!(/#{attr}_/, '')
|
162
|
+
value = '%-16s (0x%02x)' % [value, self[attr].to_i]
|
163
|
+
str = PacketGen::Inspect.shift_level
|
164
|
+
str << PacketGen::Inspect::FMT_ATTR % [self[attr].class.to_s.sub(/.*::/, ''),
|
165
|
+
attr, value]
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
# TODO: move this in netbios file when packetgen3 will be out
|
170
|
+
PacketGen::Header::TCP.bind PacketGen::Header::NetBIOS::Session, dport: 445
|
171
|
+
PacketGen::Header::TCP.bind PacketGen::Header::NetBIOS::Session, sport: 445
|
172
|
+
|
173
|
+
PacketGen::Header.add_class SMB2
|
174
|
+
PacketGen::Header::NetBIOS::Session.bind SMB2, body: ->(val) { val.nil? ? SMB2::MARKER : val[0..3] == SMB2::MARKER }
|
175
|
+
PacketGen::Header::NetBIOS::Datagram.bind SMB2, body: ->(val) { val.nil? ? SMB2::MARKER : val[0..3] == SMB2::MARKER }
|
176
|
+
end
|
177
|
+
|
178
|
+
require_relative 'smb2/base'
|
179
|
+
require_relative 'smb2/negotiate'
|
180
|
+
require_relative 'smb2/session_setup'
|
181
|
+
require_relative 'smb2/error'
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# This file is part of packetgen-plugin-smb.
|
2
|
+
# See https://github.com/sdaubert/packetgen-plugin-smb for more informations
|
3
|
+
# Copyright (C) 2018 Sylvain Daubert <sylvain.daubert@laposte.net>
|
4
|
+
# This program is published under MIT license.
|
5
|
+
|
6
|
+
# frozen_string_literal: true
|
7
|
+
|
8
|
+
require_relative 'guid'
|
9
|
+
|
10
|
+
module PacketGen::Plugin
|
11
|
+
class SMB2
|
12
|
+
# Helper class to ease definition of SMB2 classes
|
13
|
+
# @author Sylvain Daubert
|
14
|
+
class Base < PacketGen::Header::Base
|
15
|
+
# Helper to define pad fields used to align next field on 8-byte
|
16
|
+
# offset
|
17
|
+
# @param [Symbol] name name of padding field
|
18
|
+
# @return [void]
|
19
|
+
def self.define_smb2_pad_field(name)
|
20
|
+
prev_field = self.fields.last
|
21
|
+
lf = lambda do |hdr|
|
22
|
+
len = 8 - (hdr.offset_of(prev_field) + hdr[prev_field].sz) % 8
|
23
|
+
len = 0 if len == 8
|
24
|
+
len
|
25
|
+
end
|
26
|
+
define_field name, PacketGen::Types::String, default: [0].pack('q').freeze,
|
27
|
+
builder: ->(h, t) { t.new(length_from: -> { lf[h] }) }
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# This file is part of packetgen-plugin-smb.
|
2
|
+
# See https://github.com/sdaubert/packetgen-plugin-smb for more informations
|
3
|
+
# Copyright (C) 2018 Sylvain Daubert <sylvain.daubert@laposte.net>
|
4
|
+
# This program is published under MIT license.
|
5
|
+
|
6
|
+
# frozen_string_literal: true
|
7
|
+
|
8
|
+
module PacketGen::Plugin
|
9
|
+
class SMB2
|
10
|
+
# SMB2 Error response structure
|
11
|
+
# 0 1 2 3
|
12
|
+
# 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
13
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
14
|
+
# | StructureSize | ContextCount | Reserved |
|
15
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
16
|
+
# | ByteCount |
|
17
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
18
|
+
# | ErrorData |
|
19
|
+
# + +
|
20
|
+
# | ... |
|
21
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
22
|
+
# @author Sylvain Daubert
|
23
|
+
class ErrorResponse < PacketGen::Header::Base
|
24
|
+
# @!attribute structure_size
|
25
|
+
# 16-bit error response structure. Should be 9.
|
26
|
+
# @return [Integer]
|
27
|
+
define_field :structure_size, PacketGen::Types::Int16le, default: 9
|
28
|
+
# !@attribute context_count
|
29
|
+
# Only for SMB3 dialect. If non zero, this is the number of element
|
30
|
+
# in {#data}, formatted as a variable length array.
|
31
|
+
# @return [Integer]
|
32
|
+
define_field :context_count, PacketGen::Types::Int8
|
33
|
+
# !@attribute reserved
|
34
|
+
# 8-bit reserved value
|
35
|
+
# @return [Integer]
|
36
|
+
define_field :reserved, PacketGen::Types::Int8
|
37
|
+
# @!attribute byte_count
|
38
|
+
# 32-bit value indicating the number of bytes contained in {#data}
|
39
|
+
# @return [Integer]
|
40
|
+
define_field :byte_count, PacketGen::Types::Int32le
|
41
|
+
# @!attribute data
|
42
|
+
# Variable-length data field.
|
43
|
+
# @return [String]
|
44
|
+
define_field :data, PacketGen::Types::String
|
45
|
+
end
|
46
|
+
end
|
47
|
+
PacketGen::Header.add_class SMB2::ErrorResponse
|
48
|
+
SMB2.bind SMB2::ErrorResponse, status: ->(v) { v > 0 }
|
49
|
+
end
|
50
|
+
|
@@ -0,0 +1,68 @@
|
|
1
|
+
# This file is part of packetgen-plugin-smb.
|
2
|
+
# See https://github.com/sdaubert/packetgen-plugin-smb for more informations
|
3
|
+
# Copyright (C) 2018 Sylvain Daubert <sylvain.daubert@laposte.net>
|
4
|
+
# This program is published under MIT license.
|
5
|
+
|
6
|
+
# frozen_string_literal: true
|
7
|
+
|
8
|
+
module PacketGen::Plugin
|
9
|
+
class SMB2
|
10
|
+
# GUID, also known as UUID, is a 16-byte structure, intended to serve
|
11
|
+
# as a unique identifier for an object.
|
12
|
+
# 0 1 2 3
|
13
|
+
# 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
|
14
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
15
|
+
# | Data1 |
|
16
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
17
|
+
# | Data2 | Data3 |
|
18
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
19
|
+
# | Data4 |
|
20
|
+
# + +
|
21
|
+
# | |
|
22
|
+
# +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|
23
|
+
# @author Sylvain Daubert
|
24
|
+
class GUID < PacketGen::Types::Fields
|
25
|
+
# @!attribute data1
|
26
|
+
# 32-bit little-endian data1
|
27
|
+
# @return [Integer]
|
28
|
+
define_field :data1, PacketGen::Types::Int32le
|
29
|
+
# @!attribute data2
|
30
|
+
# 16-bit little-endian data2
|
31
|
+
# @return [Integer]
|
32
|
+
define_field :data2, PacketGen::Types::Int16le
|
33
|
+
# @!attribute data3
|
34
|
+
# 16-bit little-endian data3
|
35
|
+
# @return [Integer]
|
36
|
+
define_field :data3, PacketGen::Types::Int16le
|
37
|
+
# @!attribute data4
|
38
|
+
# 64-bit big-endian data4
|
39
|
+
# @return [Integer]
|
40
|
+
define_field :data4, PacketGen::Types::Int64
|
41
|
+
|
42
|
+
# Get a human-readable GUID, as specified in RFC 4122
|
43
|
+
# guid.to_human # => "7aedb437-01b9-41d4-a5f7-9e6c06e16c8a"
|
44
|
+
# @return [String]
|
45
|
+
def to_human
|
46
|
+
data4p1 = data4 >> 48
|
47
|
+
data4p2 = data4 & 0xffff_ffff_ffff
|
48
|
+
"%08x-%04x-%04x-%04x-%012x" % [data1, data2, data3, data4p1, data4p2]
|
49
|
+
end
|
50
|
+
|
51
|
+
# Set GUID from a human-readable string
|
52
|
+
# @param [String] guid
|
53
|
+
# @return [self]
|
54
|
+
def from_human(guid)
|
55
|
+
return self
|
56
|
+
values = guid.split('-')
|
57
|
+
return self if values.size != 5
|
58
|
+
|
59
|
+
self.data1 = values[0].to_i(16)
|
60
|
+
self.data2 = values[1].to_i(16)
|
61
|
+
self.data3 = values[2].to_i(16)
|
62
|
+
self.data4 = values[3].to_i(16) << 48 | values[4].to_i(16)
|
63
|
+
self
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# This file is part of packetgen-plugin-smb.
|
2
|
+
# See https://github.com/sdaubert/packetgen-plugin-smb for more informations
|
3
|
+
# Copyright (C) 2018 Sylvain Daubert <sylvain.daubert@laposte.net>
|
4
|
+
# This program is published under MIT license.
|
5
|
+
|
6
|
+
# frozen_string_literal: true
|
7
|
+
|
8
|
+
require_relative 'guid'
|
9
|
+
|
10
|
+
module PacketGen::Plugin
|
11
|
+
class SMB2
|
12
|
+
# Namespace for NEGOTIATE related classes
|
13
|
+
# @author Sylvain Daubert
|
14
|
+
module Negotiate; end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
require_relative 'negotiate/context'
|
19
|
+
require_relative 'negotiate/request'
|
20
|
+
require_relative 'negotiate/response'
|
21
|
+
|
22
|
+
PacketGen::Plugin::SMB2.bind_command 'negotiate'
|