PowerShell防止脚本注入攻击分享
![](/skin/2018/images/text-message.png)
与其他编程语言一样,PowerShell 脚本容易受到注入攻击。 当用户向包含额外命令的易受攻击的函数提供输入时,会发生注入攻击。 易受攻击的函数运行额外的命令,这可能是严重的安全漏洞。 例如,恶意用户可能会滥用易受攻击的函数在远程计算机上运行任意代码,从而损害该计算机并获取对网络上其他计算机的访问权限。
了解问题后,可通过多种方式防范注入攻击。
易受攻击的代码示例
PowerShell 代码注入漏洞涉及包含脚本代码的用户输入。 用户输入添加到易受攻击的脚本中,由 PowerShell 分析和运行。
function Get-ProcessById { param ($ProcId) Invoke-Expression -Command "Get-Process -Id $ProcId" }
Get-ProcessById 函数按其 ID 值查找本地进程。 它采用任何类型的 $ProcId 参数。 然后将 $ProcId 转换为字符串,并插入到使用 Invoke-Expression cmdlet 分析和运行的另一个脚本中。 传入有效的进程 ID 整数时,此函数正常工作。
Get-ProcessById $pid NPM(K) PM(M) WS(M) CPU(s) Id SI ProcessName ------ ----- ----- ------ -- -- ----------- 97 50.09 132.72 1.20 12528 3 pwsh
但是,$ProcId 参数未指定类型。 它接受任何可以包含其他命令的任意字符串值。
Get-ProcessById "$pid; Write-Host 'pwnd!'"
在此示例中,函数正确检索了由 $pid 标识的进程,但也运行了注入脚本 Write-Host 'pwnd!'。
NPM(K) PM(M) WS(M) CPU(s) Id SI ProcessName ------ ----- ----- ------ -- -- ----------- 92 45.66 122.52 1.06 21736 3 pwsh pwnd!
防范注入攻击的方法
可通过多种方式防范注入攻击。
使用类型化输入
可以为 $ProcId 参数指定类型。
function Get-ProcessById { param ([int] $ProcId) Invoke-Expression -Command "Get-Process -Id $ProcId" } Get-ProcessById "$pid; Write-Host 'pwnd!'"
Get-ProcessById: Line | 7 | Get-ProcessById "$pid; Write-Host 'pwnd!'" | ~~~~~~~~~~~~~~~~~~~~~~~~~ | Cannot process argument transformation on parameter 'ProcId'. Cannot convert value "8064; Write-Host 'pwnd!'" to type "System.Int32". Error: "The input string '8064; Write-Host 'pwnd!' was not in a correct format."
此处,$ProcId 输入参数仅限于整数类型,因此,当传入不能转换为整数的字符串时,会发生错误。
不要使用 Invoke-Expression
无需使用 Invoke-Expression,直接调用 Get-Process,让 PowerShell 的参数绑定器验证输入。
function Get-ProcessById { param ($ProcId) Get-Process -Id $ProcId } Get-ProcessById "$pid; Write-Host 'pwnd!'"
Get-Process: Line | 5 | Get-Process -Id $ProcId | ~~~~~~~ | Cannot bind parameter 'Id'. Cannot convert value "8064; Write-Host 'pwnd!'" to type "System.Int32". Error: "The input string '8064; Write-Host 'pwnd!' was not in a correct format."
作为最佳做法,应避免使用 Invoke-Expression,尤其是在处理用户输入时。 Invoke-Expression 很危险,因为它会分析和运行你提供的任何字符串内容,使其容易受到注入攻击。 最好依赖于 PowerShell 参数绑定。
将字符串包含在单引号中
但是,有时使用 Invoke-Expression 是不可避免的,你还需要处理用户字符串输入。 可以使用每个字符串输入变量周围的单引号安全地处理用户输入。 单引号可确保 PowerShell 分析程序将用户输入视为单个字符串文本。
function Get-ProcessById { param ($ProcId) Invoke-Expression -Command "Get-Process -Id '$ProcId'" } Get-ProcessById "$pid; Write-Host 'pwnd!'"
Get-Process: Cannot bind parameter 'Id'. Cannot convert value "8064; Write-Host " to type "System.Int32". Error: "The input string '8064; Write-Host' was not in a correct format."
但是,此版本函数对于防范注入攻击还不是完全安全的。 恶意用户仍然可以在其输入中使用单引号来注入代码。
Get-ProcessById "$pid'; Write-Host 'pwnd!';'"
此示例在用户输入中使用单引号来强制函数运行三个单独的语句,其中一个语句是由用户注入的任意代码。
NPM(K) PM(M) WS(M) CPU(s) Id SI ProcessName ------ ----- ----- ------ -- -- ----------- 97 46.08 183.10 1.08 2524 3 pwsh pwnd!
使用 EscapeSingleQuotedStringContent() 方法
若要防止用户插入自己的单引号字符来利用函数,必须使用 EscapeSingleQuotedStringContent() API。 这是 PowerShell System.Management.Automation.Language.CodeGeneration 类的静态公共方法。 此方法通过转义用户输入中包含的任何单引号来确保用户输入的安全性。
function Get-ProcessById { param ($ProcId) $ProcIdClean = [System.Management.Automation.Language.CodeGeneration]:: EscapeSingleQuotedStringContent("$ProcId") Invoke-Expression -Command "Get-Process -Id '$ProcIdClean'" } Get-ProcessById "$pid'; Write-Host 'pwnd!';'"
Get-Process: Cannot bind parameter 'Id'. Cannot convert value "8064'; Write-Host 'pwnd!';'" to type "System.Int32". Error: "The input string '8064'; Write-Host 'pwnd!';'' was not in a correct format."
使用 Injection Hunter 检测易受攻击的代码
Injection Hunter 是 Lee Holmes 编写的模块,其中包含用于检测代码注入漏洞的 PowerShell 脚本分析器规则。 使用以下命令之一从 PowerShell 库安装模块:
# Use PowerShellGet v2.x Install-Module InjectionHunter # Use PowerShellGet v3.x Install-PSResource InjectionHunter
可以使用此模块在生成、持续集成过程、部署和其他方案中自动执行安全分析。
$RulePath = (Get-Module -list InjectionHunter).Path Invoke-ScriptAnalyzer -CustomRulePath $RulePath -Path .\Invoke-Dangerous.ps1
RuleName Severity ScriptName Line Message -------- -------- ---------- ---- ------- InjectionRisk.InvokeExpression Warning Invoke-Dan 3 Possible script injection risk via the gerous.ps1 Invoke-Expression cmdlet. Untrusted input can cause arbitrary PowerShell expressions to be run. Variables may be used directly for dynamic parameter arguments, splatting can be used for dynamic parameter names, and the invocation operator can be used for dynamic command names. If content escaping is truly needed, PowerShell has several valid quote characters, so [System.Management.Automation.Languag e.CodeGeneration]::Escape* should be used.
相关文章
- 本文来介绍一下thinkphp官方修复的一个getshell漏洞,框架对控制器没有进行足够的检测导致的一处getshell,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随2018-12-12
记 FineUI 官方论坛discuz所遭受的一次真实网络攻击
这篇文章主要介绍了记 FineUI 官方论坛discuz所遭受的一次真实网络攻击,需要的朋友可以参考下2018-11-30- 这篇文章主要介绍了Linux 下多种反弹 shell 方法,需要的朋友可以参考下2017-09-06
- 这篇文章主要为大家介绍了基于反射的XSS攻击,主要依靠站点服务端返回脚本,在客户端触发执行从而发起Web攻击,需要的朋友可以参考下2017-05-20
- 这篇文章主要介绍了SQL注入黑客防线网站实例分析,需要的朋友可以参考下2017-05-19
- 这里为大家分享一下sql注入的一些语句,很多情况下由于程序员的安全意识薄弱或基本功不足就容易导致sql注入安全问题,建议大家多看一下网上的安全文章,最好的防范就是先学2017-05-19
- 对于目前流行的sql注入,程序员在编写程序时,都普遍的加入防注入程序,有些防注入程序只要在我们提交一些非法的参数后,就会自动的记录下你的IP地址,提交的非法参数和动作等,2017-04-29
- 我们友情进行XSS检查,偶然跳出个小弹窗,其中我们总结了一些平时可能用到的XSS插入方式,方便我们以后进行快速检查,也提供了一定的思路,其中XSS有反射、存储、DOM这三类2016-12-27
- 这篇文章主要介绍了Python 爬虫使用动态切换ip防止封杀的相关资料,需要的朋友可以参考下2016-10-08
- 这篇文章主要介绍了使用爬虫采集网站时,解决被封IP的几种方法的相关资料,需要的朋友可以参考下2016-10-08
最新评论