Python编写TCP代理

TCP Proxy

可用来未知协议,修改发送到应用的数据包,或者为模糊测试创建一个环境。
usgae:tcp_proxy.py [本地IP][本地端口][远程IP][远程端口][recevice_first]

效果

[*] Listening on 127.0.0.1:21
[===>] Recived from 127.0.0.1:49990
0000   32 32 30 20 4D 69 63 72 6F 73 6F 66 74 20 46 54    220 Microsoft FT
0010   50 20 53 65 72 76 69 63 65 0D 0A                   P Service..
[<==] Sending 27 bytes to loaclhsot.
0000   32 32 30 20 4D 69 63 72 6F 73 6F 66 74 20 46 54    220 Microsoft FT
0010   50 20 53 65 72 76 69 63 65 0D 0A                   P Service..0000   32 32 30 20 4D 69 63 72 6F 73 6F 66 74 20 46 54    220 Microsoft FT
0010   50 20 53 65 72 76 69 63 65 0D 0A                   P Service..
[<==] Sending 27 bytes to loaclhsot.

[<==] Sending 27 bytes to loaclhsot. [==>] Rec 11 bytes from loaclhost
0000   55 53 45 52 20 72 6F 6F 74 0D 0A                   USER root..
[==>] Send to remote
[==>] Rec 11 bytes from loaclhost
0000   55 53 45 52 20 72 6F 6F 74 0D 0A                   USER root..
[==>] Rec 11 bytes from loaclhost
 0000   55 53 45 52 20 72 6F 6F 74 0D 0A                   USER root..
[==>] Send to remote
[==>] Send to remote
[<==] Rec 33 bytes from remote
0000   33 33 31 20 50 61 73 73 77 6F 72 64 20 72 65 71    331 Password req
0010   75 69 72 65 64 20 66 6F 72 20 72 6F 6F 74 2E 0D    uired for root..
0020   0A                                                 .
[<==] Send to local
[<==] Rec 33 bytes from remote
0000   33 33 31 20 50 61 73 73 77 6F 72 64 20 72 65 71    331 Password req
0010   75 69 72 65 64 20 66 6F 72 20 72 6F 6F 74 2E 0D    uired for root..
0020   0A                                                 .
[<==] Send to local
[<==] Rec 33 bytes from remote
0000   33 33 31 20 50 61 73 73 77 6F 72 64 20 72 65 71    331 Password req
0010   75 69 72 65 64 20 66 6F 72 20 72 6F 6F 74 2E 0D    uired for root..
0020   0A                                                 .
[<==] Send to local [==>] Rec 15 bytes from loaclhost
0000   50 41 53 53 20 70 61 73 73 77 6F 72 64 0D 0A       PASS password..
[==>] Send to remote
[==>] Rec 9 bytes from loaclhost
0000   50 41 53 53 20 22 22 0D 0A                         PASS ""..
[==>] Send to remote
[==>] Rec 11 bytes from loaclhost
0000   50 41 53 53 20 72 6F 6F 74 0D 0A                   PASS root..
[==>] Send to remote
[<==] Rec 25 bytes from remote
0000   35 33 30 20 55 73 65 72 20 63 61 6E 6E 6F 74 20    530 User cannot 
0010   6C 6F 67 20 69 6E 2E 0D 0A                         log in...
[<==] Send to local
[<==] Rec 25 bytes from remote
0000   35 33 30 20 55 73 65 72 20 63 61 6E 6E 6F 74 20    530 User cannot 
0010   6C 6F 67 20 69 6E 2E 0D 0A                         log in...
[<==] Send to local
[<==] Rec 25 bytes from remote
0000   35 33 30 20 55 73 65 72 20 63 61 6E 6E 6F 74 20    530 User cannot 
0010   6C 6F 67 20 69 6E 2E 0D 0A                         log in...
[<==] Send to local
[*] No more date,close socket
[*] No more date,close socket
[*] No more date,close socket

Python代码

#-*-coding:utf-8-*-
import sys
import socket
import threading
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 loaclhsot." % len(remote_buffer)
            len(remote_buffer)
            client_socket.send(remote_buffer)
 
    while True:
 
        #发送给我们的本地请求
        local_buffer = receive_from(client_socket)
        if len(local_buffer):
            print "[==>] Rec %d bytes from loaclhost" % len(local_buffer)
            hexdump(local_buffer)
 
            local_buffer = response_handler(local_buffer)
 
            remote_socket.send(local_buffer)
            print "[==>] Send to remote"
 
        #接受响应数据
        remote_buffer = receive_from(remote_socket)    
        if len(remote_buffer):
            print "[<==] Rec %d bytes from remote" % len(remote_buffer)
            hexdump(remote_buffer)
            #发送到响应处理函数response_handler
            remote_buffer = response_handler(remote_buffer)
 
            client_socket.send(remote_buffer)
            print "[<==] Send to local"
 
        #两边没数据关闭链接    
        if not len(local_buffer) or not len(remote_buffer):
            client_socket.close()
            remote_socket.close()
            print "[*] No more date,close socket"
            break
# this is a pretty hex dumping function directly taken from
# http://code.activestate.com/recipes/142812-hex-dumper/
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):
 
    buffer = ""
 
    #设置2秒超时
    connection.settimeout(2)
 
    try:
        #持续读取到没有数据或超时
        while True:
            date = connection.recv(4096)
            if not date:
                break
            buffer += date
 
    except:
        pass
    return buffer
 
#对目标是远程主机的请求
def request_handler(buffer):
    #修改操作
    return buffer
 
#球目标是本地的相应
def response_handler(buffer):
    #修改操作
    return buffer
 
 
 
 
def server_loop(local_host,local_port,remote_host,remote_port,recevice_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_scoket,addr = server.accept()
 
        print "[===>] Recived from %s:%d" % (addr[0],addr[1])
        proxy_thread = threading.Thread(group=None, target=proxy_handler, name=None, 
                                       args=(client_scoket,remote_host,remote_port,
                                             recevice_first), 
                                       kwargs=None, 
                                       verbose=None)
        proxy_thread.start()
 
def main():
    if len(sys.argv[1:]) != 5:
        print "usgae:tcp_proxy.py [localhsot][loacalport][remotehost][remoteport][recevice_first]"
        sys.exit()
 
    local_host = sys.argv[1]
    local_port = int(sys.argv[2])
 
    remote_host = sys.argv[3]
    remote_port = int(sys.argv[4])
 
    recevice_first =sys.argv[5]
 
    if "True" in recevice_first:
        recevice_first = True
    else:
        recevice_first = False
 
    server_loop(local_host, local_port, remote_host, remote_port, 
               recevice_first)
main()

发表评论

邮箱地址不会被公开。 必填项已用*标注