Class: Rex::Proto::DCERPC::WDSCP::Packet

Inherits:
Object
  • Object
show all
Defined in:
lib/rex/proto/dcerpc/wdscp/packet.rb

Constant Summary collapse

WDS_CONST =
Rex::Proto::DCERPC::WDSCP::Constants

Instance Method Summary collapse

Constructor Details

#initialize(packet_type, opcode) ⇒ Packet

Returns a new instance of Packet


10
11
12
13
14
15
16
17
18
# File 'lib/rex/proto/dcerpc/wdscp/packet.rb', line 10

def initialize(packet_type, opcode)
  if opcode.nil? || packet_type.nil?
    raise(ArgumentError, "Packet arguments cannot be nil")
  end

  @variables = []
  @packet_type = WDS_CONST::PACKET_TYPE[packet_type]
  @opcode = WDS_CONST::OPCODE[opcode]
end

Instance Method Details

#add_var(name, type_mod = 0, value_length = nil, array_size = 0, value) ⇒ Object


20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/rex/proto/dcerpc/wdscp/packet.rb', line 20

def add_var(name, type_mod=0, value_length=nil, array_size=0, value)
  padding = 0
  vt = WDS_CONST::VAR_TYPE_LOOKUP[name]
  value_type = WDS_CONST::BASE_TYPE[vt]
  name = Rex::Text.to_unicode(name).unpack('H*')[0]

  # Terminate strings with null char
  if vt == :STRING
    value << "\x00"
  elsif vt == :WSTRING
    value = Rex::Text.to_unicode(value)
    value << "\x00\x00"
  end

  value_length ||= value.length
  # Variable block total size should be evenly divisible by 16.
  len = 16 * (1 + (value_length/16))
  @variables << 
    [	name,
      padding,
      value_type,
      type_mod,
      value_length,
      array_size,
      value
    ].pack('H132vvvVVa%i' % len)
end

#createObject


48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/rex/proto/dcerpc/wdscp/packet.rb', line 48

def create
  packet = []
  var_count = @variables.count

  packet_size = 0
  @variables.each do |var|
    packet_size += var.length
  end

  # variables + operation
  packet_size += 16

  # These bytes are not part of the spec but are not part of DCERPC according to Wireshark
  # Perhaps something from MSRPC specific? Basically length of the WDSCP packet twice...
  packet << [(packet_size+40)].pack('V') * 2
  packet << create_endpoint_header(packet_size)
  packet << create_operation_header(packet_size, var_count, @packet_type, @opcode)
  packet.concat(@variables)

  return packet.join
end

#create_endpoint_header(packet_size) ⇒ Object


81
82
83
84
85
86
87
88
89
# File 'lib/rex/proto/dcerpc/wdscp/packet.rb', line 81

def create_endpoint_header(packet_size)
  return [
      40,                            # Header_Size
      256,                           # Version
      packet_size,                   # Packet_Size - This doesn't differ from operation header despite the spec...
      WDS_CONST::OS_DEPLOYMENT_GUID, # GUID
      "\x00"*16,                     # Reserved
    ].pack('vvVa16a16')
end

#create_operation_header(packet_size, var_count, packet_type = :REQUEST, opcode) ⇒ Object


70
71
72
73
74
75
76
77
78
79
# File 'lib/rex/proto/dcerpc/wdscp/packet.rb', line 70

def create_operation_header(packet_size, var_count, packet_type=:REQUEST, opcode)
  return 	[
      packet_size, # PacketSize
      256,         # Version
      packet_type, # Packet_Type
      0,           # Padding
      opcode,      # Opcode
      var_count,   # Variable Count
    ].pack('VvCCVV')
end