diff --git a/smbclientng/core/SMBSession.py b/smbclientng/core/SMBSession.py index 709bd52..5d67157 100644 --- a/smbclientng/core/SMBSession.py +++ b/smbclientng/core/SMBSession.py @@ -1248,7 +1248,12 @@ def set_share(self, shareName): self.smb_share = self.available_shares[shareName.lower()]["name"] self.smb_cwd = "" # Connects the tree - self.smb_tree_id = self.smbClient.connectTree(self.smb_share) + try: + self.smb_tree_id = self.smbClient.connectTree(self.smb_share) + except impacket.smbconnection.SessionError as err: + self.smb_share = None + self.smb_cwd = "" + self.logger.error("Could not access share '%s': %s" % (shareName, err)) else: self.logger.error("Could not set share '%s', it does not exist remotely." % shareName) else: diff --git a/smbclientng/modules/Find.py b/smbclientng/modules/Find.py index e34941c..648261f 100644 --- a/smbclientng/modules/Find.py +++ b/smbclientng/modules/Find.py @@ -1,11 +1,10 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- -# File name : InteractiveShell.py +# File name : Find.py # Author : Podalirius (@podalirius_) # Date created : 23 may 2024 -import impacket import ntpath import re from smbclientng.core.Module import Module diff --git a/smbclientng/modules/GPPPasswords.py b/smbclientng/modules/GPPPasswords.py index 400c1bd..db3b036 100644 --- a/smbclientng/modules/GPPPasswords.py +++ b/smbclientng/modules/GPPPasswords.py @@ -12,7 +12,6 @@ import impacket import io import ntpath -import re from smbclientng.core.Module import Module from smbclientng.core.ModuleArgumentParser import ModuleArgumentParser from smbclientng.core.utils import windows_ls_entry diff --git a/smbclientng/modules/Users.py b/smbclientng/modules/Users.py new file mode 100644 index 0000000..671787a --- /dev/null +++ b/smbclientng/modules/Users.py @@ -0,0 +1,132 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +# File name : Users.py +# Author : Podalirius (@podalirius_) +# Date created : 23 may 2024 + + +import ntpath +import re +from smbclientng.core.Module import Module +from smbclientng.core.ModuleArgumentParser import ModuleArgumentParser +from smbclientng.core.utils import windows_ls_entry + + +class Users(Module): + + name = "users" + description = "Detects habits of users by the presence of cache files." + + checks = { + "browser": { + "name": "Browser Profiles", + "checks": { + "Brave": "/Users/{user}/AppData/Local/BraveSoftware/", + "Google Chrome": "/Users/{user}/AppData/Local/Google/Chrome/", + "Microsoft Edge": "/Users/{user}/AppData/Local/Microsoft/Edge/", + "Mozilla Firefox": "/Users/{user}/AppData/Local/Mozilla/Firefox/", + "Opera": "/Users/{user}/AppData/Local/Opera Software/", + "Safari": "/Users/{user}/AppData/Local/Apple Computer/Safari/" + } + }, + "email": { + "name": "Email Clients", + "checks": { + "Microsoft Outlook": "/Users/{user}/AppData/Local/Microsoft/Outlook/", + "Mozilla Thunderbird": "/Users/{user}/AppData/Local/Mozilla/Thunderbird/", + "Windows Mail": "/Users/{user}/AppData/Local/Microsoft/Windows Mail/" + } + }, + "productivity": { + "name": "Productivity Software", + "checks": { + "Microsoft Office": "/Users/{user}/AppData/Local/Microsoft/Office/", + "LibreOffice": "/Users/{user}/AppData/Local/LibreOffice/", + "OpenOffice": "/Users/{user}/AppData/Local/OpenOffice/" + } + } + } + + def parseArgs(self, arguments): + """ + Parses the command line arguments provided to the module. + + This method initializes the argument parser with the module's name and description, and defines all the necessary arguments that the module accepts. It then parses the provided command line arguments based on these definitions. + + Args: + arguments (str): A string of command line arguments. + + Returns: + ModuleArgumentParser.Namespace | None: The parsed arguments as a Namespace object if successful, None if there are no arguments or help is requested. + """ + + parser = ModuleArgumentParser(prog=self.name, description=self.description) + + parser.add_argument("-v", "--verbose", dest="verbose", action="store_true", default=False, help="Verbose mode.") + + self.options = self.processArguments(parser, arguments) + + return self.options + + def getListOfUsersHomes(self): + """ + Retrieves a list of user home directories from the SMB share. + + This method connects to the SMB share, navigates to the Users directory, and lists all subdirectories. It then filters out the current directory (.) and parent directory (..) to only include actual user home directories. The method returns a list of user home directory names. + + Returns: + list: A list of user home directory names. + """ + + old_share = self.smbSession.smb_share + old_pwd = self.smbSession.smb_cwd + + users = [] + self.smbSession.set_share('C$') + if self.smbSession.path_isdir("/Users/"): + self.smbSession.set_cwd("/Users/") + for entryname, entry in self.smbSession.list_contents("").items(): + if (entry.get_longname() not in [".",".."]) and (entry.is_directory()): + users.append(entry.get_longname()) + + self.smbSession.set_share(old_share) + self.smbSession.set_cwd(old_pwd) + + return users + + #=[Browser]==================================================================== + + def perform_checks(self, user): + for category_key in self.checks.keys(): + category = self.checks[category_key] + at_least_one_found = False + for check_name, check_path in category["checks"].items(): + check_path = check_path.format(user=user) + if self.smbSession.path_isdir(pathFromRoot=check_path): + if not at_least_one_found: + print(" ├──> %s:" % category["name"]) + at_least_one_found = True + print(" │ ├──> \x1b[92muses '%s'\x1b[0m" % (check_name)) + elif self.options.verbose: + print(" │ ├──> \x1b[91mdoes not use '%s'\x1b[0m" % (check_name)) + + #=[Run]==================================================================== + + def run(self, arguments): + self.options = self.parseArgs(arguments=arguments) + + if self.options is not None: + # Entrypoint + try: + users = self.getListOfUsersHomes() + for user in users: + print("[+] Analyzing user: '%s'" % user) + self.perform_checks(user=user) + + except (BrokenPipeError, KeyboardInterrupt) as e: + print("[!] Interrupted.") + self.smbSession.close_smb_session() + self.smbSession.init_smb_session() + + +