A very simple TCP redirector written in python as an experiment. It redirects any data sent to local port’s to a target host, port. It acts as a bridge between local port and the target host, port pair. You can run it by specifying a local port, target host and target host’s port. For example the following will redirect all HTTP request to local port 8080 into Google web server
$ ./SimpleTCPRedirector localhost 8080 www.google.com 80
#!/usr/bin/env python
import socket
import threading
import select
import sys
terminateAll = False
class ClientThread(threading.Thread):
def __init__(self, clientSocket, targetHost, targetPort):
threading.Thread.__init__(self)
self.__clientSocket = clientSocket
self.__targetHost = targetHost
self.__targetPort = targetPort
def run(self):
print "Client Thread started"
self.__clientSocket.setblocking(0)
targetHostSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
targetHostSocket.connect((self.__targetHost, self.__targetPort))
targetHostSocket.setblocking(0)
clientData = ""
targetHostData = ""
terminate = False
while not terminate and not terminateAll:
inputs = [self.__clientSocket, targetHostSocket]
outputs = []
if len(clientData) > 0:
outputs.append(self.__clientSocket)
if len(targetHostData) > 0:
outputs.append(targetHostSocket)
try:
inputsReady, outputsReady, errorsReady = select.select(inputs, outputs, [], 1.0)
except Exception, e:
print e
break
for inp in inputsReady:
if inp == self.__clientSocket:
try:
data = self.__clientSocket.recv(4096)
except Exception, e:
print e
if data != None:
if len(data) > 0:
targetHostData += data
else:
terminate = True
elif inp == targetHostSocket:
try:
data = targetHostSocket.recv(4096)
except Exception, e:
print e
if data != None:
if len(data) > 0:
clientData += data
else:
terminate = True
for out in outputsReady:
if out == self.__clientSocket and len(clientData) > 0:
bytesWritten = self.__clientSocket.send(clientData)
if bytesWritten > 0:
clientData = clientData[bytesWritten:]
elif out == targetHostSocket and len(targetHostData) > 0:
bytesWritten = targetHostSocket.send(targetHostData)
if bytesWritten > 0:
targetHostData = targetHostData[bytesWritten:]
self.__clientSocket.close()
targetHostSocket.close()
print "ClienThread terminating"
if __name__ == '__main__':
if len(sys.argv) != 5:
print 'Usage:\n\tpython SimpleTCPRedirector '
print 'Example:\n\tpython SimpleTCPRedirector localhost 8080 www.google.com 80'
sys.exit(0)
localHost = sys.argv[1]
localPort = int(sys.argv[2])
targetHost = sys.argv[3]
targetPort = int(sys.argv[4])
serverSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
serverSocket.bind((localHost, localPort))
serverSocket.listen(5)
print "Waiting for client..."
while True:
try:
clientSocket, address = serverSocket.accept()
except KeyboardInterrupt:
print "\nTerminating..."
terminateAll = True
break
ClientThread(clientSocket, targetHost, targetPort).start()
serverSocket.close()