使用 Black Hat Python v2 重新创建 NetCat 时出现类型错误

问题描述 投票:0回答:0

希望你能看到我做错了什么。

BHP 的第四章让我们尝试重新创建一个基本版本的 netcat。尝试将程序作为侦听器运行时出现类型错误,但我无法弄清楚原因。据我所知,一切都已检查完毕,但它说我正在尝试在我的“监听方法”中将“str”作为“int”运行

Screengrab of error

回溯(最后一次通话): 文件“/home/steelcoyote/PycharmProjects/toolkit/netcat_custom.py”,第 172 行,位于 数控运行() 运行中的文件“/home/steelcoyote/PycharmProjects/toolkit/netcat_custom.py”,第 39 行 自.listen() 文件“/home/steelcoyote/PycharmProjects/toolkit/netcat_custom.py”,第 85 行,在 listen 中 self.socket.bind((self.args.target, self.args.port)) # 1 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^ 类型错误:“str”对象不能解释为整数

有人能看到我看不到的东西吗?

import argparse
import socket
import shlex
import subprocess
import sys
import textwrap
import threading


def execute(cmd):
    cmd = cmd.strip()
    if not cmd:
        return
    output = subprocess.check_output(shlex.split(cmd), stderr=subprocess.STDOUT)
    return output.decode()


'''
subprocess.check_output() runs a command on the local operating system,
and then returns the output from that command.
'''


class NetCat:
    def __init__(self, args, buffer=None):  # 1
        self.args = args
        self.buffer = buffer
        self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)     #2
        self.socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
    '''
    1.  We initialize the NetCat object with the arguments from the command line and the buffer
    2.  We create the socket object
        the SO_REUSEADDR flag tells the kernel to reuse a local socket in TIME_WAIT state,
        without waiting for its natural timeout to expire. 
    '''

    def run(self):
        if self.args.listen:
            self.listen()
        else:
            self.send()
    '''
    RUN METHOD
    If we are setting up a listener, then the program will call the listen method,
    Otherwise it will call the send method.    
    '''

    def send(self):
        self.socket.connect((self.args.target, self.args.port))     # 1
        if self.buffer:
            self.socket.send(self.buffer)

        try:    # 2
            while True:     # 3
                recv_len = 1
                response = ''
                while recv_len:
                    data = self.socket.recv(4096)
                    recv_len = len(data)
                    response += data.decode()
                    if recv_len < 4096:
                        break   # 4
                if response:
                    print(response)
                    buffer = input('> ')
                    buffer += '\n'
                    self.socket.send(buffer.encode())   # 5
        except KeyboardInterrupt:   # 6
            print('User Terminated.')
            self.socket.close()
            sys.exit()
    '''
    SEND METHOD
    1.  We connect the target and port. If we havea buffer we connect that to the target first.
        The we set up a try/catch block so we can manually close the connection with ctrl-c
    2.  We start a loop
    3.  Loop receives data from target. If there is no more data
    4.  We break out of the loop.
    5.  Otherwise, we print the response data and pause to get interactive input,
        send the input and continue the loop.
    6. Loop will continue until KeyboardInterrupt occurs, ctrl-c, which will close the socket.
    '''

    def listen(self):
        self.socket.bind((self.args.target, self.args.port))    # 1
        self.socket.listen(5)

        while True:     # 2
            client_socket, _ = self.socket.accept()
            client_thread = threading.Thread(target=self.handle, args=(client_socket,))     # 3
            client_thread.start()
    '''
    1.  The listen method binds to the target and the port
    2.  Starts listening in a loop.
    3.  Passes the connected socket to the handle method  
    '''

    def handle(self, client_socket):
        if self.args.execute:   # 1
            output = execute(self.args.execute)
            client_socket.send(output.encode())

        elif self.args.upload:  # 2
            file_buffer = b''
            while True:
                data = client_socket.recv(4096)
                if data:
                    file_buffer += data
                else:
                    break

        elif self.args.command: # 3
            cmd_buffer = b''
            while True:
                try:
                    client_socket.send(b'BHP: $> ')
                    while '\n' not in cmd_buffer.decode():
                        cmd_buffer += client_socket.recv(64)
                    response = execute(cmd_buffer.decode())
                    if response:
                        client_socket.send(response.encode())
                    cmd_buffer = b''
                except Exception as e:
                    print(f'server killed {e}')
                    self.socket.close()
                    sys.exit()
    '''
    HANDLE METHOD
    The handle method executes the task corresponding to the command line argument it receives.
    
    1. The handle method passed the given command to the execute function
        and sends the output back on the socket.
    2. If a file should be uploaded, we set up a loop to listen for content on the listening socket
        and receive data until there's no more data coming in. 
        Then the accumulated content is written to the specified file.
    3. Finally, if a shell is to be created, we set up a loop, send a prompt to the sender, and wait for a 
        command string to come back. We then execute the command by using the execute function and return the output
        of the command to the sender.
        
        The shell scan for a newline character to determine when to process a command, 
        which makes it netcat friendly. Meaning, we can use this program on the listener side
        and use netcat itself on the sender side.
        However, if we are coming up with a Python program to speak to it, we need to remember to
        add the newline character. 
        In the send method you can see the character was added after receiving input from the console.
    '''


