2015-09-08 48 views
0

我正在學習Black Hat Python並試圖瞭解TCP代理代碼。使用Python的TCP代理

我現在幾乎理解,但是當我嘗試在一個終端與

python proxy.py localhost 21 ftp.target.ca 21 True 

進行測試和

ftp ftp.target.ca 21 
在另一個

它不是做得比較工作。

在第一個終端中,我只能聽到端口21上的本地主機,而沒有其他的東西;而在第二個終端中,發生了我和服務器之間的連接,並且我寫了用戶名和密碼。

在我和服務器之間傳輸的包應該出現在第一個終端中。

我在做什麼錯?

下面是代碼:

import sys 
import socket 
import threading 



# 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 = "" 

    # We set a 2 second time out depending on your 
    # target this may need to be adjusted 
    connection.settimeout(2) 

     try: 
       # keep reading into the buffer until there's no more data 
     # or we time out 
       while True: 
         data = connection.recv(4096) 

         if not data: 
           break 

         buffer += data 


     except: 
     pass 

     return buffer 

# modify any requests destined for the remote host 
def request_handler(buffer): 
    # perform packet modifications 
    return buffer 

# modify any responses destined for the local host 
def response_handler(buffer): 
    # perform packet modifications 
    return buffer 


def proxy_handler(client_socket, remote_host, remote_port, receive_first): 

     # connect to the remote host 
     remote_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) 
     remote_socket.connect((remote_host,remote_port)) 

     # receive data from the remote end if necessary 
     if receive_first: 

       remote_buffer = receive_from(remote_socket) 
       hexdump(remote_buffer) 

       # send it to our response handler 
     remote_buffer = response_handler(remote_buffer) 

       # if we have data to send to our local client send it 
       if len(remote_buffer): 
         print "[<==] Sending %d bytes to localhost." % len(remote_buffer) 
         client_socket.send(remote_buffer) 

    # now let's loop and reading from local, send to remote, send to local 
    # rinse wash repeat 
    while True: 

     # read from local host 
     local_buffer = receive_from(client_socket) 


     if len(local_buffer): 

      print "[==>] Received %d bytes from localhost." % len(local_buffer) 
      hexdump(local_buffer) 

      # send it to our request handler 
      local_buffer = request_handler(local_buffer) 

      # send off the data to the remote host 
      remote_socket.send(local_buffer) 
      print "[==>] Sent to remote." 


     # receive back the response 
     remote_buffer = receive_from(remote_socket) 

     if len(remote_buffer): 

      print "[<==] Received %d bytes from remote." % len(remote_buffer) 
      hexdump(remote_buffer) 

      # send to our response handler 
      remote_buffer = response_handler(remote_buffer) 

      # send the response to the local socket 
      client_socket.send(remote_buffer) 

      print "[<==] Sent to localhost." 

     # if no more data on either side close the connections 
     if not len(local_buffer) or not len(remote_buffer): 
      client_socket.close() 
      remote_socket.close() 
      print "[*] No more data. Closing connections." 

      break 

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 out the local connection information 
       print "[==>] Received incoming connection from %s:%d" % (addr[0],addr[1]) 

       # start a thread to talk to the remote host 
       proxy_thread = threading.Thread(target=proxy_handler,args=(client_socket,remote_host,remote_port,receive_first)) 
       proxy_thread.start() 

def main(): 

    # no fancy command line parsing here 
    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) 

    # setup local listening parameters 
    local_host = sys.argv[1] 
    local_port = int(sys.argv[2]) 

    # setup remote target 
    remote_host = sys.argv[3] 
    remote_port = int(sys.argv[4]) 

    # this tells our proxy to connect and receive data 
    # before sending to the remote host 
    receive_first = sys.argv[5] 

    if "True" in receive_first: 
     receive_first = True 
    else: 
     receive_first = False 


    # now spin up our listening socket 
    server_loop(local_host,local_port,remote_host,remote_port,receive_first) 

main() 
+0

嗨@AN HA。此代碼的許可證是什麼? – erjoalgo

回答

0

只需運行端口21上的代理服務器不會使FTP客戶端使用它 - 所以你不應該試圖連接到遠程主機。如果命令行在例如9000上運行代理,則將ftp傳送到該端口,即localhost 9000,並且代理將向/從該遠程主機轉發通信。

+0

我在proftpd.conf中將ftp端口更改爲1234,這就是你的意思,沒有任何事情發生,我寫了python proxy.py localhost 1234 ftp.target.ca 21真正的和相同的結果 –

+0

嘗試而不是ftp ftp.target.ca 21做FTP本地主機21(假設你在同一主機上運行代理),因爲proxy.py命令行告訴它將端口21轉發到ftp.target.ca – barny

+0

像這樣python proxy.py localhost 1234 localhost 1234 True並且在另一個終端ftp localhost 1234?如何或我明白錯 –