Class: PacketGen::Plugin::SMB2

Inherits:
Header::Base
  • Object
show all
Defined in:
lib/packetgen/plugin/smb2.rb,
lib/packetgen/plugin/smb2/negotiate.rb,
lib/packetgen/plugin/smb2/session_setup.rb,
lib/packetgen/plugin/smb2/negotiate/context.rb,
lib/packetgen/plugin/smb2/negotiate/request.rb,
lib/packetgen/plugin/smb2/negotiate/response.rb,
lib/packetgen/plugin/smb2/session_setup/request.rb,
lib/packetgen/plugin/smb2/session_setup/response.rb,
lib/packetgen/plugin/smb2/error.rb,
lib/packetgen/plugin/smb2/guid.rb,
lib/packetgen/plugin/smb2/base.rb

Overview

Server Message Block version 2 and 3 (SMB2) header.

Author:

  • Sylvain Daubert

Defined Under Namespace

Modules: Negotiate, SessionSetup Classes: Base, ErrorResponse, GUID

Constant Summary collapse

COMMANDS =

Known commands

{
  'negotiate' => 0,
  'session_setup' => 1,
  'logoff' => 2,
  'tree_connect' => 3,
  'tree_disconnect' => 4,
  'create' => 5,
  'close' => 6,
  'flush' => 7,
  'read' => 8,
  'write' => 9,
  'lock' => 10,
  'ioctl' => 11,
  'cancel' => 12,
  'echo' => 13,
  'query_directory' => 14,
  'change_notify' => 15,
  'query_info' => 16,
  'set_info' => 17,
  'oplock_break' => 18
}.freeze
MARKER =

SMB marker, on start of header

PacketGen.force_binary("\xfeSMB").freeze
HEADER_SIZE =

SMB2 header size

64
MAX_PADDING =

SMB2 pad field at its maximum length

[0].pack('q').freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#async_idInteger

64-bit unique ID that is created by the server to handle operations asynchronously. Only present for asynchronous messages.

Returns:

  • (Integer)


87
# File 'lib/packetgen/plugin/smb2.rb', line 87

define_field :async_id, PacketGen::Types::Int64le, optional: ->(h) { h.flags & 2 == 2 }

#bodyString

Returns:

  • (String)


108
# File 'lib/packetgen/plugin/smb2.rb', line 108

define_field :body, PacketGen::Types::String

#commandInteger

16-bit command field

Returns:

  • (Integer)


63
# File 'lib/packetgen/plugin/smb2.rb', line 63

define_field :command, PacketGen::Types::Int16leEnum, enum: COMMANDS

#creditInteger

16-bit credit field. This is the number of credits a client is requesting in a request, and the number of credits granted in a response.

Returns:

  • (Integer)


68
# File 'lib/packetgen/plugin/smb2.rb', line 68

define_field :credit, PacketGen::Types::Int16le

#credit charge(charge) ⇒ Integer

16-bit credit charge field. Must not be used and must be set to 0.

Returns:

  • (Integer)


55
# File 'lib/packetgen/plugin/smb2.rb', line 55

define_field :credit_charge, PacketGen::Types::Int16le

#flagsInteger

32-bit flags field

Returns:

  • (Integer)


72
# File 'lib/packetgen/plugin/smb2.rb', line 72

define_field :flags, PacketGen::Types::Int32le

#flags_async?Boolean

When set, the message is a asynchronous.

Returns:

  • (Boolean)


136
137
138
139
# File 'lib/packetgen/plugin/smb2.rb', line 136

define_bit_fields_on :flags, :flags_rsv1, 2, :flags_smb3_replay_op, :flags_dfs_op,
:flags_rsv2, 21, :flags_smb3_priority, 3,
:flags_signed, :flags_related_op, :flags_async,
:flags_response

#flags_dsf_op?Boolean

When set, the command is a Distributed File System (DFS) operation..

Returns:

  • (Boolean)


136
137
138
139
# File 'lib/packetgen/plugin/smb2.rb', line 136