if __name__ == '__main__':
    parser = argparse.ArgumentParser(description='BHP Net Tool',
        formatter_class=argparse.RawDescriptionHelpFormatter,
        epilog=textwrap.dedent('''Example:
            netcat.py -t 192.168.1.108 -p 5555 -l -c # command shell
            netcat.py -t 192.168.1.108 -p 5555 -l -u=mytest.txt # upload to file
            netcat.py -t 192.168.1.108 -p 5555 -l -e=\"cat /etc/passwd\" # execute command
            echo 'ABC' | ./netcat.py -t 192.168.1.108 -p 135 # echo text to server port 135
            netcat.py -t 192.168.1.108 -p 5555 # connect to server
        '''))
    parser.add_argument('-c', '--command', action='store_true', help='command_shell')
    parser.add_argument('-e', '--execute', help='execute specified command')
    parser.add_argument('-l', '--listen', action='store_true', help='listen')
    parser.add_argument('-p', '--port', default=5555, help='specified port')
    parser.add_argument('-t', '--target', default='192.168.1.203', help='specified IP')
    parser.add_argument('-u', '--upload', help='upload file')
    args = parser.parse_args()
    if args.listen:
        buffer = ''
    else:
        buffer = sys.stdin.read()

    nc = NetCat(args, buffer.encode())
    nc.run()

'''
1.  We use the argparse module from the standard library tpp create command line interface.
2.  We provide example usage that the program will display when the user invokes it with '--help',
    and add six arguments that specify how we want the program to behave.
3.  the -c argument sets up an interactive shell,
    the -e argument executes one specific command,
    the -l argument indicates a listener should be set up,
    the -p argument specifies the port on which to communicate,
    the -t argument specifies the target IP
    the -u argument specifies the name of a file to upload.
    
    Both the sender and receiver can use this program, so arguments determine whether its invoked to send or listen.
    The -c, -e, and -u arguments imply the -l argument, because those arguments apply to only the listener side of 
    of the communication.
    Senders only connect to the listener so they only need -t and -p arguments to define their target.
    
4.  When setting up a listener, we invoke the NetCat object with and empty buffer string.
    Otherwise, we send the buffer content from stdin.
    Finally, we call the run method to start it up.
'''

我跑的时候 'python3 netcat_custom.py -t 192.168.116.128 -p 5555 -l -c'

我应该能够进入命令 shell,或者如果我去掉 -c 参数,它应该以侦听器模式运行,但我得到了类型错误:

回溯(最后一次通话): 文件“/home/steelcoyote/PycharmProjects/toolkit/netcat_custom.py”,第 172 行,位于 数控运行() 运行中的文件“/home/steelcoyote/PycharmProjects/toolkit/netcat_custom.py”,第 39 行 自.listen() 文件“/home/steelcoyote/PycharmProjects/toolkit/netcat_custom.py”,第 85 行,在 listen 中 self.socket.bind((self.args.target, self.args.port)) # 1 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^ 类型错误:“str”对象不能解释为整数

python-3.x typeerror netcat listen
© www.soinside.com 2019 - 2024. All rights reserved.