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

Python3 support added #7

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
76 changes: 38 additions & 38 deletions client.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@


def key_by_value(my_dict, value):
for k, v in my_dict.iteritems():
for k, v in my_dict.items():
if v == value:
return k
return None
Expand Down Expand Up @@ -80,21 +80,21 @@ def run(self):
logger.info('SIGINT received. Closing relay and exiting')
self.send_remote_cmd(self.bc_sock, relay.CLOSE_RELAY)
self.shutdown()
except select.error as (code, msg):
logger.debug('Select error on select. Errno: {0} Msg: {1}'.format(errno.errorcode[code], msg))
except select.error as e:
logger.debug('Select error on select. Errno: {0} Msg: {1}'.format(e.errno, e.strerror))
self.shutdown()
except socket.error as (code, msg):
logger.debug('Socket error on select. Errno: {0} Msg: {1}'.format(errno.errorcode[code], msg))
except socket.error as e:
logger.debug('Socket error on select. Errno: {0} Msg: {1}'.format(e.errno, e.strerror))
self.shutdown()

for sock in outputready:
channel_id = self.establishing_dict[sock]
logger.debug('Establishing connection with channel id {0}'.format(channel_id))
try:
sock.recv(0)
except socket.error as (code, err_msg):
if code == errno.ECONNREFUSED or code == errno.ETIMEDOUT:
logger.debug('Connection {0}'.format(errno.errorcode[code]))
except socket.error as e:
if e.errno == errno.ECONNREFUSED or e.errno == errno.ETIMEDOUT:
logger.debug('Connection {0}'.format(e.errno))

if sock in inputready:
inputready.remove(sock)
Expand All @@ -104,9 +104,9 @@ def run(self):
self.send_remote_cmd(self.bc_sock, relay.FORWARD_CONNECTION_FAILURE, channel_id)
sock.close()
continue
elif code == errno.EAGAIN:
elif e.errno == errno.EAGAIN:
logger.debug('Recv(0) return errno.EAGAIN for socket {0} on channel {1}. Connection established.'.format(sock, channel_id))
elif code == 10035:
elif e.errno == 10035:
logger.debug('Recv(0) raised windows-specific exception 10035. Connection established.')
else:
raise
Expand All @@ -131,7 +131,7 @@ def run(self):
self.manage_forward_socket(self.selected_input_socket)

def handle_remote_cmd(self, data):
cmd = data[0]
cmd = data[0].to_bytes(1, 'big')
logger.debug('Received cmd data from remote side. Cmd: {0}'.format(relay.cmd_names[cmd]))
if cmd == relay.CHANNEL_CLOSE_CMD:
channel_id = unpack('<H', data[1:3])[0]
Expand Down Expand Up @@ -168,9 +168,9 @@ def get_channel_data(self, sock):
tlv_header = relay.recvall(sock, 4)
channel_id, tlv_data_len = unpack('<HH', tlv_header)
data = relay.recvall(sock, tlv_data_len)
except socket.error as (code, msg):
except socket.error as e:
logger.debug('Exception on receiving tlv message from remote side. Exiting')
logger.debug('Errno: {0} Msg: {1}'.format(errno.errorcode[code], msg))
logger.debug('Errno: {0} Msg: {1}'.format(e.errno, e.strerror))
raise relay.RelayError

return channel_id, data
Expand All @@ -188,7 +188,7 @@ def manage_remote_socket(self, sock):
elif channel_id in self.channel:
relay_to_sock = self.channel[channel_id]
logger.debug('Got data to relay from remote side. Channel id {0}. Data length: {1}'.format(channel_id, len(data)))
logger.debug('Data contents: {0}'.format(data.encode('hex')))
logger.debug('Data contents: {0}'.format(data))
self.relay(data, relay_to_sock)
else:
logger.debug('Relay from socket {0} with channel {1} not possible. Channel does not exist'.format(sock, channel_id))
Expand All @@ -206,9 +206,9 @@ def manage_forward_socket(self, sock):
#logger.debug('Readable socket {0} with channel id {1}'.format(sock, channel_id))
try:
data = sock.recv(relay.buffer_size)
except socket.error as (code, msg):
except socket.error as e:
logger.debug('Exception on receiving data from socket {0} with channel id {1}'.format(sock, channel_id))
logger.debug('Errno: {0} Msg: {1}'.format(errno.errorcode[code], msg))
logger.debug('Errno: {0} Msg: {1}'.format(e.errno, e.strerror))
logger.debug('Closing socket {0} with channel id {1}'.format(sock, channel_id))
self.close_forward_connection(sock)
return
Expand All @@ -220,8 +220,8 @@ def manage_forward_socket(self, sock):
channel_id = self.id_by_socket[sock]
tlv_header = pack('<HH', channel_id, len(data))
logger.debug('Got data to relay from app side. Channel id {0}. Data length: {1}'.format(channel_id, len(data)))
logger.debug('Preparing tlv header: {0}'.format(tlv_header.encode('hex')))
logger.debug('Data contents: {0}'.format(data.encode('hex')))
logger.debug('Preparing tlv header: {0}'.format(tlv_header))
logger.debug('Data contents: {0}'.format(data))
self.relay(tlv_header + data, self.bc_sock)

