Fix reply status codes and domainname addresses

This commit is contained in:
Spencer McIntyre 2018-03-22 16:10:16 -04:00
parent 6859856101
commit 1de5a464e7
3 changed files with 62 additions and 45 deletions

View File

@ -10,22 +10,10 @@ module Proxy
module Socks5
SOCKS_VERSION = 5
class AuthRequestPacket < BinData::Record
endian :big
uint8 :version, :initial_value => SOCKS_VERSION
uint8 :supported_methods_length
array :supported_methods, :type => :uint8, :initial_length => :supported_methods_length
end
class AuthResponsePacket < BinData::Record
endian :big
uint8 :version, :initial_value => SOCKS_VERSION
uint8 :chosen_method
end
module AddressMixin
#
# Mixin for socks5 packets to include an address field.
#
module Address
ADDRESS_TYPE_IPV4 = 1
ADDRESS_TYPE_DOMAINNAME = 3
ADDRESS_TYPE_IPV6 = 4
@ -42,14 +30,16 @@ module Socks5
if Rex::Socket.is_ipv4?(value)
address_type.assign(ADDRESS_TYPE_IPV4)
domainname_length.assign(0)
value = Rex::Socket.addr_aton(value)
elsif Rex::Socket.is_ipv6?(value)
address_type.assign(ADDRESS_TYPE_IPV6)
domainname_length.assign(0)
value = Rex::Socket.addr_aton(value)
else
address_type.assign(ADDRESS_TYPE_DOMAINNAME)
domainname_length.assign(value.length)
end
address_array.assign(Rex::Socket.addr_aton(value).unpack('C*'))
address_array.assign(value.unpack('C*'))
end
def address_length
@ -66,8 +56,23 @@ module Socks5
end
end
class AuthRequestPacket < BinData::Record
endian :big
uint8 :version, :initial_value => SOCKS_VERSION
uint8 :supported_methods_length
array :supported_methods, :type => :uint8, :initial_length => :supported_methods_length
end
class AuthResponsePacket < BinData::Record
endian :big
uint8 :version, :initial_value => SOCKS_VERSION
uint8 :chosen_method
end
class RequestPacket < BinData::Record
include AddressMixin
include Address
endian :big
hide :reserved, :domainname_length
@ -82,6 +87,19 @@ module Socks5
class ResponsePacket < RequestPacket
end
class UdpPacket < BinData::Record
include Address
endian :big
hide :reserved, :domainname_length
uint16 :reserved
uint8 :frag
uint8 :address_type
uint8 :domainname_length, :onlyif => lambda { address_type == ADDRESS_TYPE_DOMAINNAME }
array :address_array, :type => :uint8, :initial_length => lambda { address_length }
uint16 :port
end
end
end
end

View File

@ -1,7 +1,4 @@
# -*- coding: binary -*-
#
# sf - Sept 2010 (original socks4a code)
# zeroSteiner - March 2018 (socks 5 update)
require 'thread'
require 'rex/logging'
@ -39,7 +36,7 @@ module Socks5
end
#
# Start the Socks4a server.
# Start the Socks5 server.
#
def start
begin
@ -77,7 +74,7 @@ module Socks5
end
#
# Stop the Socks4a server.
# Stop the Socks5 server.
#
def stop
if @running

View File

@ -76,19 +76,24 @@ module Socks5
# A client connected to the Socks5 server.
#
class ServerClient
AUTH_NONE = 0
AUTH_GSSAPI = 1
AUTH_CREDS = 2
AUTH_NO_ACCEPTABLE_METHODS = 255
AUTH_NONE = 0
AUTH_GSSAPI = 1
AUTH_CREDS = 2
AUTH_NO_ACCEPTABLE_METHODS = 255
COMMAND_CONNECT = 1
COMMAND_BIND = 2
COMMAND_UDP_ASSOCIATE = 3
COMMAND_CONNECT = 1
COMMAND_BIND = 2
COMMAND_UDP_ASSOCIATE = 3
REQUEST_GRANTED = 90
REQUEST_REJECT_FAILED = 91
REQUEST_REJECT_CONNECT = 92
REQUEST_REJECT_USERID = 93
REPLY_SUCCEEDED = 0
REPLY_GENERAL_FAILURE = 1
REPLY_NOT_ALLOWED = 2
REPLY_NET_UNREACHABLE = 3
REPLY_HOST_UNREACHABLE = 4
REPLY_CONNECTION_REFUSED = 5
REPLY_TTL_EXPIRED = 6
REPLY_CMD_NOT_SUPPORTED = 7
REPLY_ADDRESS_TYPE_NOT_SUPPORTED = 8
#
# Create a new client connected to the server.
@ -147,6 +152,7 @@ module Socks5
when COMMAND_UDP_ASSOCIATE
response = handle_command_udp_associate(request)
end
if response.nil?
STDERR.puts "Command did not return a proper response object"
else
@ -158,7 +164,7 @@ module Socks5
STDERR.puts exception.backtrace
# send back failure to the client
response = ResponsePacket.new
response.command = REQUEST_REJECT_FAILED
response.command = REPLY_GENERAL_FAILURE
@lsock.put(response.to_binary_s)
# raise an exception to close this client connection
raise "Failed to handle the clients request."
@ -176,7 +182,7 @@ module Socks5
# send back the bind success to the client
response = ResponsePacket.new
response.command = REQUEST_GRANTED
response.command = REPLY_SUCCEEDED
response.address = bsock.localhost
response.port = bsock.localport
@lsock.put(response.to_binary_s)
@ -194,10 +200,9 @@ module Socks5
bsock.close
response = ResponsePacket.new
response.version = REPLY_VERSION
response.command = REQUEST_GRANTED
response.address = rpeer[HOST]
response.port = rpeer[PORT]
response.command = REPLY_SUCCEEDED
response.address = @rsock.peerhost
response.port = @rsock.peerport
response
end
@ -211,7 +216,7 @@ module Socks5
@rsock = Rex::Socket::Tcp.create(params)
response = ResponsePacket.new
response.command = REQUEST_GRANTED
response.command = REPLY_SUCCEEDED
response.address = @rsock.peerhost
response.port = @rsock.peerport
response
@ -228,7 +233,7 @@ module Socks5
# send back the bind success to the client
response = ResponsePacket.new
response.command = REQUEST_GRANTED
response.command = REPLY_SUCCEEDED
response.address = @rsock.localhost
response.port = @rsock.localport
response
@ -251,14 +256,11 @@ module Socks5
end
@client_thread.kill if @client_thread and @client_thread.alive?
@server.remove_client(self)
@closed = true
end
end
end
end
end
end