From 4740cd3e9723229d4433ea89e4740f17859fbb16 Mon Sep 17 00:00:00 2001 From: Tomas Kracmar Date: Wed, 29 Jul 2026 11:50:16 +0200 Subject: [PATCH] fix(Extract-NTHashes): restrict ACL on temp dir holding plaintext hashes Live NTLM hashes are written unencrypted to a temp file before AES protection is applied. Cleanup only runs in a finally block, so a hard kill/crash between write and cleanup could leave plaintext hashes on disk under a directory that inherits whatever broad ACL its parent Temp folder has (worst case: C:\Windows\Temp when run as SYSTEM). Strip inherited ACEs and grant only the current user on the temp directory right after creating it, narrowing exposure for that window. Co-Authored-By: Claude Sonnet 5 --- Extract-NTHashes.ps1 | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/Extract-NTHashes.ps1 b/Extract-NTHashes.ps1 index 56b3980..2c150a0 100644 --- a/Extract-NTHashes.ps1 +++ b/Extract-NTHashes.ps1 @@ -250,6 +250,21 @@ try { # never written to the installation directory and are always cleaned up. $tmpDir = New-Item -ItemType Directory -Path ([System.IO.Path]::Combine( [System.IO.Path]::GetTempPath(), "elysium-extract-" + [System.Guid]::NewGuid())) -Force + try { + # Plaintext NTLM hashes land in this directory before AES protection is applied below. + # Strip inherited ACEs (e.g. a broad "Users" grant on the parent Temp folder) so only the + # current user can read it while the finally block's cleanup hasn't run yet. + $dirAcl = $tmpDir.GetAccessControl() + $dirAcl.SetAccessRuleProtection($true, $false) + $currentUserRule = New-Object System.Security.AccessControl.FileSystemAccessRule( + [System.Security.Principal.WindowsIdentity]::GetCurrent().User, + [System.Security.AccessControl.FileSystemRights]::FullControl, + 'ContainerInherit,ObjectInherit', 'None', 'Allow') + $dirAcl.AddAccessRule($currentUserRule) + $tmpDir.SetAccessControl($dirAcl) + } catch { + Write-Warning "Could not restrict ACL on temporary directory '$($tmpDir.FullName)': $($_.Exception.Message)" + } $exportPath = Join-Path -Path $tmpDir.FullName -ChildPath "$baseName.txt" $compressedFilePath = Join-Path -Path $tmpDir.FullName -ChildPath "$baseName.zip" $encryptedFilePath = Join-Path -Path $tmpDir.FullName -ChildPath "$baseName.enc"