Python Netcat不返回命令外壳

时间:2020-05-07 00:37:54

标签: python python-3.x sockets

下面的代码用于复制netcat的功能,以用于从服务器删除了netcat却没有删除python的情况。但是,无论我尝试什么,我似乎都无法解决以下问题: 我运行以下

./Netcat.py -l -p 9999 -c

之后

./Netcat.py -t localhost -p 9999

在另一个终端中。我可以确认,当充当服务器时,脚本确实从脚本的第二个实例接收连接,并且在设置脚本时(按CTRL + D)它会接收数据。但是,然后我得到一个挂起的终端,该终端没有收到命令提示符,也没有发送更多数据的能力。我希望有人可以指出这一点上的错误。

应该发生的情况如下:

  1. 提高服务器效率
  2. 以客户端身份运行脚本
  3. 键入一些数据,然后用CTRL + D关闭STDIN,此时客户端将数据发送到服务器
  4. 然后服务器应接收数据并将命令提示符发送回客户端

问题出在第四步,此时我正在拔头发。

编辑

运行strace后,我确定客户端程序挂起,等待接收数据,我注意到代码中的相应行。我不明白为什么会这样。

import sys                #  used for accessing command line args
import socket             #  creation of socket objects to listen & send/receive data
import getopt             #  helps scripts to parse the command line arguments in sys.argv
import concurrent.futures #  for running commands in a subshell
import subprocess         #  The subprocess module allows you to spawn new processes, connect to their input/output/error pipes, and obtain their return codes.


##  Globals  ##
listen             = False
command            = False
target             = ""
port               = 0
## END GLOBALS ##


def client_sender(buffer):
    client = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

    try:
        client.connect((target, port))

        if len(buffer):
            # bytes([source[, encoding[, errors]]])
            client.send(bytes(buffer, 'utf-8'))

        # continue sending and receiving data until user kills script
        while True:

            recv_len = 1
            response = ''

            while recv_len:

                data      = client.recv(4096) #<-- PROBLEM
                recv_len  = len(data)
                response += data.decode('utf-8')

                if recv_len < 4096:
                    break

                print(response)

            buffer = input('#: ')
            buffer += '\n'

            client.send(buffer)

    except socket.error as e:

        print('[*] Exception! Exiting')
        print(e)

        client.close()


def server_loop():
    global target
    global port
    # if no target is defined, listen on all interfaces
    if not len(target):
        target = '0.0.0.0'

    server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    server.bind((target, port))

    server.listen(5)
    print(f'listening on {target}:{port}')

    while True:
        client_socket, addr = server.accept()

        with concurrent.futures.ThreadPoolExecutor(max_workers=5) as executor:
            executor.submit(client_handler, client_socket)


def run_command(command):

    command = command.rstrip()

    # run command & retrieve output
    try:
        output = subprocess.check_output(command, stderr=subprocess.STDOUT, shell=True)
    except:
        return 'Failed to execute command.\r\n'


def client_handler(client_socket):
    global command

    # check if shell requested
    if command:

        while True:
            client_socket.send('<BHP:#> ')

            # receive until linefeed
            cmd_buffer = ''
            while '\n' not in cmd_buffer:
                cmd_buffer += client_socket.recv(1024)

            response = run_command(bufffer)
            client_socket.send(response)


def main():
    global listen
    global port
    global command
    global target

    # make sure the user provided options & arguments
    if not len(sys.argv[1:]):
        usage()

    # parse commandline options
    try:
        opts, args = getopt.getopt(sys.argv[1:],"lt:p:c", #: succeeds options which expect an argument
                                    ['listen', 'target', 'port', 'command'])
    except getopt.GetoptError as err:
        print(str(err))
        usage()

    # handle commandline options
    for option, argument in opts:

        elif option in ('-l', '--listen'):
            listen = True
        elif option in ('-e', '--execute'):
            execute = argument
        elif option in ('-c', '--commandshell'):
            command = True
        elif option in ('-t', '--target'):
            target = argument
        elif option in ('-p', '--port'):
            port = int(argument)

    # not listening; sending data from stdin
    if not listen and len(target) and port > 0:
        buffer = sys.stdin.read()

        client_sender(buffer)

    if listen:
        server_loop()


if __name__ == '__main__':
    main()

0 个答案:

没有答案