Active Directory Permissions are similar to file system permission we set every day on our servers. UI is almost exactly the same, the permission names are obviously a little bit different. And we set the permissions in almost the same way. The problem with Active Directory Permissions is actually that many Active Directory administrators don’t have enough faith in themselves and they are afraid of making any modifications because they think they will break stuff.
This is not true. You can safely modify in the permissions in Active Directory if everything is well-planned, well-thought before you implement the change you should be good to go.
Why Are The Permissions So Important?
The permissions determine the rules for reading our objects and their attributes, updating, creating, and removing the objects from Active Directory. Before you start setting up permissions, it is important that you understand your environment and determine which information is sensitive for you.
I will give you a short example here. Maybe for me, it’s not important that all users in my Active Directory can read full number attribute of other users in Active Directory because this information is not sensitive in my case. However, I can have multiple other attributes in Active Directory where I store sensitive information and those attributes I would like to protect. But, here it will vary if the environment is set to be different so you have to spend some time on proper design.
When it comes to permission management, don’t be afraid. If you plan everything well before, it’s not a big headache. You just have to set up a proper permission and inheritance schemes in your Active Directory architecture and you will be set for several years ahead of you. No issues here. There is a problem, however, when it comes to built-in GUI tools that are offered by Microsoft. Unfortunately, they have a lot of limitations. This is why you either have to learn how to use dsacls tool or PowerShell. My personal favorite is PowerShell for this task, but your tool is your choice.
On top of setting permissions that will either allow or deny an operation on AD object, we have to think about auditing. This is also set up in the same UI. Auditing rules are actually close shell because if you set them correctly your Windows operating system can keep track of all operation in Windows security event log and you can easily write a script or integrate to alert you or report all the changes you made in Active Directory. This is not the topic for today, but it will be nice if you think about it later on.
How Active Directory Permissions Behave?
Each AD object stores permissions as a security descriptor in the security descriptor attribute. What security descriptor contains? Information about inheritance. Then, we have deep DACL, which is access control list that consists of ACEs, which define the permissions the user has to this object. Then, we have system access control list, that also consists of access control entries. That defines the permission events that will trigger both success and failure audit messages. So, things that would be recorded in security event log.
Those two lists consist of ACE. Today, we are focused on DACL. Each access control entry consists of the following properties. We’ve got a Trustee, so this is the SID of a user or group to which ACE applies. Pretty straight-forward. The next property is ACE Type. This determines if ACE allows access or deny access. Object Type is schemaIDGUID. Often object type to which ACE applies or rightGUID if this is a property set. Obviously, we don’t work on GUIDs as humans so normally we have to resolve the GUID to visual representation.
Then we have another property called Inherited Object Type. This is a schemaIDGUID for a type of a child object that can inherit this ACE. Access Mask defines a type of access read guide for instance and Flags specify inheritance settings.
IWhat can be a little bit cryptic are those object types, but don’t be afraid. It’s very simple to realize how it works. Object Type user has one GUID, a very long unique string object type, Computer has different schemaIDGUID and so on. Those long strings can be resolved to proper classes using Active Directory Database.
Inherited vs Explicit Permissions
Now, the next thing when we are talking about Active Directory permissions is to know the difference between inherited and explicit permissions. Explicit permissions are permissions that are directly applied to an object. And inherited permissions are permissions that are applied at some level of the tree above the object and flow down to the object and its children, so they’re inherited. Pretty straight-forward. Here is one myth that I would like to debunk straight-away. Trainers, consultants, often say deny overrides everything. Nope. It’s not true. There are certain situations, and I will show you that on the demo, where denying doesn’t override everything.
When we are talking about the permissions in ID, you have to understand three rules. Deny ACEs override grant ACEs of the same type, and point in the directory tree. So, if on a single object, on the same level, we have allow and deny, deny will win. However, there is also the second rule. Explicit ACEs override inherited ACEs. So, the permission that is nearer the object would apply, in plain English. And the last rule is that inherited ACEs are hierarchical and inherited deny applied to a container will be overridden by an inherited grant applied to containers nested below it.
Active Directory is a tree structure, and also it applies to inheritance, how it flows through the branches. So, let’s move to the first demo of today.
Demonstrating that deny doesn’t always override all. Let me start with the creation of TestOuPerm and TestOuPermChild. Let me show you a graphical representation. Nice and clear.
Now, let’s play a little bit. Let’s move to TestOuPerm. Security tab, let’s click. Advanced. And I will select my test username, Bob. Okay. Let me clear. Let me full permissions. Yep, everything is clear. I will change the type to deny and will deny Bob from creating computer accounts. Create computer objects. Okay. Apply. Okay.
So, generally, this should prevent Bob from creating computer accounts under TestOuPerm. Now, I will modify TestOuPermChild. I’m not going to disable inheritance, so let me just add Bob here. Come on, Bob. I will clear all the permissions and I will allow Bob to create computer objects. Apply. Okay. And okay. Again.
I will move to Windows 10 machine. Let’s check who am I. I’m Bob. Let’s try to execute. This command let. And as you can see, computer account was created.
Let’s create another computer account, however, on a different path. This is directly under TestOuPerm. And as you can see, I wasn’t able to do that. Please remember this lesson. For you, explicit permission will override inherited permission. So, although Bob is prevented from creating computers here when we allow him to create computer accounts here as you can see, he is able to do so.
3 Ways To Delegate Permissions
Okay, let’s move back to the presentation. The major topic of today, delegation permissions. There are three ways to delegate permissions. The first one is pretty straight-forward, although we don’t have too much control over it. When we install a software, often the software installation will require that some of the permissions will be delegated. A good example here is the installation of Exchange server, that will delegate multiple Active Directory permissions to groups related to exchange server. Okay. We should be able to report all those delegated permissions, but if we would like to install everything without changing the default proposed by Microsoft, we don’t have too much say here. Obviously, we can, on our list, modify the permission after the installation.
The second type of delegation occurs when domain administrator or another privileged account delegates the permissions manual. So, this is not often done, but from time-to-time, we perform manual operations, and here the rule also applies that we should perform proper change management for that.
The third and the most common type of permission delegation is the usage of the delegation of control wizard. This tool will allow administrators to delegate management of certain types of objects to individuals or groups within the organization. So common things like creating a support group, help desk group, delegating a help desk operator permissions to manage users who sits near to him, so Active Directory that is divided into geographical regions, those things would be common. However, this tool is far from perfect.
What Are Attackers Hunting For?
The wizard is useful only when we need to delegate clearly applied for permissions. Like, for instance, create computer accounts, or create users. However, it’s not useful when we would like to specify deny permissions. There is no such option. Okay, another problem would be to remove previously delegated control. And this is what actually attackers are hunting for. You delegate the permissions, you grant too many permissions by mistakes to someone, but because there is no nice wizard to remove the permissions you just keep them without any modifications hanging for an attacker to abuse them.
Also, the wizard doesn’t allow me to delegate control over individual objects or apply special permissions to branches of my Active Directory tree. So, there are some limitations to know there. Because of this limitation and the fact that many Active Directory administrators don’t like to work with PowerShell or command line tools, quite often what I see during audits an inaccurate control of permissions we delegated to certain users.
Also, I see quite often a lack of general concept that can lead to whole Active Directory compromise by an attacker. So, as I told you at the beginning, a good plan, good architecture is crucial here.
Another issue coming from Microsoft, there is no easy way to report all permissions on Active Directory objects. Obviously, you can use some tools provided by third party vendors, or you can use a custom PowerShell script and this method I will demonstrate. This is a script you should analyze after this episode of Hacks Weekly, and you should try to build up using as a baseline this script so we can create a really nice custom too.
Diving Into Code Of The Script
Let me just walk you through the code of this script. It’s not long. It’s quite straight-forward.
Okay. First, we select those system guids because ideally would prepare to see user computer instead of system guid.
So this is done here, and here I’m guttering the guids of extended rights.
This would be nice for me to have a textual representation. I’m defining another of containers, so I’m starting with a domain, this is also an object on which I can set permissions in Active Directory. Then I’m moving to containers, object class container, and then I’m gathering all Ous in my environment. And the final step is to loop through all ous and containers that are here and just apply a standard common lets Get-Acl. We have the prefix AD obviously to get Active Directory object. Guid resolution and finally export to CSV.
Okay, I will show you the final result. As you can see from a small example domain, quite a long script.
But you can simply add filtering and for instance, let’s report the permissions of user Bob. Okay, and the same can be applied to any column of this report.
So, here we can see that Bob has some permissions when it comes to computer accounts, and also some user accounts. Okay, so, the script and the usage is straightforward and I would highly recommend you to gather such information and compare it over time. You can do it on a schedule every month or every quarter. Depends on your environment, obviously.
Adjusting Active Directory Rights
On top of it, you can also adjust what Active Directory rights you’ve gathered, because only certain rights are interesting for an attacker. And, let me describe the most interesting that I see in Active Directory that I can use during a pen test.
Force change password, okay. This gives me an ability to change user password without knowing it’s current value. So this is a password reset. Add members. This is an ability to add members to Active Directory group. And obviously, if the group is privileged, like domain admins, for instance, then it’s pretty straight-forward.
GenericAll. This is basically full control over Active Directory object. Even in guid’s written full control if you would be interested in setting it to guid. Possible attacks here, change the password, add the user to a group, Kerberoast attack. Three of the most common. There are potentially some other. GenericWrite. This is an ability to write to any non-protected property of an object. As you know, every object class in Active Directory has multiple properties and here I can modify them. Example attacks, add a member to a group, Kerberoast attack. Those two should be enough.
Here, another tool, my favorite two permissions to abuse. WriteDACL. This gives me an ability to actually write a new DACL on an object, which means that I can modify any permission.
WriteOwner. Another interesting permission because I can grant object ownership to another security principle. And a small hint when you’ll be using that during an attack, object owner can override what is written in DACL. So, actually, this renders DACL ineffective for object owner.
And, the last is AllExtendedRights. This permission gives me an ability to perform any function defined as extended right. You can use my example script for listing permission for all potential extended rights. And, here, examples would be, again, changing the password, adding to a group. And, very nice permission, last, but definitely not least is DcSync. This gives me an ability to become a domain controller. Obviously, I want to become a normal domain controller, but if I have DcSync permission it means that other domain controllers will think of me as a domain controller, and this exposes the environment to a bunch of potential attacks. Okay, so we are done with theory, let’s move to practice. I will show you how a small mistake with delegation can dismantle your whole organization.
Practical Approach On A Real Example
Let me create a new organization that you need for a test called Berlin.
Let me create a new user under Berlin for you. Okay. We’re good to go. Tom is my new domain admin working in Berlin, so let’s add him to domain admins. Perfect. Now, let’s say that I want to delegate control over BerlinOu to Bob. Bob is a support person working in Berlin location. He will be helping users with common problems. Okay, so, let’s select Bob. And Bob will be responsible for the creation, deletion and management of user accounts, and also for resetting their passwords. As we all know, people tend to forget their passwords, so this is quite standard set of net permissions that we delegate to support or help desk person. Next, finish. Perfect.
Now, let’s go here to Windows 10 machine. Okay, and I can see user Tom. I don’t know his password, however, I’m ahead of this guy, so a guy with a lot of powers. So, let me reset his password. And I will set his password to hash, capital E N D C, four R F B.
Okay. Let me just kill it. Let’s open CMD as user Bob. Well, I’m Bob. Bob is even not a local admin on this machine, so let me run CMD as user Tom. Right now I’m Tom. It wasn’t any issue, because I just set Tom’s password. Let me quickly create a backdoor user. And let me add my backdoor user to domain admins group. Okay. Perfect.
Now, this was pretty straight-forward. You all know the comments knocking fence. However, this is not a good practice when attack. Because the next day that Tom will come to his job he will realize that the password was changed. And Tom, he’s a smart guy, and he will start digging into the logs, what the hell happened. So, what a smart attacker can do? A smart attacker can pull one more trick from his sleeve. We’ll do something like this, so we’ll be using mimikatz. I will do lsadump::dcsync for user tom. On domain cqure.lab.
Okay. Let me scroll a little bit. And what we can see here, a passwords history for user Tom. So, and here ntlm 0 is my current password. Ntlm 1 is my old password. So let me copy my old password, actually Tom’s old password and will use lsadump module again, but this time with setntlm. User again Tom. Here the switch is a server so we provide a domain controller on which this comment will be executed, so dc zero one cqure.lab in my case, and we provide the old ntlm hash. We’re good to go. Let me exit, exit, and here you have to trust me that I will open CMD with old Tom’s password, which is standard Microsoft password. So now it worked, so try it at home if you don’t trust me. And as the last step I’ll show you that we have a user called backdoor and this user is a member of domain admins.
Okay, that will be all for today. I hope you liked it. So, have a play with what I showed you and test security in your Active Directory.