Python Netcat模拟问题

时间:2018-09-14 04:07:53

标签: python python-3.x

我正在使用Kali Linux VirtualBox机器练习网络编码。我正在从工作簿中使用Python练习Netcat模拟。问题是工作簿使用的是python 2,而我使用的是Python3。我在两个不同的终端中运行代码,一个在服务器上运行脚本以侦听连接,另一个在终端上运行脚本作为客户端连接到服务器。

  

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

以服务器模式运行脚本。

  

./ Netcat.py -t本地主机-p 9999

以客户端模式运行脚本。

在客户端模式下,如果未通过stdin发送任何内容以按命令提示符,则按CTRL-D。

在提示符打开的情况下,您应该能够发送回常规命令,例如“ ls”,以查看目录中的文件列表等。但是在尝试绕过sys.stdin.read()时出现错误。

这是脚本:

#!/usr/bin/python3
"""
Netcat is the utility knife of networking for reading from and writing
to network connections using TCP or UDP. Netcat is designed to be a dependable
back-end investigation tool.

Features include:
- Port scanning
- Transferring files
- Port listening
- Backdoor
"""


"""
We begin by reading in all of the command-line options,
setting the necessary variables depending on the options
we detect. If any of the command-line options don't match
our criteria, we print out a useful usage information.

We are trying to mimic Netcat to read data from stdin
and send in across the network. If you plan on sending
data interactively, you need to send a CTRL-D to bypass
the stdin read.

Then we set up a listening socket and process further
commands (upload a file, execute a command, start a
command shell).
"""

import sys
import socket
import getopt
import threading
import subprocess

# Define some global variables
listen              = False
command             = False
upload              = False
execute             = ""
target              = ""
upload_destination  = ""
port                = 0


# The main functions for handling command line arguments
def usage():
    print("Netcat Net Tool")
    print()
    print("Usage: Netcat.py -t target_host -p port")
    print("-l --listen              - listen on [host]:[post] for "
                                    " incoming connections")
    print("-e --execute=file_to_run - execute the given file upon"
                                    " receiving a connection")
    print("-c --command             - initialize a command shell")
    print("-u --upload=destination  - upon receiving connection upload a"
                                    " file and write to [destination]")
    sys.exit()

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

    # check the length of the command line input.
    if not len(sys.argv[1:]):
        usage()

    # read command line options
    try:
        opts, args = getopt.getopt(sys.argv[1:], "hle:t:p:cu:",
        ["help", "listen", "execute", "target", "port", "command", "upload"])
    except getopt.GetoptError as err:
        print(str(err))
        usage()

    for o, a in opts:
        if o in ("-h", "--help"):
            usage()
        elif o in ("-l", "listen"):
            listen = True
        elif o in ("-e", "execute"):
            execute = a
        elif o in ("-c", "commandshell"):
            command = True
        elif o in ("-u", "upload"):
            upload_destination = a
        elif o in ("-t", "target"):
            target = a
        elif o in ("-p", "port"):
            port = int(a)
        else:
                assert False, "Unhandled Option"

    # are we going to listen or just send data from stdin?
    if not listen and len(target) and port > 0:

        # read in the buffer from the commandline
        # this will block, so send CTRL-D if not sending input
        # to stdin
        buffer = sys.stdin.read()

        # send data off
        client_sender(buffer)

    # we are going to listen and potentially
    # upload things, execute commands, and drop a shell back
    # depending on our command line options above
    if listen:
        server_loop()


"""
Now we will put in the plumbing for some of these
features. Starting with our client code.

We start by setting up our TCP socket object and test
to see if we have received any input from stdin. If
all is well, we ship the data off to the remote target
and receive data until there is no more data to
receive.

Then we wait for further input from the user and
continue sending and receiving data until the user
kills the script.
"""


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

    try:

        # connect to our target host
        client.connect((target, port))

        if len(buffer):
            client.send(buffer)

        while True:

            # now wait for data back
            recv_len = 1
            response = ""

            while recv_len:

                data        = client.recv(4096)
                recv_len    = len(data)
                response   += data

                if recv_len < 4096:
                    break

            print(response),

            # wait for more input
            buffer  = input("")
            buffer += "\n"

            # send it off
            client.send(buffer)

    except:

        print("[*] Exception! Exiting.")

        # tear down the connection
        client.close()

