canix1 / adaclscanner Goto Github PK
View Code? Open in Web Editor NEWRepo for ADACLScan.ps1 - Your number one script for ACL's in Active Directory
License: Microsoft Public License
Repo for ADACLScan.ps1 - Your number one script for ACL's in Active Directory
License: Microsoft Public License
The following errors are registered when invoking the domain picker, if the machine which cannot connect to LDAP:
Exception calling "SendRequest" with "1" argument(s): "The LDAP server returned an unknown error."
At C:\Users\kf\OneDrive\Scripts\Release\ADACLScanner\ADACLScan.ps1:4775 char:1
+ $response = $LDAPConnection.SendRequest($request)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : LdapException
Exception calling "SendRequest" with "1" argument(s): "The LDAP server is unavailable."
At C:\Users\kf\OneDrive\Scripts\Release\ADACLScanner\ADACLScan.ps1:4787 char:1
+ $response = $LDAPConnection.SendRequest($request)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], MethodInvocationException
+ FullyQualifiedErrorId : LdapException
Feature request - an option to include CanonicalName (in addition to or instead of DistinguishedName) to make reports easier to sort.
CSV output does not include "Inheritance Disabled" column, unlike HTML report.
$strScriptName = $($MyInvocation.MyCommand.Name)
That variable is not used anywhere in the script, except for the line above.
Is there a way to invoke the Effective Permissions functionality from the command line? So far, I have only gotten aggregate reports.
It looks like this script can only be run on the domain controller, is it possible to run it remotely?
Hello,
Actually if you open a csv in Excel, then convert data with default ',' you will have an issue with the OU path containing ','.
I advise to add a delimiter when export-csv.
It is easier when you use a csv in Excel.
export-csv -delimiter ';'
Hi, there is a typo on line 16139, which is }D
instead of just }
. Consequence:
D : The term 'D' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.
At C:\ADControls\ADACLScan.ps1:16139 char:30
+ }D
+ ~
+ CategoryInfo : ObjectNotFound: (D:String) [], CommandNotFoundException
+ FullyQualifiedErrorId : CommandNotFoundException
Hello,
In the template CSV, I found several ACE with the same information. For example for adminsdholder : BUILTIN\Pre-Windows 2000 Compatible Access has the same permission (Generic Read - All)
I get the same information with get-ACL.
Any idea why many ACE are duplicated with Get-ACL (and in the templates too, but I suppose is is related to Get-ACL output command used to generate your templates).
Thanks
When a pop-up window, like the object scanner, or the domain picker, is opened and user switches to another application, that window disappears and the main script window continues to be locked. The pop-up window can be found if the user minimizes all opened windows, but it would be much easier if we could just to Alt-Tab to it.
Hi,
I cannot figure out a way to show the inherited permissions when using effective rights from Powershell. I can see it when I run the GUI and select the user principle I want to view.
Running a Compare scan shows the correct results for new and removed ACLs in the HTML output.
When selecting the CSV output, all new entries are shown as "Matched" instead of "New". Removed entries are correctly shown as "Missing".
Sample CSV entry:
"OU=Administration,OU=Groups,OU=XY1,DC=HSLAB2,DC=local","organizationalUnit","HSLAB2\TestUser2","HSLAB2\TestUser2","GenericAll","Descendents","00000000-0000-0000-0000-000000000000","bf967aba-0de6-11d0-a285-00aa003049e2","InheritedObjectAceTypePresent","Allow","False","ContainerInherit","InheritOnly","2019-03-08 12:06:35","7d1dbe1f-0ae1-4e28-9fe0-30409cdf0118","1117506","","Match"
Hello,
When I run .\adaclscan.ps1 I get the errors in the attached file. I've tried running on a 2012 R2 and 2019 Domain Controllers as well as a Windows 10 system, all return the same error.
I'm logged into the computers as an administrator and am running PowerShell as an administrator as well.
Thanks!
Chris
Hi, i need to get the users list who have the delegated rights in AD
Hi Robin
First of all thanks for a very useful tool. I'm using it correlate some findings by another tool.
I gave a question about the values in the state column when running a compare against the default templates for Server 2016 and I'm curious about the meanings of the values that show up,
For example what does Missing mean versus Out of Policy, mean exactly? I need to explain this to customer and I'm not 100% usure.
Any help would be appreciated.
Hello there,
thanks for thsi great tool.
Unfortunatelly the links for the CSV templates are not reachable.
Regards,
Tom
Hello,
I found an issue and don't understand why.
If I set an object (ie an user) protected from deletion, the parent object gets ACE Deny
with DeleteChild
for Everyone
.
Get-ACL -path "AD:$object" | select -ExpandProperty Access | ?{ $_.IdentityReference -eq "Everyone" }
ActiveDirectoryRights : DeleteChild
InheritanceType : None
ObjectType : 00000000-0000-0000-0000-000000000000
InheritedObjectType : 00000000-0000-0000-0000-000000000000
ObjectFlags : None
AccessControlType : Deny
IdentityReference : Everyone
IsInherited : False
InheritanceFlags : None
PropagationFlags : None
But, with ADACLScan, I get the permissions Delete
instead of DeleteChild
:
Object : xxx
ObjectClass : organizationalUnit
IdentityReference : S-1-1-0
Trustee : Everyone
Access : Deny
Inherited : False
Apply To : This Object Only
Permission : Delete
Hello,
From the 6.5 version, you remove public class IconExtractor.
I don't know if it's wanted or not but the icons don't show anymore (tested on WS 2016 WS 2019, 10 21H1).
The code below is doubled.
if ($chkBoxEffectiveRightsColor.IsChecked -eq $false) {
Switch ($objRights) {
"Self" {
#Self right are never express in gui it's a validated write ( 0x00000008 ACTRL_DS_SELF)
$objRights = ""
}
"DeleteChild, DeleteTree, Delete" {
$objRights = "DeleteChild, DeleteTree, Delete"
}
"GenericRead" {
$objRights = "Read Permissions,List Contents,Read All Properties,List"
}
"CreateChild" {
$objRights = "Create"
}
"DeleteChild" {
$objRights = "Delete"
}
"GenericAll" {
$objRights = "Full Control"
}
"CreateChild, DeleteChild" {
$objRights = "Create/Delete"
}
"ReadProperty" {
Switch ($objInheritanceType) {
"None" {
Switch ($objFlags) {
"ObjectAceTypePresent" {
$objRights = "Read"
}
"ObjectAceTypePresent, InheritedObjectAceTypePresent" {
$objRights = "Read"
}
default
{ $objRights = "Read All Properties" }
}#End switch
}
"Children" {
Switch ($objFlags) {
"ObjectAceTypePresent" {
$objRights = "Read"
}
"ObjectAceTypePresent, InheritedObjectAceTypePresent" {
$objRights = "Read"
}
default
{ $objRights = "Read All Properties" }
}#End switch
}
"Descendents" {
Switch ($objFlags) {
"ObjectAceTypePresent" {
$objRights = "Read"
}
"ObjectAceTypePresent, InheritedObjectAceTypePresent" {
$objRights = "Read"
}
default
{ $objRights = "Read All Properties" }
}#End switch
}
default
{ $objRights = "Read All Properties" }
}#End switch
}
"ReadProperty, WriteProperty" {
$objRights = "Read All Properties;Write All Properties"
}
"WriteProperty" {
Switch ($objInheritanceType) {
"None" {
Switch ($objFlags) {
"ObjectAceTypePresent" {
$objRights = "Write"
}
"ObjectAceTypePresent, InheritedObjectAceTypePresent" {
$objRights = "Write"
}
default
{ $objRights = "Write All Properties" }
}#End switch
}
"Children" {
Switch ($objFlags) {
"ObjectAceTypePresent" {
$objRights = "Write"
}
"ObjectAceTypePresent, InheritedObjectAceTypePresent" {
$objRights = "Write"
}
default
{ $objRights = "Write All Properties" }
}#End switch
}
"Descendents" {
Switch ($objFlags) {
"ObjectAceTypePresent" {
$objRights = "Write"
}
"ObjectAceTypePresent, InheritedObjectAceTypePresent" {
$objRights = "Write"
}
default
{ $objRights = "Write All Properties" }
}#End switch
}
default
{ $objRights = "Write All Properties" }
}#End switch
}
}# End Switch
} else {
Switch ($objRights) {
"Self" {
#Self right are never express in gui it's a validated write ( 0x00000008 ACTRL_DS_SELF)
$objRights = ""
}
"GenericRead" {
$objRights = "Read Permissions,List Contents,Read All Properties,List"
}
"CreateChild" {
$objRights = "Create"
}
"DeleteChild" {
$objRights = "Delete"
}
"GenericAll" {
$objRights = "Full Control"
}
"CreateChild, DeleteChild" {
$objRights = "Create/Delete"
}
"ReadProperty" {
Switch ($objInheritanceType) {
"None" {
Switch ($objFlags) {
"ObjectAceTypePresent" {
$objRights = "Read"
}
"ObjectAceTypePresent, InheritedObjectAceTypePresent" {
$objRights = "Read"
}
default
{ $objRights = "Read All Properties" }
}#End switch
}
"Children" {
Switch ($objFlags) {
"ObjectAceTypePresent" {
$objRights = "Read"
}
"ObjectAceTypePresent, InheritedObjectAceTypePresent" {
$objRights = "Read"
}
default
{ $objRights = "Read All Properties" }
}#End switch
}
"Descendents" {
Switch ($objFlags) {
"ObjectAceTypePresent" {
$objRights = "Read"
}
"ObjectAceTypePresent, InheritedObjectAceTypePresent" {
$objRights = "Read"
}
default
{ $objRights = "Read All Properties" }
}#End switch
}
default
{ $objRights = "Read All Properties" }
}#End switch
}
"ReadProperty, WriteProperty" {
$objRights = "Read All Properties;Write All Properties"
}
"WriteProperty" {
Switch ($objInheritanceType) {
"None" {
Switch ($objFlags) {
"ObjectAceTypePresent" {
$objRights = "Write"
}
"ObjectAceTypePresent, InheritedObjectAceTypePresent" {
$objRights = "Write"
}
default {
$objRights = "Write All Properties"
}
}#End switch
}
"Children" {
Switch ($objFlags) {
"ObjectAceTypePresent" {
$objRights = "Write"
}
"ObjectAceTypePresent, InheritedObjectAceTypePresent" {
$objRights = "Write"
}
default {
$objRights = "Write All Properties"
}
}#End switch
}
"Descendents" {
Switch ($objFlags) {
"ObjectAceTypePresent" {
$objRights = "Write"
}
"ObjectAceTypePresent, InheritedObjectAceTypePresent" {
$objRights = "Write"
}
default {
$objRights = "Write All Properties"
}
}#End switch
}
default {
$objRights = "Write All Properties"
}
}#End switch
}
default {
}
}# End Switch
$intCriticalityValue = GetCriticality $_.IdentityReference.toString() $_.ActiveDirectoryRights.toString() $_.AccessControlType.toString() $_.ObjectFlags.toString() $_.InheritanceType.toString() $_.ObjectType.toString() $_.InheritedObjectType.toString()
Switch ($intCriticalityValue) {
0 { $strLegendText = "Info"; $strLegendColor = $strLegendColorInfo }
1 { $strLegendText = "Low"; $strLegendColor = $strLegendColorLow }
2 { $strLegendText = "Medium"; $strLegendColor = $strLegendColorMedium }
3 { $strLegendText = "Warning"; $strLegendColor = $strLegendColorWarning }
4 { $strLegendText = "Critical"; $strLegendColor = $strLegendColorCritical }
}
$strLegendTextVal = $strLegendText
if ($intCriticalityValue -gt $global:intShowCriticalityLevel) {
$global:intShowCriticalityLevel = $intCriticalityValue
}
}#End IF else
Between If/Else there's only one difference
"DeleteChild, DeleteTree, Delete" {
$objRights = "DeleteChild, DeleteTree, Delete"
}
You can probably optimize this.
Hi,
I run a lot of the powershell scripts on remote machines, without copying script files. When I do lines:
--> $CurrentFSPath = split-path -parent $MyInvocation.MyCommand.Path
throw an error. If you change it to
-->
It will do the same thing, but will not throw errors when working from clipboard
Within the Effective Rights tab I can Get-Account from the same domain, but not from other domains or child domains despite selecting the location properly and seeing that the status above the input box for the user account changes to the NETLOGON name of the domain. Attempting to use domain\ or username@domainfqdn in anny combination fails as well.
Hello Robin,
Any chance to add a switch -HideProgressBar
to speed up the searches via command line?
Thanks
When you run two or more instances of the script at the same time, they use the same temporary files, which results in incorrect reporting. My suggestion is to append unique random ID (GUID, for example) for each session file names, so they would be named like this: ACLHTML-116dc1d9-ff8c-4e1b-85fb-284cd9ec2873.hta
PS C:\Users****\Desktop> .\ADACLScan.ps1 -Base "DC=,DC=,DC=*" -Scope subtree -E
sPrincipal ****
Found security principal
Get-Perm : Cannot process argument transformation on parameter 'bolGetOwnerEna'. Cannot convert value "" to
"System.Boolean". Boolean parameters accept only Boolean values and numbers, such as $True, $False, 1 or 0.
At C:\Users*\Desktop\ADACLScan.ps1:14635 char:99
This error occurs regardless of the filter or scope.:
Log Error: No objects returned! Does your filter reflect the objects you are looking for?
The command line outputs this error:
Cannot bind argument to parameter 'stringList' because it is null
I also noticed that the Effective Rights scan report does not include the permission. Only the groups, is there a more detailed documentation available for using this tool?
running powershell version 2.0.
and .Net 4.5
Is there a windows feature that needs to be enabled other than active directory or group policy?
Or maybe another module that needs to be installed?
I am running ADACLScan.ps1 version 6.8 to uncover AD groups with Critical, Warning & Medium permissions & rights that are not already being reviewed as built-in groups.
The auditors are asking me to justify use of ADACLScan.ps1. They want to know what permissions are identified and why the criticality Level rates them as Critical, Warning & Medium. Why am I excluding Low criticality permissions?
Is there an extract of permissions & rights captured by ADACLScan.ps1 (with their criticality levels)?
If so, I could then refer the auditors to the Microsoft descriptions, such as
https://docs.microsoft.com/en-us/dotnet/api/system.directoryservices.activedirectoryrights?view=net-5.0
Examples of what I am looking for are:
"Create Object"="Warning";
"Read permissions, Modify permissions" {$intCriticalityLevel = 4 }
if($objIdentity -eq "NT AUTHORITY\SELF"){$intCriticalityLevel = 1 else {$intCriticalityLevel = 2}}
Good Day!
please help me, tell me how I can make a report what rights a certain group has in the domain, while leaving only those OUs where the rights are assigned, and not displaying those where the rights are inheritedю Example:
This with Inherited - false save in the report
and this with Inherited - True remove from report
I will be glad for any help
Hi, I wonder if anyone has templates that include Exchange-related default SDs and would be willing to share them.
Hello,
line 15776, in Get-Perm function, argument's name "Access" is not correct.
It must be replaced by AccessType
I just pulled down the new 6.8 version and was comparing to v6.4. Running the script produced quite a few errors too. I noticed the following:
line 1266, 1267, 1271, 15217, 15218, 15222, 15600, 15601, 15602, 15605 - show hidden character
line 3042, 3063, 11846, 11860, 15054 - quotes are showing as funny character
line 14254 - hidden character
Sorry, I can't attach a file to visually show for you
This looks like an awesome tool, but in among its options, should be the ability to search for specific lists of known exploits, backdoors, & nondefault configurations. While the tools does appear to be intended for finding just those things, it appears from the doc page (and I have to admit I haven't actually tried it out yet) that the reports it typically generates are likely to have much of this buried in reams and reams of other data. Another possibility might be to assign each flagged entry a 'badness' value from 1-10, so that the report might be sorted with the most interesting data at the top. I admit I've been looking for something like this ever since I watched Harmj0y's 'An ACE in the Hole: Stealthy Host Persistence via Security Descriptors' presentation at Derbycon in 2017.
Hi,
Can you confirm what information is collected (if any)?
Thanks!
Hello,
First of all thanks for your great work, I use it often to detect ACL issue!
The CSVs for Windows 2016 has SID for Identity Reference, it is great because we can compare with non-english Active Directory.
But the olders CSVs (2000 to 2012 R2) used sometimes SID, sometimes english name like 'Everyone', etc. That's lead to bad comparison if the AD is not in english.
Is this possible to update the CSV templates ?
Last thing: in the CSV templates download window, there is a little typo problem : Configration NC instead of Configuration NC.
Hello @canix1 , I have stumbled upon this behavior of ADACLScanner 7.3 and I am not sure if it is a bug or expected behavior. It seems that the -FilterTrustee
parameter gets evaluated before the -RecursiveFind
parameter.
For example, I am trying to look up the permissions to create computer objects. If I run this:
.\ADACLScan.ps1 -Base 'DC=contoso,DC=com' `
-Scope onelevel `
-Filter '(|(objectClass=domainDNS)(objectClass=organizationalUnit)(objectClass=container))' `
-AccessType Allow `
-ApplyTo computer `
-Permission create `
-RecursiveFind `
-Output HTML `
-Show
I get the following results, as john is a member of Account Operators:
But if I add the -FilterTrustee
parameter:
.\ADACLScan.ps1 -Base 'DC=contoso,DC=com' `
-Scope onelevel `
-Filter '(|(objectClass=domainDNS)(objectClass=organizationalUnit)(objectClass=container))' `
-AccessType Allow `
-ApplyTo computer `
-Permission create `
-FilterTrustee 'CONTOSO\john' `
-RecursiveFind `
-Output HTML `
-Show
I just get No Permissions found!
Some version of PowerShell does not recongnize New-Guid
Hi!
First off, thanks for the awesome tool!
I might be off on this, but it seems like the GUI provides a bit more flexibility in what you collect. It would be helpful to have these available via parameters.
Cheers!
Hi Robin
Thank yor for a very useful tool.
I would like to schedule a weekly run to document all changes made to my AD.
The GUI makes perfect sense, but I'm having trouble translating all the GUI options into command line syntax. How about an option in the GUI, that displays the command line of the options selected in the GUI? Right now it's a bit of trial and error and with a big AD each run takes a long time to finish.
Best regards
Christian
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.