Class: Rex::Proto::Proxy::Socks4a::Client::Packet

Inherits:
Object
  • Object
show all
Defined in:
lib/rex/proto/proxy/socks4a.rb

Overview

A Socks4a packet.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize ⇒ Packet

Returns a new instance of Packet.



41
42
43
44
45
46
47
# File 'lib/rex/proto/proxy/socks4a.rb', line 41

def initialize
  @version   = REQUEST_VERSION
  @command   = 0
  @dest_port = 0
  @dest_ip   = '0.0.0.0'
  @userid    = ''
end

Instance Attribute Details

#command ⇒ Object

Returns the value of attribute command.



124
125
126
# File 'lib/rex/proto/proxy/socks4a.rb', line 124

def command
  @command
end

#dest_ip ⇒ Object

Returns the value of attribute dest_ip.



124
125
126
# File 'lib/rex/proto/proxy/socks4a.rb', line 124

def dest_ip
  @dest_ip
end

#dest_port ⇒ Object

Returns the value of attribute dest_port.



124
125
126
# File 'lib/rex/proto/proxy/socks4a.rb', line 124

def dest_port
  @dest_port
end

#userid ⇒ Object

Returns the value of attribute userid.



124
125
126
# File 'lib/rex/proto/proxy/socks4a.rb', line 124

def userid
  @userid
end

#version ⇒ Object

Returns the value of attribute version.



124
125
126
# File 'lib/rex/proto/proxy/socks4a.rb', line 124

def version
  @version
end

Instance Method Details

#from_r(raw) ⇒ Object

Unpack a raw packet into its components.



94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/rex/proto/proxy/socks4a.rb', line 94

def from_r( raw )
  return false if( raw.length < 8 )
  @version   = raw[0..0].unpack( 'C' ).first
  return false if( @version != REQUEST_VERSION and @version != REPLY_VERSION )
  @command   = raw[1..1].unpack( 'C' ).first
  @dest_port = raw[2..3].unpack( 'n' ).first
  @dest_ip   = Rex::Socket.addr_itoa( raw[4..7].unpack( 'N' ).first )
  if( raw.length > 8 )
    @userid = raw[8..raw.length].unpack( 'Z*' ).first
    # if this is a socks4a request we can resolve the provided hostname
    if( self.is_hostname? )
      hostname = raw[(8+@userid.length+1)..raw.length].unpack( 'Z*' ).first
      @dest_ip = self.resolve( hostname )
      # fail if we couldnt resolve the hostname
      return false if( not @dest_ip )
    end
  else
    @userid  = ''
  end
  return true
end

#is_bind? ⇒ Boolean

Returns:

  • (Boolean)


120
121
122
# File 'lib/rex/proto/proxy/socks4a.rb', line 120

def is_bind?
  @command == COMMAND_BIND ? true : false
end

#is_connect? ⇒ Boolean

Returns:

  • (Boolean)


116
117
118
# File 'lib/rex/proto/proxy/socks4a.rb', line 116

def is_connect?
  @command == COMMAND_CONNECT ? true : false
end

#is_hostname? ⇒ Boolean (protected)

As per the Socks4a spec, check to see if the provided dest_ip is 0.0.0.XX which indicates after the @userid field contains a hostname to resolve.

Returns:

  • (Boolean)


146
147
148
149
150
151
152
# File 'lib/rex/proto/proxy/socks4a.rb', line 146

def is_hostname?
  ip = Rex::Socket.addr_atoi( @dest_ip )
  if( ip & 0xFFFFFF00 == 0x00000000 )
    return true if( ip & 0x000000FF != 0x00 )
  end
  return false
end

#resolve(hostname) ⇒ Object (protected)

Resolve the given hostname into a dotted IP address.



131
132
133
134
135
136
137
138
139
140
# File 'lib/rex/proto/proxy/socks4a.rb', line 131

def resolve( hostname )
  if( not hostname.empty? )
    begin
      return Rex::Socket.getaddress(hostname, false)
    rescue ::SocketError
      return nil
    end
  end
  return nil
end

#to_r ⇒ Object

Pack a packet into raw bytes for transmitting on the wire.



85
86
87
88
89
# File 'lib/rex/proto/proxy/socks4a.rb', line 85

def to_r
  raw = [ @version, @command, @dest_port, Rex::Socket.addr_atoi( @dest_ip ) ].pack( 'CCnN' )
  return raw if( @userid.empty? )
  return raw + [ @userid ].pack( 'Z*' )
end