假设所有基于脚本的语言(例如VBscript和Powershell)每次都在客户机器上“嵌入”整个代码,我应该假设这段代码是“开放的”吗?我的意思是,有一些方法可以保护基于脚本的代码以便阅读(并因此写入)?
答案 0 :(得分:5)
有些工具可以将VBScript转换为可执行文件,例如vbs2exe,vbsedit和scriptcryptor。 doing it yourself in .net,using PowerGUI Pro或ps2exe也可以通过PowerShell创建可执行文件。
使用这些工具,您可以使脚本“关闭”。与(几乎)所有客户端站点代码一样,它仍然可能被黑客入侵,但这需要更多的工具和知识,而不仅仅是在记事本中打开vbs文件并窥视脚本。
答案 1 :(得分:3)
我不相信有任何完整的证据方式,混淆和最小化是试图保护代码的方法(并且在最小化的情况下减少存储/传输大小)但最终有足够时间的人可以逆转通过调试/反汇编工具设计或观察程序的执行。我认为你最安全的假设客户端机器上的任何东西都可以被玩弄,并且保护代码或信息的最佳选择是将它存储/执行在具有适当安全性的服务器上,并且不断更新安全漏洞补丁。 / p>
答案 2 :(得分:0)
是的!您可以为此使用我的模板。并且不要忘记将密码从“ qweasd”更改为其他密码!
function global:Decrypt-String { param($Encrypted,$Passphrase,$salt,$init) if ($Encrypted -is [string]) { $Encrypted = [Convert]::FromBase64String($Encrypted) } $r = New-Object System.Security.Cryptography.RijndaelManaged $pass = [System.Text.Encoding]::UTF8.GetBytes($Passphrase) $salt = [System.Text.Encoding]::UTF8.GetBytes($salt) $r.Key = (New-Object Security.Cryptography.PasswordDeriveBytes $pass,$salt,"SHA256",5).GetBytes(256/8) $r.IV = (New-Object Security.Cryptography.SHA1Managed).ComputeHash([Text.Encoding]::UTF8.GetBytes($init))[0..15] $d = $r.CreateDecryptor() $ms = New-Object IO.MemoryStream @(,$Encrypted) $cs = New-Object Security.Cryptography.CryptoStream $ms,$d,"Read" $sr = New-Object IO.StreamReader $cs Write-Output $sr.ReadToEnd() $sr.Close() $cs.Close() $ms.Close() $r.Clear() } function global:Run-Decrypt ([string]$encrypted) { $private:pass = Read-Host "Enter password to decode script code" -AsSecureString $private:BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($private:pass) $private:UnsecurePassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($private:BSTR) $block = (global:Decrypt-String -Encrypted $encrypted -Passphrase $private:UnsecurePassword -salt "d35104f3-dcd0-4cd7-80bb-5e66388e6ede" -init "3982c1d2-04da-4883-9a46-4b860794084e") return $block } function global:Save-Decrypt ([string]$encrypted) { try { $answer = Read-Host "Save decoded script version? (y/n)" switch ($answer) { Y {} N {return} Default {return} } $decrypted = Run-Decrypt $encrypted $p = (Read-Host "Enter path for new file") if (-Not (Is-ValidPath $p)) { return } if ($host.version -ne "2.0") { $offset = $global:secure.StartPosition.Start + 1 } else { $offset = $global:secure.StartPosition.Start } (Get-Content $global:secure.File | Out-String).Remove($offset,$global:secure.ToString().Length).Insert($offset, $decrypted) | Out-File -FilePath $p -NoClobber Write-Host 'Decoded file successfully saved.' } catch { Write-Host 'Error while saving file.' Write-Host $error[0] } } function global:Is-ValidPath([string]$path) { if ($path -eq '') { Write-Host 'No path. Failed to create a file.'; return $false } elseif (-not (Test-Path (Split-Path $path -Parent))) { Write-Host 'Path does not exists. Failed to create a file.'; return $false } elseif (Test-Path $path) { Write-Host 'File already exists. Failed to create a file.'; return $false } return $true; } $global:secure = { function global:Encrypt-String { param($String,$Passphrase,$salt,$init,[switch]$arrayOutput) $r = New-Object System.Security.Cryptography.RijndaelManaged $pass = [Text.Encoding]::UTF8.GetBytes($Passphrase) $salt = [Text.Encoding]::UTF8.GetBytes($salt) $r.Key = (New-Object Security.Cryptography.PasswordDeriveBytes $pass,$salt,"SHA256",5).GetBytes(256/8) $r.IV = (New-Object Security.Cryptography.SHA1Managed).ComputeHash([Text.Encoding]::UTF8.GetBytes($init))[0..15] $c = $r.CreateEncryptor() $ms = New-Object IO.MemoryStream $cs = New-Object Security.Cryptography.CryptoStream $ms,$c,"Write" $sw = New-Object IO.StreamWriter $cs $sw.Write($String) $sw.Close() $cs.Close() $ms.Close() $r.Clear() [byte[]]$result = $ms.ToArray() if ($arrayOutput) { return $result } else { return [Convert]::ToBase64String($result) } } function global:Save-Encrypt () { $answer = Read-Host "`nSave encoded version of this script? (y/n)" switch ($answer) { Y {} N {return} Default {return} } try { $path = (Read-Host "Enter path for encoded file").Trim("`"'") if (-Not (Is-ValidPath $path)) {return} Run-Encrypt | Out-File -FilePath $path -NoClobber Write-Host 'Encoded file successfully saved.' } catch { Write-Host 'Error while saving file.' Write-Host $error[0] } } function global:Run-Encrypt () { param( $pass = "qweasd", $salt = "d35104f3-dcd0-4cd7-80bb-5e66388e6ede", $init = "3982c1d2-04da-4883-9a46-4b860794084e" ) $encrypted = global:Encrypt-String -String $global:secure -Passphrase $pass -salt $salt -init $init if ($host.version -ne "2.0") { $offset = $global:secure.StartPosition.Start + 1 } else { $offset = $global:secure.StartPosition.Start } $block = (Get-Content $global:secure.File | Out-String).Remove($offset, $global:secure.ToString().Length).Insert($offset, "New-Object -TypeName System.String '$encrypted'") return $block } #program starts here Write-Host "Hello World!" #program ends here } try { $null = $global:secure.GetSteppablePipeline() #dirty hack Write-Warning "Script encoded!" try { Invoke-Command -ScriptBlock ([Scriptblock]::Create((Run-Decrypt $global:secure.Invoke()))) } finally { Save-Decrypt $global:secure.Invoke() } } catch { try { Invoke-Command -ScriptBlock $global:secure } finally { Get-Job | Remove-Job -Force Save-Encrypt } }
答案 3 :(得分:-1)
我对可执行方法并不满意,因为我发现复杂的脚本不容易编译(通常根本不编译),最后也很难处理。正如许多人所指出的那样,对于坚定的人来说,可执行文件不是障碍。我决定一个更好的方法只是让人类可读的脚本更难以改变,然后只是要求原始开发人员进行更改。
我编写obfuscate-powershell来更改变量和函数名称,删除注释并更改空格只是为了使代码更易于阅读和理解。它仍然没有任何安全保障,但它总比什么都不做更好。