Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/317.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 为什么输出保持空白?_Python_Python 3.x_Proxy - Fatal编程技术网

Python 为什么输出保持空白?

Python 为什么输出保持空白?,python,python-3.x,proxy,Python,Python 3.x,Proxy,我在阅读《黑帽Python》一书,作者创建了一个TCP代理,但我似乎无法让它工作 以下是我正在使用的代码: 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): r

我在阅读《黑帽Python》一书,作者创建了一个TCP代理,但我似乎无法让它工作

以下是我正在使用的代码:

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, str) else 2

    for i in range(0, len(src), length):
        s = src[i:i + length]
        hexa = b' '.join([b"%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 = b''

    # 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 TimeoutError:
        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 read 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 socket.error as exc:
        print("[!!] Failed to listen on %s:%d" % (local_host,
                                                  local_port))
        print("[!!] Check for other listening sockets or correct "
              "permissions.")
        print(f"[!!] Caught exception error: {exc}")
        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()
程序应给出如下输出:

[*] Listening on 127.0.0.1:21
[==>] Received incoming connection from 127.0.0.1:59218
0000 32 32 30 20 50 72 6F 46 54 50 44 20 31 2E 33 2E 220 ProFTPD 1.3.
0010 33 61 20 53 65 72 76 65 72 20 28 44 65 62 69 61 3a Server (Debia
0020 6E 29 20 5B 3A 3A 66 66 66 66 3A 35 30 2E 35 37 n) [::ffff:22.22
0030 2E 31 36 38 2E 39 33 5D 0D 0A .22.22]..
[<==] Sending 58 bytes to localhost.
[==>] Received 12 bytes from localhost.
0000 55 53 45 52 20 74 65 73 74 79 0D 0A USER testy..
[==>] Sent to remote.
[<==] Received 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 74 65 73 74 79 0D uired for testy.
0020 0A .
[<==] Sent to localhost.
[==>] Received 13 bytes from localhost.
0000 50 41 53 53 20 74 65 73 74 65 72 0D 0A PASS tester..
[==>] Sent to remote.
[*] No more data. Closing connections.
)

我错过了什么


如果您使用
127.0.0.1 21

sudo ./proxy.py 127.0.0.1 21 ftp.dlptest.com 21 True
然后,您必须使用

ftp 127.0.0.1 21
然后它开始工作


但是有不同的问题:它似乎是为Python2创建的
hextump
,它将
bytes
str
视为相同类型的数据,并使用
ord()
将字符转换为其代码/数字。在Python3中不需要它

您还可以直接将其代码转换为字符串
chr(x)
,并连接到要显示的字符串

def hexdump(src, length=16):
    result = []
    digits = 4 if isinstance(src, str) else 2

    #print('[DEBUG] src:', type(src))

    for i in range(0, len(src), length):
        s = src[i:i+length]

        data = ['%0*X' % (digits, x) for x in s]     
        #print('[DEBUG] data:', data)
        hexa = ' '.join(data)
        #print('[DEBUG] hexa:', hexa)
        
        data = [chr(x) if 0x20 <= x < 0x7F else '.' for x in s]
        #print('[DEBUG] data:', data)
        text = ''.join(data)
        #print('[DEBUG] text:', text)
        
        result.append(
            "%04X   %-*s   %s" % (i, length * (digits+1), hexa, text))

    print('\n'.join(result))
但对于本地数据,它需要10秒

local_buffer = receive_from(client_socket, 10)

顺便说一句:

我还捕获了
KeyboardInterrupt
,以便在使用
Ctrl+C
停止服务器时关闭连接

我还要补充一点

server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
要解决服务器再次启动时错误
[Errno 98]地址已在使用的问题


代码:

第二

 ftp 127.0.0.1 5005
然后我得到

$ sudo python3.7 proxy.py 127.0.0.1 5005 ftp.dlptest.com 21 True

[*] Listening on 127.0.0.1:5005
[==>] Received incoming connection from 127.0.0.1:50124
<socket.socket fd=4, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 5005), raddr=('127.0.0.1', 50124)>
ftp.dlptest.com 21
True
receive first
[DEBUG] buffer:
220-#########################################################
220-Please upload your web files to the public_html directory.
220-Note that letters are case sensitive.
220-#########################################################
220 This is a private system - No anonymous login

