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

"\xfeSMB".b.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)


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

define_attr :async_id, BinStruct::Int64le, optional: ->(h) { h.flags & 2 == 2 }

#bodyString

Returns:

  • (String)


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

define_attr :body, BinStruct::String

#commandInteger

16-bit command field

Returns:

  • (Integer)


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

define_attr :command, BinStruct::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_attr :credit, BinStruct::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_attr :credit_charge, BinStruct::Int16le

#flags_async?Boolean

When set, the message is a asynchronous.

Returns:

  • (Boolean)


96
97
98
99
100
# File 'lib/packetgen/plugin/smb2.rb', line 96

define_bit_attr :flags, endian: :little,
flags_rsv1: 2, flags_smb3_replay_op: 1, flags_dfs_op: 1,
flags_rsv2: 21, flags_smb3_priority: 3,
flags_signed: 1, flags_related_op: 1, flags_async: 1,
flags_response: 1

#flags_dsf_op?Boolean

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

Returns:

  • (Boolean)


96
97
98
99
100
# File 'lib/packetgen/plugin/smb2.rb', line 96

define_bit_attr :flags, endian: :little,
flags_rsv1: 2, flags_smb3_replay_op: 1, flags_dfs_op: 1,
flags_rsv2: 21, flags_smb3_priority: 3,
flags_signed: 1, flags_related_op: 1, flags_async: 1,
flags_response: 1

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

Returns:

  • (Boolean)


96
97
98
99
100
# File 'lib/packetgen/plugin/smb2.rb', line 96

define_bit_attr :flags, endian: :little,
flags_rsv1: 2, flags_smb3_replay_op: 1, flags_dfs_op: 1,
flags_rsv2: 21, flags_smb3_priority: 3,
flags_signed: 1, flags_related_op: 1, flags_async: 1,
flags_response: 1

#flags_response?Boolean

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

Returns:

  • (Boolean)


96
97
98
99
100
# File 'lib/packetgen/plugin/smb2.rb', line 96

define_bit_attr :flags, endian: :little,
flags_rsv1: 2, flags_smb3_replay_op: 1, flags_dfs_op: 1,
flags_rsv2: 21, flags_smb3_priority: 3,
flags_signed: 1, flags_related_op: 1, flags_async: 1,
flags_response: 1

#flags_rsv1Integer

2-bit reserved field

Returns:

  • (Integer)


96
97
98
99
100
# File 'lib/packetgen/plugin/smb2.rb', line 96

define_bit_attr :flags, endian: :little,
flags_rsv1: 2, flags_smb3_replay_op: 1, flags_dfs_op: 1,
flags_rsv2: 21, flags_smb3_priority: 3,
flags_signed: 1, flags_related_op: 1, flags_async: 1,
flags_response: 1

#flags_rsv2Integer

21-bit reserved field

Returns:

  • (Integer)


96
97
98
99
100
# File 'lib/packetgen/plugin/smb2.rb', line 96

define_bit_attr :flags, endian: :little,
flags_rsv1: 2, flags_smb3_replay_op: 1, flags_dfs_op: 1,
flags_rsv2: 21, flags_smb3_priority: 3,
flags_signed: 1, flags_related_op: 1, flags_async: 1,
flags_response: 1

#flags_signed?Boolean

When set, the message is signed.

Returns:

  • (Boolean)


96
97
98
99
100
# File 'lib/packetgen/plugin/smb2.rb', line 96

define_bit_attr :flags, endian: :little,
flags_rsv1: 2, flags_smb3_replay_op: 1, flags_dfs_op: 1,
flags_rsv2: 21, flags_smb3_priority: 3,
flags_signed: 1, flags_related_op: 1, flags_async: 1,
flags_response: 1

#flags_smb3_priorityInteger

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

Returns:

  • (Integer)


96
97
98
99
100
# File 'lib/packetgen/plugin/smb2.rb', line 96

define_bit_attr :flags, endian: :little,
flags_rsv1: 2, flags_smb3_replay_op: 1, flags_dfs_op: 1,
flags_rsv2: 21, flags_smb3_priority: 3,
flags_signed: 1, flags_related_op: 1, flags_async: 1,
flags_response: 1

#flags_smb3_replay_op?Boolean

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

Returns:

  • (Boolean)


96
97
98
99
100
# File 'lib/packetgen/plugin/smb2.rb', line 96

define_bit_attr :flags, endian: :little,
flags_rsv1: 2, flags_smb3_replay_op: 1, flags_dfs_op: 1,
flags_rsv2: 21, flags_smb3_priority: 3,
flags_signed: 1, flags_related_op: 1, flags_async: 1,
flags_response: 1

#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)


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

define_attr :message_id, BinStruct::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)


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

define_attr :next_command, BinStruct::Int32le

#protocolString

This field must contain SMB2 marker

Returns:

  • (String)


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

define_attr :protocol, BinStruct::String, static_length: 4, default: MARKER

#reservedInteger

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

Returns:

  • (Integer)


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

define_attr :reserved, BinStruct::Int32le, optional: ->(h) { h.flags.nobits?(2) }

#session_idInteger

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

Returns:

  • (Integer)


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

define_attr :session_id, BinStruct::Int64le

#signatureString

16-byte message signature

Returns:

  • (String)


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

define_attr :signature, BinStruct::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_attr :status, BinStruct::Int32le

#structure_sizeInteger

16-bit SMB2 header size. Should be 64.

Returns:

  • (Integer)


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

define_attr :structure_size, BinStruct::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)


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

define_attr :tree_id, BinStruct::Int32le, optional: ->(h) { h.flags.nobits?(2) }

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



141
142
143
144
145
146
147
148
149
# File 'lib/packetgen/plugin/smb2.rb', line 141

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.nobits?(1) }
  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)


164
165
166
167
168
169
170
171
172
173
174
175
176
# File 'lib/packetgen/plugin/smb2.rb', line 164

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

    value = bits_on(attr).select { |b| respond_to?("#{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].type_name, attr, value])
  end
end

#parse?Boolean

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

Returns:

  • (Boolean)


159
160
161
# File 'lib/packetgen/plugin/smb2.rb', line 159

def parse?
  protocol == MARKER
end

#reply!self

Returns:

  • (self)


153
154
155
# File 'lib/packetgen/plugin/smb2.rb', line 153

def reply!
  self.flags_response = !flags_response?
end