"""
Now we move on to creating our primary server loop
and a stub function that will handle both our command
execution  and our full command shell.
"""

def server_loop():
    global target

    # if no target is defined, we 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)

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

        # spin off a thread to handle our new client
        client_thread = threading.Thread(target=client_handler,
args=(client_socket,))
        client_thread.start()

"""
Subprocess provides a powerful process-creation interface
that gives you a number of ways to interact with client
programs.

We are simply running the command that's passed in. Running
it on a locale OS and returning the output from the command
back to the client that is connected to us.
"""

def run_command(command):

    # trim the new line
    command = command.rstrip()

    # run the command and get the output back
    try:
        output = subprocess.check_output(command,
stderr=subprocess.STDOUT, shell=True)

    except:
        output = "Failed to execute command.\r\n"

    # send the output back to the client
    return output

"""
Now we need to write the code that handles uploads, command
execution, and our shell.

Our first chunk of code is responsible for telling us if
our network tool is set to receive a file when it receives
a connection. Useful for upload-and-execute exercises or
for installing malware and letting our malware remove our
Python callback.

We receive the file data in a loop to make sure we receive
it all. Then we simply open a file handle and write out
the contents of the file. The wb flag ensures that we are
writing the file with binary mode enabled which ensures
that uploading and writing a binary executable will be
successful.

Next we process our execute functionality, which calls
our previously written run_command function
and simply sends the result back across the network.

Our last bit of code handles our command shell; it
continues to execute commands as we send them in and sends
back the output. You'll notice that it is scanning
for a newline character to determine when to process a command.
Which makes it netcat-friendly. However, if you are
conjuring up a Python client to speak to it, remember
to add the newline character
"""

def client_handler(client_socket):
    global upload
    global execute
    global command

    # check for upload
    if len(upload_destination):

        # read in all bytes and write to our destination
        file_buffer = ""

        # keep reading data until none is available
        while True:
            data = client_socket.recv(1024)

            if not data:
                break

            else:
                file_buffer += data

        # now we take these bytes and try to write them out
        try:
            file_descriptor = open(upload_destination, "wb")
            file_descriptor.write(file_buffer)
            file_descriptor.close()

            # acknowledge that we wrote the file out
            client_socket.send("Sucessfully saved file to"
                               "%s\r\n" % upload_destination)
        except:
            client_socket.send("Failed to save file to"
                               "%s\r\n" % upload_destination)

    # check for command execution
    if len(execute):

        # run the command
        output = run_command(execute)

        client_socket.send(output)

    # now we go into another loop if command shell was requested
    if command:

        while True:
            # show a simple prompt
            client_socket.send("<Netcat:#> ".encode('utf-8'))

            # now we receive until we see a linefeed
            cmd_buffer = ""
            while "\n" not in cmd_buffer:
                cmd_buffer += client_socket.recv(1024)

            # send back the command output
            response = run_command(cmd_buffer)

            # send back the response
            client_socket.send(response)

main()

main()函数的结尾是CTRL-D起作用的地方:

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

    # check the length of the command line input.
    if not len(sys.argv[1:]):
        usage()

    # read command line options
    try:
        opts, args = getopt.getopt(sys.argv[1:], "hle:t:p:cu:",
        ["help", "listen", "execute", "target", "port", "command", "upload"])
    except getopt.GetoptError as err:
        print(str(err))
        usage()

    for o, a in opts:
        if o in ("-h", "--help"):
            usage()
        elif o in ("-l", "listen"):
            listen = True
        elif o in ("-e", "execute"):
            execute = a
        elif o in ("-c", "commandshell"):
            command = True
        elif o in ("-u", "upload"):
            upload_destination = a
        elif o in ("-t", "target"):
            target = a
        elif o in ("-p", "port"):
            port = int(a)
        else:
                assert False, "Unhandled Option"

    # are we going to listen or just send data from stdin?
    if not listen and len(target) and port > 0:

        # read in the buffer from the commandline
        # this will block, so send CTRL-D if not sending input
        # to stdin
        buffer = sys.stdin.read()

        # send data off
        client_sender(buffer)

    # we are going to listen and potentially
    # upload things, execute commands, and drop a shell back
    # depending on our command line options above
    if listen:
        server_loop()

服务器端在左边,客户端在右边

My Error

0 个答案:

没有答案