0000   32 32 30 2D 23 23 23 23 23 23 23 23 23 23 23 23    220-############
0010   23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23    ################
0020   23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23    ################
0030   23 23 23 23 23 23 23 23 23 23 23 23 23 0D 0A 32    #############..2
0040   32 30 2D 50 6C 65 61 73 65 20 75 70 6C 6F 61 64    20-Please upload
0050   20 79 6F 75 72 20 77 65 62 20 66 69 6C 65 73 20     your web files 
0060   74 6F 20 74 68 65 20 70 75 62 6C 69 63 5F 68 74    to the public_ht
0070   6D 6C 20 64 69 72 65 63 74 6F 72 79 2E 0D 0A 32    ml directory...2
0080   32 30 2D 4E 6F 74 65 20 74 68 61 74 20 6C 65 74    20-Note that let
0090   74 65 72 73 20 61 72 65 20 63 61 73 65 20 73 65    ters are case se
00A0   6E 73 69 74 69 76 65 2E 0D 0A 32 32 30 2D 23 23    nsitive...220-##
00B0   23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23    ################
00C0   23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23    ################
00D0   23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23    ################
00E0   23 23 23 23 23 23 23 0D 0A 32 32 30 20 54 68 69    #######..220 Thi
00F0   73 20 69 73 20 61 20 70 72 69 76 61 74 65 20 73    s is a private s
0100   79 73 74 65 6D 20 2D 20 4E 6F 20 61 6E 6F 6E 79    ystem - No anony
0110   6D 6F 75 73 20 6C 6F 67 69 6E 0D 0A                mous login..
[<==] Sending 284 bytes to localhost.
[DEBUG] buffer:
USER furas

[==>] Received 12 bytes from localhost.
0000   55 53 45 52 20 66 75 72 61 73 0D 0A                USER furas..
[==>] Sent to remote.
[DEBUG] buffer:
331 User furas OK. Password required

[<==] Received 38 bytes from remote.
0000   33 33 31 20 55 73 65 72 20 66 75 72 61 73 20 4F    331 User furas O
0010   4B 2E 20 50 61 73 73 77 6F 72 64 20 72 65 71 75    K. Password requ
0020   69 72 65 64 0D 0A                                  ired..
[<==] Sent to localhost.
[DEBUG] buffer:
PASS adasdasda

[==>] Received 16 bytes from localhost.
0000   50 41 53 53 20 61 64 61 73 64 61 73 64 61 0D 0A    PASS adasdasda..
[==>] Sent to remote.
[DEBUG] buffer:

[*] No more data. Closing connections.
^CKeyboardInterrupt


顺便说一句:如果您使用的端口大于
1024
(如我的回答中的
5005
),那么它应该在没有
sudo的情况下运行,只是为了清楚起见,“输出保持空白”意味着您运行此脚本,但它根本不打印任何内容,而是立即退出?我的意思是它被卡在“侦听…”上,它不接收(?)传入连接您应该运行
ftp 127.0.0.1 21
与服务器连接。这给我提供了从127.0.0.1:52776接收到的
[=>]传入连接。但它仍然需要一些更改下一个问题-您必须使用
socket.timeout
而不是
timeout
来捕获超时下一个问题-代码不需要
ord()
,因为它从服务器获取字节。这段代码似乎是为
python2
而创建的,它需要
ord()
,因为它像
str
一样处理
字节,用你的代码我得到了预期的结果,我需要彻底研究它谢谢你,我真的学到了很多
server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
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, str) else 2

    #print('[DEBUG] src:', type(src))

    for i in range(0, len(src), length):
        s = src[i:i+length]

        data = ['%0*X' % (digits, x) for x in s]     
        #print('[DEBUG] data:', data)
        hexa = ' '.join(data)
        #print('[DEBUG] hexa:', hexa)
        
        data = [chr(x) if 0x20 <= x < 0x7F else '.' for x in s]
        #print('[DEBUG] data:', data)
        text = ''.join(data)
        #print('[DEBUG] text:', text)
        
        result.append(
            "%04X   %-*s   %s" % (i, length * (digits+1), hexa, text))

    print('\n'.join(result))


