Parent

Class/Module Index [+]

Quicksearch

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

[Validate]

Generated with the Darkfish Rdoc Generator 2.