2

假设所有基于脚本的语言(例如 VBscript 和 Powershell)每次都将整个代码“嵌入”在客户机器上,我是否应该假设该代码是“开放的”?我的意思是,有一些方法可以保护基于脚本的代码阅读(并因此写作)?

4

4 回答 4

5

有一些工具可以将 VBScript 转换为可执行文件,例如vbs2exevbseditscriptcryptor。通过 PowerShell 创建可执行文件也可以通过自己在 .net使用 PowerGUI Props2exe 来完成

使用这些工具,您可以使您的脚本“关闭”。与(几乎)所有客户端站点代码一样,它仍然可能被黑客入侵,但这需要更多的工具和知识,而不仅仅是在记事本中打开 vbs 文件并查看脚本。

于 2012-05-29T06:05:07.000 回答
3

我不相信有任何完整的证明方法,混淆和最小化是试图保护代码的方法(并且在最小化的情况下减少存储/传输大小)但最终有足够时间的人可以进行逆向工程或观看通过调试/反汇编工具执行程序。我认为你是最安全的假设客户端机器上的任何东西都可以被玩弄,并且保护代码或信息的最佳选择是将其存储/执行在具有适当安全性的服务器上,并不断更新安全漏洞补丁。

于 2012-05-28T17:56:41.937 回答
0

是的!您可以为此使用我的模板。并且不要忘记将密码从“qweasd”更改为其他密码!

    函数全局:解密字符串 {
        参数($Encrypted,$Passphrase,$salt,$init)

        if ($Encrypted -is [字符串]) {
            $Encrypted = [转换]::FromBase64String($Encrypted)
        }

        $r = 新对象 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 = 新对象 IO.MemoryStream @(,$Encrypted)
        $cs = 新对象 Security.Cryptography.CryptoStream $ms,$d,"Read"
        $sr = 新对象 IO.StreamReader $cs
        写输出 $sr.ReadToEnd()
        $sr.Close()
        $cs.Close()
        $ms.Close()
        $r.清除()
    }

    函数全局:运行解密([字符串]$加密){
        $private:pass = Read-Host "输入密码以解码脚本代码" -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")
        返回$块
    }

    函数全局:保存解密([字符串]$加密){
        尝试 {
            $answer = Read-Host "保存解码后的脚本版本?(y/n)"
            开关($答案){
                是{}
                N {返回}
                默认 {return}
            }
            $decrypted = 运行解密 $encrypted
            $p = (Read-Host "输入新文件的路径")
            if (-Not (Is-ValidPath $p)) { return }
            if ($host.version -ne "2.0") {
                $offset = $global:secure.StartPosition.Start + 1
            } 别的 {
                $offset = $global:secure.StartPosition.Start
            }
            (Get-Content $global:secure.File | Out-String).Remove($offset,$global:secure.ToString().Length).Insert($offset, $decrypted) | 输出文件 -FilePath $p -NoClobber
            ' Write-Host '解码文件成功保存。'
        } 抓住 {
            Write-Host '保存文件时出错。'
            写主机 $error[0]  
        }
    }

    函数全局:Is-ValidPath([string]$path) {
        if ($path -eq '') {
            Write-Host '没有路径。创建文件失败。'; 返回 $false
        } elseif (-not (Test-Path (Split-Path $path -Parent))) {
            Write-Host '路径不存在。创建文件失败。'; 返回 $false
        } elseif (测试路径 $path) {
            Write-Host '文件已经存在。创建文件失败。'; 返回 $false
        }
        返回 $true;
    }

    $全球:安全= {
        函数全局:加密字符串 {
            参数($String,$Passphrase,$salt,$init,[switch]$arrayOutput)

            $r = 新对象 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 = 新对象 IO.MemoryStream
            $cs = 新对象 Security.Cryptography.CryptoStream $ms,$c,"Write"
            $sw = 新对象 IO.StreamWriter $cs
            $sw.Write($String)
            $sw.Close()
            $cs.Close()
            $ms.Close()
            $r.清除()
            [字节[]]$result = $ms.ToArray()
            if ($arrayOutput) {
                返回$结果
            } 别的 {
                返回 [转换]::ToBase64String($result)
            }
        }

        函数全局:保存加密(){
            $answer = Read-Host "`n保存此脚本的编码版本?(y/n)"
            开关($答案){
                是{}
                N {返回}
               默认 {return}
            }
            尝试 {
                $path = (Read-Host "输入编码文件的路径").Trim("`"'")
                if (-Not (Is-ValidPath $path)) {return}
                运行加密 | 输出文件 -FilePath $path -NoClobber
                ' Write-Host '编码文件已成功保存。'
            } 抓住 {
                Write-Host '保存文件时出错。'
                写主机 $error[0]
            }
        }

        函数全局:运行加密(){
            参数(
            $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
            } 别的 {
                $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 '$加密'")
            返回$块
        }

        #程序从这里开始

        写主机“Hello World!”

        #程序到此结束
    }

    尝试 {
        $null = $global:secure.GetSteppablePipeline() #dirty hack
        写警告“脚本编码!”
        尝试 {
            Invoke-Command -ScriptBlock ([Scriptblock]::Create((Run-Decrypt $global:secure.Invoke())))
        } 最后 {
            保存解密 $global:secure.Invoke()
        }
    } 抓住 {
        尝试 {
            调用命令 -ScriptBlock $global:secure
        } 最后 {
            找工作 | 移除作业强制
            保存加密
        }
    }

于 2019-12-12T20:06:53.827 回答
-2

我对可执行的方法并不满意,因为我发现复杂的脚本不容易编译(而且通常根本编译不了),而且最终很难使用。正如许多人所指出的,对于有决心的人来说,可执行文件不是障碍。我决定一个更好的方法是简单地使人类可读的脚本更难更改,然后简单地要求原始开发人员进行更改。

我编写了obfuscate-powershell来更改变量和函数名称、删除注释和更改空格,只是为了降低代码的可读性和可理解性。它仍然不安全,但总比什么都不做要好。

于 2014-07-07T15:31:18.777 回答