define_bit_fields_on :flags, :flags_rsv1, 2, :flags_smb3_replay_op, :flags_dfs_op,
:flags_rsv2, 21, :flags_smb3_priority, 3,
:flags_signed, :flags_related_op, :flags_async,
:flags_response

When set, the message is a related operation in a compounded chain.

Returns:

  • (Boolean)


136
137
138
139
# File 'lib/packetgen/plugin/smb2.rb', line 136

define_bit_fields_on :flags, :flags_rsv1, 2, :flags_smb3_replay_op, :flags_dfs_op,
:flags_rsv2, 21, :flags_smb3_priority, 3,
:flags_signed, :flags_related_op, :flags_async,
:flags_response

#flags_response?Boolean

When set, the message is a response from server to client.

Returns:

  • (Boolean)


136
137
138
139
# File 'lib/packetgen/plugin/smb2.rb', line 136

define_bit_fields_on :flags, :flags_rsv1, 2, :flags_smb3_replay_op, :flags_dfs_op,
:flags_rsv2, 21, :flags_smb3_priority, 3,
:flags_signed, :flags_related_op, :flags_async,
:flags_response

#flags_rsv1Integer

2-bit reserved field

Returns:

  • (Integer)


136
137
138
139
# File 'lib/packetgen/plugin/smb2.rb', line 136

define_bit_fields_on :flags, :flags_rsv1, 2, :flags_smb3_replay_op, :flags_dfs_op,
:flags_rsv2, 21, :flags_smb3_priority, 3,
:flags_signed, :flags_related_op, :flags_async,
:flags_response

#flags_rsv2Integer

21-bit reserved field

Returns:

  • (Integer)


136
137
138
139
# File 'lib/packetgen/plugin/smb2.rb', line 136

define_bit_fields_on :flags, :flags_rsv1, 2, :flags_smb3_replay_op, :flags_dfs_op,
:flags_rsv2, 21, :flags_smb3_priority, 3,
:flags_signed, :flags_related_op, :flags_async,
:flags_response

#flags_signed?Boolean

When set, the message is signed.

Returns:

  • (Boolean)


136
137
138
139
# File 'lib/packetgen/plugin/smb2.rb', line 136

define_bit_fields_on :flags, :flags_rsv1, 2, :flags_smb3_replay_op, :flags_dfs_op,
:flags_rsv2, 21, :flags_smb3_priority, 3,
:flags_signed, :flags_related_op, :flags_async,
:flags_response

#flags_smb3_priorityInteger

3-bit value of I/O priority (only SMB 3 dialect).

Returns:

  • (Integer)


136
137
138
139
# File 'lib/packetgen/plugin/smb2.rb', line 136

define_bit_fields_on :flags, :flags_rsv1, 2, :flags_smb3_replay_op, :flags_dfs_op,
:flags_rsv2, 21, :flags_smb3_priority, 3,
:flags_signed, :flags_related_op, :flags_async,
:flags_response

#flags_smb3_replay_op?Boolean

When set, the command is a replay operation (only SMB 3 dialect).

Returns:

  • (Boolean)


136
137
138
139
# File 'lib/packetgen/plugin/smb2.rb', line 136

define_bit_fields_on :flags, :flags_rsv1, 2, :flags_smb3_replay_op, :flags_dfs_op,
:flags_rsv2, 21, :flags_smb3_priority, 3,
:flags_signed, :flags_related_op, :flags_async,
:flags_response

#message_idInteger

64-bit alue that identifies a message request and response uniquely across all messages that are sent on the same SMB 2 Protocol transport connection.

Returns:

  • (Integer)


82
# File 'lib/packetgen/plugin/smb2.rb', line 82

define_field :message_id, PacketGen::Types::Int64le

#next_commandInteger

32-bit offset from the beginning of this SMB2 header to the start of the subsequent 8-byte aligned SMB2 header (only for compounded requests).

Returns:

  • (Integer)


77
# File 'lib/packetgen/plugin/smb2.rb', line 77

