由于black hat python中的代码是采用python2实现的,而python2已经太过久远了,所以用python3实现了一遍,算是复习了一下socket编程的基础部分。其中hexdump函数很有意思,由于写的时候忘掉了bytes相关的东西,所以借鉴了某位大佬的代码,当然实现的效果还不错,很像一些16进制编辑器读取的样子。
#!/usr/local/bin/python3
import sys
import socket
import threading
def server_loop(local_host,local_port,remote_host,remote_port,receive_first):
server = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
try:
server.bind((local_host,local_port))
except:
print("[!] Failed to listen on %s:%d." % (local_host,local_port))
print("[!] Check for other listening sockets or correct permissions.")
sys.exit(0)
print("[*] Listening on %s:%d" % (local_host,local_port))
server.listen(5)
while True:
client_socket, addr = server.accept()
print("[==>] Received incoming connection from %s:%d" % (addr[0],addr[1]))
proxy_thread = threading.Thread(target=proxy_handler,args=(client_socket,remote_host,remote_port,receive_first))
proxy_thread.start()
def main():
if len(sys.argv[1:]) != 5:
print("Usage: ./proxy.py [local_host][local_port][remote_host][remote_port][receive_first]")
print("Example: ./proxy.py 127.0.0.1 9000 10.12.132.1 9000 True")
sys.exit(0)
#设置本地监听参数
local_host = sys.argv[1]
local_port = int(sys.argv[2])
#设置远程主机参数
remote_host = sys.argv[3]
remote_port = int(sys.argv[4])
receive_first = sys.argv[5]
if "True" in receive_first:
receive_first = True
else:
receive_first = False
server_loop(local_host,local_port,remote_host,remote_port,receive_first)
def proxy_handler(client_socket,remote_host,remote_port,receive_first):
remote_socket = socket.socket(socket.AF_INET,socket.SOCK_STREAM)
remote_socket.connect((remote_host,remote_port))
if receive_first:
remote_buffer = receive_from(remote_socket)
hexdump(remote_buffer)
remote_buffer = response_handler(remote_buffer)
if len(remote_buffer):
print("[<==] Sending %d bytes to localhost." % len(remote_buffer))
client_socket.send(remote_buffer)
while True:
#从本地读取数据
local_buffer = receive_from(client_socket)
if len(local_buffer):
print("[==>] Received %d bytes from localhost." % len(local_buffer))
hexdump(local_buffer)
local_buffer = request_handler(local_buffer)
remote_socket.send(local_buffer)
print("[==>] Sent to remote.")
#从远程主机读取数据
remote_buffer = receive_from(remote_socket)
if len(remote_buffer):
print("[<==] Received %d bytes from remote." % len(remote_buffer))
hexdump(remote_buffer)
remote_buffer = response_handler(remote_buffer)
client_socket.send(remote_buffer)
print("[==>] Sent to client.")
if not len(local_buffer) and not len(remote_buffer):
client_socket.close()
remote_socket.close()
print("No more data. Closing connections.")
break
def hexdump(src,length = 16):
result = []
digits = 2 if isinstance(src,str) else 4
for i in range(0, len(src),length):
s = src[i:i+length]
hexa = ' '.join([hex(x)[2:].upper().zfill(digits) for x in s])
text = ''.join([chr(x) if 0x20 <= x < 0x7F else '.' for x in s])
result.append("{0:04X}".format(i) + ' ' * 4 + hexa.ljust(length * (digits + 1)) + ' ' * 4 + "{0}".format(text))
for i in result:
print(i)
def receive_from(connection):
buffer = ""
connection.settimeout(2)
try:
while True:
data = connection.recv(4096)
print(type(data))
if not data:
break
data = bytes.decode(data)
buffer += data
buffer = str.encode(buffer)
except:
pass
return buffer
def request_handler(buffer):
return buffer
def response_handler(buffer):
return buffer
main()
用curl测试比较好,浏览器代理会失败,原因还未知。