Weak folder permission enumeration

This script enumerates all directories within System32 or %PATH% that NT AUTHORITY\Authenticated Users, BUILTIN\Users, or Everyone can write to. It can be useful if we need to hide files in non-standard places.

function Get-ModifiablePath {
    [CmdletBinding()]
    param()

    function Test-ModifiablePath {
        [CmdletBinding()]
        Param(
            [Parameter(Position = 0, Mandatory = $True, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True)]
            [Alias('FullName')]
            [String]
            $Path
        )

        BEGIN {
            # the permissions we care about (those that will allow modification of files in the target folder)
            $ModifiableRights = @('ChangePermissions', 'CreateFiles', 'FullControl', 'Modify', 'TakeOwnership', 'Write', 'WriteData')
            # this is used to cast the above modifiable rights to a comparable class
            $Type = [Security.AccessControl.FileSystemRights]
        }

        PROCESS {
            try {
                # use a try/catch because of the weird behavior of Get-ACL
                $DirectoryAcl = Get-Acl -Path $Path -ErrorAction Stop

                $DirectoryProperties = @{'Path' = $Path}

                ForEach ($Access in $DirectoryAcl.Access) {
                    $Include = $False
                    # check for the target user identities and 'Allow'
                    if ( ($Access.IdentityReference -match 'NT AUTHORITY\\Authenticated Users|BUILTIN\\Users|Everyone') -and ($Access.AccessControlType -eq 'Allow') ) {
                        ForEach ($ModifiableRight in $ModifiableRights) {
                            # cast the right as [Security.AccessControl.FileSystemRights]
                            $Right = $ModifiableRight -as $Type
                            # check if any of the modifiable rights are present
                            if (($Access.FileSystemRights -band $Right) -eq $Right) {
                                $Include = $True
                            }
                        }
                        if ($Include) {
                            # if the coditions were set, include the access rule in the object
                            $DirectoryProperties['Access'] += @($Access)
                        }
                    }
                }

                if ($DirectoryProperties['Access']) {
                    # create an output object if there were proper results
                    New-Object -TypeName PSObject -Property $DirectoryProperties
                }
            }
            catch {
                Write-Verbose "Error retrieving ACL for: $Path"
            }
        }
    }

    # check all folders in %PATH%
    $ENV:Path -split ';' | Where-Object { $_ -and (Test-Path ([Environment]::ExpandEnvironmentVariables($_))) } | Test-ModifiablePath

    # check all directories in C:\Windows\System32\ (note using $ENV:windir)
    Get-ChildItem -Directory "$ENV:windir\System32\" -Recurse -ErrorAction SilentlyContinue | Test-ModifiablePath
}

References:

Last updated