利用“.VHDX虚拟磁盘格式”挂载后无法被勒索病毒等修改破坏的机理,用C#在Windows系统磁盘中创建“.VHDX虚拟磁盘格式”文件,备份前将此“.VHDX虚拟磁盘格式”文件挂载为可读写虚拟磁盘,备份完毕后,再将虚拟磁盘卸载重新挂载为只读,这样就可以确保备份文件不会被勒索病毒破坏了。
使用.VHDX虚拟磁盘格式结合只读挂载来保护备份文件,是一种有效的防勒索病毒方案。以下是技术分析和C#实现方案:
一、技术可行性分析
1、VHDX文件特性
VHDX是微软的虚拟磁盘格式,支持离线存储和动态扩展,可通过Windows磁盘管理工具挂载为物理磁盘。
当挂载为只读模式时,系统会阻止任何写入操作,包括勒索病毒对文件的加密或删除。
2、防护原理
3、潜在风险
需确保挂载操作本身不会被恶意程序劫持(例如通过提权修改挂载参数)。
若备份过程中系统崩溃,可能残留可写状态的VHDX文件(需设计异常处理机制)。
二、C#实现方案
1、核心逻辑
创建VHDX文件并挂载为可读写模式
执行备份操作
卸载VHDX后重新挂载为只读模式
2、代码实现(需管理员权限运行)
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Security.AccessControl;
using System.Security.Principal;
class VhdxBackupManager
{
const string VhdxPath = @"D:\Backup.vhdx";
const string AdminAccount = "Administrators";
static char _currentDriveLetter = 'E';
public static void ExecuteSafeBackup()
{
try
{
if (!File.Exists(VhdxPath))
{
CreateNewVhdx();
SetVhdxPermissions();
}
char driveLetter = FindAvailableDriveLetter();
MountVhdx(driveLetter, readOnly: false);
File.Copy("C:\\Data\\important.txt", $"{driveLetter}:\\important.txt", true);
DismountVhdx(driveLetter);
MountVhdx(driveLetter, readOnly: true);
}
catch (Exception ex)
{
DismountVhdx(_currentDriveLetter);
Console.WriteLine($"Error: {ex.Message}");
}
}
private static char FindAvailableDriveLetter()
{
var usedDrives = DriveInfo.GetDrives()
.Select(d => d.Name[0])
.ToList();
for (char c = 'E'; c <= 'Z'; c++)
{
if (!usedDrives.Contains(c))
{
_currentDriveLetter = c;
return c;
}
}
throw new InvalidOperationException("没有可用的驱动器盘符");
}
private static void MountVhdx(char driveLetter, bool readOnly)
{
var script = $@"
select vdisk file={VhdxPath}
attach vdisk {(readOnly ? "readonly" : "")}
assign letter={driveLetter}
exit
";
ExecuteDiskPart(script);
if (!Directory.Exists($"{driveLetter}:\\"))
{
throw new Exception($"挂载到 {driveLetter}: 失败");
}
}
private static void DismountVhdx(char driveLetter)
{
var script = $@"
select vdisk file={VhdxPath}
detach vdisk
exit
";
ExecuteDiskPart(script);
}
private static void SetVhdxPermissions()
{
var fileInfo = new FileInfo(VhdxPath);
FileSecurity fSecurity = fileInfo.GetAccessControl();
fSecurity.SetAccessRuleProtection(true, false);
AuthorizationRuleCollection rules = fSecurity.GetAccessRules(true, true, typeof(NTAccount));
foreach (FileSystemAccessRule rule in rules)
{
fSecurity.RemoveAccessRule(rule);
}
fSecurity.AddAccessRule(new FileSystemAccessRule(
new SecurityIdentifier(WellKnownSidType.LocalSystemSid, null),
FileSystemRights.FullControl,
AccessControlType.Allow));
fSecurity.AddAccessRule(new FileSystemAccessRule(
new NTAccount(AdminAccount),
FileSystemRights.Read | FileSystemRights.ExecuteFile,
InheritanceFlags.None,
PropagationFlags.None,
AccessControlType.Allow));
fSecurity.AddAccessRule(new FileSystemAccessRule(
new SecurityIdentifier(WellKnownSidType.WorldSid, null),
FileSystemRights.Write,
AccessControlType.Deny));
fileInfo.SetAccessControl(fSecurity);
}
private static void CreateNewVhdx()
{
var script = $@"
create vdisk file={VhdxPath} maximum=10240 type=expandable
select vdisk file={VhdxPath}
attach vdisk
create partition primary
format quick fs=ntfs label=BackupDrive
detach vdisk
exit
";
ExecuteDiskPart(script);
}
private static void ExecuteDiskPart(string script)
{
var tempFile = Path.GetTempFileName();
File.WriteAllText(tempFile, script);
using (var process = new Process())
{
process.StartInfo = new ProcessStartInfo
{
FileName = "diskpart",
Arguments = $"/s {tempFile}",
UseShellExecute = false,
CreateNoWindow = true
};
process.Start();
process.WaitForExit(15000);
if (process.ExitCode != 0)
{
File.Delete(tempFile);
throw new Exception("diskpart执行失败,返回码:" + process.ExitCode);
}
}
File.Delete(tempFile);
}
}
权限设置关键点说明:
1、三层权限控制:
2、权限继承处理:
fSecurity.SetAccessRuleProtection(true, false);
3、最小权限原则:
使用注意事项:
1、运行要求:
2、挂载状态验证:
if (!Directory.Exists(MountPoint))
{
throw new Exception("挂载失败,请检查diskpart输出");
}
3、安全增强建议:
File.SetAttributes(VhdxPath, FileAttributes.Hidden);
该方案通过以下机制确保VHDX文件安全:
1、物理文件保护:挂载时系统会锁定VHDX文件
2、权限双重保障:
3、系统级隔离:虚拟磁盘与宿主系统分离
建议配合Windows Defender的受控文件夹访问功能,形成多层防御体系。
优化点说明:
1、动态盘符分配:
2、挂载验证机制:
if (!Directory.Exists($"{driveLetter}:\\")){
throw new Exception($"挂载到 {driveLetter}: 失败");}
异常处理增强:
diskpart执行失败时抛出详细错误
finally块中确保清理临时文件
异常时自动尝试卸载当前盘符
盘符生命周期管理:
使用场景示例:
VhdxBackupManager.ExecuteSafeBackup();
VhdxBackupManager.ExecuteSafeBackup();
扩展建议:
1、盘符偏好设置:
char[] preferredLetters = { 'X', 'Y', 'Z' };
foreach (char c in preferredLetters)
{
if (!usedDrives.Contains(c))
{
return c;
}
}
2、多线程安全:
private static readonly object _driveLock = new object();
lock (_driveLock)
{
}
3、盘符释放确认:
private static void EnsureDriveUnmounted(char driveLetter)
{
if (Directory.Exists($"{driveLetter}:\\"))
{
throw new InvalidOperationException($"驱动器 {driveLetter}: 仍处于挂载状态");
}
}
该方案通过动态盘符管理实现了以下优势:
避免与现有驱动器冲突
支持在复杂存储环境中的重复运行
提供清晰的错误反馈机制
确保资源释放的可靠性
三、强化防护的配套措施
文件系统权限控制
对VHDX文件设置NTFS权限:禁止Everyone组的写入权限,仅允许SYSTEM和指定管理员读取。
加密存储
使用BitLocker加密VHDX文件,即使文件被复制也无法解密。
版本控制
结合增量备份,保留多个历史版本的VHDX文件(如Backup_20230516.vhdx)。
物理隔离
定期将VHDX文件复制到未挂载的移动硬盘,实现Air Gap隔离。
相关教程:
【C#】如何判断虚拟磁盘VHDX文件是否已经被挂载,挂载到了哪一个盘符,并且当前是挂载为只读模式还是可读写模式[
1]
http://31167.oa22.cn
该文章在 2025/5/16 11:05:13 编辑过