创建一个图形化的沙箱操作工具,名为 Sandbox Guardian。这个工具将实现之前讨论的最佳实践,并通过直观的界面让用户轻松安全地操作。
设计思路
我将使用 PowerShell 的 Windows Forms 来创建一个图形界面,包含以下功能:
- 文件/文件夹选择
- 安全选项配置(只读、网络隔离等)
- 一键启动沙箱
- 操作日志显示
- 临时文件管理
完整 PowerShell 脚本代码
powershell
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
# 创建主窗体
$form = New-Object System.Windows.Forms.Form
$form.Text = "Sandbox Guardian - 安全沙箱操作工具"
$form.Size = New-Object System.Drawing.Size(700, 600)
$form.StartPosition = "CenterScreen"
$form.MinimumSize = New-Object System.Drawing.Size(700, 600)
$form.BackColor = [System.Drawing.Color]::FromArgb(240, 240, 240)
$form.Font = New-Object System.Drawing.Font("Microsoft YaHei", 9)
# 图标(使用系统图标)
$form.Icon = [System.Drawing.Icon]::ExtractAssociatedIcon((Get-Command powershell).Path)
# 顶部标题
$headerLabel = New-Object System.Windows.Forms.Label
$headerLabel.Text = "Sandbox Guardian"
$headerLabel.Font = New-Object System.Drawing.Font("Microsoft YaHei", 16, [System.Drawing.FontStyle]::Bold)
$headerLabel.ForeColor = [System.Drawing.Color]::Navy
$headerLabel.Size = New-Object System.Drawing.Size(300, 40)
$headerLabel.Location = New-Object System.Drawing.Point(20, 15)
$form.Controls.Add($headerLabel)
$subHeaderLabel = New-Object System.Windows.Forms.Label
$subHeaderLabel.Text = "安全沙箱测试最佳实践工具"
$subHeaderLabel.Font = New-Object System.Drawing.Font("Microsoft YaHei", 10)
$subHeaderLabel.ForeColor = [System.Drawing.Color]::DarkSlateGray
$subHeaderLabel.Size = New-Object System.Drawing.Size(300, 20)
$subHeaderLabel.Location = New-Object System.Drawing.Point(22, 55)
$form.Controls.Add($subHeaderLabel)
# 分隔线
$separator = New-Object System.Windows.Forms.Label
$separator.BorderStyle = [System.Windows.Forms.BorderStyle]::Fixed3D
$separator.Size = New-Object System.Drawing.Size(650, 2)
$separator.Location = New-Object System.Drawing.Point(20, 85)
$form.Controls.Add($separator)
# 选择文件区域
$fileGroup = New-Object System.Windows.Forms.GroupBox
$fileGroup.Text = "选择测试目标"
$fileGroup.Size = New-Object System.Drawing.Size(650, 120)
$fileGroup.Location = New-Object System.Drawing.Point(20, 100)
$form.Controls.Add($fileGroup)
$fileLabel = New-Object System.Windows.Forms.Label
$fileLabel.Text = "文件或文件夹路径:"
$fileLabel.Size = New-Object System.Drawing.Size(120, 20)
$fileLabel.Location = New-Object System.Drawing.Point(20, 25)
$fileGroup.Controls.Add($fileLabel)
$fileTextBox = New-Object System.Windows.Forms.TextBox
$fileTextBox.Size = New-Object System.Drawing.Size(400, 20)
$fileTextBox.Location = New-Object System.Drawing.Point(140, 25)
$fileTextBox.ReadOnly = $true
$fileGroup.Controls.Add($fileTextBox)
$browseFileButton = New-Object System.Windows.Forms.Button
$browseFileButton.Text = "选择文件"
$browseFileButton.Size = New-Object System.Drawing.Size(80, 25)
$browseFileButton.Location = New-Object System.Drawing.Point(550, 23)
$browseFileButton.Add_Click({
$openFileDialog = New-Object System.Windows.Forms.OpenFileDialog
$openFileDialog.Filter = "所有文件 (*.*)|*.*"
if ($openFileDialog.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) {
$fileTextBox.Text = $openFileDialog.FileName
Update-StartButtonState
}
})
$fileGroup.Controls.Add($browseFileButton)
$browseFolderButton = New-Object System.Windows.Forms.Button
$browseFolderButton.Text = "选择文件夹"
$browseFolderButton.Size = New-Object System.Drawing.Size(80, 25)
$browseFolderButton.Location = New-Object System.Drawing.Point(550, 53)
$browseFolderButton.Add_Click({
$folderBrowserDialog = New-Object System.Windows.Forms.FolderBrowserDialog
if ($folderBrowserDialog.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) {
$fileTextBox.Text = $folderBrowserDialog.SelectedPath
Update-StartButtonState
}
})
$fileGroup.Controls.Add($browseFolderButton)
$clearButton = New-Object System.Windows.Forms.Button
$clearButton.Text = "清除"
$clearButton.Size = New-Object System.Drawing.Size(80, 25)
$clearButton.Location = New-Object System.Drawing.Point(550, 83)
$clearButton.Add_Click({
$fileTextBox.Text = ""
Update-StartButtonState
})
$fileGroup.Controls.Add($clearButton)
# 安全选项区域
$optionsGroup = New-Object System.Windows.Forms.GroupBox
$optionsGroup.Text = "安全选项 (最佳实践推荐配置)"
$optionsGroup.Size = New-Object System.Drawing.Size(650, 150)
$optionsGroup.Location = New-Object System.Drawing.Point(20, 230)
$form.Controls.Add($optionsGroup)
$readOnlyCheckBox = New-Object System.Windows.Forms.CheckBox
$readOnlyCheckBox.Text = "只读模式 (防止文件修改)"
$readOnlyCheckBox.Size = New-Object System.Drawing.Size(250, 20)
$readOnlyCheckBox.Location = New-Object System.Drawing.Point(20, 25)
$readOnlyCheckBox.Checked = $true
$optionsGroup.Controls.Add($readOnlyCheckBox)
$clipboardCheckBox = New-Object System.Windows.Forms.CheckBox
$clipboardCheckBox.Text = "禁用剪贴板共享 (防止数据泄露)"
$clipboardCheckBox.Size = New-Object System.Drawing.Size(250, 20)
$clipboardCheckBox.Location = New-Object System.Drawing.Point(20, 55)
$clipboardCheckBox.Checked = $true
$optionsGroup.Controls.Add($clipboardCheckBox)
$audioCheckBox = New-Object System.Windows.Forms.CheckBox
$audioCheckBox.Text = "禁用音频输入 (麦克风)"
$audioCheckBox.Size = New-Object System.Drawing.Size(250, 20)
$audioCheckBox.Location = New-Object System.Drawing.Point(20, 85)
$audioCheckBox.Checked = $true
$optionsGroup.Controls.Add($audioCheckBox)
$networkCheckBox = New-Object System.Windows.Forms.CheckBox
$networkCheckBox.Text = "禁用网络访问 (推荐用于恶意软件分析)"
$networkCheckBox.Size = New-Object System.Drawing.Size(280, 20)
$networkCheckBox.Location = New-Object System.Drawing.Point(20, 115)
$networkCheckBox.Checked = $false
$optionsGroup.Controls.Add($networkCheckBox)
$printerCheckBox = New-Object System.Windows.Forms.CheckBox
$printerCheckBox.Text = "禁用打印机共享"
$printerCheckBox.Size = New-Object System.Drawing.Size(250, 20)
$printerCheckBox.Location = New-Object System.Drawing.Point(300, 25)
$printerCheckBox.Checked = $true
$optionsGroup.Controls.Add($printerCheckBox)
$videoCheckBox = New-Object System.Windows.Forms.CheckBox
$videoCheckBox.Text = "禁用视频输入 (摄像头)"
$videoCheckBox.Size = New-Object System.Drawing.Size(250, 20)
$videoCheckBox.Location = New-Object System.Drawing.Point(300, 55)
$videoCheckBox.Checked = $true
$optionsGroup.Controls.Add($videoCheckBox)
$memoryLabel = New-Object System.Windows.Forms.Label
$memoryLabel.Text = "分配内存 (MB):"
$memoryLabel.Size = New-Object System.Drawing.Size(100, 20)
$memoryLabel.Location = New-Object System.Drawing.Point(300, 90)
$optionsGroup.Controls.Add($memoryLabel)
$memoryNumeric = New-Object System.Windows.Forms.NumericUpDown
$memoryNumeric.Size = New-Object System.Drawing.Size(80, 20)
$memoryNumeric.Location = New-Object System.Drawing.Point(400, 88)
$memoryNumeric.Minimum = 1024
$memoryNumeric.Maximum = 8192
$memoryNumeric.Value = 4096
$memoryNumeric.Increment = 512
$optionsGroup.Controls.Add($memoryNumeric)
# 操作按钮区域
$buttonGroup = New-Object System.Windows.Forms.GroupBox
$buttonGroup.Text = "操作"
$buttonGroup.Size = New-Object System.Drawing.Size(650, 70)
$buttonGroup.Location = New-Object System.Drawing.Point(20, 390)
$form.Controls.Add($buttonGroup)
$startButton = New-Object System.Windows.Forms.Button
$startButton.Text = "启动安全沙箱"
$startButton.Size = New-Object System.Drawing.Size(120, 35)
$startButton.Location = New-Object System.Drawing.Point(20, 25)
$startButton.BackColor = [System.Drawing.Color]::LightGreen
$startButton.Enabled = $false
$startButton.Add_Click({
Start-SandboxSession
})
$buttonGroup.Controls.Add($startButton)
$cleanupButton = New-Object System.Windows.Forms.Button
$cleanupButton.Text = "清理临时文件"
$cleanupButton.Size = New-Object System.Drawing.Size(120, 35)
$cleanupButton.Location = New-Object System.Drawing.Point(150, 25)
$cleanupButton.Add_Click({
Cleanup-TempFiles
})
$buttonGroup.Controls.Add($cleanupButton)
$viewLogButton = New-Object System.Windows.Forms.Button
$viewLogButton.Text = "查看日志"
$viewLogButton.Size = New-Object System.Drawing.Size(120, 35)
$viewLogButton.Location = New-Object System.Drawing.Point(280, 25)
$viewLogButton.Add_Click({
if (Test-Path $global:LogPath) {
Invoke-Item $global:LogPath
} else {
[System.Windows.Forms.MessageBox]::Show("暂无日志文件", "信息", "OK", "Information")
}
})
$buttonGroup.Controls.Add($viewLogButton)
# 日志区域
$logGroup = New-Object System.Windows.Forms.GroupBox
$logGroup.Text = "操作日志"
$logGroup.Size = New-Object System.Drawing.Size(650, 150)
$logGroup.Location = New-Object System.Drawing.Point(20, 470)
$form.Controls.Add($logGroup)
$logTextBox = New-Object System.Windows.Forms.TextBox
$logTextBox.Multiline = $true
$logTextBox.ScrollBars = "Vertical"
$logTextBox.Size = New-Object System.Drawing.Size(630, 120)
$logTextBox.Location = New-Object System.Drawing.Point(10, 20)
$logTextBox.ReadOnly = $true
$logTextBox.BackColor = [System.Drawing.Color]::White
$logTextBox.Font = New-Object System.Drawing.Font("Consolas", 9)
$logGroup.Controls.Add($logTextBox)
# 全局变量
$global:LogPath = Join-Path $env:TEMP "SandboxGuardian.log"
$global:TempDirs = @()
# 函数:更新启动按钮状态
function Update-StartButtonState {
$startButton.Enabled = (-not [string]::IsNullOrEmpty($fileTextBox.Text)) -and (Test-Path $fileTextBox.Text)
}
# 函数:添加日志
function Add-Log {
param($Message)
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$logEntry = "[$timestamp] $Message"
$logTextBox.AppendText("$logEntry`r`n")
$logTextBox.ScrollToCaret()
# 同时写入文件
Add-Content -Path $global:LogPath -Value $logEntry -Encoding UTF8
}
# 函数:清理临时文件
function Cleanup-TempFiles {
$cleanedCount = 0
foreach ($dir in $global:TempDirs) {
if (Test-Path $dir) {
try {
Remove-Item -Path $dir -Recurse -Force -ErrorAction Stop
Add-Log "已清理临时目录: $dir"
$cleanedCount++
} catch {
Add-Log "警告: 清理目录失败 $dir - $_"
}
}
}
$global:TempDirs = @()
if ($cleanedCount -gt 0) {
[System.Windows.Forms.MessageBox]::Show("已清理 $cleanedCount 个临时目录", "清理完成", "OK", "Information")
} else {
[System.Windows.Forms.MessageBox]::Show("没有需要清理的临时文件", "信息", "OK", "Information")
}
}
# 函数:启动沙箱会话
function Start-SandboxSession {
$targetPath = $fileTextBox.Text
if (-not (Test-Path $targetPath)) {
[System.Windows.Forms.MessageBox]::Show("指定的文件或路径不存在", "错误", "OK", "Error")
return
}
# 检查 Windows Sandbox 是否可用
Add-Log "检查系统要求..."
$SandboxFeature = Get-WindowsOptionalFeature -Online -FeatureName "Containers-DisposableClientVM" -ErrorAction SilentlyContinue
if ($SandboxFeature -eq $null -or $SandboxFeature.State -ne "Enabled") {
$result = [System.Windows.Forms.MessageBox]::Show("Windows Sandbox 未启用。是否现在启用?(需要管理员权限)", "功能未启用", "YesNo", "Question")
if ($result -eq [System.Windows.Forms.DialogResult]::Yes) {
try {
Enable-WindowsOptionalFeature -Online -FeatureName "Containers-DisposableClientVM" -NoRestart
Add-Log "已启用 Windows Sandbox 功能,可能需要重启电脑"
[System.Windows.Forms.MessageBox]::Show("Windows Sandbox 已启用。某些更改可能需要重启电脑后才能生效。", "提示", "OK", "Information")
} catch {
Add-Log "错误: 启用 Windows Sandbox 失败 - $_"
[System.Windows.Forms.MessageBox]::Show("启用 Windows Sandbox 失败。请手动通过'启用或关闭 Windows 功能'启用。", "错误", "OK", "Error")
}
}
return
}
# 创建临时工作目录
$TempParentDir = [System.IO.Path]::GetTempPath()
$TempDirName = "SandboxGuardian_$(Get-Date -Format 'yyyyMMdd_HHmmss')"
$TempWorkingDir = Join-Path -Path $TempParentDir -ChildPath $TempDirName
New-Item -ItemType Directory -Path $TempWorkingDir -Force | Out-Null
$global:TempDirs += $TempWorkingDir
Add-Log "创建临时工作目录: $TempWorkingDir"
# 复制文件/文件夹到临时目录
$SandboxTargetPath = Join-Path -Path "C:\Users\WDAGUtilityAccount\Desktop" -ChildPath (Split-Path $targetPath -Leaf)
$TempSourceCopy = Join-Path -Path $TempWorkingDir -ChildPath (Split-Path $targetPath -Leaf)
try {
if (Test-Path $targetPath -PathType Container) {
Copy-Item -Path $targetPath -Destination $TempWorkingDir -Recurse -Force
Add-Log "已复制文件夹到临时目录"
} else {
Copy-Item -Path $targetPath -Destination $TempSourceCopy -Force
Add-Log "已复制文件到临时目录"
}
} catch {
Add-Log "错误: 复制文件失败 - $_"
[System.Windows.Forms.MessageBox]::Show("复制文件失败: $_", "错误", "OK", "Error")
return
}
# 生成 WSB 配置文件
$WsbConfigContent = @"
<Configuration>
<MappedFolders>
<MappedFolder>
<HostFolder>$TempWorkingDir</HostFolder>
<ReadOnly>$($readOnlyCheckBox.Checked.ToString().ToLower())</ReadOnly>
</MappedFolder>
</MappedFolders>
<LogonCommand>
<Command>explorer.exe "$SandboxTargetPath"</Command>
</LogonCommand>
<AudioInput>$($audioCheckBox.Checked.ToString().ToLower())</AudioInput>
<VideoInput>$($videoCheckBox.Checked.ToString().ToLower())</VideoInput>
<ClipboardRedirection>$($clipboardCheckBox.Checked.ToString().ToLower())</ClipboardRedirection>
<PrinterRedirection>$($printerCheckBox.Checked.ToString().ToLower())</PrinterRedirection>
<Networking>$($networkCheckBox.Checked.ToString().ToLower())</Networking>
<MemoryInMB>$($memoryNumeric.Value)</MemoryInMB>
</Configuration>
"@
$WsbFilePath = Join-Path -Path $TempWorkingDir -ChildPath "SecureSandbox.wsb"
$WsbConfigContent | Out-File -FilePath $WsbFilePath -Encoding UTF8
Add-Log "已生成沙箱配置文件: $WsbFilePath"
# 显示安全配置摘要
Add-Log "安全配置: 只读=$($readOnlyCheckBox.Checked), 剪贴板=$($clipboardCheckBox.Checked), 网络=$($networkCheckBox.Checked)"
# 启动沙箱
Add-Log "正在启动 Windows Sandbox..."
try {
Start-Process -FilePath "WindowsSandbox" -ArgumentList $WsbFilePath -NoNewWindow
Add-Log "沙箱已启动。请在沙箱环境中进行操作。"
[System.Windows.Forms.MessageBox]::Show("沙箱已启动。请在该隔离环境中进行测试。`n`n关闭沙箱窗口后,所有更改将被丢弃。", "沙箱已启动", "OK", "Information")
} catch {
Add-Log "错误: 启动沙箱失败 - $_"
[System.Windows.Forms.MessageBox]::Show("启动沙箱失败: $_", "错误", "OK", "Error")
}
}
# 初始化日志
Add-Log "Sandbox Guardian 启动 - 安全沙箱操作工具"
Add-Log "当前用户: $env:USERNAME"
Add-Log "系统: $([Environment]::OSVersion.VersionString)"
# 显示窗体
[void]$form.ShowDialog()
使用说明
-
保存脚本 :将上面的代码保存为
SandboxGuardian.ps1
-
运行脚本:
powershellSet-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser .\SandboxGuardian.ps1
-
功能说明:
- 选择文件/文件夹:通过按钮选择要测试的目标
- 安全选项:配置沙箱的安全设置(推荐保持默认的最佳实践配置)
- 启动沙箱:一键创建并启动隔离环境
- 查看日志:查看所有操作的详细记录
- 清理文件:手动清理所有临时文件
图形界面特点
- 直观易用:清晰的分组和标签说明
- 安全默认值:所有安全选项默认启用最佳实践配置
- 实时反馈:操作日志实时显示执行状态
- 错误处理:完善的错误处理和用户提示
- 美观界面:使用现代Windows界面风格,布局合理
这个工具让沙箱操作变得简单安全,即使是普通用户也能轻松遵循安全最佳实践。