smbclientng.core.InteractiveShell
1#!/usr/bin/env python3 2# -*- coding: utf-8 -*- 3# File name : InteractiveShell.py 4# Author : Podalirius (@podalirius_) 5# Date created : 23 may 2024 6 7 8import datetime 9import impacket 10from importlib import import_module 11import ntpath 12import os 13import readline 14import shutil 15import sys 16import traceback 17from rich.console import Console 18from rich.table import Table 19from smbclientng.core.CommandCompleter import CommandCompleter 20from smbclientng.core.utils import b_filesize, unix_permissions, windows_ls_entry, local_tree 21 22 23## Decorators 24 25def command_arguments_required(func): 26 def wrapper(*args, **kwargs): 27 self, arguments,command = args[0], args[1], args[2] 28 if len(arguments) != 0: 29 return func(*args, **kwargs) 30 else: 31 self.commandCompleterObject.print_help(command=command) 32 return None 33 return wrapper 34 35def active_smb_connection_needed(func): 36 def wrapper(*args, **kwargs): 37 self, arguments,command = args[0], args[1], args[2] 38 # 39 self.smbSession.ping_smb_session() 40 if self.smbSession.connected: 41 return func(*args, **kwargs) 42 else: 43 print("[!] SMB Session is disconnected.") 44 return None 45 return wrapper 46 47def smb_share_is_set(func): 48 def wrapper(*args, **kwargs): 49 self, arguments,command = args[0], args[1], args[2] 50 if self.smbSession.smb_share is not None: 51 return func(*args, **kwargs) 52 else: 53 print("[!] You must open a share first, try the 'use <share>' command.") 54 return None 55 return wrapper 56 57 58class InteractiveShell(object): 59 """ 60 Class InteractiveShell is designed to manage the interactive command line interface for smbclient-ng. 61 62 This class handles user input, executes commands, and manages the state of the SMB session. It provides 63 a command line interface for users to interact with SMB shares, execute commands like directory listing, 64 file transfer, and more. 65 66 Attributes: 67 smbSession (SMBConnection): The active SMB connection session. 68 debug (bool): Flag to enable or disable debug mode. 69 smb_share (str): The current SMB share in use. 70 smb_path (str): The current path within the SMB share. 71 commandCompleterObject (CommandCompleter): Object to handle command completion and help generation. 72 73 Methods: 74 __init__(self, smbSession, debug=False): Initializes the InteractiveShell with the given SMB session and debug mode. 75 run(self): Starts the command line interface loop, processing user input until exit. 76 """ 77 78 def __init__(self, smbSession, config): 79 # Objects 80 self.smbSession = smbSession 81 self.config = config 82 self.commandCompleterObject = CommandCompleter(smbSession=self.smbSession, config=self.config) 83 readline.set_completer(self.commandCompleterObject.complete) 84 readline.parse_and_bind("tab: complete") 85 readline.set_completer_delims("\n") 86 # Additional modules 87 self.modules = {} 88 self.__load_modules() 89 90 def run(self): 91 running = True 92 while running: 93 try: 94 user_input = input(self.__prompt()).strip().split(" ") 95 command, arguments = user_input[0].lower(), user_input[1:] 96 97 # Exit the command line 98 if command == "exit": 99 running = False 100 101 elif command in self.commandCompleterObject.commands.keys(): 102 self.process_command( 103 command=command, 104 arguments=arguments 105 ) 106 107 elif command.strip() == "": 108 pass 109 110 # Fallback to unknown command 111 else: 112 print("Unknown command. Type \"help\" for help.") 113 114 except KeyboardInterrupt as e: 115 print() 116 117 except EOFError as e: 118 print() 119 running = False 120 121 except Exception as e: 122 if self.config.debug: 123 traceback.print_exc() 124 print("[!] Error: %s" % str(e)) 125 126 def process_command(self, command, arguments=[]): 127 # Skip 128 if command.strip() == "": 129 pass 130 131 # Display help 132 elif command == "help": 133 self.command_help(arguments, command) 134 135 # Closes the current SMB session 136 elif command == "close": 137 self.command_close(arguments, command) 138 139 # Change directory in the current share 140 elif command == "cd": 141 self.command_cd(arguments, command) 142 143 # Get a file 144 elif command == "get": 145 self.command_get(arguments, command) 146 147 # SMB server info 148 elif command == "info": 149 self.command_info(arguments, command) 150 151 # List directory contents in a share 152 elif command in ["ls", "dir"]: 153 self.command_ls(arguments, command) 154 155 # Creates a new remote directory 156 elif command == "mkdir": 157 self.command_mkdir(arguments, command) 158 159 # Put a file 160 elif command == "put": 161 self.command_put(arguments, command) 162 163 # Changes the current local directory 164 elif command == "lcd": 165 self.command_lcd(arguments, command) 166 167 # Lists the contents of the current local directory 168 elif command == "lls": 169 self.command_lls(arguments, command) 170 171 # Creates a new local directory 172 elif command == "lmkdir": 173 self.command_lmkdir(arguments, command) 174 175 # Shows the current local directory 176 elif command == "lpwd": 177 self.command_lpwd(arguments, command) 178 179 # Removes a local file 180 elif command == "lrm": 181 self.command_lrm(arguments, command) 182 183 # Removes a local directory 184 elif command == "lrmdir": 185 self.command_lrmdir(arguments, command) 186 187 # Shows the current local directory 188 elif command == "ltree": 189 self.command_ltree(arguments, command) 190 191 # Modules 192 elif command == "module": 193 self.command_module(arguments, command) 194 195 # Reconnects the current SMB session 196 elif command in ["connect", "reconnect"]: 197 self.command_reconnect(arguments, command) 198 199 # Reset the TTY output 200 elif command == "reset": 201 self.command_reset(arguments, command) 202 203 # Removes a remote file 204 elif command == "rm": 205 self.command_rm(arguments, command) 206 207 # Removes a remote directory 208 elif command == "rmdir": 209 self.command_rmdir(arguments, command) 210 211 # List shares 212 elif command == "shares": 213 self.command_shares(arguments, command) 214 215 # Displays a tree view of the CWD 216 elif command == "tree": 217 self.command_tree(arguments, command) 218 219 # Use a share 220 elif command == "use": 221 self.command_use(arguments, command) 222 223 # Commands ================================================================ 224 225 @command_arguments_required 226 @active_smb_connection_needed 227 @smb_share_is_set 228 def command_cd(self, arguments, command): 229 # Command arguments required : Yes 230 # Active SMB connection needed : Yes 231 # SMB share needed : Yes 232 233 path = ' '.join(arguments) 234 try: 235 self.smbSession.set_cwd(path=path) 236 except impacket.smbconnection.SessionError as e: 237 print("[!] SMB Error: %s" % e) 238 239 def command_close(self, arguments, command): 240 # Command arguments required : No 241 # Active SMB connection needed : No 242 # SMB share needed : No 243 244 self.smbSession.ping_smb_session() 245 if self.smbSession.connected: 246 self.smbSession.close_smb_session() 247 248 @command_arguments_required 249 @active_smb_connection_needed 250 @smb_share_is_set 251 def command_get(self, arguments, command): 252 # Command arguments required : Yes 253 # Active SMB connection needed : Yes 254 # SMB share needed : Yes 255 256 # Get files recursively 257 if arguments[0] == "-r": 258 path = ' '.join(arguments[1:]).replace('/', ntpath.sep) 259 try: 260 self.smbSession.get_file_recursively(path=path) 261 except impacket.smbconnection.SessionError as e: 262 print("[!] SMB Error: %s" % e) 263 # Get a single file 264 else: 265 path = ' '.join(arguments).replace('/', ntpath.sep) 266 try: 267 self.smbSession.get_file(path=path) 268 except impacket.smbconnection.SessionError as e: 269 print("[!] SMB Error: %s" % e) 270 271 def command_help(self, arguments, command): 272 # Command arguments required : No 273 # Active SMB connection needed : No 274 # SMB share needed : No 275 276 if len(arguments) != 0: 277 self.commandCompleterObject.print_help(command=arguments[0]) 278 else: 279 self.commandCompleterObject.print_help(command=None) 280 281 @active_smb_connection_needed 282 def command_info(self, arguments, command): 283 # Command arguments required : No 284 # Active SMB connection needed : Yes 285 # SMB share needed : No 286 287 print_server_info = False 288 print_share_info = False 289 if len(arguments) != 0: 290 print_server_info = (arguments[0].lower() == "server") 291 print_share_info = (arguments[0].lower() == "share") 292 else: 293 print_server_info = True 294 print_share_info = True 295 296 try: 297 self.smbSession.info( 298 share=print_share_info, 299 server=print_server_info 300 ) 301 except impacket.smbconnection.SessionError as e: 302 print("[!] SMB Error: %s" % e) 303 304 @command_arguments_required 305 def command_lcd(self, arguments, command): 306 # Command arguments required : Yes 307 # Active SMB connection needed : No 308 # SMB share needed : No 309 310 path = ' '.join(arguments) 311 if os.path.exists(path=path): 312 if os.path.isdir(s=path): 313 os.chdir(path=path) 314 else: 315 print("[!] Path '%s' is not a directory." % path) 316 else: 317 print("[!] Directory '%s' does not exists." % path) 318 319 def command_lls(self, arguments, command): 320 # Command arguments required : No 321 # Active SMB connection needed : No 322 # SMB share needed : No 323 324 if len(arguments) == 0: 325 path = '.' 326 else: 327 path = ' '.join(arguments) 328 329 # lls <directory> 330 if os.path.isdir(path): 331 directory_contents = os.listdir(path=path) 332 for entryname in sorted(directory_contents): 333 path_to_file = path + os.path.sep + entryname 334 rights_str = unix_permissions(path_to_file) 335 size_str = b_filesize(os.path.getsize(filename=path_to_file)) 336 date_str = datetime.datetime.fromtimestamp(os.path.getmtime(filename=path_to_file)).strftime("%Y-%m-%d %H:%M") 337 338 if os.path.isdir(s=entryname): 339 if self.config.no_colors: 340 print("%s %10s %s %s%s" % (rights_str, size_str, date_str, entryname, os.path.sep)) 341 else: 342 print("%s %10s %s \x1b[1;96m%s\x1b[0m%s" % (rights_str, size_str, date_str, entryname, os.path.sep)) 343 else: 344 if self.config.no_colors: 345 print("%s %10s %s %s" % (rights_str, size_str, date_str, entryname)) 346 else: 347 print("%s %10s %s \x1b[1m%s\x1b[0m" % (rights_str, size_str, date_str, entryname)) 348 # lls <file> 349 elif os.path.isfile(path): 350 rights_str = unix_permissions(path) 351 size_str = b_filesize(os.path.getsize(filename=path)) 352 date_str = datetime.datetime.fromtimestamp(os.path.getmtime(filename=path)).strftime("%Y-%m-%d %H:%M") 353 if self.config.no_colors: 354 print("%s %10s %s %s" % (rights_str, size_str, date_str, os.path.basename(path))) 355 else: 356 print("%s %10s %s \x1b[1m%s\x1b[0m" % (rights_str, size_str, date_str, os.path.basename(path))) 357 else: 358 print("[!] No such file or directory.") 359 360 @command_arguments_required 361 def command_lmkdir(self, arguments, command): 362 # Command arguments required : Yes 363 # Active SMB connection needed : No 364 # SMB share needed : No 365 366 path = ' '.join(arguments) 367 368 # Split each dir 369 if os.path.sep in path: 370 path = path.strip(os.path.sep).split(os.path.sep) 371 else: 372 path = [path] 373 374 # Create each dir in the path 375 for depth in range(1, len(path)+1): 376 tmp_path = os.path.sep.join(path[:depth]) 377 if not os.path.exists(tmp_path): 378 os.mkdir(path=tmp_path) 379 380 def command_lpwd(self, arguments, command): 381 # Command arguments required : No 382 # Active SMB connection needed : No 383 # SMB share needed : No 384 385 print(os.getcwd()) 386 387 @command_arguments_required 388 def command_lrm(self, arguments, command): 389 # Command arguments required : Yes 390 # Active SMB connection needed : No 391 # SMB share needed : No 392 393 path = ' '.join(arguments) 394 if os.path.exists(path): 395 if not os.path.isdir(s=path): 396 try: 397 os.remove(path=path) 398 except Exception as e: 399 print("[!] Error removing file '%s' : %s" % path) 400 else: 401 print("[!] Cannot delete '%s'. It is a directory, use 'lrmdir <directory>' instead." % path) 402 else: 403 print("[!] Path '%s' does not exist." % path) 404 405 @command_arguments_required 406 def command_lrmdir(self, arguments, command): 407 # Command arguments required : Yes 408 # Active SMB connection needed : No 409 # SMB share needed : No 410 411 path = ' '.join(arguments) 412 if os.path.exists(path): 413 if os.path.isdir(s=path): 414 try: 415 shutil.rmtree(path=path) 416 except Exception as e: 417 print("[!] Error removing directory '%s' : %s" % path) 418 else: 419 print("[!] Cannot delete '%s'. It is a file, use 'lrm <file>' instead." % path) 420 else: 421 print("[!] Path '%s' does not exist." % path) 422 423 def command_ltree(self, arguments, command): 424 # Command arguments required : No 425 # Active SMB connection needed : No 426 # SMB share needed : No 427 428 if len(arguments) == 0: 429 local_tree(path='.', config=self.config) 430 else: 431 local_tree(path=' '.join(arguments), config=self.config) 432 433 @active_smb_connection_needed 434 @smb_share_is_set 435 def command_ls(self, arguments, command): 436 # Command arguments required : No 437 # Active SMB connection needed : Yes 438 # SMB share needed : Yes 439 440 # Read the files 441 directory_contents = self.smbSession.list_contents(path=' '.join(arguments)) 442 443 for longname in sorted(directory_contents.keys(), key=lambda x:x.lower()): 444 windows_ls_entry(directory_contents[longname], self.config) 445 446 @command_arguments_required 447 @active_smb_connection_needed 448 @smb_share_is_set 449 def command_mkdir(self, arguments, command): 450 # Command arguments required : Yes 451 # Active SMB connection needed : Yes 452 # SMB share needed : Yes 453 454 path = ' '.join(arguments) 455 self.smbSession.mkdir(path=path) 456 457 @command_arguments_required 458 @active_smb_connection_needed 459 @smb_share_is_set 460 def command_module(self, arguments, command): 461 module_name = arguments[0] 462 463 if module_name in self.modules.keys(): 464 module = self.modules[module_name](self.smbSession, self.config) 465 module.run(' '.join(arguments[1:])) 466 else: 467 print("[!] Module '%s' does not exist." % module_name) 468 469 @command_arguments_required 470 @active_smb_connection_needed 471 @smb_share_is_set 472 def command_put(self, arguments, command): 473 # Command arguments required : Yes 474 # Active SMB connection needed : Yes 475 # SMB share needed : Yes 476 477 # Put files recursively 478 if arguments[0] == "-r": 479 localpath = ' '.join(arguments[1:]) 480 try: 481 self.smbSession.put_file_recursively(localpath=localpath) 482 except impacket.smbconnection.SessionError as e: 483 print("[!] SMB Error: %s" % e) 484 485 # Put a single file 486 else: 487 localpath = ' '.join(arguments) 488 try: 489 self.smbSession.put_file(localpath=localpath) 490 except impacket.smbconnection.SessionError as e: 491 print("[!] SMB Error: %s" % e) 492 493 def command_reconnect(self, arguments, command): 494 # Command arguments required : No 495 # Active SMB connection needed : No 496 # SMB share needed : No 497 498 self.smbSession.ping_smb_session() 499 if self.smbSession.connected: 500 self.smbSession.close_smb_session() 501 self.smbSession.init_smb_session() 502 else: 503 self.smbSession.init_smb_session() 504 505 def command_reset(self, arguments, command): 506 # Command arguments required : No 507 # Active SMB connection needed : No 508 # SMB share needed : No 509 sys.stdout.write('\x1b[?25h') # Sets the cursor to on 510 sys.stdout.write('\x1b[v') 511 sys.stdout.write('\x1b[o') # Reset 512 sys.stdout.flush() 513 514 @command_arguments_required 515 @active_smb_connection_needed 516 @smb_share_is_set 517 def command_rm(self, arguments, command): 518 # Command arguments required : Yes 519 # Active SMB connection needed : Yes 520 # SMB share needed : Yes 521 522 path = ' '.join(arguments) 523 if self.smbSession.path_exists(path): 524 if self.smbSession.path_isfile(path): 525 try: 526 self.smbSession.rm(path=path) 527 except Exception as e: 528 print("[!] Error removing file '%s' : %s" % path) 529 else: 530 print("[!] Cannot delete '%s': This is a directory, use 'rmdir <directory>' instead." % path) 531 else: 532 print("[!] Remote file '%s' does not exist." % path) 533 534 @command_arguments_required 535 @active_smb_connection_needed 536 @smb_share_is_set 537 def command_rmdir(self, arguments, command): 538 # Command arguments required : Yes 539 # Active SMB connection needed : Yes 540 # SMB share needed : Yes 541 542 path = ' '.join(arguments) 543 if self.smbSession.path_exists(path): 544 if self.smbSession.path_isdir(path): 545 try: 546 self.smbSession.rmdir(path=path) 547 except Exception as e: 548 print("[!] Error removing directory '%s' : %s" % path) 549 else: 550 print("[!] Cannot delete '%s': This is a file, use 'rm <file>' instead." % path) 551 else: 552 print("[!] Remote directory '%s' does not exist." % path) 553 554 @active_smb_connection_needed 555 def command_shares(self, arguments, command): 556 # Command arguments required : No 557 # Active SMB connection needed : Yes 558 # SMB share needed : No 559 560 shares = self.smbSession.list_shares() 561 if len(shares.keys()) != 0: 562 table = Table(title=None) 563 table.add_column("Share") 564 table.add_column("Hidden") 565 table.add_column("Type") 566 table.add_column("Description", justify="left") 567 568 for sharename in sorted(shares.keys()): 569 is_hidden = bool(sharename.endswith('$')) 570 types = ', '.join([s.replace("STYPE_","") for s in shares[sharename]["type"]]) 571 if is_hidden: 572 table.add_row(sharename, str(is_hidden), types, shares[sharename]["comment"]) 573 else: 574 table.add_row(sharename, str(is_hidden), types, shares[sharename]["comment"]) 575 576 Console().print(table) 577 else: 578 print("[!] No share served on '%s'" % self.smbSession.address) 579 580 @active_smb_connection_needed 581 @smb_share_is_set 582 def command_tree(self, arguments, command): 583 # Command arguments required : No 584 # Active SMB connection needed : Yes 585 # SMB share needed : Yes 586 587 if len(arguments) == 0: 588 self.smbSession.tree(path='.') 589 else: 590 self.smbSession.tree(path=' '.join(arguments)) 591 592 @command_arguments_required 593 @active_smb_connection_needed 594 def command_use(self, arguments, command): 595 # Command arguments required : Yes 596 # Active SMB connection needed : Yes 597 # SMB share needed : No 598 599 sharename = ' '.join(arguments) 600 # Reload the list of shares 601 shares = self.smbSession.list_shares() 602 shares = [s.lower() for s in shares.keys()] 603 if sharename.lower() in shares: 604 self.smbSession.set_share(sharename) 605 else: 606 print("[!] No share named '%s' on '%s'" % (sharename, self.smbSession.address)) 607 608 # Private functions ======================================================= 609 610 def __load_modules(self): 611 612 613 self.modules.clear() 614 615 modules_dir = os.path.normpath(os.path.dirname(__file__) + os.path.sep + ".." + os.path.sep + "modules") 616 if self.config.debug: 617 print("[debug] Loading modules from %s ..." % modules_dir) 618 sys.path.extend([modules_dir]) 619 620 for file in os.listdir(modules_dir): 621 filepath = os.path.normpath(modules_dir + os.path.sep + file) 622 if file.endswith('.py'): 623 if os.path.isfile(filepath) and file not in ["__init__.py"]: 624 try: 625 module_file = import_module('smbclientng.modules.%s' % (file[:-3])) 626 module = module_file.__getattribute__(file[:-3]) 627 self.modules[module.name.lower()] = module 628 except AttributeError as e: 629 pass 630 631 if self.config.debug: 632 if len(self.modules.keys()) == 0: 633 print("[debug] Loaded 0 modules.") 634 elif len(self.modules.keys()) == 1: 635 print("[debug] Loaded 1 module:") 636 else: 637 print("[debug] Loaded %d modules:" % len(self.modules.keys())) 638 for modulename in sorted(self.modules.keys()): 639 print("[debug] %s : \"%s\"" % (module.name, module.description)) 640 641 if self.commandCompleterObject is not None: 642 self.commandCompleterObject.commands["module"]["subcommands"] = list(self.modules.keys()) 643 644 def __prompt(self): 645 """ 646 Prints the command prompt for the interactive shell. 647 648 This method constructs and returns the command prompt string based on the current state of the SMB session. 649 The prompt indicates the connection status with a visual symbol and displays the current working directory 650 or the SMB share path. The prompt appearance changes based on whether colors are enabled in the configuration. 651 652 Returns: 653 str: The formatted command prompt string. 654 """ 655 656 self.smbSession.ping_smb_session() 657 if self.smbSession.connected: 658 if self.config.no_colors: 659 connected_dot = "[v]" 660 else: 661 connected_dot = "\x1b[1;92m⏺\x1b[0m" 662 else: 663 if self.config.no_colors: 664 connected_dot = "[x]" 665 else: 666 connected_dot = "\x1b[1;91m⏺\x1b[0m" 667 668 if self.smbSession.smb_share is None: 669 if self.config.no_colors: 670 str_prompt = "%s[\\\\%s\\]> " % (connected_dot, self.smbSession.address) 671 else: 672 str_prompt = "%s[\x1b[1;94m\\\\%s\\\x1b[0m]> " % (connected_dot, self.smbSession.address) 673 else: 674 str_path = "\\\\%s\\%s\\%s" % (self.smbSession.address, self.smbSession.smb_share, self.smbSession.smb_cwd.lstrip(ntpath.sep)) 675 if self.config.no_colors: 676 str_prompt = "%s[%s]> " % (connected_dot, str_path) 677 else: 678 str_prompt = "%s[\x1b[1;94m%s\x1b[0m]> " % (connected_dot, str_path) 679 680 return str_prompt
36def active_smb_connection_needed(func): 37 def wrapper(*args, **kwargs): 38 self, arguments,command = args[0], args[1], args[2] 39 # 40 self.smbSession.ping_smb_session() 41 if self.smbSession.connected: 42 return func(*args, **kwargs) 43 else: 44 print("[!] SMB Session is disconnected.") 45 return None 46 return wrapper
59class InteractiveShell(object): 60 """ 61 Class InteractiveShell is designed to manage the interactive command line interface for smbclient-ng. 62 63 This class handles user input, executes commands, and manages the state of the SMB session. It provides 64 a command line interface for users to interact with SMB shares, execute commands like directory listing, 65 file transfer, and more. 66 67 Attributes: 68 smbSession (SMBConnection): The active SMB connection session. 69 debug (bool): Flag to enable or disable debug mode. 70 smb_share (str): The current SMB share in use. 71 smb_path (str): The current path within the SMB share. 72 commandCompleterObject (CommandCompleter): Object to handle command completion and help generation. 73 74 Methods: 75 __init__(self, smbSession, debug=False): Initializes the InteractiveShell with the given SMB session and debug mode. 76 run(self): Starts the command line interface loop, processing user input until exit. 77 """ 78 79 def __init__(self, smbSession, config): 80 # Objects 81 self.smbSession = smbSession 82 self.config = config 83 self.commandCompleterObject = CommandCompleter(smbSession=self.smbSession, config=self.config) 84 readline.set_completer(self.commandCompleterObject.complete) 85 readline.parse_and_bind("tab: complete") 86 readline.set_completer_delims("\n") 87 # Additional modules 88 self.modules = {} 89 self.__load_modules() 90 91 def run(self): 92 running = True 93 while running: 94 try: 95 user_input = input(self.__prompt()).strip().split(" ") 96 command, arguments = user_input[0].lower(), user_input[1:] 97 98 # Exit the command line 99 if command == "exit": 100 running = False 101 102 elif command in self.commandCompleterObject.commands.keys(): 103 self.process_command( 104 command=command, 105 arguments=arguments 106 ) 107 108 elif command.strip() == "": 109 pass 110 111 # Fallback to unknown command 112 else: 113 print("Unknown command. Type \"help\" for help.") 114 115 except KeyboardInterrupt as e: 116 print() 117 118 except EOFError as e: 119 print() 120 running = False 121 122 except Exception as e: 123 if self.config.debug: 124 traceback.print_exc() 125 print("[!] Error: %s" % str(e)) 126 127 def process_command(self, command, arguments=[]): 128 # Skip 129 if command.strip() == "": 130 pass 131 132 # Display help 133 elif command == "help": 134 self.command_help(arguments, command) 135 136 # Closes the current SMB session 137 elif command == "close": 138 self.command_close(arguments, command) 139 140 # Change directory in the current share 141 elif command == "cd": 142 self.command_cd(arguments, command) 143 144 # Get a file 145 elif command == "get": 146 self.command_get(arguments, command) 147 148 # SMB server info 149 elif command == "info": 150 self.command_info(arguments, command) 151 152 # List directory contents in a share 153 elif command in ["ls", "dir"]: 154 self.command_ls(arguments, command) 155 156 # Creates a new remote directory 157 elif command == "mkdir": 158 self.command_mkdir(arguments, command) 159 160 # Put a file 161 elif command == "put": 162 self.command_put(arguments, command) 163 164 # Changes the current local directory 165 elif command == "lcd": 166 self.command_lcd(arguments, command) 167 168 # Lists the contents of the current local directory 169 elif command == "lls": 170 self.command_lls(arguments, command) 171 172 # Creates a new local directory 173 elif command == "lmkdir": 174 self.command_lmkdir(arguments, command) 175 176 # Shows the current local directory 177 elif command == "lpwd": 178 self.command_lpwd(arguments, command) 179 180 # Removes a local file 181 elif command == "lrm": 182 self.command_lrm(arguments, command) 183 184 # Removes a local directory 185 elif command == "lrmdir": 186 self.command_lrmdir(arguments, command) 187 188 # Shows the current local directory 189 elif command == "ltree": 190 self.command_ltree(arguments, command) 191 192 # Modules 193 elif command == "module": 194 self.command_module(arguments, command) 195 196 # Reconnects the current SMB session 197 elif command in ["connect", "reconnect"]: 198 self.command_reconnect(arguments, command) 199 200 # Reset the TTY output 201 elif command == "reset": 202 self.command_reset(arguments, command) 203 204 # Removes a remote file 205 elif command == "rm": 206 self.command_rm(arguments, command) 207 208 # Removes a remote directory 209 elif command == "rmdir": 210 self.command_rmdir(arguments, command) 211 212 # List shares 213 elif command == "shares": 214 self.command_shares(arguments, command) 215 216 # Displays a tree view of the CWD 217 elif command == "tree": 218 self.command_tree(arguments, command) 219 220 # Use a share 221 elif command == "use": 222 self.command_use(arguments, command) 223 224 # Commands ================================================================ 225 226 @command_arguments_required 227 @active_smb_connection_needed 228 @smb_share_is_set 229 def command_cd(self, arguments, command): 230 # Command arguments required : Yes 231 # Active SMB connection needed : Yes 232 # SMB share needed : Yes 233 234 path = ' '.join(arguments) 235 try: 236 self.smbSession.set_cwd(path=path) 237 except impacket.smbconnection.SessionError as e: 238 print("[!] SMB Error: %s" % e) 239 240 def command_close(self, arguments, command): 241 # Command arguments required : No 242 # Active SMB connection needed : No 243 # SMB share needed : No 244 245 self.smbSession.ping_smb_session() 246 if self.smbSession.connected: 247 self.smbSession.close_smb_session() 248 249 @command_arguments_required 250 @active_smb_connection_needed 251 @smb_share_is_set 252 def command_get(self, arguments, command): 253 # Command arguments required : Yes 254 # Active SMB connection needed : Yes 255 # SMB share needed : Yes 256 257 # Get files recursively 258 if arguments[0] == "-r": 259 path = ' '.join(arguments[1:]).replace('/', ntpath.sep) 260 try: 261 self.smbSession.get_file_recursively(path=path) 262 except impacket.smbconnection.SessionError as e: 263 print("[!] SMB Error: %s" % e) 264 # Get a single file 265 else: 266 path = ' '.join(arguments).replace('/', ntpath.sep) 267 try: 268 self.smbSession.get_file(path=path) 269 except impacket.smbconnection.SessionError as e: 270 print("[!] SMB Error: %s" % e) 271 272 def command_help(self, arguments, command): 273 # Command arguments required : No 274 # Active SMB connection needed : No 275 # SMB share needed : No 276 277 if len(arguments) != 0: 278 self.commandCompleterObject.print_help(command=arguments[0]) 279 else: 280 self.commandCompleterObject.print_help(command=None) 281 282 @active_smb_connection_needed 283 def command_info(self, arguments, command): 284 # Command arguments required : No 285 # Active SMB connection needed : Yes 286 # SMB share needed : No 287 288 print_server_info = False 289 print_share_info = False 290 if len(arguments) != 0: 291 print_server_info = (arguments[0].lower() == "server") 292 print_share_info = (arguments[0].lower() == "share") 293 else: 294 print_server_info = True 295 print_share_info = True 296 297 try: 298 self.smbSession.info( 299 share=print_share_info, 300 server=print_server_info 301 ) 302 except impacket.smbconnection.SessionError as e: 303 print("[!] SMB Error: %s" % e) 304 305 @command_arguments_required 306 def command_lcd(self, arguments, command): 307 # Command arguments required : Yes 308 # Active SMB connection needed : No 309 # SMB share needed : No 310 311 path = ' '.join(arguments) 312 if os.path.exists(path=path): 313 if os.path.isdir(s=path): 314 os.chdir(path=path) 315 else: 316 print("[!] Path '%s' is not a directory." % path) 317 else: 318 print("[!] Directory '%s' does not exists." % path) 319 320 def command_lls(self, arguments, command): 321 # Command arguments required : No 322 # Active SMB connection needed : No 323 # SMB share needed : No 324 325 if len(arguments) == 0: 326 path = '.' 327 else: 328 path = ' '.join(arguments) 329 330 # lls <directory> 331 if os.path.isdir(path): 332 directory_contents = os.listdir(path=path) 333 for entryname in sorted(directory_contents): 334 path_to_file = path + os.path.sep + entryname 335 rights_str = unix_permissions(path_to_file) 336 size_str = b_filesize(os.path.getsize(filename=path_to_file)) 337 date_str = datetime.datetime.fromtimestamp(os.path.getmtime(filename=path_to_file)).strftime("%Y-%m-%d %H:%M") 338 339 if os.path.isdir(s=entryname): 340 if self.config.no_colors: 341 print("%s %10s %s %s%s" % (rights_str, size_str, date_str, entryname, os.path.sep)) 342 else: 343 print("%s %10s %s \x1b[1;96m%s\x1b[0m%s" % (rights_str, size_str, date_str, entryname, os.path.sep)) 344 else: 345 if self.config.no_colors: 346 print("%s %10s %s %s" % (rights_str, size_str, date_str, entryname)) 347 else: 348 print("%s %10s %s \x1b[1m%s\x1b[0m" % (rights_str, size_str, date_str, entryname)) 349 # lls <file> 350 elif os.path.isfile(path): 351 rights_str = unix_permissions(path) 352 size_str = b_filesize(os.path.getsize(filename=path)) 353 date_str = datetime.datetime.fromtimestamp(os.path.getmtime(filename=path)).strftime("%Y-%m-%d %H:%M") 354 if self.config.no_colors: 355 print("%s %10s %s %s" % (rights_str, size_str, date_str, os.path.basename(path))) 356 else: 357 print("%s %10s %s \x1b[1m%s\x1b[0m" % (rights_str, size_str, date_str, os.path.basename(path))) 358 else: 359 print("[!] No such file or directory.") 360 361 @command_arguments_required 362 def command_lmkdir(self, arguments, command): 363 # Command arguments required : Yes 364 # Active SMB connection needed : No 365 # SMB share needed : No 366 367 path = ' '.join(arguments) 368 369 # Split each dir 370 if os.path.sep in path: 371 path = path.strip(os.path.sep).split(os.path.sep) 372 else: 373 path = [path] 374 375 # Create each dir in the path 376 for depth in range(1, len(path)+1): 377 tmp_path = os.path.sep.join(path[:depth]) 378 if not os.path.exists(tmp_path): 379 os.mkdir(path=tmp_path) 380 381 def command_lpwd(self, arguments, command): 382 # Command arguments required : No 383 # Active SMB connection needed : No 384 # SMB share needed : No 385 386 print(os.getcwd()) 387 388 @command_arguments_required 389 def command_lrm(self, arguments, command): 390 # Command arguments required : Yes 391 # Active SMB connection needed : No 392 # SMB share needed : No 393 394 path = ' '.join(arguments) 395 if os.path.exists(path): 396 if not os.path.isdir(s=path): 397 try: 398 os.remove(path=path) 399 except Exception as e: 400 print("[!] Error removing file '%s' : %s" % path) 401 else: 402 print("[!] Cannot delete '%s'. It is a directory, use 'lrmdir <directory>' instead." % path) 403 else: 404 print("[!] Path '%s' does not exist." % path) 405 406 @command_arguments_required 407 def command_lrmdir(self, arguments, command): 408 # Command arguments required : Yes 409 # Active SMB connection needed : No 410 # SMB share needed : No 411 412 path = ' '.join(arguments) 413 if os.path.exists(path): 414 if os.path.isdir(s=path): 415 try: 416 shutil.rmtree(path=path) 417 except Exception as e: 418 print("[!] Error removing directory '%s' : %s" % path) 419 else: 420 print("[!] Cannot delete '%s'. It is a file, use 'lrm <file>' instead." % path) 421 else: 422 print("[!] Path '%s' does not exist." % path) 423 424 def command_ltree(self, arguments, command): 425 # Command arguments required : No 426 # Active SMB connection needed : No 427 # SMB share needed : No 428 429 if len(arguments) == 0: 430 local_tree(path='.', config=self.config) 431 else: 432 local_tree(path=' '.join(arguments), config=self.config) 433 434 @active_smb_connection_needed 435 @smb_share_is_set 436 def command_ls(self, arguments, command): 437 # Command arguments required : No 438 # Active SMB connection needed : Yes 439 # SMB share needed : Yes 440 441 # Read the files 442 directory_contents = self.smbSession.list_contents(path=' '.join(arguments)) 443 444 for longname in sorted(directory_contents.keys(), key=lambda x:x.lower()): 445 windows_ls_entry(directory_contents[longname], self.config) 446 447 @command_arguments_required 448 @active_smb_connection_needed 449 @smb_share_is_set 450 def command_mkdir(self, arguments, command): 451 # Command arguments required : Yes 452 # Active SMB connection needed : Yes 453 # SMB share needed : Yes 454 455 path = ' '.join(arguments) 456 self.smbSession.mkdir(path=path) 457 458 @command_arguments_required 459 @active_smb_connection_needed 460 @smb_share_is_set 461 def command_module(self, arguments, command): 462 module_name = arguments[0] 463 464 if module_name in self.modules.keys(): 465 module = self.modules[module_name](self.smbSession, self.config) 466 module.run(' '.join(arguments[1:])) 467 else: 468 print("[!] Module '%s' does not exist." % module_name) 469 470 @command_arguments_required 471 @active_smb_connection_needed 472 @smb_share_is_set 473 def command_put(self, arguments, command): 474 # Command arguments required : Yes 475 # Active SMB connection needed : Yes 476 # SMB share needed : Yes 477 478 # Put files recursively 479 if arguments[0] == "-r": 480 localpath = ' '.join(arguments[1:]) 481 try: 482 self.smbSession.put_file_recursively(localpath=localpath) 483 except impacket.smbconnection.SessionError as e: 484 print("[!] SMB Error: %s" % e) 485 486 # Put a single file 487 else: 488 localpath = ' '.join(arguments) 489 try: 490 self.smbSession.put_file(localpath=localpath) 491 except impacket.smbconnection.SessionError as e: 492 print("[!] SMB Error: %s" % e) 493 494 def command_reconnect(self, arguments, command): 495 # Command arguments required : No 496 # Active SMB connection needed : No 497 # SMB share needed : No 498 499 self.smbSession.ping_smb_session() 500 if self.smbSession.connected: 501 self.smbSession.close_smb_session() 502 self.smbSession.init_smb_session() 503 else: 504 self.smbSession.init_smb_session() 505 506 def command_reset(self, arguments, command): 507 # Command arguments required : No 508 # Active SMB connection needed : No 509 # SMB share needed : No 510 sys.stdout.write('\x1b[?25h') # Sets the cursor to on 511 sys.stdout.write('\x1b[v') 512 sys.stdout.write('\x1b[o') # Reset 513 sys.stdout.flush() 514 515 @command_arguments_required 516 @active_smb_connection_needed 517 @smb_share_is_set 518 def command_rm(self, arguments, command): 519 # Command arguments required : Yes 520 # Active SMB connection needed : Yes 521 # SMB share needed : Yes 522 523 path = ' '.join(arguments) 524 if self.smbSession.path_exists(path): 525 if self.smbSession.path_isfile(path): 526 try: 527 self.smbSession.rm(path=path) 528 except Exception as e: 529 print("[!] Error removing file '%s' : %s" % path) 530 else: 531 print("[!] Cannot delete '%s': This is a directory, use 'rmdir <directory>' instead." % path) 532 else: 533 print("[!] Remote file '%s' does not exist." % path) 534 535 @command_arguments_required 536 @active_smb_connection_needed 537 @smb_share_is_set 538 def command_rmdir(self, arguments, command): 539 # Command arguments required : Yes 540 # Active SMB connection needed : Yes 541 # SMB share needed : Yes 542 543 path = ' '.join(arguments) 544 if self.smbSession.path_exists(path): 545 if self.smbSession.path_isdir(path): 546 try: 547 self.smbSession.rmdir(path=path) 548 except Exception as e: 549 print("[!] Error removing directory '%s' : %s" % path) 550 else: 551 print("[!] Cannot delete '%s': This is a file, use 'rm <file>' instead." % path) 552 else: 553 print("[!] Remote directory '%s' does not exist." % path) 554 555 @active_smb_connection_needed 556 def command_shares(self, arguments, command): 557 # Command arguments required : No 558 # Active SMB connection needed : Yes 559 # SMB share needed : No 560 561 shares = self.smbSession.list_shares() 562 if len(shares.keys()) != 0: 563 table = Table(title=None) 564 table.add_column("Share") 565 table.add_column("Hidden") 566 table.add_column("Type") 567 table.add_column("Description", justify="left") 568 569 for sharename in sorted(shares.keys()): 570 is_hidden = bool(sharename.endswith('$')) 571 types = ', '.join([s.replace("STYPE_","") for s in shares[sharename]["type"]]) 572 if is_hidden: 573 table.add_row(sharename, str(is_hidden), types, shares[sharename]["comment"]) 574 else: 575 table.add_row(sharename, str(is_hidden), types, shares[sharename]["comment"]) 576 577 Console().print(table) 578 else: 579 print("[!] No share served on '%s'" % self.smbSession.address) 580 581 @active_smb_connection_needed 582 @smb_share_is_set 583 def command_tree(self, arguments, command): 584 # Command arguments required : No 585 # Active SMB connection needed : Yes 586 # SMB share needed : Yes 587 588 if len(arguments) == 0: 589 self.smbSession.tree(path='.') 590 else: 591 self.smbSession.tree(path=' '.join(arguments)) 592 593 @command_arguments_required 594 @active_smb_connection_needed 595 def command_use(self, arguments, command): 596 # Command arguments required : Yes 597 # Active SMB connection needed : Yes 598 # SMB share needed : No 599 600 sharename = ' '.join(arguments) 601 # Reload the list of shares 602 shares = self.smbSession.list_shares() 603 shares = [s.lower() for s in shares.keys()] 604 if sharename.lower() in shares: 605 self.smbSession.set_share(sharename) 606 else: 607 print("[!] No share named '%s' on '%s'" % (sharename, self.smbSession.address)) 608 609 # Private functions ======================================================= 610 611 def __load_modules(self): 612 613 614 self.modules.clear() 615 616 modules_dir = os.path.normpath(os.path.dirname(__file__) + os.path.sep + ".." + os.path.sep + "modules") 617 if self.config.debug: 618 print("[debug] Loading modules from %s ..." % modules_dir) 619 sys.path.extend([modules_dir]) 620 621 for file in os.listdir(modules_dir): 622 filepath = os.path.normpath(modules_dir + os.path.sep + file) 623 if file.endswith('.py'): 624 if os.path.isfile(filepath) and file not in ["__init__.py"]: 625 try: 626 module_file = import_module('smbclientng.modules.%s' % (file[:-3])) 627 module = module_file.__getattribute__(file[:-3]) 628 self.modules[module.name.lower()] = module 629 except AttributeError as e: 630 pass 631 632 if self.config.debug: 633 if len(self.modules.keys()) == 0: 634 print("[debug] Loaded 0 modules.") 635 elif len(self.modules.keys()) == 1: 636 print("[debug] Loaded 1 module:") 637 else: 638 print("[debug] Loaded %d modules:" % len(self.modules.keys())) 639 for modulename in sorted(self.modules.keys()): 640 print("[debug] %s : \"%s\"" % (module.name, module.description)) 641 642 if self.commandCompleterObject is not None: 643 self.commandCompleterObject.commands["module"]["subcommands"] = list(self.modules.keys()) 644 645 def __prompt(self): 646 """ 647 Prints the command prompt for the interactive shell. 648 649 This method constructs and returns the command prompt string based on the current state of the SMB session. 650 The prompt indicates the connection status with a visual symbol and displays the current working directory 651 or the SMB share path. The prompt appearance changes based on whether colors are enabled in the configuration. 652 653 Returns: 654 str: The formatted command prompt string. 655 """ 656 657 self.smbSession.ping_smb_session() 658 if self.smbSession.connected: 659 if self.config.no_colors: 660 connected_dot = "[v]" 661 else: 662 connected_dot = "\x1b[1;92m⏺\x1b[0m" 663 else: 664 if self.config.no_colors: 665 connected_dot = "[x]" 666 else: 667 connected_dot = "\x1b[1;91m⏺\x1b[0m" 668 669 if self.smbSession.smb_share is None: 670 if self.config.no_colors: 671 str_prompt = "%s[\\\\%s\\]> " % (connected_dot, self.smbSession.address) 672 else: 673 str_prompt = "%s[\x1b[1;94m\\\\%s\\\x1b[0m]> " % (connected_dot, self.smbSession.address) 674 else: 675 str_path = "\\\\%s\\%s\\%s" % (self.smbSession.address, self.smbSession.smb_share, self.smbSession.smb_cwd.lstrip(ntpath.sep)) 676 if self.config.no_colors: 677 str_prompt = "%s[%s]> " % (connected_dot, str_path) 678 else: 679 str_prompt = "%s[\x1b[1;94m%s\x1b[0m]> " % (connected_dot, str_path) 680 681 return str_prompt
Class InteractiveShell is designed to manage the interactive command line interface for smbclient-ng.
This class handles user input, executes commands, and manages the state of the SMB session. It provides a command line interface for users to interact with SMB shares, execute commands like directory listing, file transfer, and more.
Attributes: smbSession (SMBConnection): The active SMB connection session. debug (bool): Flag to enable or disable debug mode. smb_share (str): The current SMB share in use. smb_path (str): The current path within the SMB share. commandCompleterObject (CommandCompleter): Object to handle command completion and help generation.
Methods: __init__(self, smbSession, debug=False): Initializes the InteractiveShell with the given SMB session and debug mode. run(self): Starts the command line interface loop, processing user input until exit.
79 def __init__(self, smbSession, config): 80 # Objects 81 self.smbSession = smbSession 82 self.config = config 83 self.commandCompleterObject = CommandCompleter(smbSession=self.smbSession, config=self.config) 84 readline.set_completer(self.commandCompleterObject.complete) 85 readline.parse_and_bind("tab: complete") 86 readline.set_completer_delims("\n") 87 # Additional modules 88 self.modules = {} 89 self.__load_modules()
91 def run(self): 92 running = True 93 while running: 94 try: 95 user_input = input(self.__prompt()).strip().split(" ") 96 command, arguments = user_input[0].lower(), user_input[1:] 97 98 # Exit the command line 99 if command == "exit": 100 running = False 101 102 elif command in self.commandCompleterObject.commands.keys(): 103 self.process_command( 104 command=command, 105 arguments=arguments 106 ) 107 108 elif command.strip() == "": 109 pass 110 111 # Fallback to unknown command 112 else: 113 print("Unknown command. Type \"help\" for help.") 114 115 except KeyboardInterrupt as e: 116 print() 117 118 except EOFError as e: 119 print() 120 running = False 121 122 except Exception as e: 123 if self.config.debug: 124 traceback.print_exc() 125 print("[!] Error: %s" % str(e))
127 def process_command(self, command, arguments=[]): 128 # Skip 129 if command.strip() == "": 130 pass 131 132 # Display help 133 elif command == "help": 134 self.command_help(arguments, command) 135 136 # Closes the current SMB session 137 elif command == "close": 138 self.command_close(arguments, command) 139 140 # Change directory in the current share 141 elif command == "cd": 142 self.command_cd(arguments, command) 143 144 # Get a file 145 elif command == "get": 146 self.command_get(arguments, command) 147 148 # SMB server info 149 elif command == "info": 150 self.command_info(arguments, command) 151 152 # List directory contents in a share 153 elif command in ["ls", "dir"]: 154 self.command_ls(arguments, command) 155 156 # Creates a new remote directory 157 elif command == "mkdir": 158 self.command_mkdir(arguments, command) 159 160 # Put a file 161 elif command == "put": 162 self.command_put(arguments, command) 163 164 # Changes the current local directory 165 elif command == "lcd": 166 self.command_lcd(arguments, command) 167 168 # Lists the contents of the current local directory 169 elif command == "lls": 170 self.command_lls(arguments, command) 171 172 # Creates a new local directory 173 elif command == "lmkdir": 174 self.command_lmkdir(arguments, command) 175 176 # Shows the current local directory 177 elif command == "lpwd": 178 self.command_lpwd(arguments, command) 179 180 # Removes a local file 181 elif command == "lrm": 182 self.command_lrm(arguments, command) 183 184 # Removes a local directory 185 elif command == "lrmdir": 186 self.command_lrmdir(arguments, command) 187 188 # Shows the current local directory 189 elif command == "ltree": 190 self.command_ltree(arguments, command) 191 192 # Modules 193 elif command == "module": 194 self.command_module(arguments, command) 195 196 # Reconnects the current SMB session 197 elif command in ["connect", "reconnect"]: 198 self.command_reconnect(arguments, command) 199 200 # Reset the TTY output 201 elif command == "reset": 202 self.command_reset(arguments, command) 203 204 # Removes a remote file 205 elif command == "rm": 206 self.command_rm(arguments, command) 207 208 # Removes a remote directory 209 elif command == "rmdir": 210 self.command_rmdir(arguments, command) 211 212 # List shares 213 elif command == "shares": 214 self.command_shares(arguments, command) 215 216 # Displays a tree view of the CWD 217 elif command == "tree": 218 self.command_tree(arguments, command) 219 220 # Use a share 221 elif command == "use": 222 self.command_use(arguments, command)
272 def command_help(self, arguments, command): 273 # Command arguments required : No 274 # Active SMB connection needed : No 275 # SMB share needed : No 276 277 if len(arguments) != 0: 278 self.commandCompleterObject.print_help(command=arguments[0]) 279 else: 280 self.commandCompleterObject.print_help(command=None)
320 def command_lls(self, arguments, command): 321 # Command arguments required : No 322 # Active SMB connection needed : No 323 # SMB share needed : No 324 325 if len(arguments) == 0: 326 path = '.' 327 else: 328 path = ' '.join(arguments) 329 330 # lls <directory> 331 if os.path.isdir(path): 332 directory_contents = os.listdir(path=path) 333 for entryname in sorted(directory_contents): 334 path_to_file = path + os.path.sep + entryname 335 rights_str = unix_permissions(path_to_file) 336 size_str = b_filesize(os.path.getsize(filename=path_to_file)) 337 date_str = datetime.datetime.fromtimestamp(os.path.getmtime(filename=path_to_file)).strftime("%Y-%m-%d %H:%M") 338 339 if os.path.isdir(s=entryname): 340 if self.config.no_colors: 341 print("%s %10s %s %s%s" % (rights_str, size_str, date_str, entryname, os.path.sep)) 342 else: 343 print("%s %10s %s \x1b[1;96m%s\x1b[0m%s" % (rights_str, size_str, date_str, entryname, os.path.sep)) 344 else: 345 if self.config.no_colors: 346 print("%s %10s %s %s" % (rights_str, size_str, date_str, entryname)) 347 else: 348 print("%s %10s %s \x1b[1m%s\x1b[0m" % (rights_str, size_str, date_str, entryname)) 349 # lls <file> 350 elif os.path.isfile(path): 351 rights_str = unix_permissions(path) 352 size_str = b_filesize(os.path.getsize(filename=path)) 353 date_str = datetime.datetime.fromtimestamp(os.path.getmtime(filename=path)).strftime("%Y-%m-%d %H:%M") 354 if self.config.no_colors: 355 print("%s %10s %s %s" % (rights_str, size_str, date_str, os.path.basename(path))) 356 else: 357 print("%s %10s %s \x1b[1m%s\x1b[0m" % (rights_str, size_str, date_str, os.path.basename(path))) 358 else: 359 print("[!] No such file or directory.")
424 def command_ltree(self, arguments, command): 425 # Command arguments required : No 426 # Active SMB connection needed : No 427 # SMB share needed : No 428 429 if len(arguments) == 0: 430 local_tree(path='.', config=self.config) 431 else: 432 local_tree(path=' '.join(arguments), config=self.config)
494 def command_reconnect(self, arguments, command): 495 # Command arguments required : No 496 # Active SMB connection needed : No 497 # SMB share needed : No 498 499 self.smbSession.ping_smb_session() 500 if self.smbSession.connected: 501 self.smbSession.close_smb_session() 502 self.smbSession.init_smb_session() 503 else: 504 self.smbSession.init_smb_session()
506 def command_reset(self, arguments, command): 507 # Command arguments required : No 508 # Active SMB connection needed : No 509 # SMB share needed : No 510 sys.stdout.write('\x1b[?25h') # Sets the cursor to on 511 sys.stdout.write('\x1b[v') 512 sys.stdout.write('\x1b[o') # Reset 513 sys.stdout.flush()