def close_forward_connection(self, sock):
Expand Down Expand Up @@ -250,8 +250,8 @@ def send_remote_cmd(self, sock, cmd, *args):
tlv_header = pack('<HH', relay.COMMAND_CHANNEL, len(cmd_buffer))
try:
sock.send(tlv_header + cmd_buffer)
except socket.error as (code, cmd):
logger.error('Socket error on sending command to remote side. Code {0}. Msg {1}'.format(code, cmd))
except socket.error as e:
logger.error('Socket error on sending command to remote side. Code {0}. Msg {1}'.format(e.errno, e.strerror))

def set_channel(self, sock, channel_id):
self.channel[channel_id] = sock
Expand All @@ -267,8 +267,8 @@ def establish_forward_socket(self, channel_id, host, port):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setblocking(0)
sock.connect_ex((host, port))
except socket.error as (code, msg):
logger.debug("Caught exception socket.error during establishing forward connection. Code {0}. Msg {1}".format(code, msg))
except socket.error as e:
logger.debug("Caught exception socket.error during establishing forward connection. Code {0}. Msg {1}".format(e.errno, e.strerror))
self.send_remote_cmd(self.bc_sock, relay.FORWARD_CONNECTION_FAILURE, channel_id)
return
logger.debug('Adding new pending forward connection with channel id {0} and socket {1}'.format(channel_id, sock))
Expand All @@ -279,9 +279,9 @@ def relay(self, data, to_socket):
return
try:
to_socket.send(data)
except socket.error as (code, msg):
except socket.error as e:
logger.debug('Exception on relaying data to socket {0}'.format(to_socket))
logger.debug('Errno: {0} Msg: {1}'.format(errno.errorcode[code], msg))
logger.debug('Errno: {0} Msg: {1}'.format(e.errno, e.strerror))
if to_socket == self.bc_sock:
raise relay.RelayError
else:
Expand Down Expand Up @@ -330,15 +330,15 @@ def connect(self, host_port):
self._sock.connect((self._proxy_ip, self._proxy_port))
self._sock.send(NtlmProxyContext.negotiate_request.format(host, str(port), negotiate_message))
resp = self._sock.recv(4096)
except socket.error as (code, msg):
logger.error("Caught socket error trying to establish connection to proxy. Code {0}. Msg {1}".format(code, msg))
except socket.error as e:
logger.error("Caught socket error trying to establish connection to proxy. Code {0}. Msg {1}".format(e.errno, e.strerror))
raise

try:
chal_msg = NtlmProxyContext.get_challenge(resp)
ntlm_context.parse_challenge_message(chal_msg)
except TypeError:
logger.error("Couldn't parse proxy challenge. Code {0}. Msg {1}".format(code, msg))
logger.error("Couldn't parse proxy challenge. Code {0}. Msg {1}".format(e.errno, e.strerror))
if resp is not None:
logger.error("Challenge contents: {0}".format(resp))
else:
Expand All @@ -356,8 +356,8 @@ def connect(self, host_port):
try:
self._sock.send(NtlmProxyContext.authenticate_request.format(host, str(port), authenticate_message))
resp = self._sock.recv(4096)
except socket.error as (code, msg):
logger.error("Caught socket error trying to send challenge response connection to proxy. Code {0}. Msg {1}".format(code, msg))
except socket.error as e:
logger.error("Caught socket error trying to send challenge response connection to proxy. Code {0}. Msg {1}".format(e.errno, e.strerror))
self._sock.close()
raise

Expand Down Expand Up @@ -421,7 +421,7 @@ def main():

