涉密文件处理方案二:原地打包
- IT
- 2天前
- 15热度
- 0评论
实践表明,吉印测绘地理信息数据安全检查系统不仅仅通过CAD的文件名来筛查,它还会扫描CAD中的所有图层,如果图层名称涉密也会被筛查出来。不仅如此,除了dwg文件,还会检查tif文件,通过其内容判断tif是否属于涉密数据。那么之前的“通过文件名与文件大小”来筛查的思路就行不通了,而编写一个能解析dwg、tif内容的程序显然不太现实。
于是想到采用压缩文件。经测试,安全检查系统不会检测压缩包内的文件,原因是显而易见的:
1、全盘的压缩文件都解压缩一遍,费时费力。
2、压缩文件很容易加上密码,那么检查系统就无法查看里面的具体内容。
总体思路与关键逻辑
基本思路:
对本地分区的所有dwg、tif逐个进行压缩操作,并存放在原始位置。那么需要用到winrar的命令行工具rar.exe,它是winrar自带的。
由于所有的文件都在原地,应还能方便地针对某一个文件夹及其子文件夹进行单独操作,可以考虑把它加入到文件夹的右键菜单。
关键安全逻辑:
1、脚本应跳过用户映射的网络驱动器,只处理真正的本地分区文件。
2、需要考虑到潜在的文件权限问题,仅当压缩/解压缩成功时,才删除原始文件/原始压缩文件。
3、由于涉及到多个后缀名,用户可能对处理的后缀名进行扩展,应对敏感后缀名进行校验,避免处理exe、dll等会破坏系统的后缀。
4、应输出完整的log日志文件。
操作友好性:
1、用注册表添加文件夹的右键菜单,并指定使用winrar.exe中包含的现成图标。
2、将针对某个文件夹操作的脚本copy到system32目录,实现在任意位置的便捷执行。
工具实现
准备winrar
首先提供winrar安装程序,默认应安装在c:\program files\winrar。
环境配置文件:setup.vbs
setup.vbs负责6件事情:1)自动提权,因为注册表操作、复制文件到system32都需要管理员权限;2)检测winrar是否存在;3)将rar.exe所在目录写入系统环境变量;4)初始化powershell的执行策略;5)复制必要的文件到c:\windows\system32;6)导入右键菜单注册表。
Option Explicit
' 初始化对象
Dim fso, shell, ws
Set fso = CreateObject("Scripting.FileSystemObject")
Set shell = CreateObject("Shell.Application")
Set ws = CreateObject("WScript.Shell")
' 自动提权检测(用RegWrite法,最稳)
On Error Resume Next
ws.RegWrite "HKLM\SOFTWARE\TestAdminKey", "1", "REG_SZ"
If Err.Number <> 0 Then
shell.ShellExecute "wscript.exe", """" & WScript.ScriptFullName & """ uac", "", "runas", 1
WScript.Quit
End If
ws.RegDelete "HKLM\SOFTWARE\TestAdminKey"
On Error GoTo 0
' 基本路径和日志初始化
Dim sys32, regfile, scriptPath, logPath, logfile
sys32 = ws.ExpandEnvironmentStrings("%SystemRoot%\System32")
scriptPath = fso.GetParentFolderName(WScript.ScriptFullName)
logPath = scriptPath & "\setup_log.txt"
Set logfile = fso.OpenTextFile(logPath, 8, True)
Sub Log(msg)
logfile.WriteLine Now & " " & msg
End Sub
'---1. 检查WinRAR是否安装在 C:\Program Files\WinRAR\ ---
Dim winrar
winrar = "C:\Program Files\WinRAR\WinRAR.exe"
If Not fso.FileExists(winrar) Then
MsgBox "未检测到WinRAR,或WinRAR未安装在C:\Program Files\WinRAR\!" & vbCrLf & "请手动安装WinRAR到默认路径。", 48, "WinRAR未安装"
Log "WinRAR未安装或位置不符,脚本终止"
logfile.Close
WScript.Quit
End If
Log "检测到WinRAR,路径:" & winrar
'---2. 把 WinRAR 加入系统环境变量 Path ---
Dim pathEnv, pathKey, newPath, pathAlreadySet
Dim envTarget
envTarget = "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\Environment\Path"
pathAlreadySet = False
On Error Resume Next
pathEnv = ws.RegRead(envTarget)
If Err.Number <> 0 Then
MsgBox "无法读取系统环境变量 Path,请确保以管理员权限运行!", 16, "权限不足"
Log "无法读取系统环境变量 Path,脚本终止"
logfile.Close
WScript.Quit
End If
On Error GoTo 0
If InStr(1, LCase(pathEnv), LCase("C:\Program Files\WinRAR"), vbTextCompare) > 0 Then
pathAlreadySet = True
Log "WinRAR 路径已存在于 Path,无需添加"
Else
If Right(pathEnv, 1) <> ";" Then
newPath = pathEnv & ";C:\Program Files\WinRAR"
Else
newPath = pathEnv & "C:\Program Files\WinRAR"
End If
On Error Resume Next
ws.RegWrite envTarget, newPath, "REG_EXPAND_SZ"
If Err.Number = 0 Then
Log "已将 WinRAR 路径加入系统环境变量 Path"
Else
Log "写入 Path 环境变量失败,请手动添加"
MsgBox "写入 Path 环境变量失败,请手动添加:C:\Program Files\WinRAR", 16, "写入失败"
logfile.Close
WScript.Quit
End If
On Error GoTo 0
End If
'---3. 设置执行策略---
Dim cmd, exec
cmd = "powershell -NoProfile -Command ""Set-ExecutionPolicy RemoteSigned -Scope CurrentUser -Force"""
Set exec = ws.Exec(cmd)
Do While exec.Status = 0
WScript.Sleep 200
Loop
Log "已设置执行策略 RemoteSigned"
'---4. 复制四个文件到System32,来源于setup.vbs当前目录的system32子目录---
Dim filelist, file, src, dst, srcDir
srcDir = scriptPath & "\system32"
filelist = Array("CompressCur.ps1", "DecompressCur.ps1", "jieyasuo.bat", "yasuo.bat")
For Each file In filelist
src = srcDir & "\" & file
dst = sys32 & "\" & file
If Not fso.FileExists(src) Then
MsgBox "缺少文件:" & src & vbCrLf & "请确保system32子文件夹中包含全部脚本!", 16, "缺少文件"
Log "缺少文件:" & src
logfile.Close
WScript.Quit
End If
fso.CopyFile src, dst, True
Log "已复制:" & src & " 到 " & dst
Next
'---5. 导入注册表文件,文件名为“右键注册表.reg”---
regfile = scriptPath & "\右键注册表.reg"
If Not fso.FileExists(regfile) Then
MsgBox "缺少注册表文件:右键注册表.reg" & vbCrLf & "请放在setup.vbs同一目录下!", 16, "缺少文件"
Log "缺少注册表文件"
logfile.Close
WScript.Quit
End If
cmd = "reg import """ & regfile & """"
Set exec = ws.Exec(cmd)
Do While exec.Status = 0
WScript.Sleep 200
Loop
Log "已导入注册表:" & regfile
MsgBox "全部准备工作已自动完成!日志文件见:" & logPath, 64, "安装完成"
logfile.Close
全盘检索并压缩备份脚本:CompressALL.ps1
它负责校验处理的后缀名,检索全部本地分区(跳过网络映射分区),调用rar.exe压缩,文件名加上特殊的后缀以与正常压缩文件区分。随后检测压缩成功后删除原文件。全部过程写入日志文件,日志位于c:\logs。ps1脚本使用UTF-8带BOM编码,以取得最高的兼容性。
$suffixes = @('dwg','tif')
$forbidden = @(
'exe','dll','com','bat','cmd','msi','vbs','js','ps1','vbe','wsh','wsf','sh','inf',
'rar','zip','7z','tar','gz','cab',
'sys','drv','ocx','scr',
'ini','cfg','conf','reg',
'db','mdb','ldb','sqlite','sqlite3',
'tmp','bak','log','lnk',
'asp','aspx','php','jsp','html','htm'
)
$forbiddenMatch = $suffixes | Where-Object { $forbidden -contains $_.ToLower() }
if ($forbiddenMatch) {
Write-Host "后缀配置包含敏感/高危后缀:$($forbiddenMatch -join ', '),程序终止执行。" -ForegroundColor Red
exit 2
}
$drives = Get-PSDrive -PSProvider FileSystem | Where-Object { $_.DisplayRoot -notlike '\\*' }
$logDir = "C:\logs"
if (-not (Test-Path $logDir)) {
New-Item -Path $logDir -ItemType Directory | Out-Null
}
$timestamp = Get-Date -Format "yyyyMMdd_HHmmss"
$log = Join-Path $logDir "CompressALL_$timestamp.log"
foreach ($drive in $drives) {
Write-Host "正在扫描分区: $($drive.Root)" -ForegroundColor Yellow
Get-ChildItem -Path $drive.Root -Recurse -File -ErrorAction SilentlyContinue | Where-Object {
$ext = $_.Extension.TrimStart('.').ToLower()
$suffixes -contains $ext
} | ForEach-Object {
$file = $_
$suffix = $file.Extension.TrimStart('.').ToLower()
$rarName = "$($file.DirectoryName)\$($file.BaseName)-Compressed-$suffix-ByScript.rar"
Write-Host "正在压缩: $($file.FullName)" -ForegroundColor Cyan
$winrar = "C:\Program Files\WinRAR\rar.exe"
$res = & $winrar a -ep1 "$rarName" "$($file.FullName)" | Out-Null
if ((Test-Path -LiteralPath $rarName) -and ((Get-Item -LiteralPath $rarName).Length -gt 0)) {
Remove-Item -LiteralPath $file.FullName -Force
$msg = "$(Get-Date) 成功压缩并删除: $($file.FullName) -> $rarName"
Write-Host $msg -ForegroundColor Green
Add-Content -Path $log -Value $msg
} else {
$msg = "$(Get-Date) 压缩失败: $($file.FullName)"
Write-Host $msg -ForegroundColor Red
Add-Content -Path $log -Value $msg
}
}
}
Write-Host "全部压缩任务完成。日志文件位于:$log" -ForegroundColor Yellow
全盘检索并解压缩恢复脚本:DecompressAll.ps1
它负责检索全部本地分区的特殊压缩文件,调用rar.exe解压缩,检测解压缩成功后删除压缩包。全部过程写入日志文件,日志位于c:\logs。ps1脚本使用UTF-8带BOM编码,以取得最高的兼容性。
$suffixes = @('dwg', 'tif')
$forbidden = @(
'exe','dll','com','bat','cmd','msi','vbs','js','ps1','vbe','wsh','wsf','sh','inf',
'rar','zip','7z','tar','gz','cab',
'sys','drv','ocx','scr',
'ini','cfg','conf','reg',
'db','mdb','ldb','sqlite','sqlite3',
'tmp','bak','log','lnk',
'asp','aspx','php','jsp','html','htm'
)
$forbiddenMatch = $suffixes | Where-Object { $forbidden -contains $_.ToLower() }
if ($forbiddenMatch) {
Write-Host "后缀配置包含敏感/高危后缀:$($forbiddenMatch -join ', '),程序终止执行。" -ForegroundColor Red
exit 2
}
$drives = Get-PSDrive -PSProvider FileSystem | Where-Object { $_.DisplayRoot -notlike '\\*' }
$logDir = "C:\logs"
if (-not (Test-Path $logDir)) {
New-Item -Path $logDir -ItemType Directory | Out-Null
}
$timestamp = Get-Date -Format "yyyyMMdd_HHmmss"
$log = Join-Path $logDir "DecompressALL_$timestamp.log"
foreach ($drive in $drives) {
Write-Host "正在扫描分区: $($drive.Root)" -ForegroundColor Yellow
# 全量递归,不用任何筛选参数,防止漏查
Get-ChildItem -Path $drive.Root -Recurse -File -ErrorAction SilentlyContinue | Where-Object {
$file = $_.Name
foreach ($suffix in $suffixes) {
if ($file -like "*-Compressed-$suffix-ByScript.rar") { return $true }
}
return $false
} | ForEach-Object {
$file = $_
$suffix = $suffixes | Where-Object { $file.Name -like "*-Compressed-$_-ByScript.rar" }
if (-not $suffix) { return }
# 这里用BaseName更安全
$pattern = "-Compressed-$suffix-ByScript$"
$origBase = $file.BaseName -replace $pattern, ''
$origFile = Join-Path $file.DirectoryName "$origBase.$suffix"
Write-Host "正在解压: $($file.FullName)" -ForegroundColor Cyan
$winrar = "C:\Program Files\WinRAR\rar.exe"
$res = & $winrar x -o+ "$($file.FullName)" "$($file.DirectoryName)" | Out-Null
if ((Test-Path -LiteralPath $origFile) -and ((Get-Item -LiteralPath $origFile).Length -gt 0)) {
Remove-Item -LiteralPath $file.FullName -Force
$msg = "$(Get-Date) 解压成功并删除压缩包: $($file.FullName) -> $origFile"
Write-Host $msg -ForegroundColor Green
Add-Content -Path $log -Value $msg
} else {
$msg = "$(Get-Date) 解压失败: $($file.FullName)"
Write-Host $msg -ForegroundColor Red
Add-Content -Path $log -Value $msg
}
}
}
Write-Host "全部解压任务完成。日志文件位于:$log" -ForegroundColor Yellow
两个用于执行ps1脚本的bat
为了方便用户直接鼠标点击即可执行ps1,增加两个bat,分别用来执行上述两个ps1。注意,bat需要保存为ANSI格式。
1全盘压缩dwg和tif.bat
@echo off
setlocal enabledelayedexpansion
echo.
echo 即将开始用rar处理潜在的涉密文件。
pause
rem 当前目录下的 ps1
set "script_dir=%~dp0"
set "ps1_path=%script_dir%CompressAll.ps1"
rem 以管理员启动 PowerShell ;-NoExit 保持窗口, -Wait 让 bat 等待
powershell -NoProfile -ExecutionPolicy Bypass -Command ^
"Start-Process powershell -Verb RunAs -Wait -ArgumentList '-NoProfile','-ExecutionPolicy','Bypass','-NoExit','-File','\"%ps1_path%\"'"
endlocal
2全盘解压缩dwg和tif.bat,内容基本相同,只需要修改一下ps1的文件名称即可。
单个文件夹处理的ps1脚本
首先是CompressCur.ps1,用于压缩。接受一个参数,用来传递“当前工作目录”。
param(
[string]$targetDir = (Get-Location).Path
)
if (-not (Test-Path $targetDir)) {
Write-Host "目录不存在:$targetDir" -ForegroundColor Red
exit 1
}
# 检查是否为网络映射分区
$driveLetter = $targetDir.Substring(0,2)
$isNet = Get-PSDrive -PSProvider FileSystem | Where-Object { $_.Name + ':' -eq $driveLetter -and $_.DisplayRoot -like '\\*' }
if ($isNet) {
Write-Host "当前目录是网络映射盘,终止执行。" -ForegroundColor Yellow
exit 0
}
$suffixes = @('dwg','tif')
$forbidden = @(
'exe','dll','com','bat','cmd','msi','vbs','js','ps1','vbe','wsh','wsf','sh','inf',
'rar','zip','7z','tar','gz','cab',
'sys','drv','ocx','scr',
'ini','cfg','conf','reg',
'db','mdb','ldb','sqlite','sqlite3',
'tmp','bak','log','lnk',
'asp','aspx','php','jsp','html','htm'
)
$forbiddenMatch = $suffixes | Where-Object { $forbidden -contains $_.ToLower() }
if ($forbiddenMatch) {
Write-Host "后缀配置包含敏感/高危后缀:$($forbiddenMatch -join ', '),程序终止执行。" -ForegroundColor Red
exit 2
}
$logDir = "C:\logs"
if (-not (Test-Path $logDir)) {
New-Item -Path $logDir -ItemType Directory | Out-Null
}
$timestamp = Get-Date -Format "yyyyMMdd_HHmmss"
$log = Join-Path $logDir "CompressCur_$timestamp.log"
Write-Host "正在扫描当前目录及子目录: $targetDir" -ForegroundColor Yellow
Get-ChildItem -Path $targetDir -Recurse -File -ErrorAction SilentlyContinue | Where-Object {
$ext = $_.Extension.TrimStart('.').ToLower()
$suffixes -contains $ext
} | ForEach-Object {
$file = $_
$suffix = $file.Extension.TrimStart('.').ToLower()
$rarName = "$($file.DirectoryName)\$($file.BaseName)-Compressed-$suffix-ByScript.rar"
Write-Host "正在压缩: $($file.FullName)" -ForegroundColor Cyan
$winrar = "C:\Program Files\WinRAR\rar.exe"
$res = & $winrar a -ep1 "$rarName" "$($file.FullName)" | Out-Null
if ((Test-Path -LiteralPath $rarName) -and ((Get-Item -LiteralPath $rarName).Length -gt 0)) {
Remove-Item -LiteralPath $file.FullName -Force
$msg = "$(Get-Date) 成功压缩并删除: $($file.FullName) -> $rarName"
Write-Host $msg -ForegroundColor Green
Add-Content -Path $log -Value $msg
} else {
$msg = "$(Get-Date) 压缩失败: $($file.FullName)"
Write-Host $msg -ForegroundColor Red
Add-Content -Path $log -Value $msg
}
}
Write-Host "全部压缩任务完成。日志文件位于:$log" -ForegroundColor Yellow
然后是DecompressCur.ps1,用来解压缩,同样接受一个参数,用来传递“当前工作目录”。
param(
[string]$targetDir = (Get-Location).Path
)
if (-not (Test-Path $targetDir)) {
Write-Host "目录不存在:$targetDir" -ForegroundColor Red
exit 1
}
# 检查是否为网络映射分区
$driveLetter = $targetDir.Substring(0,2)
$isNet = Get-PSDrive -PSProvider FileSystem | Where-Object { $_.Name + ':' -eq $driveLetter -and $_.DisplayRoot -like '\\*' }
if ($isNet) {
Write-Host "当前目录是网络映射盘,终止执行。" -ForegroundColor Yellow
exit 0
}
$suffixes = @('dwg','tif')
$forbidden = @(
'exe','dll','com','bat','cmd','msi','vbs','js','ps1','vbe','wsh','wsf','sh','inf',
'rar','zip','7z','tar','gz','cab',
'sys','drv','ocx','scr',
'ini','cfg','conf','reg',
'db','mdb','ldb','sqlite','sqlite3',
'tmp','bak','log','lnk',
'asp','aspx','php','jsp','html','htm'
)
$forbiddenMatch = $suffixes | Where-Object { $forbidden -contains $_.ToLower() }
if ($forbiddenMatch) {
Write-Host "后缀配置包含敏感/高危后缀:$($forbiddenMatch -join ', '),程序终止执行。" -ForegroundColor Red
exit 2
}
$logDir = "C:\logs"
if (-not (Test-Path $logDir)) {
New-Item -Path $logDir -ItemType Directory | Out-Null
}
$timestamp = Get-Date -Format "yyyyMMdd_HHmmss"
$log = Join-Path $logDir "DecompressCur_$timestamp.log"
Write-Host "正在扫描当前目录及子目录: $targetDir" -ForegroundColor Yellow
Get-ChildItem -Path $targetDir -Recurse -File -ErrorAction SilentlyContinue | Where-Object {
$file = $_.BaseName
foreach ($suffix in $suffixes) {
if ($file -like "*-Compressed-$suffix-ByScript") { return $true }
}
return $false
} | ForEach-Object {
$file = $_
$suffix = $suffixes | Where-Object { $file.BaseName -like "*-Compressed-$_-ByScript" }
if (-not $suffix) { return }
$pattern = "-Compressed-$suffix-ByScript$"
$origBase = $file.BaseName -replace $pattern, ''
$origFile = Join-Path $file.DirectoryName "$origBase.$suffix"
Write-Host "正在解压: $($file.FullName)" -ForegroundColor Cyan
$winrar = "C:\Program Files\WinRAR\rar.exe"
$res = & $winrar x -o+ "$($file.FullName)" "$($file.DirectoryName)" | Out-Null
if ((Test-Path -LiteralPath $origFile) -and ((Get-Item -LiteralPath $origFile).Length -gt 0)) {
Remove-Item -LiteralPath $file.FullName -Force
$msg = "$(Get-Date) 解压成功并删除压缩包: $($file.FullName) -> $origFile"
Write-Host $msg -ForegroundColor Green
Add-Content -Path $log -Value $msg
} else {
$msg = "$(Get-Date) 解压失败: $($file.FullName)"
Write-Host $msg -ForegroundColor Red
Add-Content -Path $log -Value $msg
}
}
Write-Host "全部解压任务完成。日志文件位于:$log" -ForegroundColor Yellow
单个文件夹处理的bat脚本
将上述两个ps1拷贝到system32文件夹后,右键已经可以执行它们了。但为了满足更灵活的使用场景,再追加两个bat文件。
yasuo.bat,顾名思义,“压缩”的拼音。它也接受一个参数,也可以不设参数。不设参数时,target即为当前文件夹。
@echo off
if "%~1"=="" (
set "target=%cd%"
) else (
set "target=%~1"
)
powershell -NoProfile -ExecutionPolicy Bypass -File "c:\windows\system32\CompressCur.ps1" "%target%"
jieyasuo.bat,负责执行解压缩ps1。
@echo off
if "%~1"=="" (
set "target=%cd%"
) else (
set "target=%~1"
)
powershell -NoProfile -ExecutionPolicy Bypass -File "c:\windows\system32\DecompressCur.ps1" "%target%"
上述4个文件复制到c:\windows\system32,以便在命令行的任意当前目录下直接执行bat,或右键点击文件夹执行对应的ps1脚本。
右键注册表.reg
编辑“右键注册表.reg”,注意使用ANSI编码。在添加两个右键菜单的同时,设置好对应的图标,就用winrar.exe中的现成图标。内容如下:
Windows Registry Editor Version 5.00
[HKEY_CLASSES_ROOT\Directory\shell\CompressSecure]
@="压缩潜在涉密文件"
"Icon"="C:\\program files\\winrar\\winrar.exe,4"
[HKEY_CLASSES_ROOT\Directory\shell\CompressSecure\command]
@="powershell -NoExit -NoProfile -WindowStyle Normal -ExecutionPolicy Bypass -File \"c:\\windows\\system32\\CompressCur.ps1\" \"%1\""
[HKEY_CLASSES_ROOT\Directory\shell\DecompressSecure]
@="恢复潜在涉密文件"
"Icon"="C:\\program files\\winrar\\winrar.exe,5"
[HKEY_CLASSES_ROOT\Directory\shell\DecompressSecure\command]
@="powershell -NoExit -NoProfile -WindowStyle Normal -ExecutionPolicy Bypass -File \"c:\\windows\\system32\\DecompressCur.ps1\" \"%1\""
文件准备
假设保存所有相关脚本的文件夹是c:\tools。
为了清爽起见,将以下4个文件放到c:\tools\system32子目录,防止误操作(因为它们不是用来直接双击执行的)。
CompressCur.ps1
DecompressCur.ps1
jieyasuo.bat
yasuo.bat
setup.vbs中已经注明了它们的位置,在执行setup.vbs的时候会自动将它们copy到c:\windows\system32。
使用方法
相关工具下载:点击下载
具体使用方法详见压缩包中的“使用说明.txt”。