smbclientng.core.SessionsManager
1#!/usr/bin/env python3 2# -*- coding: utf-8 -*- 3# File name : SessionsManager.py 4# Author : Podalirius (@podalirius_) 5# Date created : 20 may 2024 6 7import datetime 8from smbclientng.core.Credentials import Credentials 9from smbclientng.core.ModuleArgumentParser import ModuleArgumentParser 10from smbclientng.core.SMBSession import SMBSession 11import time 12 13 14class SessionsManager(object): 15 """ 16 A class to manage SMB sessions. 17 18 This class is responsible for creating, managing, and switching between multiple SMB sessions. It allows for the creation of new sessions with specified credentials and hosts, and provides methods to switch between existing sessions. It also keeps track of the current session and its ID. 19 20 Attributes: 21 next_session_id (int): The next available session ID. 22 current_session (SMBSession): The currently active SMB session. 23 current_session_id (int): The ID of the currently active session. 24 sessions (dict): A dictionary of all active sessions, keyed by their session ID. 25 """ 26 27 next_session_id = 1 28 current_session = None 29 current_session_id = None 30 sessions = {} 31 32 def __init__(self, config, logger): 33 self.sessions = {} 34 self.next_session_id = 1 35 self.current_session = None 36 self.current_session_id = None 37 38 self.config = config 39 self.logger = logger 40 41 def create_new_session(self, credentials, host, port=445): 42 """ 43 Creates a new session with the given session information. 44 45 Args: 46 session_info (dict): Information necessary to start a new session. 47 48 Returns: 49 None 50 """ 51 52 smbSession = SMBSession( 53 host=host, 54 port=port, 55 credentials=credentials, 56 config=self.config, 57 logger=self.logger 58 ) 59 smbSession.init_smb_session() 60 61 self.sessions[self.next_session_id] = { 62 "id": self.next_session_id, 63 "smbSession": smbSession, 64 "created_at": int(time.time()), 65 } 66 self.switch_session(self.next_session_id) 67 self.next_session_id += 1 68 69 def switch_session(self, session_id): 70 """ 71 Switches the current session to the session with the specified ID. 72 73 Args: 74 session_id (int): The ID of the session to switch to. 75 76 Returns: 77 bool: True if the session was successfully switched, False otherwise. 78 """ 79 80 if session_id in self.sessions.keys(): 81 self.current_session = self.sessions[session_id]["smbSession"] 82 self.current_session_id = session_id 83 return True 84 else: 85 return False 86 87 def delete_session(self, session_id): 88 """ 89 Deletes a session with the given session ID. 90 91 Args: 92 session_id (int): The ID of the session to delete. 93 94 Returns: 95 bool: True if the session was successfully deleted, False otherwise. 96 """ 97 98 if session_id in self.sessions.keys(): 99 self.sessions[session_id]["smbSession"].close_smb_session() 100 del self.sessions[session_id] 101 if self.current_session_id == session_id: 102 self.current_session = None 103 self.current_session_id = None 104 return True 105 return False 106 107 def process_command_line(self, arguments): 108 """ 109 Processes command line arguments to manage SMB sessions. 110 111 This function parses the command line arguments provided to the application and determines the appropriate action to take, 112 such as creating, interacting, deleting, or listing SMB sessions, or executing a command in one or more sessions. 113 114 Args: 115 arguments (list of str): The command line arguments. 116 117 Returns: 118 None 119 """ 120 121 parser = ModuleArgumentParser(add_help=True, prog="sessions", description="") 122 123 # interact 124 mode_interact = ModuleArgumentParser(add_help=False, description="Switch to the specified session.") 125 mode_interact.add_argument("-i", "--session-id", type=int, default=None, required=True, help="Session ID to interact with.") 126 127 # Create 128 mode_create = ModuleArgumentParser(add_help=False, description="Create a new session.") 129 group_target = mode_create.add_argument_group("Target") 130 group_target.add_argument("--host", action="store", metavar="HOST", required=True, type=str, help="IP address or hostname of the SMB Server to connect to.") 131 group_target.add_argument("--port", action="store", metavar="PORT", type=int, default=445, help="Port of the SMB Server to connect to. (default: 445)") 132 authconn = mode_create.add_argument_group("Authentication & connection") 133 authconn.add_argument("--kdcHost", dest="kdcHost", action="store", metavar="FQDN KDC", help="FQDN of KDC for Kerberos.") 134 authconn.add_argument("-d", "--domain", dest="auth_domain", metavar="DOMAIN", action="store", default='.', help="(FQDN) domain to authenticate to.") 135 authconn.add_argument("-u", "--user", dest="auth_username", metavar="USER", action="store", help="User to authenticate with.") 136 secret = mode_create.add_argument_group() 137 cred = secret.add_mutually_exclusive_group() 138 cred.add_argument("--no-pass", action="store_true", help="Don't ask for password (useful for -k).") 139 cred.add_argument("-p", "--password", dest="auth_password", metavar="PASSWORD", action="store", nargs="?", help="Password to authenticate with.") 140 cred.add_argument("-H", "--hashes", dest="auth_hashes", action="store", metavar="[LMHASH:]NTHASH", help="NT/LM hashes, format is LMhash:NThash.") 141 cred.add_argument("--aes-key", dest="aesKey", action="store", metavar="hex key", help="AES key to use for Kerberos Authentication (128 or 256 bits).") 142 secret.add_argument("-k", "--kerberos", dest="use_kerberos", action="store_true", help="Use Kerberos authentication. Grabs credentials from .ccache file (KRB5CCNAME) based on target parameters. If valid credentials cannot be found, it will use the ones specified in the command line.") 143 144 # Delete 145 mode_delete = ModuleArgumentParser(add_help=False, description="Delete the specified session.") 146 group_sessions = mode_delete.add_mutually_exclusive_group(required=True) 147 group_sessions.add_argument("-i", "--session-id", type=int, default=[], action="append", help="One or more ID of sessions to target.") 148 group_sessions.add_argument("-a", "--all", default=False, action="store_true", help="Delete all sessions.") 149 150 # Execute 151 mode_execute = ModuleArgumentParser(add_help=False, description="Send a smbclient-ng command line in one or more sessions.") 152 group_sessions = mode_execute.add_mutually_exclusive_group(required=True) 153 group_sessions.add_argument("-i", "--session-id", type=int, default=[], action="append", help="One or more ID of sessions to target.") 154 group_sessions.add_argument("-a", "--all", default=False, action="store_true", help="Execute command in all sessions.") 155 mode_execute.add_argument("-c", "--command", type=str, required=True, help="Command to execute in the target sessions.") 156 157 # List 158 mode_list = ModuleArgumentParser(add_help=False, description="List the registered sessions.") 159 160 # Register subparsers 161 subparsers = parser.add_subparsers(help="Action", dest="action", required=True) 162 subparsers.add_parser("interact", parents=[mode_interact], help=mode_interact.description) 163 subparsers.add_parser("create", parents=[mode_create], help=mode_create.description) 164 subparsers.add_parser("delete", parents=[mode_delete], help=mode_delete.description) 165 subparsers.add_parser("execute", parents=[mode_execute], help=mode_execute.description) 166 subparsers.add_parser("list", parents=[mode_list], help=mode_list.description) 167 168 try: 169 options = parser.parse_args(arguments) 170 except SystemExit as e: 171 pass 172 173 # Process actions 174 175 # 176 if options.action == "interact": 177 if options.session_id is not None: 178 if options.session_id in self.sessions.keys(): 179 self.logger.info("Switching to session #%d" % options.session_id) 180 self.switch_session(session_id=options.session_id) 181 else: 182 self.logger.error("No session with id #%d" % options.session_id) 183 184 # 185 elif options.action == "create": 186 credentials = Credentials( 187 domain=options.auth_domain, 188 username=options.auth_username, 189 password=options.auth_password, 190 hashes=options.auth_hashes, 191 use_kerberos=options.use_kerberos, 192 aesKey=options.aesKey, 193 kdcHost=options.kdcHost 194 ) 195 self.create_new_session( 196 credentials=credentials, 197 host=options.host, 198 port=options.port 199 ) 200 201 # 202 elif options.action == "delete": 203 if len(options.session_id) != 0: 204 for session_id in options.session_id: 205 if session_id in self.sessions.keys(): 206 self.logger.info("Closing and deleting session #%d" % session_id) 207 self.delete_session(session_id=session_id) 208 else: 209 self.logger.error("No session with id #%d" % session_id) 210 elif options.all == True: 211 all_session_ids = list(self.sessions.keys()) 212 for session_id in all_session_ids: 213 print("[+] Closing and deleting session #%d" % session_id) 214 self.delete_session(session_id=session_id) 215 216 # 217 elif options.action == "execute": 218 if options.command is not None: 219 if len(options.session_id) != 0: 220 for session_id in session_id: 221 if session_id in self.sessions.keys(): 222 self.logger.info("Executing '%s to session #%d" % (options.command, options.session_id)) 223 else: 224 self.logger.error("No session with id #%d" % options.session_id) 225 elif options.all == True: 226 all_session_ids = list(self.sessions.keys()) 227 for session_id in all_session_ids: 228 pass 229 230 # 231 elif options.action == "list": 232 for sessionId in sorted(self.sessions.keys()): 233 session = self.sessions[sessionId]["smbSession"] 234 created_at_str = str(datetime.datetime.fromtimestamp(self.sessions[sessionId]["created_at"])) 235 if sessionId == self.current_session_id: 236 if self.config.no_colors: 237 print(f"=> [#{sessionId:<2} - '{session.credentials.domain}\\{session.credentials.username}' @ {session.host}:{session.port}] created at [{created_at_str}] [current session]") 238 else: 239 print(f"\x1b[48;2;50;50;50m=> #{sessionId:<2} - '\x1b[1;96m{session.credentials.domain}\x1b[0m\x1b[48;2;50;50;50m\\\x1b[1;96m{session.credentials.username}\x1b[0m\x1b[48;2;50;50;50m\x1b[1m' @ {session.host}:{session.port} created at [{created_at_str}]\x1b[0m\x1b[48;2;50;50;50m [\x1b[93mcurrent session\x1b[0m\x1b[48;2;50;50;50m]\x1b[0m") 240 else: 241 print(f"── #{sessionId:<2} - '\x1b[1;96m{session.credentials.domain}\x1b[0m\\\x1b[1;96m{session.credentials.username}\x1b[0m\x1b[1m' @ {session.host}:{session.port} created at [{created_at_str}]\x1b[0m") 242
15class SessionsManager(object): 16 """ 17 A class to manage SMB sessions. 18 19 This class is responsible for creating, managing, and switching between multiple SMB sessions. It allows for the creation of new sessions with specified credentials and hosts, and provides methods to switch between existing sessions. It also keeps track of the current session and its ID. 20 21 Attributes: 22 next_session_id (int): The next available session ID. 23 current_session (SMBSession): The currently active SMB session. 24 current_session_id (int): The ID of the currently active session. 25 sessions (dict): A dictionary of all active sessions, keyed by their session ID. 26 """ 27 28 next_session_id = 1 29 current_session = None 30 current_session_id = None 31 sessions = {} 32 33 def __init__(self, config, logger): 34 self.sessions = {} 35 self.next_session_id = 1 36 self.current_session = None 37 self.current_session_id = None 38 39 self.config = config 40 self.logger = logger 41 42 def create_new_session(self, credentials, host, port=445): 43 """ 44 Creates a new session with the given session information. 45 46 Args: 47 session_info (dict): Information necessary to start a new session. 48 49 Returns: 50 None 51 """ 52 53 smbSession = SMBSession( 54 host=host, 55 port=port, 56 credentials=credentials, 57 config=self.config, 58 logger=self.logger 59 ) 60 smbSession.init_smb_session() 61 62 self.sessions[self.next_session_id] = { 63 "id": self.next_session_id, 64 "smbSession": smbSession, 65 "created_at": int(time.time()), 66 } 67 self.switch_session(self.next_session_id) 68 self.next_session_id += 1 69 70 def switch_session(self, session_id): 71 """ 72 Switches the current session to the session with the specified ID. 73 74 Args: 75 session_id (int): The ID of the session to switch to. 76 77 Returns: 78 bool: True if the session was successfully switched, False otherwise. 79 """ 80 81 if session_id in self.sessions.keys(): 82 self.current_session = self.sessions[session_id]["smbSession"] 83 self.current_session_id = session_id 84 return True 85 else: 86 return False 87 88 def delete_session(self, session_id): 89 """ 90 Deletes a session with the given session ID. 91 92 Args: 93 session_id (int): The ID of the session to delete. 94 95 Returns: 96 bool: True if the session was successfully deleted, False otherwise. 97 """ 98 99 if session_id in self.sessions.keys(): 100 self.sessions[session_id]["smbSession"].close_smb_session() 101 del self.sessions[session_id] 102 if self.current_session_id == session_id: 103 self.current_session = None 104 self.current_session_id = None 105 return True 106 return False 107 108 def process_command_line(self, arguments): 109 """ 110 Processes command line arguments to manage SMB sessions. 111 112 This function parses the command line arguments provided to the application and determines the appropriate action to take, 113 such as creating, interacting, deleting, or listing SMB sessions, or executing a command in one or more sessions. 114 115 Args: 116 arguments (list of str): The command line arguments. 117 118 Returns: 119 None 120 """ 121 122 parser = ModuleArgumentParser(add_help=True, prog="sessions", description="") 123 124 # interact 125 mode_interact = ModuleArgumentParser(add_help=False, description="Switch to the specified session.") 126 mode_interact.add_argument("-i", "--session-id", type=int, default=None, required=True, help="Session ID to interact with.") 127 128 # Create 129 mode_create = ModuleArgumentParser(add_help=False, description="Create a new session.") 130 group_target = mode_create.add_argument_group("Target") 131 group_target.add_argument("--host", action="store", metavar="HOST", required=True, type=str, help="IP address or hostname of the SMB Server to connect to.") 132 group_target.add_argument("--port", action="store", metavar="PORT", type=int, default=445, help="Port of the SMB Server to connect to. (default: 445)") 133 authconn = mode_create.add_argument_group("Authentication & connection") 134 authconn.add_argument("--kdcHost", dest="kdcHost", action="store", metavar="FQDN KDC", help="FQDN of KDC for Kerberos.") 135 authconn.add_argument("-d", "--domain", dest="auth_domain", metavar="DOMAIN", action="store", default='.', help="(FQDN) domain to authenticate to.") 136 authconn.add_argument("-u", "--user", dest="auth_username", metavar="USER", action="store", help="User to authenticate with.") 137 secret = mode_create.add_argument_group() 138 cred = secret.add_mutually_exclusive_group() 139 cred.add_argument("--no-pass", action="store_true", help="Don't ask for password (useful for -k).") 140 cred.add_argument("-p", "--password", dest="auth_password", metavar="PASSWORD", action="store", nargs="?", help="Password to authenticate with.") 141 cred.add_argument("-H", "--hashes", dest="auth_hashes", action="store", metavar="[LMHASH:]NTHASH", help="NT/LM hashes, format is LMhash:NThash.") 142 cred.add_argument("--aes-key", dest="aesKey", action="store", metavar="hex key", help="AES key to use for Kerberos Authentication (128 or 256 bits).") 143 secret.add_argument("-k", "--kerberos", dest="use_kerberos", action="store_true", help="Use Kerberos authentication. Grabs credentials from .ccache file (KRB5CCNAME) based on target parameters. If valid credentials cannot be found, it will use the ones specified in the command line.") 144 145 # Delete 146 mode_delete = ModuleArgumentParser(add_help=False, description="Delete the specified session.") 147 group_sessions = mode_delete.add_mutually_exclusive_group(required=True) 148 group_sessions.add_argument("-i", "--session-id", type=int, default=[], action="append", help="One or more ID of sessions to target.") 149 group_sessions.add_argument("-a", "--all", default=False, action="store_true", help="Delete all sessions.") 150 151 # Execute 152 mode_execute = ModuleArgumentParser(add_help=False, description="Send a smbclient-ng command line in one or more sessions.") 153 group_sessions = mode_execute.add_mutually_exclusive_group(required=True) 154 group_sessions.add_argument("-i", "--session-id", type=int, default=[], action="append", help="One or more ID of sessions to target.") 155 group_sessions.add_argument("-a", "--all", default=False, action="store_true", help="Execute command in all sessions.") 156 mode_execute.add_argument("-c", "--command", type=str, required=True, help="Command to execute in the target sessions.") 157 158 # List 159 mode_list = ModuleArgumentParser(add_help=False, description="List the registered sessions.") 160 161 # Register subparsers 162 subparsers = parser.add_subparsers(help="Action", dest="action", required=True) 163 subparsers.add_parser("interact", parents=[mode_interact], help=mode_interact.description) 164 subparsers.add_parser("create", parents=[mode_create], help=mode_create.description) 165 subparsers.add_parser("delete", parents=[mode_delete], help=mode_delete.description) 166 subparsers.add_parser("execute", parents=[mode_execute], help=mode_execute.description) 167 subparsers.add_parser("list", parents=[mode_list], help=mode_list.description) 168 169 try: 170 options = parser.parse_args(arguments) 171 except SystemExit as e: 172 pass 173 174 # Process actions 175 176 # 177 if options.action == "interact": 178 if options.session_id is not None: 179 if options.session_id in self.sessions.keys(): 180 self.logger.info("Switching to session #%d" % options.session_id) 181 self.switch_session(session_id=options.session_id) 182 else: 183 self.logger.error("No session with id #%d" % options.session_id) 184 185 # 186 elif options.action == "create": 187 credentials = Credentials( 188 domain=options.auth_domain, 189 username=options.auth_username, 190 password=options.auth_password, 191 hashes=options.auth_hashes, 192 use_kerberos=options.use_kerberos, 193 aesKey=options.aesKey, 194 kdcHost=options.kdcHost 195 ) 196 self.create_new_session( 197 credentials=credentials, 198 host=options.host, 199 port=options.port 200 ) 201 202 # 203 elif options.action == "delete": 204 if len(options.session_id) != 0: 205 for session_id in options.session_id: 206 if session_id in self.sessions.keys(): 207 self.logger.info("Closing and deleting session #%d" % session_id) 208 self.delete_session(session_id=session_id) 209 else: 210 self.logger.error("No session with id #%d" % session_id) 211 elif options.all == True: 212 all_session_ids = list(self.sessions.keys()) 213 for session_id in all_session_ids: 214 print("[+] Closing and deleting session #%d" % session_id) 215 self.delete_session(session_id=session_id) 216 217 # 218 elif options.action == "execute": 219 if options.command is not None: 220 if len(options.session_id) != 0: 221 for session_id in session_id: 222 if session_id in self.sessions.keys(): 223 self.logger.info("Executing '%s to session #%d" % (options.command, options.session_id)) 224 else: 225 self.logger.error("No session with id #%d" % options.session_id) 226 elif options.all == True: 227 all_session_ids = list(self.sessions.keys()) 228 for session_id in all_session_ids: 229 pass 230 231 # 232 elif options.action == "list": 233 for sessionId in sorted(self.sessions.keys()): 234 session = self.sessions[sessionId]["smbSession"] 235 created_at_str = str(datetime.datetime.fromtimestamp(self.sessions[sessionId]["created_at"])) 236 if sessionId == self.current_session_id: 237 if self.config.no_colors: 238 print(f"=> [#{sessionId:<2} - '{session.credentials.domain}\\{session.credentials.username}' @ {session.host}:{session.port}] created at [{created_at_str}] [current session]") 239 else: 240 print(f"\x1b[48;2;50;50;50m=> #{sessionId:<2} - '\x1b[1;96m{session.credentials.domain}\x1b[0m\x1b[48;2;50;50;50m\\\x1b[1;96m{session.credentials.username}\x1b[0m\x1b[48;2;50;50;50m\x1b[1m' @ {session.host}:{session.port} created at [{created_at_str}]\x1b[0m\x1b[48;2;50;50;50m [\x1b[93mcurrent session\x1b[0m\x1b[48;2;50;50;50m]\x1b[0m") 241 else: 242 print(f"── #{sessionId:<2} - '\x1b[1;96m{session.credentials.domain}\x1b[0m\\\x1b[1;96m{session.credentials.username}\x1b[0m\x1b[1m' @ {session.host}:{session.port} created at [{created_at_str}]\x1b[0m")
A class to manage SMB sessions.
This class is responsible for creating, managing, and switching between multiple SMB sessions. It allows for the creation of new sessions with specified credentials and hosts, and provides methods to switch between existing sessions. It also keeps track of the current session and its ID.
Attributes: next_session_id (int): The next available session ID. current_session (SMBSession): The currently active SMB session. current_session_id (int): The ID of the currently active session. sessions (dict): A dictionary of all active sessions, keyed by their session ID.
42 def create_new_session(self, credentials, host, port=445): 43 """ 44 Creates a new session with the given session information. 45 46 Args: 47 session_info (dict): Information necessary to start a new session. 48 49 Returns: 50 None 51 """ 52 53 smbSession = SMBSession( 54 host=host, 55 port=port, 56 credentials=credentials, 57 config=self.config, 58 logger=self.logger 59 ) 60 smbSession.init_smb_session() 61 62 self.sessions[self.next_session_id] = { 63 "id": self.next_session_id, 64 "smbSession": smbSession, 65 "created_at": int(time.time()), 66 } 67 self.switch_session(self.next_session_id) 68 self.next_session_id += 1
Creates a new session with the given session information.
Args: session_info (dict): Information necessary to start a new session.
Returns: None
70 def switch_session(self, session_id): 71 """ 72 Switches the current session to the session with the specified ID. 73 74 Args: 75 session_id (int): The ID of the session to switch to. 76 77 Returns: 78 bool: True if the session was successfully switched, False otherwise. 79 """ 80 81 if session_id in self.sessions.keys(): 82 self.current_session = self.sessions[session_id]["smbSession"] 83 self.current_session_id = session_id 84 return True 85 else: 86 return False
Switches the current session to the session with the specified ID.
Args: session_id (int): The ID of the session to switch to.
Returns: bool: True if the session was successfully switched, False otherwise.
88 def delete_session(self, session_id): 89 """ 90 Deletes a session with the given session ID. 91 92 Args: 93 session_id (int): The ID of the session to delete. 94 95 Returns: 96 bool: True if the session was successfully deleted, False otherwise. 97 """ 98 99 if session_id in self.sessions.keys(): 100 self.sessions[session_id]["smbSession"].close_smb_session() 101 del self.sessions[session_id] 102 if self.current_session_id == session_id: 103 self.current_session = None 104 self.current_session_id = None 105 return True 106 return False
Deletes a session with the given session ID.
Args: session_id (int): The ID of the session to delete.
Returns: bool: True if the session was successfully deleted, False otherwise.
108 def process_command_line(self, arguments): 109 """ 110 Processes command line arguments to manage SMB sessions. 111 112 This function parses the command line arguments provided to the application and determines the appropriate action to take, 113 such as creating, interacting, deleting, or listing SMB sessions, or executing a command in one or more sessions. 114 115 Args: 116 arguments (list of str): The command line arguments. 117 118 Returns: 119 None 120 """ 121 122 parser = ModuleArgumentParser(add_help=True, prog="sessions", description="") 123 124 # interact 125 mode_interact = ModuleArgumentParser(add_help=False, description="Switch to the specified session.") 126 mode_interact.add_argument("-i", "--session-id", type=int, default=None, required=True, help="Session ID to interact with.") 127 128 # Create 129 mode_create = ModuleArgumentParser(add_help=False, description="Create a new session.") 130 group_target = mode_create.add_argument_group("Target") 131 group_target.add_argument("--host", action="store", metavar="HOST", required=True, type=str, help="IP address or hostname of the SMB Server to connect to.") 132 group_target.add_argument("--port", action="store", metavar="PORT", type=int, default=445, help="Port of the SMB Server to connect to. (default: 445)") 133 authconn = mode_create.add_argument_group("Authentication & connection") 134 authconn.add_argument("--kdcHost", dest="kdcHost", action="store", metavar="FQDN KDC", help="FQDN of KDC for Kerberos.") 135 authconn.add_argument("-d", "--domain", dest="auth_domain", metavar="DOMAIN", action="store", default='.', help="(FQDN) domain to authenticate to.") 136 authconn.add_argument("-u", "--user", dest="auth_username", metavar="USER", action="store", help="User to authenticate with.") 137 secret = mode_create.add_argument_group() 138 cred = secret.add_mutually_exclusive_group() 139 cred.add_argument("--no-pass", action="store_true", help="Don't ask for password (useful for -k).") 140 cred.add_argument("-p", "--password", dest="auth_password", metavar="PASSWORD", action="store", nargs="?", help="Password to authenticate with.") 141 cred.add_argument("-H", "--hashes", dest="auth_hashes", action="store", metavar="[LMHASH:]NTHASH", help="NT/LM hashes, format is LMhash:NThash.") 142 cred.add_argument("--aes-key", dest="aesKey", action="store", metavar="hex key", help="AES key to use for Kerberos Authentication (128 or 256 bits).") 143 secret.add_argument("-k", "--kerberos", dest="use_kerberos", action="store_true", help="Use Kerberos authentication. Grabs credentials from .ccache file (KRB5CCNAME) based on target parameters. If valid credentials cannot be found, it will use the ones specified in the command line.") 144 145 # Delete 146 mode_delete = ModuleArgumentParser(add_help=False, description="Delete the specified session.") 147 group_sessions = mode_delete.add_mutually_exclusive_group(required=True) 148 group_sessions.add_argument("-i", "--session-id", type=int, default=[], action="append", help="One or more ID of sessions to target.") 149 group_sessions.add_argument("-a", "--all", default=False, action="store_true", help="Delete all sessions.") 150 151 # Execute 152 mode_execute = ModuleArgumentParser(add_help=False, description="Send a smbclient-ng command line in one or more sessions.") 153 group_sessions = mode_execute.add_mutually_exclusive_group(required=True) 154 group_sessions.add_argument("-i", "--session-id", type=int, default=[], action="append", help="One or more ID of sessions to target.") 155 group_sessions.add_argument("-a", "--all", default=False, action="store_true", help="Execute command in all sessions.") 156 mode_execute.add_argument("-c", "--command", type=str, required=True, help="Command to execute in the target sessions.") 157 158 # List 159 mode_list = ModuleArgumentParser(add_help=False, description="List the registered sessions.") 160 161 # Register subparsers 162 subparsers = parser.add_subparsers(help="Action", dest="action", required=True) 163 subparsers.add_parser("interact", parents=[mode_interact], help=mode_interact.description) 164 subparsers.add_parser("create", parents=[mode_create], help=mode_create.description) 165 subparsers.add_parser("delete", parents=[mode_delete], help=mode_delete.description) 166 subparsers.add_parser("execute", parents=[mode_execute], help=mode_execute.description) 167 subparsers.add_parser("list", parents=[mode_list], help=mode_list.description) 168 169 try: 170 options = parser.parse_args(arguments) 171 except SystemExit as e: 172 pass 173 174 # Process actions 175 176 # 177 if options.action == "interact": 178 if options.session_id is not None: 179 if options.session_id in self.sessions.keys(): 180 self.logger.info("Switching to session #%d" % options.session_id) 181 self.switch_session(session_id=options.session_id) 182 else: 183 self.logger.error("No session with id #%d" % options.session_id) 184 185 # 186 elif options.action == "create": 187 credentials = Credentials( 188 domain=options.auth_domain, 189 username=options.auth_username, 190 password=options.auth_password, 191 hashes=options.auth_hashes, 192 use_kerberos=options.use_kerberos, 193 aesKey=options.aesKey, 194 kdcHost=options.kdcHost 195 ) 196 self.create_new_session( 197 credentials=credentials, 198 host=options.host, 199 port=options.port 200 ) 201 202 # 203 elif options.action == "delete": 204 if len(options.session_id) != 0: 205 for session_id in options.session_id: 206 if session_id in self.sessions.keys(): 207 self.logger.info("Closing and deleting session #%d" % session_id) 208 self.delete_session(session_id=session_id) 209 else: 210 self.logger.error("No session with id #%d" % session_id) 211 elif options.all == True: 212 all_session_ids = list(self.sessions.keys()) 213 for session_id in all_session_ids: 214 print("[+] Closing and deleting session #%d" % session_id) 215 self.delete_session(session_id=session_id) 216 217 # 218 elif options.action == "execute": 219 if options.command is not None: 220 if len(options.session_id) != 0: 221 for session_id in session_id: 222 if session_id in self.sessions.keys(): 223 self.logger.info("Executing '%s to session #%d" % (options.command, options.session_id)) 224 else: 225 self.logger.error("No session with id #%d" % options.session_id) 226 elif options.all == True: 227 all_session_ids = list(self.sessions.keys()) 228 for session_id in all_session_ids: 229 pass 230 231 # 232 elif options.action == "list": 233 for sessionId in sorted(self.sessions.keys()): 234 session = self.sessions[sessionId]["smbSession"] 235 created_at_str = str(datetime.datetime.fromtimestamp(self.sessions[sessionId]["created_at"])) 236 if sessionId == self.current_session_id: 237 if self.config.no_colors: 238 print(f"=> [#{sessionId:<2} - '{session.credentials.domain}\\{session.credentials.username}' @ {session.host}:{session.port}] created at [{created_at_str}] [current session]") 239 else: 240 print(f"\x1b[48;2;50;50;50m=> #{sessionId:<2} - '\x1b[1;96m{session.credentials.domain}\x1b[0m\x1b[48;2;50;50;50m\\\x1b[1;96m{session.credentials.username}\x1b[0m\x1b[48;2;50;50;50m\x1b[1m' @ {session.host}:{session.port} created at [{created_at_str}]\x1b[0m\x1b[48;2;50;50;50m [\x1b[93mcurrent session\x1b[0m\x1b[48;2;50;50;50m]\x1b[0m") 241 else: 242 print(f"── #{sessionId:<2} - '\x1b[1;96m{session.credentials.domain}\x1b[0m\\\x1b[1;96m{session.credentials.username}\x1b[0m\x1b[1m' @ {session.host}:{session.port} created at [{created_at_str}]\x1b[0m")
Processes command line arguments to manage SMB sessions.
This function parses the command line arguments provided to the application and determines the appropriate action to take, such as creating, interacting, deleting, or listing SMB sessions, or executing a command in one or more sessions.
Args: arguments (list of str): The command line arguments.
Returns: None