Class: Rex::Proto::Proxy::Socks4a::Client::Packet
- Inherits:
-
Object
- Object
- Rex::Proto::Proxy::Socks4a::Client::Packet
- Defined in:
- lib/rex/proto/proxy/socks4a.rb
Overview
A Socks4a packet.
Instance Attribute Summary collapse
-
#command ⇒ Object
Returns the value of attribute command.
-
#dest_ip ⇒ Object
Returns the value of attribute dest_ip.
-
#dest_port ⇒ Object
Returns the value of attribute dest_port.
-
#userid ⇒ Object
Returns the value of attribute userid.
-
#version ⇒ Object
Returns the value of attribute version.
Class Method Summary collapse
-
.recv(sock, timeout = 30) ⇒ Object
A helper function to recv in a Socks4a packet byte by byte.
Instance Method Summary collapse
-
#from_r(raw) ⇒ Object
Unpack a raw packet into its components.
-
#initialize ⇒ Packet
constructor
A new instance of Packet.
- #is_bind? ⇒ Boolean
- #is_connect? ⇒ Boolean
-
#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.
-
#resolve(hostname) ⇒ Object
protected
Resolve the given hostname into a dotted IP address.
-
#to_r ⇒ Object
Pack a packet into raw bytes for transmitting on the wire.
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 |
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.
55 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 |
# 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 |
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
120 121 122 |
# File 'lib/rex/proto/proxy/socks4a.rb', line 120 def is_bind? @command == COMMAND_BIND ? true : false end |
#is_connect? ⇒ 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.
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 |