From 7dc074c2d6842056e8c130584b2bc1e534d39496 Mon Sep 17 00:00:00 2001 From: Peter Marszalik Date: Tue, 18 Nov 2014 22:24:37 -0600 Subject: [PATCH 1/2] powerdump.powershell bug - corrupt hash fix Fixed the bug where the hashes are not being extracted correctly when LM is disabled and history is enabled. Rather than relying on length, LM and NT headers are checked. Four bytes at 0xa0 show if LM exists and four bytes at 0xac show if NT exists. Details on this known issue can be found at the following whitepaper from blackhat: https://media.blackhat.com/bh-us-12/Briefings/Reynolds/BH_US_12_Reynods_Stamp_Out_Hash_WP.pdf --- src/powershell/powerdump.powershell | 28 ++++++++++++++++++++++------ 1 file changed, 22 insertions(+), 6 deletions(-) diff --git a/src/powershell/powerdump.powershell b/src/powershell/powerdump.powershell index 49b4cca5d..faadf5654 100644 --- a/src/powershell/powerdump.powershell +++ b/src/powershell/powerdump.powershell @@ -278,20 +278,36 @@ function Get-UserName([byte[]]$V) function Get-UserHashes($u, [byte[]]$hbootkey) { - [byte[]]$enc_lm_hash = $null; [byte[]]$enc_nt_hash = $null; - if ($u.HashOffset + 0x28 -lt $u.V.Length) + [byte[]]$enc_lm_hash = $null; [byte[]]$enc_nt_hash = $null; + + # check if hashes exist (if byte memory equals to 20, then we've got a hash) + $LM_exists = $false; + $NT_exists = $false; + # LM header check + if ($u.V[0xa0..0xa3] -eq 20) + { + $LM_exists = $true; + } + # NT header check + elseif ($u.V[0xac..0xaf] -eq 20) + { + $NT_exists = $true; + } + + if ($LM_exists -eq $true) { - $lm_hash_offset = $u.HashOffset + 4; + $lm_hash_offset = $u.HashOffset + 4; $nt_hash_offset = $u.HashOffset + 8 + 0x10; $enc_lm_hash = $u.V[$($lm_hash_offset)..$($lm_hash_offset+0x0f)]; $enc_nt_hash = $u.V[$($nt_hash_offset)..$($nt_hash_offset+0x0f)]; } - elseif ($u.HashOffset + 0x14 -lt $u.V.Length) - { + + elseif ($NT_exists -eq $true) + { $nt_hash_offset = $u.HashOffset + 8; $enc_nt_hash = [byte[]]$u.V[$($nt_hash_offset)..$($nt_hash_offset+0x0f)]; } - return ,(DecryptHashes $u.Rid $enc_lm_hash $enc_nt_hash $hbootkey); + return (DecryptHashes $u.Rid $enc_lm_hash $enc_nt_hash $hbootkey); } function DecryptHashes($rid, [byte[]]$enc_lm_hash, [byte[]]$enc_nt_hash, [byte[]]$hbootkey) From b1e92e9eb05763934019efba2a75f281af6f1dd8 Mon Sep 17 00:00:00 2001 From: Peter Marszalik Date: Tue, 18 Nov 2014 22:48:47 -0600 Subject: [PATCH 2/2] cleaned up indentation --- src/powershell/powerdump.powershell | 40 ++++++++++++++--------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/powershell/powerdump.powershell b/src/powershell/powerdump.powershell index faadf5654..f20e00a13 100644 --- a/src/powershell/powerdump.powershell +++ b/src/powershell/powerdump.powershell @@ -278,36 +278,36 @@ function Get-UserName([byte[]]$V) function Get-UserHashes($u, [byte[]]$hbootkey) { - [byte[]]$enc_lm_hash = $null; [byte[]]$enc_nt_hash = $null; - - # check if hashes exist (if byte memory equals to 20, then we've got a hash) - $LM_exists = $false; - $NT_exists = $false; - # LM header check - if ($u.V[0xa0..0xa3] -eq 20) - { - $LM_exists = $true; - } - # NT header check - elseif ($u.V[0xac..0xaf] -eq 20) - { - $NT_exists = $true; - } - - if ($LM_exists -eq $true) + [byte[]]$enc_lm_hash = $null; [byte[]]$enc_nt_hash = $null; + + # check if hashes exist (if byte memory equals to 20, then we've got a hash) + $LM_exists = $false; + $NT_exists = $false; + # LM header check + if ($u.V[0xa0..0xa3] -eq 20) { - $lm_hash_offset = $u.HashOffset + 4; + $LM_exists = $true; + } + # NT header check + elseif ($u.V[0xac..0xaf] -eq 20) + { + $NT_exists = $true; + } + + if ($LM_exists -eq $true) + { + $lm_hash_offset = $u.HashOffset + 4; $nt_hash_offset = $u.HashOffset + 8 + 0x10; $enc_lm_hash = $u.V[$($lm_hash_offset)..$($lm_hash_offset+0x0f)]; $enc_nt_hash = $u.V[$($nt_hash_offset)..$($nt_hash_offset+0x0f)]; } elseif ($NT_exists -eq $true) - { + { $nt_hash_offset = $u.HashOffset + 8; $enc_nt_hash = [byte[]]$u.V[$($nt_hash_offset)..$($nt_hash_offset+0x0f)]; } - return (DecryptHashes $u.Rid $enc_lm_hash $enc_nt_hash $hbootkey); + return ,(DecryptHashes $u.Rid $enc_lm_hash $enc_nt_hash $hbootkey); } function DecryptHashes($rid, [byte[]]$enc_lm_hash, [byte[]]$enc_nt_hash, [byte[]]$hbootkey)