define_field :next_command, PacketGen::Types::Int32le

#protocolString

This field must contain SMB2 marker

Returns:

  • (String)


47
# File 'lib/packetgen/plugin/smb2.rb', line 47

define_field :protocol, PacketGen::Types::String, static_length: 4, default: MARKER

#reservedInteger

32-bit reserved field. Only present for synchronous messages.

Returns:

  • (Integer)


92
# File 'lib/packetgen/plugin/smb2.rb', line 92

define_field :reserved, PacketGen::Types::Int32le, optional: ->(h) { (h.flags & 2).zero? }

#session_idInteger

64-bit integer that uniquely identifies the established session for the command.

Returns:

  • (Integer)


101
# File 'lib/packetgen/plugin/smb2.rb', line 101

define_field :session_id, PacketGen::Types::Int64le

#signatureString

16-byte message signature

Returns:

  • (String)


105
# File 'lib/packetgen/plugin/smb2.rb', line 105

define_field :signature, PacketGen::Types::String, static_length: 16, default: [0, 0].pack('qq')

#statusInteger

32-bit status field (SMB 2 dialect only).

Returns:

  • (Integer)


59
# File 'lib/packetgen/plugin/smb2.rb', line 59

define_field :status, PacketGen::Types::Int32le

#structure_sizeInteger

16-bit SMB2 header size. Should be 64.

Returns:

  • (Integer)


51
# File 'lib/packetgen/plugin/smb2.rb', line 51

define_field :structure_size, PacketGen::Types::Int16le, default: HEADER_SIZE

#tree_idInteger

32-bit integer that uniquely identifies the tree connect for the command. Only present for synchronous messages.

Returns:

  • (Integer)


97
# File 'lib/packetgen/plugin/smb2.rb', line 97

define_field :tree_id, PacketGen::Types::Int32le, optional: ->(h) { (h.flags & 2).zero? }

Class Method Details

.bind_command(command) ⇒ void

This method returns an undefined value.

Helper to bind a SMB2 command to PacketGen::Plugin::SMB2 header.

Parameters:

  • command (String)

    name



144
145
146
147
148
149
150
151
152
# File 'lib/packetgen/plugin/smb2.rb', line 144

def self.bind_command(command)
  contantized = command.capitalize.gsub(/_(\w)/) { $1.upcase }
  krequest = self.const_get("#{contantized}::Request")
  kresponse = self.const_get("#{contantized}::Response")
  PacketGen::Header.add_class krequest
  self.bind krequest, command: SMB2::COMMANDS[command], flags: ->(v) { v.nil? ? 0 : (v & 1).zero? }
  PacketGen::Header.add_class kresponse
  self.bind kresponse, command: SMB2::COMMANDS[command], flags: ->(v) { v.nil? ? 1 : (v & 1 == 1) }
end

Instance Method Details

#inspectString

Returns:

  • (String)


167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
# File 'lib/packetgen/plugin/smb2.rb', line 167

def inspect
  super do |attr|
    next unless attr == :flags

    value = bits_on(attr).reject { |_, v| v > 1 }
                         .keys
                         .select { |b| send("#{b}?") }
                         .map(&:to_s)
                         .join(',')
                         .gsub!(/#{attr}_/, '')
    value = '%-16s (0x%02x)' % [value, self[attr].to_i]
    str = PacketGen::Inspect.shift_level
    str << PacketGen::Inspect::FMT_ATTR % [self[attr].class.to_s.sub(/.*::/, ''),
                                           attr, value]
  end
end

#parse?Boolean

Check if this is really a SMB2 header. Check #protocol has value MARKER.

Returns:

  • (Boolean)


162
163
164
# File 'lib/packetgen/plugin/smb2.rb', line 162

def parse?
  protocol == MARKER
end

#reply!self

Returns:

  • (self)


156
157
158
# File 'lib/packetgen/plugin/smb2.rb', line 156

def reply!
  self.flags_response = !flags_response?
end