Skip to content

Commit 899c516

Browse files
authored
Update recyclebin.py
Signed-off-by: Deft_ <aurelien.chalot@protonmail.com>
1 parent bc26a1b commit 899c516

1 file changed

Lines changed: 71 additions & 70 deletions

File tree

nxc/modules/recyclebin.py

Lines changed: 71 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -30,79 +30,80 @@ def on_admin_login(self, context, connection):
3030
context.log.debug(f"Error connecting to RemoteRegistry {e} on host {connection.host}")
3131
finally:
3232
remote_ops.finish()
33-
34-
for sid_directory in connection.conn.listPath("C$", "$Recycle.Bin\\*"):
35-
if sid_directory.get_longname() and sid_directory.get_longname() not in self.false_positive:
36-
37-
# Extracts the username from the SID
38-
if remote_ops._RemoteOperations__rrp:
39-
ans = rrp.hOpenLocalMachine(remote_ops._RemoteOperations__rrp)
40-
reg_handle = ans["phKey"]
41-
ans = rrp.hBaseRegOpenKey(
42-
remote_ops._RemoteOperations__rrp,
43-
reg_handle,
44-
f"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\{sid_directory.get_longname()}"
45-
)
46-
key_handle = ans["phkResult"]
47-
_ = username = profileimagepath = None
48-
try:
49-
_, profileimagepath = rrp.hBaseRegQueryValue(
50-
remote_ops._RemoteOperations__rrp,
51-
key_handle,
52-
"ProfileImagePath\x00"
33+
34+
if remote_ops._RemoteOperations__rrp:
35+
for sid_directory in connection.conn.listPath("C$", "$Recycle.Bin\\*"):
36+
if sid_directory.get_longname() and sid_directory.get_longname() not in self.false_positive:
37+
38+
# Extracts the username from the SID
39+
if remote_ops._RemoteOperations__rrp:
40+
ans = rrp.hOpenLocalMachine(remote_ops._RemoteOperations__rrp)
41+
reg_handle = ans["phKey"]
42+
ans = rrp.hBaseRegOpenKey(
43+
remote_ops._RemoteOperations__rrp,
44+
reg_handle,
45+
f"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\ProfileList\\{sid_directory.get_longname()}"
5346
)
54-
# Get username and remove embedded null byte
55-
username = profileimagepath.split("\\")[-1].replace("\x00", "")
56-
except rrp.DCERPCSessionError as e:
57-
context.log.debug(f"Couldn't get username from SID {e} on host {connection.host}")
47+
key_handle = ans["phkResult"]
48+
_ = username = profileimagepath = None
49+
try:
50+
_, profileimagepath = rrp.hBaseRegQueryValue(
51+
remote_ops._RemoteOperations__rrp,
52+
key_handle,
53+
"ProfileImagePath\x00"
54+
)
55+
# Get username and remove embedded null byte
56+
username = profileimagepath.split("\\")[-1].replace("\x00", "")
57+
except rrp.DCERPCSessionError as e:
58+
context.log.debug(f"Couldn't get username from SID {e} on host {connection.host}")
5859

59-
# Lists for any file or directory in the recycle bin
60-
spider_folder = f"$Recycle.Bin\\{sid_directory.get_longname()}\\"
61-
paths = connection.spider(
62-
"C$",
63-
folder=spider_folder,
64-
regex=[r"(.*)"],
65-
no_print_results=True
66-
)
60+
# Lists for any file or directory in the recycle bin
61+
spider_folder = f"$Recycle.Bin\\{sid_directory.get_longname()}\\"
62+
paths = connection.spider(
63+
"C$",
64+
folder=spider_folder,
65+
regex=[r"(.*)"],
66+
no_print_results=True
67+
)
6768

68-
false_positiv = [".", "..", "desktop.ini"]
69-
filtered_file_paths = [path for path in paths if not path.endswith(tuple(false_positiv))]
70-
if filtered_file_paths:
71-
if username is not None:
72-
context.log.highlight(f"CONTENT FOUND {sid_directory.get_longname()} ({username})")
73-
else:
74-
context.log.highlight(f"CONTENT FOUND {sid_directory.get_longname()}")
69+
false_positiv = [".", "..", "desktop.ini"]
70+
filtered_file_paths = [path for path in paths if not path.endswith(tuple(false_positiv))]
71+
if filtered_file_paths:
72+
if username is not None:
73+
context.log.highlight(f"CONTENT FOUND {sid_directory.get_longname()} ({username})")
74+
else:
75+
context.log.highlight(f"CONTENT FOUND {sid_directory.get_longname()}")
7576

76-
for path in filtered_file_paths:
77-
# Returned path look like:
78-
# $Recycle.Bin\S-1-5-21-4140170355-2927207985-2497279808-500\/$I87021Q.txt
79-
# Or
80-
# $Recycle.Bin\S-1-5-21-4140170355-2927207985-2497279808-500\/$R87021Q.txt
81-
# $I files are metadata while $R are actual files so we split the path from the SID
82-
# And check that the filename contains $R only to prevent downloading useless stuff
83-
84-
if "$R" in path.split(sid_directory.get_longname())[1] and not path.endswith(tuple([".", "..", "desktop.ini"])):
85-
try:
86-
buf = BytesIO()
87-
connection.conn.getFile("C$", path, buf.write)
88-
context.log.highlight(f"\t{path}")
89-
found += 1
90-
buf.seek(0)
91-
file_path = path.split('$')[-1].replace("/", "_")
92-
if username:
93-
filename = f"{connection.host}_{username}_recyclebin_{file_path}"
94-
else:
95-
filename = f"{connection.host}_{sid_directory.get_longname()}_recyclebin_{file_path}"
96-
export_path = join(NXC_PATH, "modules", "recyclebin")
97-
path = abspath(join(export_path, filename))
98-
makedirs(export_path, exist_ok=True)
77+
for path in filtered_file_paths:
78+
# Returned path look like:
79+
# $Recycle.Bin\S-1-5-21-4140170355-2927207985-2497279808-500\/$I87021Q.txt
80+
# Or
81+
# $Recycle.Bin\S-1-5-21-4140170355-2927207985-2497279808-500\/$R87021Q.txt
82+
# $I files are metadata while $R are actual files so we split the path from the SID
83+
# And check that the filename contains $R only to prevent downloading useless stuff
84+
85+
if "$R" in path.split(sid_directory.get_longname())[1] and not path.endswith(tuple([".", "..", "desktop.ini"])):
9986
try:
100-
with open(path, "w+") as file:
101-
file.write(buf.read().decode("utf-8", errors="ignore"))
87+
buf = BytesIO()
88+
connection.conn.getFile("C$", path, buf.write)
89+
context.log.highlight(f"\t{path}")
90+
found += 1
91+
buf.seek(0)
92+
file_path = path.split('$')[-1].replace("/", "_")
93+
if username:
94+
filename = f"{connection.host}_{username}_recyclebin_{file_path}"
95+
else:
96+
filename = f"{connection.host}_{sid_directory.get_longname()}_recyclebin_{file_path}"
97+
export_path = join(NXC_PATH, "modules", "recyclebin")
98+
path = abspath(join(export_path, filename))
99+
makedirs(export_path, exist_ok=True)
100+
try:
101+
with open(path, "w+") as file:
102+
file.write(buf.read().decode("utf-8", errors="ignore"))
103+
except Exception as e:
104+
context.log.fail(f"Failed to write recyclebin file to {filename}: {e}")
102105
except Exception as e:
103-
context.log.fail(f"Failed to write recyclebin file to {filename}: {e}")
104-
except Exception as e:
105-
# Probably trying to getFile a directory which won't work
106-
context.log.debug(f"Couldn't open {path} because of {e}")
107-
if found >0:
108-
context.log.highlight(f"Recycle bin's content downloaded to {export_path}")
106+
# Probably trying to getFile a directory which won't work
107+
context.log.debug(f"Couldn't open {path} because of {e}")
108+
if found >0:
109+
context.log.highlight(f"Recycle bin's content downloaded to {export_path}")

0 commit comments

Comments
 (0)