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

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initializePacket

Returns a new instance of Packet


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

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

Instance Attribute Details

#commandObject

Returns the value of attribute command


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

def command
  @command
end

#dest_ipObject

Returns the value of attribute dest_ip


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

def dest_ip
  @dest_ip
end

#dest_portObject

Returns the value of attribute dest_port


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

def dest_port
  @dest_port
end

#useridObject

Returns the value of attribute userid


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

def userid
  @userid
end

#versionObject

Returns the value of attribute version


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

def version
  @version
end

Class Method Details

.recv(sock, timeout = 30) ⇒ Object

A helper function to recv in a Socks4a packet byte by byte.

sf: we could just call raw = sock.get_once but some clients

seem to need reading this byte by byte instead.

56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/rex/proto/proxy/socks4a.rb', line 56

def Packet.recv( sock, timeout=30 )
  raw = ''
  # read in the 8 byte header
  while( raw.length < 8 )
    raw << sock.read( 1 )
  end
  # if its a request there will be more data
  if( raw[0..0].unpack( 'C' ).first == REQUEST_VERSION )
    # read in the userid
    while( raw[8..raw.length].index( "\x00" ) == nil )
      raw << sock.read( 1 )
    end
    # if a hostname is going to be present, read it in
    ip = raw[4..7].unpack( 'N' ).first
    if( ( ip & 0xFFFFFF00 ) == 0x00000000 and ( ip & 0x000000FF ) != 0x00 )
      hostname = ''
      while( hostname.index( "\x00" ) == nil )
        hostname += sock.read( 1 )
      end
      raw << hostname
    end
  end
  # create a packet from this raw data...
  packet = Packet.new
  packet.from_r( raw ) ? packet : nil
end

Instance Method Details

#from_r(raw) ⇒ Object

Unpack a raw packet into its components.


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

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)

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

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

#is_connect?Boolean

Returns:

  • (Boolean)

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

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

#to_rObject

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


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

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