class Rex::Proto::Proxy::Socks4a::Client::Packet
A Socks4a
packet.
Attributes
command[RW]
dest_ip[RW]
dest_port[RW]
userid[RW]
version[RW]
Public Class Methods
new()
click to toggle source
# 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
recv( sock, timeout=30 )
click to toggle source
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.
# File lib/rex/proto/proxy/socks4a.rb, line 55 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
Public Instance Methods
from_r( raw )
click to toggle source
Unpack a raw packet into its components.
# 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?()
click to toggle source
# File lib/rex/proto/proxy/socks4a.rb, line 120 def is_bind? @command == COMMAND_BIND ? true : false end
is_connect?()
click to toggle source
# File lib/rex/proto/proxy/socks4a.rb, line 116 def is_connect? @command == COMMAND_CONNECT ? true : false end
to_r()
click to toggle source
Pack a packet into raw bytes for transmitting on the wire.
# 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
Protected Instance Methods
is_hostname?()
click to toggle source
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.
# 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 )
click to toggle source
Resolve the given hostname into a dotted IP address.
# File lib/rex/proto/proxy/socks4a.rb, line 131 def resolve( hostname ) if( not hostname.empty? ) begin return Rex::Socket.addr_itoa( Rex::Socket.gethostbyname( hostname )[3].unpack( 'N' ).first ) rescue ::SocketError return nil end end return nil end