Powershell 5. 最小化内存时间的SecureString解密
Powershell 5. SecureString decryption that minimizes time in memory
我有一个使用 openssl.exe 查看私钥文件的脚本。然而,这个问题与对外部程序的任何调用有关。
通过 read-host -asSecureString 请求密码。
无法将 secureString 类型传递给 openssl.exe 命令。我需要将它解密为纯字符串,然后将该字符串传递给 openssl.exe
是否可以最大限度地减少字符串在内存中为纯文本的时间?
请注意,我们使用的是 Powershell 5。PS 7 个功能对我们不可用。
我看到的两种方法:
#Decrypt the secureString to a variable.
#Create and remove that variable as soon as possible.
$securePass = Read-Host("Please enter a password") -asSecureString
$plainPass = [Net.NetworkCredential]::new('',$securePass).password
#Note there are many ways to perform the above step. If the 'Marshal method' is better, let me know.
./openssl.exe rsa -in user.key -passin pass:$plainpass
Remove-Variable $plainPass
#Decrypt the SecureString in the call to openssl.
#Hope Powershell's garbage collection removes the String object as soon as the command is issued.
$securePass = Read-Host("Please enter a password") -asSecureString
./openssl.exe rsa -in user.key -passin pass:$([Net.NetworkCredential]::new('',$securePass).password)
- 这些方法中的一种比另一种好吗?
- 考虑到脚本非常快,而且字符串永远不会写入文件,使用 secureString 是否也是一个问题?
- 无论它存在的时间有多短,我是否会通过使用字符串来破坏安全最佳实践?
既然你一直在提示,为什么不直接使用 Get-Credential 而不是 Read-Host?
$Creds = Get-Credential -Credential "$env:USERDOMAIN$env:USERNAME"
$Creds.UserName
$Creds.Password
$Creds.GetNetworkCredential().Password
# Results
<#
lab01\postanote
System.Security.SecureString
!SomeSuperSecretPassword1
#>
微软的做法:Working with Passwords, Secure Strings, and Credentials in Windows PowerShell
你应该经常清理自己。不要等系统来做。
这是我在 classes/workshops/engagements 我提供给其他人的建议方法。
# Collect all automatic and default loaded resources, put this at the top of your script
$AutomaticVariables = Get-Variable
$AutomaticAndProfileLoadedVModules = Get-Module
$AutomaticLoadedFunctions = Get-Command -CommandType Function
# Run this as the last items in your script
Function Clear-ResourceEnvironment
{
[CmdletBinding(SupportsShouldProcess)]
[Alias('cre')]
Param
(
[switch]$AdminCredStore
)
# Clear instantiate reasource interop
$null = [System.Runtime.InteropServices.Marshal]::
ReleaseComObject([System.__ComObject]$Shell)
# instantiate .Net garbage collection
[System.GC]::Collect()
[System.GC]::WaitForPendingFinalizers()
# Clear all PSSessions
Get-PSSession |
Remove-PSSession -ErrorAction SilentlyContinue
# Clear static credential store, if switch is used
If ($AdminCredStore)
{Remove-Item -Path "$env:USERPROFILE\Documents\AdminCredSet.xml" -Force}
Else
{
Write-Warning -Message "
`n`t`tYou decided not to delete the custom Admin credential store.
This store is only valid for this host and and user $env:USERNAME"
}
Write-Warning -Message "
`n`t`tRemoving the displayed session specific variable and module objects"
# Clear only variables created / used during the session
Compare-Object -ReferenceObject (Get-Variable) -DifferenceObject $AutomaticVariables -Property Name -PassThru |
Where -Property Name -ne 'AutomaticVariables' |
Remove-Variable -Verbose -Force -Scope 'global' -ErrorAction SilentlyContinue
Remove-Variable -Name AdminCredStore -Verbose -Force
# Clear only modules loaded during the session
Compare-Object -ReferenceObject (Get-Module) -DifferenceObject $AutomaticAndProfileLoadedVModules -Property Name -PassThru |
Where -Property Name -ne 'AutomaticAndProfileLoadedVModules' |
Remove-Module -Force -ErrorAction SilentlyContinue
# Clear only functions loaded during the session
Compare-Object -ReferenceObject (Get-Command -CommandType Function) -DifferenceObject $AutomaticLoadedFunctions -Property Name -PassThru |
Where -Property Name -ne 'AutomaticLoadedFunctions' |
Remove-Item -Force -ErrorAction SilentlyContinue
}
注意事项:
当你使用解密到纯文本的那一刻,如果有人能嗅出你在做什么,那就是一个问题了。因此,这句格言,保护通道,保护数据,或两者都适用。
此外,如果有任何真实的日志记录(SEIM 工具、PowerShell 审计、抄本),无论您如何从 RAM 中清除它,它都会在日志中供所有人查看,除非您记得清除它条目。
我有一个使用 openssl.exe 查看私钥文件的脚本。然而,这个问题与对外部程序的任何调用有关。
通过 read-host -asSecureString 请求密码。
无法将 secureString 类型传递给 openssl.exe 命令。我需要将它解密为纯字符串,然后将该字符串传递给 openssl.exe
是否可以最大限度地减少字符串在内存中为纯文本的时间? 请注意,我们使用的是 Powershell 5。PS 7 个功能对我们不可用。
我看到的两种方法:
#Decrypt the secureString to a variable.
#Create and remove that variable as soon as possible.
$securePass = Read-Host("Please enter a password") -asSecureString
$plainPass = [Net.NetworkCredential]::new('',$securePass).password
#Note there are many ways to perform the above step. If the 'Marshal method' is better, let me know.
./openssl.exe rsa -in user.key -passin pass:$plainpass
Remove-Variable $plainPass
#Decrypt the SecureString in the call to openssl.
#Hope Powershell's garbage collection removes the String object as soon as the command is issued.
$securePass = Read-Host("Please enter a password") -asSecureString
./openssl.exe rsa -in user.key -passin pass:$([Net.NetworkCredential]::new('',$securePass).password)
- 这些方法中的一种比另一种好吗?
- 考虑到脚本非常快,而且字符串永远不会写入文件,使用 secureString 是否也是一个问题?
- 无论它存在的时间有多短,我是否会通过使用字符串来破坏安全最佳实践?
既然你一直在提示,为什么不直接使用 Get-Credential 而不是 Read-Host?
$Creds = Get-Credential -Credential "$env:USERDOMAIN$env:USERNAME"
$Creds.UserName
$Creds.Password
$Creds.GetNetworkCredential().Password
# Results
<#
lab01\postanote
System.Security.SecureString
!SomeSuperSecretPassword1
#>
微软的做法:Working with Passwords, Secure Strings, and Credentials in Windows PowerShell
你应该经常清理自己。不要等系统来做。
这是我在 classes/workshops/engagements 我提供给其他人的建议方法。
# Collect all automatic and default loaded resources, put this at the top of your script
$AutomaticVariables = Get-Variable
$AutomaticAndProfileLoadedVModules = Get-Module
$AutomaticLoadedFunctions = Get-Command -CommandType Function
# Run this as the last items in your script
Function Clear-ResourceEnvironment
{
[CmdletBinding(SupportsShouldProcess)]
[Alias('cre')]
Param
(
[switch]$AdminCredStore
)
# Clear instantiate reasource interop
$null = [System.Runtime.InteropServices.Marshal]::
ReleaseComObject([System.__ComObject]$Shell)
# instantiate .Net garbage collection
[System.GC]::Collect()
[System.GC]::WaitForPendingFinalizers()
# Clear all PSSessions
Get-PSSession |
Remove-PSSession -ErrorAction SilentlyContinue
# Clear static credential store, if switch is used
If ($AdminCredStore)
{Remove-Item -Path "$env:USERPROFILE\Documents\AdminCredSet.xml" -Force}
Else
{
Write-Warning -Message "
`n`t`tYou decided not to delete the custom Admin credential store.
This store is only valid for this host and and user $env:USERNAME"
}
Write-Warning -Message "
`n`t`tRemoving the displayed session specific variable and module objects"
# Clear only variables created / used during the session
Compare-Object -ReferenceObject (Get-Variable) -DifferenceObject $AutomaticVariables -Property Name -PassThru |
Where -Property Name -ne 'AutomaticVariables' |
Remove-Variable -Verbose -Force -Scope 'global' -ErrorAction SilentlyContinue
Remove-Variable -Name AdminCredStore -Verbose -Force
# Clear only modules loaded during the session
Compare-Object -ReferenceObject (Get-Module) -DifferenceObject $AutomaticAndProfileLoadedVModules -Property Name -PassThru |
Where -Property Name -ne 'AutomaticAndProfileLoadedVModules' |
Remove-Module -Force -ErrorAction SilentlyContinue
# Clear only functions loaded during the session
Compare-Object -ReferenceObject (Get-Command -CommandType Function) -DifferenceObject $AutomaticLoadedFunctions -Property Name -PassThru |
Where -Property Name -ne 'AutomaticLoadedFunctions' |
Remove-Item -Force -ErrorAction SilentlyContinue
}
注意事项:
当你使用解密到纯文本的那一刻,如果有人能嗅出你在做什么,那就是一个问题了。因此,这句格言,保护通道,保护数据,或两者都适用。
此外,如果有任何真实的日志记录(SEIM 工具、PowerShell 审计、抄本),无论您如何从 RAM 中清除它,它都会在日志中供所有人查看,除非您记得清除它条目。