目的
- 写一款socket代理工具,其实就是在原来两极通信中再加一极,中间极用来转发socket的流量,可以在中间层面实现流量的拦截和篡改
代码
import socket
import sys
import threading
#构建可打印字符表
HEX_FILTER = ''.join([(len(repr(chr(i))) == 3) and chr(i) or '.' for i in range(256)])
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 Exception as e:
print(f'Error: {e}')
sys.exit(0)
print(f"[*] Listening on {local_host}: {local_port}")
server.listen(5)
while True:
client_socket, addr = server.accept()
print(f"> Received connection from {addr[0]}: {addr[1]}")
proxy_thread = threading.Thread(target=proxy_handler, args=(client_socket, remote_host, remote_port, receive_first))
proxy_thread.start()
def proxy_handler(client_socket, host, port, receive_first):
remote_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
remote_socket.connect((host, port))
if receive_first:
remote_buffer = receive_from(remote_socket)
hexdump(remote_buffer)
remote_buffer = response_handler(remote_buffer)
if len(remote_buffer):
print(f"[<==] Sending {len(remote_buffer)} bytes to localhost.")
client_socket.send(remote_buffer)
while True:
local_buffer = receive_from(client_socket)
if len(local_buffer):
line = f"[==>]Received {len(local_buffer)} bytes from localhost."
print(line)
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(f"[<==] Received {len(remote_buffer)} bytes from remote.")
hexdump(remote_buffer)
remote_buffer = response_handler(remote_buffer)
client_socket.send(remote_buffer)
print("[<==] Send to localhsot.")
# if not len(local_buffer) or not len(remote_buffer):
# client_socket.close()
# remote_socket.close()
# print("[*] No more data. Closing connections.")
# break
def request_handler(buffer):
buffer_str = buffer.decode()
buffer_str = " [Message From Client to Server has been Modified!] " + buffer_str
return buffer_str.encode()
def response_handler(buffer):
buffer_str = buffer.decode()
buffer_str = " [Message From Server to Client has been Modified!] " + buffer_str
return buffer_str.encode()
def receive_from(connection):
buffer = b""
connection.settimeout(3)
try:
while True:
data = connection.recv(4096)
if not data:
break
buffer += data
except Exception as e:
pass
return buffer
def hexdump(src, length=16, show=True):
if isinstance(src, bytes):
src = src.decode()
results = list()
for i in range(0, len(src), length):
word = str(src[i:i+length])
printable = word.translate(HEX_FILTER)
hexa = ''.join([f'{ord(c):02x}' for c in word])
hexwidth = length*3
results.append(f'{i:04x} {hexa:<{hexwidth}} {printable}')
if show:
for line in results:
print(line)
else:
return results
def main():
if len(sys.argv[1:]) !=5:
print("Usage: ./proxy.py [localhost] [localport]", end='')
print("[remotehost] [remoteport] [receive_first]")
print("Example: ./proxy.py 127.0.0.1 8999 192.168.1.168 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)
if __name__ == "__main__":
main()
import socket
import sys
import threading
def main():
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.bind((sys.argv[1], int(sys.argv[2])))
server_socket.listen(5)
while True:
client_socket, addr = server_socket.accept()
client_thread = threading.Thread(target=client_handler, args=(client_socket, ))
client_thread.start()
def client_handler(client_socket):
while True:
buffer = input("[Send] ")
client_socket.send(buffer.encode())
buffer = client_socket.recv(4096)
print(f"[Receive] {buffer.decode()}")
if __name__ == "__main__":
main()
import socket
import sys
def main():
client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
client_socket.connect((sys.argv[1], int(sys.argv[2])))
while True:
buffer = client_socket.recv(4096)
print(f"[Receive] {buffer.decode()}")
buffer = input("[Send] ")
client_socket.send(buffer.encode())
if __name__ == "__main__":
main()
效果
- 三者都运行在本机,先在9000端口启服务端,然后在8999端口启代理,最后客户端连接代理,代理将客户端流量篡改后转发给服务端
- 服务端
- 客户端
- 代理端