Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expose supported proxies #69

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions lib/rex/socket/comm/local.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
require 'rex/socket/sctp'
require 'rex/socket/sctp_server'
require 'rex/socket/ip'
require 'rex/socket/proxies'
require 'timeout'

###
Expand Down Expand Up @@ -353,7 +354,7 @@ def self.create_by_type(param, type, proto = 0)

def self.proxy(sock, type, host, port)
case type.downcase
when 'sapni'
when Rex::Socket::Proxies::ProxyType::SAPNI
packet_type = 'NI_ROUTE'
route_info_version = 2
ni_version = 39
Expand Down Expand Up @@ -422,7 +423,7 @@ def self.proxy(sock, type, host, port)
raise Rex::ConnectionProxyError.new(host, port, type, "Connection to #{host}:#{port} failed (Unknown fail)")
end

when 'http'
when Rex::Socket::Proxies::ProxyType::HTTP
setup = "CONNECT #{host}:#{port} HTTP/1.0\r\n\r\n"
size = sock.put(setup)
if size != setup.length
Expand All @@ -445,7 +446,7 @@ def self.proxy(sock, type, host, port)
if resp.code != 200
raise Rex::ConnectionProxyError.new(host, port, type, "The proxy returned a non-OK response"), caller
end
when 'socks4'
when Rex::Socket::Proxies::ProxyType::SOCKS4
supports_ipv6 = false
setup = [4,1,port.to_i].pack('CCn') + Rex::Socket.resolv_nbo(host, supports_ipv6) + Rex::Text.rand_text_alpha(rand(8)+1) + "\x00"
size = sock.put(setup)
Expand All @@ -465,7 +466,7 @@ def self.proxy(sock, type, host, port)
if ret[1,1] != "\x5a"
raise Rex::ConnectionProxyError.new(host, port, type, "Proxy responded with error code #{ret[0,1].unpack("C")[0]}"), caller
end
when 'socks5'
when Rex::Socket::Proxies::ProxyType::SOCKS5
auth_methods = [5,1,0].pack('CCC')
size = sock.put(auth_methods)
if size != auth_methods.length
Expand Down
3 changes: 2 additions & 1 deletion lib/rex/socket/parameters.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# -*- coding: binary -*-
require 'rex/socket'
require 'rex/socket/proxies'

###
#
Expand Down Expand Up @@ -163,7 +164,7 @@ def initialize(hash = {})
end

if hash['Proxies']
self.proxies = hash['Proxies'].split(',').map{|a| a.strip}.map{|a| a.split(':').map{|b| b.strip}}
self.proxies = Rex::Socket::Proxies.parse(hash['Proxies'])
end

# The protocol this socket will be using
Expand Down
24 changes: 24 additions & 0 deletions lib/rex/socket/proxies.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# -*- coding: binary -*-

module Rex
module Socket
module Proxies
module ProxyType
SAPNI = 'sapni'
HTTP = 'http'
SOCKS4 = 'socks4'
SOCKS5 = 'socks5'
end

# @param [String,nil] value A proxy chain of format {type:host:port[,type:host:port][...]}
# @return [Array] The array of proxies, i.e. {[['type', 'host', 'port']]}
def self.parse(value)
value.to_s.strip.split(',').map { |a| a.strip }.map { |a| a.split(':').map { |b| b.strip } }
end

def self.supported_types
ProxyType.constants.map { |c| ProxyType.const_get(c) }
end
end
end
end
29 changes: 29 additions & 0 deletions spec/rex/socket/proxies_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# -*- coding:binary -*-
require 'rex/socket/proxies'

RSpec.describe Rex::Socket::Proxies do
describe '.supported_types' do
it 'should equal the array of available proxies' do
expected = %w[
sapni
socks4
http
socks5
]
expect(subject.supported_types).to match_array expected
end
end

describe '.parse' do
[
{ value: nil, expected: [] },
{ value: '', expected: [] },
{ value: ' ', expected: [] },
{ value: 'sapni:198.51.100.1:8080, socks4:198.51.100.1:1080 ', expected: [['sapni', '198.51.100.1', '8080'], ['socks4', '198.51.100.1', '1080']] },
].each do |test|
it "correctly parses #{test[:value]} as #{test[:expected]}" do
expect(described_class.parse(test[:value])).to eq test[:expected]
end
end
end
end