cmd_options = parser.parse_args()[0]
if cmd_options.server_ip is None:
print 'Server IP required'
print('Server IP required')
sys.exit()
logger = logging.getLogger('root')
logger.setLevel(logging.DEBUG)
Expand Down Expand Up @@ -466,31 +466,31 @@ def main():
bc_sock = ntlm_con
bc_sock.connect((backconnect_host, backconnect_port))
break
except socket.error as (code, msg):
logger.info('Unable to connect to {0} port: {1}. Caught socket error trying to establish connection with RPIVOT server. Code {2}. Msg {3}'.format(cmd_options.server_ip, cmd_options.server_port, code, msg))
except socket.error as e:
logger.info('Unable to connect to {0} port: {1}. Caught socket error trying to establish connection with RPIVOT server. Code {2}. Msg {3}'.format(cmd_options.server_ip, cmd_options.server_port, e.errno, e.strerror))
logger.info('Retrying')
time.sleep(5)

try:
bc_sock.send(relay.banner)
banner_reponse_rcv = bc_sock.recv(4096)
bc_sock.send(relay.banner.encode('UTF-8'))
banner_reponse_rcv = bc_sock.recv(4096).decode('UTF-8')
if banner_reponse_rcv != relay.banner_response:
logger.error("Wrong banner response {0} from server. Retrying".format(repr(banner_reponse_rcv)))
bc_sock.close()
time.sleep(5)
continue
except socket.error as (code, msg):
logger.error("Caught socket error trying to establish connection with RPIVOT server. Code {0}. Msg {1}".format(code, msg))
except socket.error as e:
logger.error("Caught socket error trying to establish connection with RPIVOT server. Code {0}. Msg {1}".format(e.errno, e.strerror))
bc_sock.close()
time.sleep(5)
continue

socks_relayer = SocksRelay(bc_sock)
try:
socks_relayer.run()
except socket.error as (code, msg):
except socket.error as e:
logger.debug('Exception in socks_relayer.run(). Restarting relay')
logger.debug('Errno: {0} Msg: {1}'.format(errno.errorcode[code], msg))
logger.debug('Errno: {0} Msg: {1}'.format(e.errno, e.strerror))
bc_sock.close()
continue
time.sleep(10)
Expand Down
30 changes: 15 additions & 15 deletions relay.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,28 @@

buffer_size = 4096
delay = 0.0001
socks_server_reply_success = '\x00\x5a\xff\xff\xff\xff\xff\xff'
socks_server_reply_fail = '\x00\x5b\xff\xff\xff\xff\xff\xff'
socks_server_reply_success = b'\x00\x5a\xff\xff\xff\xff\xff\xff'
socks_server_reply_fail = b'\x00\x5b\xff\xff\xff\xff\xff\xff'
relay_timeout = 60
banner = 'RPIVOT'
banner_response = 'TUNNELRDY'

COMMAND_CHANNEL = 0

CHANNEL_CLOSE_CMD = '\xcc'
CHANNEL_OPEN_CMD = '\xdd'
FORWARD_CONNECTION_SUCCESS = '\xee'
FORWARD_CONNECTION_FAILURE = '\xff'
CLOSE_RELAY = '\xc4'
PING_CMD = '\x70'
CHANNEL_CLOSE_CMD = b'\xcc'
CHANNEL_OPEN_CMD = b'\xdd'
FORWARD_CONNECTION_SUCCESS = b'\xee'
FORWARD_CONNECTION_FAILURE = b'\xff'
CLOSE_RELAY = b'\xc4'
PING_CMD = b'\x70'

cmd_names = {
'\xcc': 'CHANNEL_CLOSE_CMD',
'\xdd': 'CHANNEL_OPEN_CMD',
'\xee': 'FORWARD_CONNECTION_SUCCESS',
'\xff': 'FORWARD_CONNECTION_FAILURE',
'\xc4': 'CLOSE_RELAY',
'\x70': 'PING_CMD'
b'\xcc': 'CHANNEL_CLOSE_CMD',
b'\xdd': 'CHANNEL_OPEN_CMD',
b'\xee': 'FORWARD_CONNECTION_SUCCESS',
b'\xff': 'FORWARD_CONNECTION_FAILURE',
b'\xc4': 'CLOSE_RELAY',
b'\x70': 'PING_CMD'
}


Expand All @@ -38,7 +38,7 @@ class RelayError(Exception):


def recvall(sock, data_len):
buf = ''
buf = b''
while True:
buf += sock.recv(data_len - len(buf))
if len(buf) == data_len:
Expand Down
Loading