为什么在存储安全字符串时要这样做?
Why would one do this when storing a secure string?
这是否会以某种方式使其比仅将安全字符串存储在凭据中更安全?为什么有人会这样做?
$secVal = read-host -AsSecureString -prompt "Enter xstoreuser password"
$strVal = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($secVal)
$dasPassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($strVal)
之后
psftp -l somelogin -pw $dasPassword -P 22 -b .\ftp.txt somehost
您展示的技术不是关于使命令更多安全的技术-相反:
您需要做额外的工作来从 [securestring]
实例恢复纯文本密码,因为 为了将密码传递给 外部程序 比如 psftp.exe
你需要一个 insecure plain-text 表示,因为外部程序对 .NET 安全字符串一无所知.
How secure is SecureString? 介绍 .NET 安全字符串及其一般限制。
顺便说一句:提取明文密码的命令可以通过 aux.h 来简化一点。 [pscredential]
实例:
# Returns the plain-text content of secure string $secVal:
(New-Object pscredential somelogin, $secVal).GetNetworkCredential().Password
唯一安全的方法是完全避免纯文本密码并且使用PKI如果目标程序支持,方法(基于public和私钥)。
证明纯文本方法不安全(即使不使用用于存储未加密密码的中间变量):
# Create a [pscredential] instance with a secure-string password:
# Note: To make this demo self-contained, I'm converting *from* plain
# text in order to construct the credential object.
# Note that you should never do that in production code.
# The need to specify -Force to do it is a reminder that it
# normally shouldn't be done.
$cred = New-Object pscredential someuser,
(ConvertTo-SecureString -AsPlainText -Force 'actualPassword')
# Open a new hidden window that passes the password *as plain text* to
# `cmd /c echo` (and then waits for a keypress, to keep the process alive).
$ps = Start-Process -PassThru -WindowStyle Hidden cmd "/c echo $($cred.GetNetworkCredential().Password) & pause"
# Now inspect the process' command line using CIM (WMI):
(Get-CimInstance Win32_Process -Filter "ProcessID = $($ps.ID)").CommandLine
# Kill (stop) the sample process.
$ps | Stop-Process
以上结果"C:\WINDOWS\system32\cmd.exe" /c echo actualPassword & pause
,说明明文密码确实可以被其他进程获取
您还可以使用 GUI 方法 检查 运行 进程的命令行:任务管理器(Taskmgr.exe
) 或者,在没有潜在截断的情况下,SysInternals' Process Explorer (procexp.exe
), which, however, must be installed on demand - see this ServerFault answer.
这是否会以某种方式使其比仅将安全字符串存储在凭据中更安全?为什么有人会这样做?
$secVal = read-host -AsSecureString -prompt "Enter xstoreuser password"
$strVal = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($secVal)
$dasPassword = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($strVal)
之后
psftp -l somelogin -pw $dasPassword -P 22 -b .\ftp.txt somehost
您展示的技术不是关于使命令更多安全的技术-相反:
您需要做额外的工作来从 [securestring]
实例恢复纯文本密码,因为 为了将密码传递给 外部程序 比如 psftp.exe
你需要一个 insecure plain-text 表示,因为外部程序对 .NET 安全字符串一无所知.
How secure is SecureString? 介绍 .NET 安全字符串及其一般限制。
顺便说一句:提取明文密码的命令可以通过 aux.h 来简化一点。 [pscredential]
实例:
# Returns the plain-text content of secure string $secVal:
(New-Object pscredential somelogin, $secVal).GetNetworkCredential().Password
唯一安全的方法是完全避免纯文本密码并且使用PKI如果目标程序支持,方法(基于public和私钥)。
证明纯文本方法不安全(即使不使用用于存储未加密密码的中间变量):
# Create a [pscredential] instance with a secure-string password:
# Note: To make this demo self-contained, I'm converting *from* plain
# text in order to construct the credential object.
# Note that you should never do that in production code.
# The need to specify -Force to do it is a reminder that it
# normally shouldn't be done.
$cred = New-Object pscredential someuser,
(ConvertTo-SecureString -AsPlainText -Force 'actualPassword')
# Open a new hidden window that passes the password *as plain text* to
# `cmd /c echo` (and then waits for a keypress, to keep the process alive).
$ps = Start-Process -PassThru -WindowStyle Hidden cmd "/c echo $($cred.GetNetworkCredential().Password) & pause"
# Now inspect the process' command line using CIM (WMI):
(Get-CimInstance Win32_Process -Filter "ProcessID = $($ps.ID)").CommandLine
# Kill (stop) the sample process.
$ps | Stop-Process
以上结果"C:\WINDOWS\system32\cmd.exe" /c echo actualPassword & pause
,说明明文密码确实可以被其他进程获取
您还可以使用 GUI 方法 检查 运行 进程的命令行:任务管理器(Taskmgr.exe
) 或者,在没有潜在截断的情况下,SysInternals' Process Explorer (procexp.exe
), which, however, must be installed on demand - see this ServerFault answer.