Parses the metadata found in Veeam full backup files (.vbk
), Veeam incremental backup files (.vib
) and Veeam reverse incremental backup files (.vrb
) to extract relevant fields for each Restore Point.
These files are generated by Veeam Backup & Replication during backup jobs. This artifact accepts full backup, incremental backup, and reverse incremental backup files from unencrypted backups of virtual and physical infrastructures.
name: Windows.Veeam.RestorePoints.BackupFiles
description: |
Parses the metadata found in Veeam full backup files (`.vbk`), Veeam incremental backup files (`.vib`) and Veeam reverse incremental backup files (`.vrb`) to extract relevant fields for each Restore Point.
These files are generated by Veeam Backup & Replication during backup jobs. This artifact accepts full backup, incremental backup, and reverse incremental backup files from **unencrypted** backups of virtual and physical infrastructures.
author: Synacktiv, Maxence Fossat - @cybiosity
type: CLIENT
precondition: SELECT OS FROM info() WHERE OS = 'windows'
parameters:
- name: BackupRepositories
description: List of Backup Repositories where ".vbk", ".vib" and ".vrb" files should be looked for.
type: csv
default: |
BackupRepoPath
C:/BackupRepo1
D:/BackupRepo2
required_permissions:
- FILESYSTEM_READ
sources:
- query: |
// ============================
// === Formatting functions ===
// ============================
// Function to format XML properties
LET format_properties(Properties) = to_dict(item={
SELECT AttrName AS _key,
Value AS _value
FROM Properties
})
// Function to format disk_info capacity for HvAuxData
LET hv_disk_capacity(Disks) = to_dict(item= {
SELECT disk_info.Attrdisk_id AS _key,
disk_info.Attrcapacity AS _value
FROM Disks
})
// Function to format Disk capacity for DesktopOibAuxData
LET desktop_disk_capacity(Disks) = to_dict(item= {
SELECT DevSetupInfo.AttrDevPath AS _key,
Capacity AS _value
FROM Disks
})
// Function to format Disk capacity for COibAuxDataVmware
LET vmware_disk_capacity(Disks) = to_dict(item= {
SELECT `Uuid` AS _key,
Capacity AS _value
FROM Disks
})
// Function to format OibFiles
LET oib_files_size(Files) = to_dict(item= {
SELECT AttrFileName AS _key,
AttrSize AS _value
FROM Files
})
// Restore Point type
LET restore_point_type = dict(
`0`='Full',
`1`='Increment'
)
// Backup encryption state
LET back_enc_state = dict(
`0`='Unencrypted',
`2`='Encrypted'
)
// ========================
// === Initial parsing ====
// ========================
LET MetadataStart <= '''
rule StartOffsetRule {
strings:
$start = "<OibSummary>"
condition: any of them
}
'''
LET MetadataEnd <= '''
rule EndOffsetRule {
strings:
$end = "</OibSummary>"
condition: any of them
}
'''
// Listing all Storage files in the Backup Repositories
LET backup_repos = SELECT BackupRepoPath FROM BackupRepositories
LET backup_files = SELECT * FROM foreach(row=backup_repos,
query={
SELECT *
FROM glob(
globs=[
'/**/*.vbk',
'/**/*.vib',
'/**/*.vrb'
],
root=BackupRepoPath,
accessor='file'
)
})
// Find last start offset of metadata for each Storage file
LET start_offsets= SELECT File.FullPath AS FilePath,
max(item=String.Offset) AS StartOffset
FROM yara(
files=backup_files.OSPath,
rules=MetadataStart,
start=0,
end=18446744073709551615,
number=100
)
GROUP BY File.FullPath
// Find end offset for each start offset, extract and parse XML
LET xml = SELECT parse_xml(
accessor='data',
file=read_file(
filename=BackupFilePath,
offset=StartOffset,
length=EndOffset - StartOffset + 13
)
) AS Metadata,
BackupFilePath
FROM foreach(row=start_offsets,
query={
SELECT File.FullPath AS BackupFilePath,
StartOffset,
String.Offset + StartOffset AS EndOffset
FROM yara(
files=pathspec(
DelegateAccessor='file',
DelegatePath=FilePath,
Path=str(str=StartOffset)
),
accessor='offset',
rules=MetadataEnd,
end=20971520,
number=1
)
})
WHERE Metadata
// =========================
// === Objects In Backup ===
// =========================
// Extracting interesting fields from OIB, OibFiles, Object, SourceHost, Storage, Point and Backup
LET oib = SELECT BackupFilePath,
Metadata.OibSummary.OIB.AttrDisplayName AS DisplayName,
Metadata.OibSummary.OIB.AttrVmName AS VMName,
Metadata.OibSummary.OIB.AttrState AS State,
Metadata.OibSummary.OIB.AttrType AS Type,
Metadata.OibSummary.OIB.AttrAlgorithm AS Algorithm,
Metadata.OibSummary.OIB.AttrHealthStatus AS HealthStatus,
Metadata.OibSummary.OIB.AttrHasIndex AS HasIndex,
Metadata.OibSummary.OIB.AttrHasExchange AS HasExchange,
Metadata.OibSummary.OIB.AttrHasSharePoint AS HasSharePoint,
Metadata.OibSummary.OIB.AttrHasSql AS HasSQL,
Metadata.OibSummary.OIB.AttrHasAd AS HasAD,
Metadata.OibSummary.OIB.AttrHasOracle AS HasOracle,
Metadata.OibSummary.OIB.AttrHasPostgreSql AS HasPostgreSQL,
Metadata.OibSummary.OIB.AttrHasVeeamArchiver AS HasVeeamArchiver,
Metadata.OibSummary.OIB.AttrIsCorrupted AS IsCorrupted,
Metadata.OibSummary.OIB.AttrIsRecheckCorrupted AS IsRecheckCorrupted,
Metadata.OibSummary.OIB.AttrIsConsistent AS IsConsistent,
Metadata.OibSummary.OIB.AttrIsPartialActiveFull AS IsPartialActiveFull,
Metadata.OibSummary.OIB.AttrProductVersion AS ProductVersion,
Metadata.OibSummary.OIB.AttrProductVersionFlags AS ProductVersionFlags,
Metadata.OibSummary.OIB.AttrProductIsRentalLicense AS ProductIsRentalLicense,
Metadata.OibSummary.SourceHost.AttrName AS HostName,
Metadata.OibSummary.SourceHost.AttrHostInstanceId AS HostInstanceID,
Metadata.OibSummary.Backup.AttrJobName AS JobName,
Metadata.OibSummary.Backup.AttrPolicyName AS PolicyName,
Metadata.OibSummary.PrevFileName AS PreviousFileInChain,
back_enc_state[Metadata.OibSummary.Backup.AttrEncryptionState] AS BackupEncryptionState,
Metadata.OibSummary.OIB.AttrEffectiveMemoryMb AS TempMemory,
Metadata.OibSummary.Object.AttrViType || 'Physical machine' AS VirtualType,
Metadata.OibSummary.Object.AttrName AS ExtractName,
Metadata.OibSummary.Object.AttrObjectId AS ExtractID,
oib_files_size(Files=Metadata.OibSummary.OibFiles.File) AS ExtractableFilesSize,
parse_xml(file=Metadata.OibSummary.Storage.AttrPartialPath, accessor='data').Path.Elements AS BackupFile,
timestamp(string=Metadata.OibSummary.OIB.AttrCreationTimeUtc) AS CreationTimeUTC,
timestamp(string=Metadata.OibSummary.OIB.AttrCompletionTimeUtc) AS CompletionTimeUTC,
humanize(bytes=int(int=Metadata.OibSummary.OIB.AttrApproxSize)) AS ApproximateSize,
split(string=Metadata.OibSummary.Point.AttrNum, sep='\\.')[0] AS RestorePointNumber,
restore_point_type[Metadata.OibSummary.Point.AttrType] AS RestorePointType,
parse_xml(file=Metadata.OibSummary.Storage.`#text`, accessor='data').CBackupStats AS Stats,
parse_xml(file=Metadata.OibSummary.OIB.AttrAuxData, accessor='data').COibAuxData AS AuxData,
format_properties(
Properties = parse_xml(file=Metadata.OibSummary.OIB.`#text`, accessor='data').GuestInfo.Property
) AS GuestInfo
FROM xml
// Expanding relevant fields into subfields
LET expand_oib = SELECT BackupFilePath, DisplayName, VMName, State, Type, Algorithm, HealthStatus, HasIndex, HasExchange, HasSharePoint, HasSQL, HasAD, HasOracle, HasPostgreSQL, HasVeeamArchiver, IsCorrupted, IsRecheckCorrupted, IsConsistent, IsPartialActiveFull, ProductVersion, ProductVersionFlags, ProductIsRentalLicense, HostName, HostInstanceID, JobName, PolicyName, PreviousFileInChain, BackupEncryptionState, VirtualType, ExtractName, ExtractID, ExtractableFilesSize, BackupFile, CreationTimeUTC, CompletionTimeUTC, ApproximateSize, RestorePointNumber, RestorePointType,
format(
format='%d MiB',
args = int(int=TempMemory) || int(int=AuxData.DesktopOibAuxData.SystemConfiguration.RAMInfo.AttrTotalSizeMB)
) AS Memory,
hv_disk_capacity(Disks=AuxData.HvAuxData.disks.disk)
+ desktop_disk_capacity(Disks=AuxData.DesktopOibAuxData.Disk)
+ vmware_disk_capacity(Disks=AuxData.COibAuxDataVmware.Disk)
AS DisksCapacity,
GuestInfo.GuestOsName AS GuestOSName,
GuestInfo.GuestOsType AS GuestOSType,
GuestInfo.DnsName AS GuestDNSName,
GuestInfo.`Ip` AS GuestIP,
GuestInfo.ToolsStatus AS GuestToolsStatus,
GuestInfo.ToolsVersionStatus AS GuestToolsVersionStatus,
Stats.BackupSize AS BackupSize,
Stats.DataSize AS DataSize,
Stats.DedupRatio AS DeduplicationRatio,
Stats.CompressRatio AS CompressionRatio
FROM oib
// ===================
// === Final query ===
// ===================
SELECT DisplayName,
CreationTimeUTC,
CompletionTimeUTC,
ApproximateSize,
DisksCapacity,
RestorePointNumber,
RestorePointType,
HostName,
HostInstanceID,
BackupFile,
BackupFilePath,
ExtractableFilesSize,
BackupSize,
DataSize,
DeduplicationRatio,
CompressionRatio,
VirtualType,
VMName,
Memory,
GuestOSName,
GuestOSType,
GuestDNSName,
GuestIP,
GuestToolsStatus,
GuestToolsVersionStatus,
State,
Type,
Algorithm,
HealthStatus,
HasIndex,
HasExchange,
HasSharePoint,
HasSQL,
HasAD,
HasOracle,
HasPostgreSQL,
HasVeeamArchiver,
IsCorrupted,
IsRecheckCorrupted,
IsConsistent,
IsPartialActiveFull,
ProductVersion,
ProductVersionFlags,
ProductIsRentalLicense,
JobName,
PolicyName,
BackupEncryptionState,
PreviousFileInChain,
ExtractName,
ExtractID
FROM expand_oib