如何在 Powershell 中进行 LM 哈希
How to LM Hash in Powershell
好的,所以我已经为此做了一些工作,但我看不出如何取得进一步的进展。我一直 运行 遇到 DESCryptoServiceProvider 的障碍,不知何故它似乎没有给出正确的答案。
LM_Hash 的 sudo 代码版本是:
LMHASH = concat(DES(Upper(PWD)[0..7],KGS!@#$%),DES(Upper(PWD)[8..13],KGS!@#$%))
第一个问题是 LM Key 我一直看到至少两个变体,它的 "KGS!@#$%" 或 "KGS!+#$%" 都没有给我正确的答案,但两者似乎都不符合起源故事(它的 KGS和 SHIFT 12345 假设美国键盘
在英国那就是 "KGS!"£$%")
我很确定我现在已经正确设置了参数,但我的理解似乎让我失望了。这是我到目前为止所拥有的,感谢任何帮助我是 运行 Powershell V5.1 on Win 10,要加密的字符串作为 $string
传入
$plaintext = "KGS!@#$%"
$OEM = [System.Text.Encoding]::GetEncoding($Host.CurrentCulture.TextInfo.OEMCodePage)
$str1 = $OEM.GetBytes($string.substring(0,7)) +[Byte]$null
$str2 = $OEM.GetBytes($string.Substring(7)) +[Byte]$null
$IV = new-object "System.Byte[]" 8
$hasher = New-Object -TypeName System.Security.Cryptography.DESCryptoServiceProvider -Property @{key=$str1; IV = $IV; mode = [System.Security.Cryptography.CipherMode]::ECB; Padding=[System.Security.Cryptography.PaddingMode]::None}
$outbyte = new-object "System.Byte[]" 8
$encrypter1 = $hasher.CreateEncryptor()
$outbyte = $encrypter1.TransformFinalBlock($OEM.GetBytes($plaintext),0,8)
$data1 = [System.BitConverter]::ToString($outbyte).replace("-","")
$encrypter1.Dispose()
理论上,这应该使用字符串的前 7 个字符 ($str1) 作为密钥(末尾有一个空字节)使用 DES 加密密钥(无论是哪个密钥),然后我们执行此操作到下半部分 ($str2) 并将它们连接在一起以获得 LMHASH。
ASCII 编码的字符串 KGS!@#$%
是正确的魔法常量
using the first 7 characters of the string ($str1) as the key (with a null byte on the end)
然而,这是不正确的。密钥不是通过在末尾用单个 0 字节填充部分输入的 7 个字节来组成的,而是通过将输入分成 8 个 7 位块并将它们左移一次(产生 8 个字节)来组成的。
在 PowerShell 中实现它的最简单方法可能是使用字符串,所以我可能会这样做:
# Convert string to byte array
$inBytes = $OEM.GetBytes($str1)
# Create a binary string from our bytes
$bitString = ''
foreach($byte in $inBytes){
$bitstring += [convert]::ToString($byte, 2).PadLeft(8, '0')
}
# Partition the byte string into 7-bit chunks
[byte[]]$key = $bitString -split '(?<=\G.{7}(?<!$))' |ForEach-Object {
# Insert 0 as the least significant bit in each chunk
# Convert resulting string back to [byte]
[convert]::ToByte("${_}0", 2)
}
try{
# Create the first encryptor from our new key, and an empty IV
[byte[]]$iv = ,0 * 8
$enc = $hasher.GetEncryptor($key, $iv)
# Calculate half of the hash
$block1 = $enc.TransformFinalBlock($plaintext, 0, 8)
}
finally{
# Dispose of the encryptor
$enc.Dispose()
}
然后重复 $str2
并连接生成的块以获得完整的 LM 哈希
任何有问题的人,基于 @mathias R. Jessen
上面的答案,这里有一个函数计算 LM-Hash 的一半,输入 7 个字符串并将哈希输出为十六进制。
Function LM-hash {
Param(
[Parameter(mandatory=$true,ValueFromPipeline=$true,position=0)]
[ValidateLength(7,7)]
[String]$Invalue
)
$plaintext = "KGS!@#$%"
$OEM = [System.Text.Encoding]::GetEncoding($Host.CurrentCulture.TextInfo.OEMCodePage)
$inBytes = $OEM.GetBytes($invalue)
$bitString = ''
foreach($byte in $inBytes){
$bitstring += [convert]::ToString($byte, 2).PadLeft(8, '0')
}
[byte[]]$key = $bitString -split '(?<=\G.{7}(?<!$))' |ForEach-Object { [convert]::ToByte("${_}0", 2)}
$iv = new-object "System.Byte[]" 8
$DESCSP = New-Object -TypeName System.Security.Cryptography.DESCryptoServiceProvider -Property @{key=$key; IV = $IV; mode = [System.Security.Cryptography.CipherMode]::ECB; Padding=[System.Security.Cryptography.PaddingMode]::None}
$enc = $DESCSP.CreateEncryptor()
$block1 = $enc.TransformFinalBlock($OEM.GetBytes($plaintext), 0, 8)
return [System.BitConverter]::ToString($block1).replace("-","")
$enc.Dispose()
}
这给出了一半哈希值的正确结果,因此将每一半单独输入并连接字符串即可得到完整的 LM 哈希值
好的,所以我已经为此做了一些工作,但我看不出如何取得进一步的进展。我一直 运行 遇到 DESCryptoServiceProvider 的障碍,不知何故它似乎没有给出正确的答案。
LM_Hash 的 sudo 代码版本是:
LMHASH = concat(DES(Upper(PWD)[0..7],KGS!@#$%),DES(Upper(PWD)[8..13],KGS!@#$%))
第一个问题是 LM Key 我一直看到至少两个变体,它的 "KGS!@#$%" 或 "KGS!+#$%" 都没有给我正确的答案,但两者似乎都不符合起源故事(它的 KGS和 SHIFT 12345 假设美国键盘 在英国那就是 "KGS!"£$%")
我很确定我现在已经正确设置了参数,但我的理解似乎让我失望了。这是我到目前为止所拥有的,感谢任何帮助我是 运行 Powershell V5.1 on Win 10,要加密的字符串作为 $string
传入 $plaintext = "KGS!@#$%"
$OEM = [System.Text.Encoding]::GetEncoding($Host.CurrentCulture.TextInfo.OEMCodePage)
$str1 = $OEM.GetBytes($string.substring(0,7)) +[Byte]$null
$str2 = $OEM.GetBytes($string.Substring(7)) +[Byte]$null
$IV = new-object "System.Byte[]" 8
$hasher = New-Object -TypeName System.Security.Cryptography.DESCryptoServiceProvider -Property @{key=$str1; IV = $IV; mode = [System.Security.Cryptography.CipherMode]::ECB; Padding=[System.Security.Cryptography.PaddingMode]::None}
$outbyte = new-object "System.Byte[]" 8
$encrypter1 = $hasher.CreateEncryptor()
$outbyte = $encrypter1.TransformFinalBlock($OEM.GetBytes($plaintext),0,8)
$data1 = [System.BitConverter]::ToString($outbyte).replace("-","")
$encrypter1.Dispose()
理论上,这应该使用字符串的前 7 个字符 ($str1) 作为密钥(末尾有一个空字节)使用 DES 加密密钥(无论是哪个密钥),然后我们执行此操作到下半部分 ($str2) 并将它们连接在一起以获得 LMHASH。
ASCII 编码的字符串 KGS!@#$%
是正确的魔法常量
using the first 7 characters of the string ($str1) as the key (with a null byte on the end)
然而,这是不正确的。密钥不是通过在末尾用单个 0 字节填充部分输入的 7 个字节来组成的,而是通过将输入分成 8 个 7 位块并将它们左移一次(产生 8 个字节)来组成的。
在 PowerShell 中实现它的最简单方法可能是使用字符串,所以我可能会这样做:
# Convert string to byte array
$inBytes = $OEM.GetBytes($str1)
# Create a binary string from our bytes
$bitString = ''
foreach($byte in $inBytes){
$bitstring += [convert]::ToString($byte, 2).PadLeft(8, '0')
}
# Partition the byte string into 7-bit chunks
[byte[]]$key = $bitString -split '(?<=\G.{7}(?<!$))' |ForEach-Object {
# Insert 0 as the least significant bit in each chunk
# Convert resulting string back to [byte]
[convert]::ToByte("${_}0", 2)
}
try{
# Create the first encryptor from our new key, and an empty IV
[byte[]]$iv = ,0 * 8
$enc = $hasher.GetEncryptor($key, $iv)
# Calculate half of the hash
$block1 = $enc.TransformFinalBlock($plaintext, 0, 8)
}
finally{
# Dispose of the encryptor
$enc.Dispose()
}
然后重复 $str2
并连接生成的块以获得完整的 LM 哈希
任何有问题的人,基于 @mathias R. Jessen 上面的答案,这里有一个函数计算 LM-Hash 的一半,输入 7 个字符串并将哈希输出为十六进制。
Function LM-hash {
Param(
[Parameter(mandatory=$true,ValueFromPipeline=$true,position=0)]
[ValidateLength(7,7)]
[String]$Invalue
)
$plaintext = "KGS!@#$%"
$OEM = [System.Text.Encoding]::GetEncoding($Host.CurrentCulture.TextInfo.OEMCodePage)
$inBytes = $OEM.GetBytes($invalue)
$bitString = ''
foreach($byte in $inBytes){
$bitstring += [convert]::ToString($byte, 2).PadLeft(8, '0')
}
[byte[]]$key = $bitString -split '(?<=\G.{7}(?<!$))' |ForEach-Object { [convert]::ToByte("${_}0", 2)}
$iv = new-object "System.Byte[]" 8
$DESCSP = New-Object -TypeName System.Security.Cryptography.DESCryptoServiceProvider -Property @{key=$key; IV = $IV; mode = [System.Security.Cryptography.CipherMode]::ECB; Padding=[System.Security.Cryptography.PaddingMode]::None}
$enc = $DESCSP.CreateEncryptor()
$block1 = $enc.TransformFinalBlock($OEM.GetBytes($plaintext), 0, 8)
return [System.BitConverter]::ToString($block1).replace("-","")
$enc.Dispose()
}
这给出了一半哈希值的正确结果,因此将每一半单独输入并连接字符串即可得到完整的 LM 哈希值