Adminxe's Blog | 低调求发展 - 潜心习安全 ,技术永无止境 | 谢谢您对本站的支持,有什么问题或者建议请及时联系:点击这里给我发消息

使用Python创建TCP代理之工业时代造轮子

Python Adminxe 4730℃ 0评论

0x00 前言

无聊之余看到XT博客说,使用python创建TCP代理,也来搞了一下,代码无优化,借鉴cnblogs大佬shaoshao的代码,进一步改良。只提供一个轮子,轮子之旅开始。

0x01 XT写的代码

import sys
import threading
import socket
def server_loop(local_host,local_port,remote_host,remote_port,receive_first):
    server=socket.socket(socket.AF_INET,socket.SOCK_STREAM)
    try:
        server.blind((local_host,local_port))
    except:
        print “[!!] Failed to listen on %s:%d” % (local_host,local_port)
        print “[!!] Check for other listing 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 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 “[<==] Sening %d bytes to localhost.” % len(remote_buffer)
            client_socket.send(remote_buffer)
    while True:
        local_buffer=receive_from(cilent_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 “[==>] Send 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)
            cilent_socket.send(remote_buffer)
            print “[<==] Sent to localhost.”
        if not len(local_buffer) or not len(remote_buffer):
            client_socket.close()
            remote_socket.close()
            print “[*] No more data.Closing connection.”
            break
def hexdump(src,length=16):
    result=[]
    digits=4 if isinstance(src,unicode) else 2
    for i in xrange(0,len(src),length):
        s=src[i:i+length]
        hexa=b’ ‘.join([“%0*X” % (digits, ord(x)) for x in s])
        text=b”.join([x if 0x20 <=ord(x) < 0x7F else b’.’  for x in s])
        result.append( b”%04X   %S” (i, length*(digits + 1),hexa,text))
    print b’\n’,join(result)
def receive_from(connection):
    buffer=””
    connection.settimeout(2)
        try:
            while True:
                data=connection.recv(4096)
                if not data:
                    break
                buffer += data
        except:
        pass
        return buffer
def request_handler(buffer):
    return buffer
def response_handler(buffer):
    return buffer
def main():
    if len(sys.argv[1:]) !=5:
        print “Usage: ./proxy.py [localhost] [localport] [remotehost] [remoteport] [receive_first]”
        print “Example: ./proxy.py 127.0.0.1 9000 10.12.132.1 9000 Ture”
        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)
main()

0x02 代理服务器

# coding:utf8
# 创建一个 TCP 代理

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:
        # 服务器监听的 host和端口
        server.bind((local_host, local_port))
    except Exception, e:
        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)

    #开始监听TCP传入连接
    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 hexdump(src, length=16):
    result = []
    digits = 4 if isinstance(src, unicode) else 2

    for i in xrange(0, len(src), length):
        s = src[i:i+length]
        hexa = b' ' . join(["%0*X" % (digits, ord(x)) for x in s])
        text = b''.join([x if 0x20 <= ord(x) < 0x7F else b'.' for x in s])
        result.append(b"%04X %-*s %s" % (i, length*(digits + 1), hexa, text))

    print b'\n'.join(result)

# 从远程服务器里面接受数据
def receive_from(connection):
    print "receive_from function start ........... "
    buffer = ""

    # 我们设置了两秒的超时, 这取决于目标的情况, 可能需要调整
    connection.settimeout(2)

    try:
        # 持续从缓存中读取数据直到没有数据或者超时
        while True:
            data = connection.recv(4096)
            print "receive_from data is %s " % data
            if not data:
                print "receive_from data is break ......."
                break

            buffer += data

    except Exception, e:
        print str(e)
        print str(Exception)
        print 'error for receive_from'

    return buffer

# 对目标是远程主机的请求进行修改
def request_handler(buffer):
    #执行包修改
    return buffer

# 对目标是本地主机的响应进行修改
def response_handler(buffer):
    #执行包修改
    return buffer



def proxy_handler(client_socket, remote_host, remote_port, receive_first):
    # 连接远程主机
    remote_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    print "remote_socket start ...... %s %d" % (remote_host, remote_port)
    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)
        print "local_buffer is %s " % local_buffer
        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)

            # 将响应发送给本地socket
            client_socket.send(remote_buffer)

        # 如果两边都没有数据, 关闭连接
        if not len(local_buffer) or not len(remote_buffer):
            client_socket.close()
            remote_socket.close()
            print "[*] No more data. Closing connections."
            sys.exit(0)
            break



def main():
    if len(sys.argv[1:]) != 5:
        print "Usage: ./proxy.py [localhost] [localport] [remotehost] [remoteport] [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

    # 设置好我们的监听 socket
    server_loop(local_host, local_port, remote_host, remote_port, receive_first)

main()


##
##python index5.py 0.0.0.0 9999 120.25.249.52 80 True
##cd D:\python_code\httPython

0x03 TCP客户端

# coding:utf8

import socket

target_host = '127.0.0.1'
target_port = 9999

# 建立一个socket 对象
# socket.AF_INET表示IPv4地址,或者主机名
# socket.SCOK_STREAM 这将是一个TCP客户端
client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

# 连接客户端
client.connect((target_host, target_port))

# 发送一些数据
client.send("GET / HTTP/1.1\r\nHost: chengzhier.com\r\n\r\n") # 这里不要直接打字符串,需要用http的形式请求

# 接收一些数据
response = client.recv(4096)

print response

0x04 总结

全篇水文,只为以后造轮子,安排!

转载请注明:Adminxe's Blog » 使用Python创建TCP代理之工业时代造轮子

喜欢 (15)or分享 (0)
发表我的评论
取消评论
表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址