Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions nxc/protocols/mssql.py
Original file line number Diff line number Diff line change
Expand Up @@ -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}")
1 change: 1 addition & 0 deletions nxc/protocols/mssql/proto_args.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
1 change: 1 addition & 0 deletions tests/e2e_commands.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down