Read unexpanded ProfileList paths before validation

This commit is contained in:
Shirofune-Security committed 2026-09-19 05:36:43 +09:00
1 parent acde16f149
commit 1acfec66a3
2 files changed
+12 -7

No files matched your search

+4 -2
View File
@@ -29,7 +29,8 @@ function Get-WelaSaclUserInventory {
}
$path = $null; $message = ''
try {
$rawPath = [string](Get-ItemProperty -LiteralPath $key.PSPath -Name ProfileImagePath -ErrorAction Stop).ProfileImagePath
$profileKey = Get-Item -LiteralPath $key.PSPath -ErrorAction Stop
$rawPath = [string]$profileKey.GetValue('ProfileImagePath', $null, [Microsoft.Win32.RegistryValueOptions]::DoNotExpandEnvironmentNames)
$path = Expand-WelaSaclProfilePath $rawPath
} catch {
$path = $null; $message = "Profile path unavailable: $($_.Exception.Message)"
@@ -38,7 +39,8 @@ function Get-WelaSaclUserInventory {
$users.Add([pscustomobject]@{ Sid = $sid; ProfilePath = $path; HiveLoaded = $loaded.ContainsKey($sid); Diagnostic = $message })
$loaded.Remove($sid)
}
$default = Expand-WelaSaclProfilePath ([string](Get-ItemProperty -LiteralPath $profileRoot -Name Default -ErrorAction Stop).Default)
$profileListKey = Get-Item -LiteralPath $profileRoot -ErrorAction Stop
$default = Expand-WelaSaclProfilePath ([string]$profileListKey.GetValue('Default', $null, [Microsoft.Win32.RegistryValueOptions]::DoNotExpandEnvironmentNames))
$users.Add([pscustomobject]@{ Sid = 'Default'; ProfilePath = $default; HiveLoaded = $false; Diagnostic = 'Future-user template; hive is not loaded by planning.' })
} catch { $diagnostics.Add("Profile inventory incomplete: $($_.Exception.Message)") }
foreach ($sid in $loaded.Keys) {
+8 -5
View File
@@ -84,12 +84,15 @@ function Get-ChildItem {
[pscustomobject]@{PSChildName='S-1-5-21-1';PSPath='Registry::profile-one'}
}
$script:profilePath = $null
function Get-ItemProperty {
param($LiteralPath,$Name,$ErrorAction)
if ($Name -eq 'Default') { return [pscustomobject]@{Default='C:\Users\Default'} }
$script:profileKey = [pscustomobject]@{}
$script:profileKey | Add-Member ScriptMethod GetValue {
param($Name,$Default,$Options)
if ($Options -ne [Microsoft.Win32.RegistryValueOptions]::DoNotExpandEnvironmentNames) { throw 'ProfileList read must preserve unexpanded tokens.' }
if ($Name -eq 'Default') { return 'C:\Users\Default' }
if ($null -eq $script:profilePath) { throw 'Profile path denied' }
[pscustomobject]@{ProfileImagePath=$script:profilePath}
return $script:profilePath
}
function Get-Item { param($LiteralPath,[switch]$Force,$ErrorAction) return $script:profileKey }
$inventory = Get-WelaSaclUserInventory
Assert (-not $inventory.Complete -and $inventory.Diagnostics.Count -gt 0 -and $inventory.Users[0].ProfilePath -eq $null) 'Unreadable per-user profile path must not yield complete inventory.'
$script:profilePath = '%USERPROFILE%\AnotherProfile'
@@ -97,7 +100,7 @@ $inventory = Get-WelaSaclUserInventory
Assert (-not $inventory.Complete -and $inventory.Users[0].ProfilePath -eq $null) 'ProfileList must not expand operator USERPROFILE for another user.'
$script:profilePath = 'C:\Users\One'
Assert (Get-WelaSaclUserInventory).Complete 'Known absolute profiles and Default form a complete inventory.'
Remove-Item Function:Get-ChildItem, Function:Get-ItemProperty
Remove-Item Function:Get-ChildItem
# Guard mapped drives and every ancestor before any descendants or ACL read.
$script:accessed = @(); $script:aclCalls = 0; $script:remoteDrive = $false
function Get-PSDrive { param($Name,$PSProvider,$ErrorAction) [pscustomobject]@{Root='C:\';DisplayRoot=$(if ($script:remoteDrive) {'\\server\share'} else {$null})} }