Python黑客编程之tcp代理

目的

  • 写一款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端口启代理,最后客户端连接代理,代理将客户端流量篡改后转发给服务端
  • 服务端
  • 客户端
  • 代理端
posted @ 2023-02-05 15:30  z5onk0  阅读(107)  评论(0编辑  收藏  举报