gpt4 book ai didi

PowerShell 安全扩展任意字符串中的非打印字符

转载 作者:行者123 更新时间:2023-12-04 14:05:56 25 4
gpt4 key购买 nike

我在 XML 文件中有数据,最终将用作注册表路径,其中可能包含非打印字符(例如,将路径从网站复制到 XML 时)。我想验证数据并在发现非打印字符时抛出特定错误。

在 Powershell 中,如果我用单引号中的非打印字符定义一个变量,然后 test-Path 它测试作为有效路径,因为非打印字符被作为文字处理。

Test-Path 'HKEY_LOCAL_MACHINE\SOFTWARE\Test\`n@microsoft.com/GENUINE\@microsoft.com/GENUINE' -isValid

同样的东西用双引号会“展开”非打印字符并返回false,这正是我需要的。

Test-Path "HKEY_LOCAL_MACHINE\SOFTWARE\Test\`n@microsoft.com/GENUINE\@microsoft.com/GENUINE" -isValid

我发现对 [string]::Format(() 的引用被用来扩展非打印字符,但是

$invalidPath = 'HKEY_LOCAL_MACHINE\SOFTWARE\Test\`n@microsoft.com/GENUINE\@microsoft.com/GENUINE'
[string]::Format("{0}",$invalidPath)

没有按预期扩展非打印字符。我还看到了使用 Invoke-Expression 的引用资料,但这不安全,也不是一个选项。

最后我找到了$ExecutionContext.InvokeCommand.ExpandString(),这似乎可行,

$ExecutionContext.InvokeCommand.ExpandString('HKEY_LOCAL_MACHINE\SOFTWARE\Test\`n@microsoft.com/GENUINE\@microsoft.com/GENUINE')

向控制台返回一个多行字符串,而$ExecutionContext.InvokeCommand.ExpandString('Write-Host "Screwed"') 将实际字符串返回到控制台,而不是实际执行 Write-Host 并且只返回 到控制台。

最后,

$invalidPath = 'HKEY_LOCAL_MACHINE\SOFTWARE\Test\`n@microsoft.com/GENUINE\@microsoft.com/GENUINE'
Test-Path ($ExecutionContext.InvokeCommand.ExpandString($invalidPath)) -isValid

按预期返回 false。这让我认为这是追求的正确方法,但考虑到其他地方的所有陷阱,我想 100% 确定没有办法将这种方法用作安全弱点。我走在正确的轨道上了吗?还是我的 Google-Fu 还没有出现?

最佳答案

Invoke-Expression , $ExecutionContext.InvokeCommand.ExpandString() 容易受到不需要的命令的注入(inject),除了在后一种情况下,此类命令只有包含在 $(...) 中才能识别>, subexpression operator ,因为这是在 expandable strings 中嵌入命令的唯一方法(方法的参数被解释为)。

例如:

$ExecutionContext.InvokeCommand.ExpandString('a $(Write-Host -Fore Red Injected!) b')

防止这种情况的一个简单方法是明确对待所有嵌入的 $ 字符。 逐字,通过使用 ` 转义它们:

'a $(Write-Host -Fore Red Injected!) b',
'There''s no place like $HOME',
'Too `$(Get-Date) clever by half' |
ForEach-Object {
$ExecutionContext.InvokeCommand.ExpandString(($_ -replace '(`*)\$', '$1$1`$$'))
}

注意:在输入字符串中verbatim $ 转义就足够了。 $(或 (/))(`u{24}(或`u{28}/`u{29}),仅受 PowerShell (Core) v6+ 支持, 一个问题,因为 PowerShell 逐字处理生成的字符。


当然,如果存在命令(或变量值)注入(inject)的风险,您可以选择报告错误,这可以很简单:

$path = 'There''s no place like $HOME'

if ($path -match '\$') { Throw 'Unsupported characters in path.' }

但是,这也会阻止在路径中合法使用逐字的 $


退一步:

您声明路径可能是从网站复制粘贴的。这样粘贴的字符串可能确实包含(可能是隐藏的)控制字符,但它们将被包含逐字而不是PowerShell_escape 序列

因此,测试/安静地从字符串的文字内容中删除控制字符可能就足够了(在调用 Test-Path -IsValid 之前):

# Test for control characters.
if ($path -match '\p{C}') { throw 'Path contains control characters.' }

# Quietly remove them.
$sanitizedPath = $path -replace '\p{C}'

关于PowerShell 安全扩展任意字符串中的非打印字符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68508218/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com