def receive_from(connection, timeout=2):
    buffer = b''

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

    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 socket.timeout as ex:
        #print('TimeoutError:', ex)
        pass

    print('[DEBUG] buffer:')
    print(buffer.decode())
    
    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):
    print(client_socket)
    print(remote_host, remote_port)
    print(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:
        print('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 read from local, send to remote, send to local
    # rinse wash repeat
    while True:
        # read from local host
        local_buffer = receive_from(client_socket, 10) # longer time for user response

        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)
    server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)

    try:
        server.bind((local_host, local_port))
    except socket.error as exc:
        print("[!!] Failed to listen on %s:%d" % (local_host,
                                                  local_port))
        print("[!!] Check for other listening sockets or correct "
              "permissions.")
        print(f"[!!] Caught exception error: {exc}")
        sys.exit(0)

    print("[*] Listening on %s:%d" % (local_host, local_port))

    server.listen(5)

    try:
        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()
    except KeyboardInterrupt:
        print('KeyboardInterrupt')
        server.close()

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]

    receive_first = ("True" in receive_first)

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

main()
 sudo python3.7 proxy.py 127.0.0.1 5005 ftp.dlptest.com 21 True
 ftp 127.0.0.1 5005
$ sudo python3.7 proxy.py 127.0.0.1 5005 ftp.dlptest.com 21 True

[*] Listening on 127.0.0.1:5005
[==>] Received incoming connection from 127.0.0.1:50124
<socket.socket fd=4, family=AddressFamily.AF_INET, type=SocketKind.SOCK_STREAM, proto=0, laddr=('127.0.0.1', 5005), raddr=('127.0.0.1', 50124)>
ftp.dlptest.com 21
True
receive first
[DEBUG] buffer:
220-#########################################################
220-Please upload your web files to the public_html directory.
220-Note that letters are case sensitive.
220-#########################################################
220 This is a private system - No anonymous login

0000   32 32 30 2D 23 23 23 23 23 23 23 23 23 23 23 23    220-############
0010   23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23    ################
0020   23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23    ################
0030   23 23 23 23 23 23 23 23 23 23 23 23 23 0D 0A 32    #############..2
0040   32 30 2D 50 6C 65 61 73 65 20 75 70 6C 6F 61 64    20-Please upload
0050   20 79 6F 75 72 20 77 65 62 20 66 69 6C 65 73 20     your web files 
0060   74 6F 20 74 68 65 20 70 75 62 6C 69 63 5F 68 74    to the public_ht
0070   6D 6C 20 64 69 72 65 63 74 6F 72 79 2E 0D 0A 32    ml directory...2
0080   32 30 2D 4E 6F 74 65 20 74 68 61 74 20 6C 65 74    20-Note that let
0090   74 65 72 73 20 61 72 65 20 63 61 73 65 20 73 65    ters are case se
00A0   6E 73 69 74 69 76 65 2E 0D 0A 32 32 30 2D 23 23    nsitive...220-##
00B0   23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23    ################
00C0   23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23    ################
00D0   23 23 23 23 23 23 23 23 23 23 23 23 23 23 23 23    ################
00E0   23 23 23 23 23 23 23 0D 0A 32 32 30 20 54 68 69    #######..220 Thi
00F0   73 20 69 73 20 61 20 70 72 69 76 61 74 65 20 73    s is a private s
0100   79 73 74 65 6D 20 2D 20 4E 6F 20 61 6E 6F 6E 79    ystem - No anony
0110   6D 6F 75 73 20 6C 6F 67 69 6E 0D 0A                mous login..
[<==] Sending 284 bytes to localhost.
[DEBUG] buffer:
USER furas

[==>] Received 12 bytes from localhost.
0000   55 53 45 52 20 66 75 72 61 73 0D 0A                USER furas..
[==>] Sent to remote.
[DEBUG] buffer:
331 User furas OK. Password required

[<==] Received 38 bytes from remote.
0000   33 33 31 20 55 73 65 72 20 66 75 72 61 73 20 4F    331 User furas O
0010   4B 2E 20 50 61 73 73 77 6F 72 64 20 72 65 71 75    K. Password requ
0020   69 72 65 64 0D 0A                                  ired..
[<==] Sent to localhost.
[DEBUG] buffer:
PASS adasdasda

[==>] Received 16 bytes from localhost.
0000   50 41 53 53 20 61 64 61 73 64 61 73 64 61 0D 0A    PASS adasdasda..
[==>] Sent to remote.
[DEBUG] buffer:

[*] No more data. Closing connections.
^CKeyboardInterrupt
$ ftp 127.0.0.1 5005

Connected to 127.0.0.1.
220-#########################################################
220-Please upload your web files to the public_html directory.
220-Note that letters are case sensitive.
220-#########################################################
220 This is a private system - No anonymous login
Name (127.0.0.1:furas): 
331 User furas OK. Password required
Password:
421 Service not available, remote server has closed connection
Login failed.
No control connection for command: Success
ftp> quit