沙箱操作工具

创建一个图形化的沙箱操作工具,名为 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()

使用说明

  1. 保存脚本 :将上面的代码保存为 SandboxGuardian.ps1

  2. 运行脚本

    powershell 复制代码
    Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
    .\SandboxGuardian.ps1
  3. 功能说明

    • 选择文件/文件夹:通过按钮选择要测试的目标
    • 安全选项:配置沙箱的安全设置(推荐保持默认的最佳实践配置)
    • 启动沙箱:一键创建并启动隔离环境
    • 查看日志:查看所有操作的详细记录
    • 清理文件:手动清理所有临时文件

图形界面特点

  • 直观易用:清晰的分组和标签说明
  • 安全默认值:所有安全选项默认启用最佳实践配置
  • 实时反馈:操作日志实时显示执行状态
  • 错误处理:完善的错误处理和用户提示
  • 美观界面:使用现代Windows界面风格,布局合理

这个工具让沙箱操作变得简单安全,即使是普通用户也能轻松遵循安全最佳实践。