0

Python Socks5 by Foul

A socks5 in Python by Foul:


''' USAGE: python socks.py >/dev/null 2>&1 & '''
''' Socks5 will bind to port 1200-1205, e.g Use IP:1200 as the socks5 proxy '''
from socket				import socket, AF_INET, SOCK_STREAM, SOL_SOCKET, SO_REUSEADDR
from multiprocessing	import Pool, log_to_stderr
from threading			import Thread
from gc					import collect
from time				import sleep
from sys				import argv
from logging			import DEBUG

class focks5(Thread):
	def __init__(self, _sock):
		Thread.__init__(self)
		self.setDaemon(True)
		self.client = _sock[0]
		self.server = None
		self.ip, self.port = self.client.getsockname()
		self.client.settimeout(5)
	
	def run(self):
		try:
			buffer = self.client.recv(5)
			version, nmethods, methods = [buffer[i] for i in range(0, 3)]
			self.client.sendall('\x05\x00')
			
			version, cmd, rsv, atyp = [i for i in self.client.recv(4)]
			
			if atyp == '\x01': ## IPv4
				dest = [str(self.client.recv(4)), str(self.client.recv(2))]
				dest[0] = '.'.join([str(ord(i)) for i in dest[0]])
				
			elif atyp == '\x03': ## Domain
				addr_len = ord(self.client.recv(1))
				dest = [str(self.client.recv(addr_len)), str(self.client.recv(2))]
				dest[0] = ''.join([unichr(ord(i)) for i in dest[0]])
				
			else:
				self.client.sendall('\x05\x08\x00\x01')
				raise Exception()
			
			
			dest[1] = int((ord(dest[1][0]) * 256) + (ord(dest[1][1])))
			server_ip = ''.join([chr(int(i)) for i in self.ip.split('.')])
			
			if cmd == '\x01': ## Connect
				self.client.sendall('\x05\x00\x00\x01' + server_ip + chr(self.port / 256) + chr(self.port % 256))
				self.server = socket(AF_INET, SOCK_STREAM)
				self.server.connect(tuple(dest))
				self.server.settimeout(300)
				self.client.settimeout(300)
				
				Thread(target = self.resend, args = [self.client, self.server]).start()
				Thread(target = self.resend, args = [self.server, self.client]).start()
				return
		except Exception, e:
			print e
		
		self.socketClose()
	
	def socketClose(self):
		try:	self.client.shutdown(2)
		except: pass
		
		try:	self.server.shutdown(2)
		except: pass
		
		try:    self.client.close()
		except: pass
		
		try:    self.server.close()
		except: pass
	
	def resend(self, source, dest):
		try:
			recv = source.recv(2048)
			while recv:
				dest.sendall(recv)
				recv = source.recv(2048)
			
			source.close()
			dest.close()
		except Exception, e:
			pass
		
		self.socketClose()
	
	
def init(port):
	listener = socket(AF_INET, SOCK_STREAM)
	listener.setsockopt(SOL_SOCKET, SO_REUSEADDR, True)
	listener.bind(('0.0.0.0', port))
	listener.listen(5)
	
	while True:
		client = listener.accept()
		proxy = focks5(client)
		proxy.start()

def cleaner():
	while True:
		collect()
		sleep(5)
init(1200)
exit()
if __name__ == '__main__':
	t = Thread(target = cleaner)
	t.daemon = True
	t.start()
	
	ports = range(1200, 1205)
	#ports = [1200, 1201, 1202, 1203, 1204, 12000]
	
	#log_to_stderr(DEBUG)
	
	pool = Pool(len(ports))
	
	pool.map(init, ports)
	pool.close()
	pool.join()