I don’ t know if I have ever mentioned, that I am in charge for the security of some of our systems. According to “The Open Web Application Security Project (OWASP)” (https://www.owasp.org/index.php/Top_10_2010-Main) security misconfiguration is at the 6th place of the TOP10 Risks. Since I am responsible for a web cluster I wrote a small PowerShell script for reporting the access control list (ACLs) . Given an root folder, the script traverse all child object recursively (depth first) and it only outputs those ACLs which are not inherited by the parent folder. I use the script for doing security reviews. This script can be also very useful if you are planning to migrate a webserver.
Clear-Host
$path = $args[0]
$outPutFile = $args[1]
$startDate = Get-Date
$newLine = "`r`n" #is a carrage return/line feed.
#check input parameters
if([System.IO.Directory]::Exists($path) -eq $false){
throw (new-object System.IO.DirectoryNotFoundException("Directory does not exist or is missing!"))
}
If($path.EndsWith("\"))
{
$path = $path.Remove($path.Length-1, 1)
}
if ([System.String]::IsNullOrEmpty($outPutFile)){
throw (new-object System.ApplicationException("OutputFile is missing!"))
}
#Build information for the header of the output file, if file exist it will be owerwritten!
$header = "Start: " + $startDate + $newLine + "Output file: " + $outPutFile + $newLine + "ACL of the analyzed path: " + $path + $newLine
$mainPathAcl = get-ACL $path | Format-List
out-file -encoding ASCII -filePath $outPutFile -InputObject $header
out-file -encoding ASCII -filePath $outPutFile -append -InputObject $mainPathAcl
#depth first traverse
$myStack = new-object System.Collections.Stack
[System.IO.DirectoryInfo]$rootInfo = New-Object System.IO.DirectoryInfo($path)
$myStack.Push($rootInfo)
while ($myStack.Count -ne 0){
$actualItem = $myStack.Pop(); #get last item
#add children to stack
if ($actualItem -is [System.IO.DirectoryInfo])
{
[System.IO.FileSystemInfo[]]$dirs2 = $actualItem.GetFileSystemInfos() | Sort-Object Name -Descending
if ($dirs2){#check if it is null.
Foreach ($dir1 in $dirs2) { #add to the stack
$myStack.Push($dir1)
}
}
if($actualItem.Parent.FullName -eq $rootInfo.FullName){
$appHeader = "" + $newLine + "------------------------" + $newLine + $actualItem.Name + $newLine + "------------------------"
out-file -encoding ASCII -filePath $outPutFile -append -InputObject $appHeader
}
}
#dump acls if not inherited
$aclActFile = Get-Acl -Path $actualItem.FullName
$WriteFileHeader = $true;
Foreach ($Access in $aclActFile.Access) {
$Inherited = [string]$Access.IsInherited
if ($Inherited -eq "False") {
#write File Header
if ($WriteFileHeader) {
$fileHeader = "File: " + $actualItem.FullName + $newLine + "SDDL: " + $aclActFile.Sddl
out-file -encoding ASCII -filePath $outPutFile -append -InputObject $fileHeader
$WriteFileHeader = $false;
}
#write AccessControl in csv
$output = "ACL: " + $Access.AccessControlType + ", " + $Access.IdentityReference + ", " + $Access.FileSystemRights
out-file -encoding ASCII -filePath $outPutFile -append -InputObject $output
}
}
}
#Footer
$endDate = Get-Date
$elapsedTime = $endDate - $startDate
$footer = "" + $newLine + "Run completed at: " + $endDate + $newLine + "Elapsed Time:" + $newLine + $elapsedTime + $newLine
out-file -encoding ASCII -filePath $outPutFile -append -InputObject $footer
Instructions:
- Copy this script in a file (example: aclDump.ps1)
- Open PowerShell
- Execute the following cmd, where parameter 1 is the root folder for dumbing ACL, and parameter 2 is the output file: .\aclDump.ps1 X:\Intepub C:\AclReport.txt.
PS: If you need to full backup ACLs or to transfer ACLs you should use tools like: SubInAcl (http://www.microsoft.com/download/en/details.aspx?id=23510)