diff --git a/nxc/protocols/mssql.py b/nxc/protocols/mssql.py index b7edc248ec..ae6e8be09e 100755 --- a/nxc/protocols/mssql.py +++ b/nxc/protocols/mssql.py @@ -618,3 +618,40 @@ def lsa(self): ) LSA.dumpCachedHashes() LSA.dumpSecrets() + + def list_backups(self): + self.logger.info("Dumping database backups") + query = """ + SELECT + bs.database_name, + bs.server_name, + bmf.physical_device_name AS backup_file_path, + CASE + WHEN bs.encryptor_type IS NULL THEN 'Unencrypted' + ELSE 'Encrypted' + END AS backup_encryption_status, + bs.encryptor_type, + bs.key_algorithm + FROM msdb.dbo.backupset AS bs + INNER JOIN msdb.dbo.backupmediafamily AS bmf + ON bs.media_set_id = bmf.media_set_id + INNER JOIN sys.databases AS d + ON bs.database_name = d.name + ORDER BY bs.backup_finish_date DESC; + """ + rows = self.conn.sql_query(query) + if self.conn.lastError: + self.logger.fail(f"Error running the SQL query: {self.conn.lastError}") + return + if not rows: + self.logger.display("No backups returned") + return + else: + self.logger.display("Enumerated backups") + self.logger.highlight(f"{'Backup Name':<20} {'Encryption':<15} {'Backup Path'}") + self.logger.highlight(f"{'-----------':<20} {'----------':<15} {'-----------'}") + for row in rows: + database_name = row.get("database_name").strip() + is_encrypted = row.get("backup_encryption_status").strip() + backup_file_path = row.get("backup_file_path").strip() + self.logger.highlight(f"{database_name:<20} {is_encrypted:<15s} {backup_file_path}") diff --git a/nxc/protocols/mssql/proto_args.py b/nxc/protocols/mssql/proto_args.py index 9d494ed44e..3293bdd5ad 100644 --- a/nxc/protocols/mssql/proto_args.py +++ b/nxc/protocols/mssql/proto_args.py @@ -36,4 +36,5 @@ def proto_args(parser, parents): mapping_enum_group = mssql_parser.add_argument_group("Mapping/Enumeration") mapping_enum_group.add_argument("--rid-brute", nargs="?", type=int, const=4000, metavar="MAX_RID", help="enumerate users by bruteforcing RIDs") + mapping_enum_group.add_argument("--list-backups", action="store_true", help="dump database backups path") return parser diff --git a/tests/e2e_commands.txt b/tests/e2e_commands.txt index 4713e1b9dd..4417b3c208 100644 --- a/tests/e2e_commands.txt +++ b/tests/e2e_commands.txt @@ -270,6 +270,7 @@ netexec mssql TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS --rid-bru netexec mssql TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS --database netexec mssql TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS --sam netexec mssql TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS --lsa +netexec mssql TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS --list-backups ##### MSSQL PowerShell netexec mssql TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -X ipconfig netexec mssql TARGET_HOST -u LOGIN_USERNAME -p LOGIN_PASSWORD KERBEROS -X ipconfig --force-ps32