The ADvice nobody takes


Why acronyms like AGDLP, AGLP and POLP are rarely followed and why non-repudiation is so rarely configured in Microsoft Active Directory. I’ll try to explain the articles Microsoft has available on the subject (for instance here) without making it too technical.

Administrator privileges

One of the most important parts of an active directory you’ll need to protect is the administrator roles. In AD alone, there are a core three of them:

The Enterprise Administrators
This administrator level has full administrative access to every domain in the forest. The Enterprise Administrator is the highest privilege you can be assigned in the Active Directory system.

The Domain Administrators
This administrator level has full administrative access to one domain in the AD forest.

The built-in Administrators
This administrator level has full access to all the domain controller computers in the domain. The administrator group includes both enterprise administrators and domain administrator groups.

In the back end the administrators are all the same in what they can do privilege-wise, the only difference is to what level the account privilege are applied.

What is common (and default) is to have both enterprise administrators and domain administrator groups nested inside of the built-in administrators group, together with the administrator standard account. This is called group “nesting” meaning you put one group inside of another. I’ve drawn the concept here:

Just to be entirely clear, this view is like a pyramid seen from above. The Enterprise administrator is the foundation of the pyramid with the greatest privileges, domain administrators are the middle, having more privileges than the top of the pyramid, the built-in administrators. Seen from the side, it’d look something like this:

Yeah, yeah, I know. Drawing perfect pyramids in Visio is hard – OK?

What is an AD forest?

I’ve referred to AD forests several times, both in this text and other articles on my site. It’s a simple idea, but I’ve worked with several consultants who get this wrong. Thus, I want to talk about it before moving on.

An AD Forest is simply a domain in an AD with a trust to a different domain. Say for instance you work for a large company called “Glory”. The company has over time bought a slew of different companies who became satellite branches. Instead of putting everyone in the same Domain Tree, the existing users where left in the same Active Directory tree they originated in. This leaves the domains blue.com and red.com, with trust between them. Domain trust means users in one domain can be authenticated by a domain controller in the other domain. Varonis drew this beautiful drawing:

Collected from here

One of the reasons for creating these domains would be in scenarios where the different trees require different group policies or configuration structures. You may have noticed the red circles called “Organizational Units – OU” in the drawing. These Organizational units are used in different ways, but are designed to put users in different “departments” – often referred to as “Organizational units”. What you’ll see often however, is that there are OU’s nested in other OU’s. It would look something like this:

All of the blue boxes are Organizational Units, allowing Group Policies to be connected to them. Here’s a drawing of the concept:

When you’re working in a domain you’re interacting with several organizational units and the policies contained there in. This is the reason why you’ll get the warning when you’re moving an object from one OU to another.

Picture collected from here

What is a group policy?

Group policy is a configuration profile assigned to a group or organizational unit making changes to computers, user profiles or servers based on .admx files stored in the Sysvol share on the domain controller. These should be updated regularly to allow for updates and better integration with new software solutions. I’ll go further into this on a later date when we’ll talk about OMA URI’s and Microsoft Endpoint Management in a different article.

The point to remember is how Group Policy manage configuration profiles assigned to organizational units.

More about Group Policies for securing AD and Microsoft networks in general below.

Layered administrator approach

So, what does this mean for the administrator structure? As you now understand – securing the administrators is one of the most important parts of securing your Active Directory implementation. The best practices article on protecting the administrator profiles states how the implementing administrator should restrict what privileges are allowed for the different administrator accounts, and provide all administrative users with several layers of users with different, difficult passwords. I’ve drawn it up like this:

The reason you should refuse Domain Administrators and Enterprise Administrators from RDP, batch and local logins is because these privileged users should not be used to log in. One of the reasons for this is because the user session can be hijacked using very simple tools.

Actions requiring domain or enterprise administrator privileges should be activated using the “Run as…” solution. This reduces the error vector as the normal user need to make deliberate authentication in order to make the changes they need. None of the administrator roles should be used for service applications or batch job functions, as this opens up for changes to the scripts or applications they run, providing a way for attackers to create higher user privileges for themselves.

Principle of least privilege

The Principle of Least Privilege is important when you’re working security minded. The idea is to only provide the users with the minimum privileges they need to accomplish the job are supposed to do. In that essence you’ll have the following best-practices requirements for the administrator users:

Open the picture in a new tab or review the PDF in the end. WordPress doesn’t do image scaling well

When your users require privileges, you should carefully investigate what privileges they require to do their jobs, and on what servers their privileges are required. After the investigation, you should only provide the user with the privileges required, and no more. This should be noted in the quality assurance system of the organization and carefully maintained.

Account Global Domain Local Privilege or Account Global Local Privilege

When we’re talking about privileges, we have to talk about file privileges. One of the things I see way too often the lack of privilege control on file servers, or simply bad implementations if they exist. One of the most common one are companies who try to implement group privileges, but fail to remove the standard privileges, allowing default privileges as well as the control-list. Or we find simply users added directly to the NTFS (file structure) privilege list.

Not removing default privileges
Well, now why would that be bad? The standard privilege structure is to allow the author full control (meaning all access and all privileges), administrators and SYSTEM get full control as well, while the rest of the users privileges are inherited. In File servers, you would usually control the root using standard settings and share settings. Commonly, these are “authenticated users” (all domain users who’s logged in) with read/write/execute privileges.

What’s so bad about never removing default privileges then? Well, you end up providing more privileges than you reduce them. If you allow all authenticated users read/write/execute privileges as well as your access control list, providing only read/write to a certain group of users – you’ve provided the group and everyone else more privileges than you wanted to.

Adding individual users to the NTFS privileges
One of the most common problem is having users added directly to the file-privileges on folders. This isn’t necessarily a problem, but it’s pretty difficult to maintain. One of the worst situations I’ve ever come across was a NTFS list on HR for a company with no less than 80 individual users assigned directly to the list with different settings.

So what’s AGDLP and AGLP? Let’s look at a what it means and what it stands for:

AAccount
G Global Group
DDomain Group
L Local Group
PPrivilege

AGLP is the same, just without the second layer of groups. The principle is easily described like this:

Drawing up the difference you have AGLP simply explained like this:

Taking you step by step through this drawing, you have the production users (Account) who are members of the Production users (Global Group) which are set in the (local) access list providing read (privilege) on the Production documents. This is usually not viewed as “great”, because you’re setting the group where users are members as privileged to the files automatically. This allows very little control on the back end, where you’ll have users who are part of the Production users, but need higher privileges. You’d have to choose either error two and assign individual user privilege or create another group and assign the user to that one.

AGDLP is not very different, but allows you a little more flexibility:

Imagine you have two offices, Oslo and London. Your AD is structured as a forest with trusts between the two AD trees. There are Production documents in the Oslo branch, and London production users need access to the share too. You add both the London and Oslo production operator groups to Production Documents Reader group, providing them with read access to the Production documents share. This is often referred to as Role Based Access Control structure in Active Directory.

If you were to provide more privileges, you should create another set of groups:
%Location% Production Operator – Writers
Production Documents – Writers
NTFS:\Write privileges

Auditing of privilege

When you’re working with privilege you’ll need to configure control of their use after the rights have been assigned. This is one of the reasons you always provide all administrator users with their own named admin user. One of the worst errors I see as an incident responder is when the leaked credentials are the one of a partner or “shared administrator”. The concept is called non-repudiation. I’ve written about it before, but here it goes again:

Non-repudiation
When you want to make certain a person has to sign their name to an action, making it impossible to say “I didn’t do this”. A signature on a contract is often a non-repudiation process, allowing the contract holder to enforce a deal even if the other party say “I didn’t sign this”.

When it comes to Active Directory, you’ll have to configure auditing yourself. Normally, AD will not audit any privilege use or object access:

If you want to meet best practices entirely, you should consider investing in a SIEM (Security Information and Event Management) platform. These servers or services collect and analyze logs from different sources, looking for anomalous actions and malicious activity. By streaming privilege use, account management (changes to privileges or creation of new users), policy changes and directory services actions, you’ll know exactly what happens to your users and privileged accounts as it is in progress.

Kali said it best:
The quieter you become, the more you’ll be able to hear.

It’s the same thing, the more information you gather of the right sources, the easier it’ll be when you’re eventually attacked.

Some Group Policies you should consider activating

There’s so many things you’ll need to do in order to completely be protected with Active Directory. Microsoft 365 notoriously have 25.000 settings, AD is almost the same. I’ve collected some things you should consider doing in order to protect yourself from being “easy pickings”.

Deactivate NetBIOS and Link-Local Multicast Name Resolution
One of the simplest attacks today is to use NetBIOS (a low level communication system for Windows computers) to redirect communication to themselves and force users to authenticate directly with the attackers computer. This would allow the attacker to harvest user accounts easily and gain lateral movement (upwards movement – privilege-wise). NetBIOS is a little tricky to turn off, as there is no Group policy for it, but I’ll put a script deactivating the function on a text file you just need to copy and paste into a PowerShell ISE window, save and put into a group policy to configure. Be certain you have no legacy systems relying on NetBIOS before you activate the script.

I’d like to point out NetBIOS has been around since the 1980’s, it’s time to let it die. See the bottom “file” area for the script and other documentation.

Link-Local Multicast Name Resolution is a function of DNS ran over either IPv4 or IPv6, allowing the lookup of a computer in the network without passing a DNS server.

Picture collected from here

The idea is to spray the entire subnet with UDP packages in the hopes a computer will respond with it’s name and IP address. What the attacker will do then is to impersonate another computer, and put itself as the man in the middle, allowing the username and password keys to be recorded and forwarded to the server you wanted, making it seem like everything is working as intended.

Luckily, it’s very simple to deactivate. There’s a GPO for it under:

Computer Configuration\Administrative Templates\Network\DNS Client\Turn Off Multicast Name Resolution where you should set the policy value to Enabled

Picture collected from here

Deactivate old protocols
This one goes without saying, but there’s not a week going by without the consultant team finding servers with SMB1.0 server configurations, unsigned SMB3.0 or allowances for old SSL encryption. Remember: Microsoft expects you to turn off everything you don’t use. This is paramount every single time you configure a computer, server or network appliance. Turn off everything you don’t need!

Turning off old SSL versions
Have you ever tried to open internet explorer on an XP computer lately? It barely works, because XP doesn’t support modern encryption methods. If you’ve turned on and secured your webpage or web-application with TLS1.2, you can safely turn off everything below it.

Picture collected from here

If you don’t turn these off, an attacker can force your server to downgrade the encryption level to a setting the attacker can decrypt using other methods. This could mean the user could start sniffing the encrypted traffic. There are programs who will help you with the process, because Microsoft IIS is stupidly difficult in this prospect. I’ve used Nartac’s IIS Crypto application to do this:

It’s free and simple, and has a button for Best Practices, and can even help restrict Cipers, Hashes and Key Exchanges, giving you a much greater handle on what is going on in your web server. You can find more information about it here.

The point is to end up here:

Picture collected from here

Insecure AAA configurations
AAA is an acronym for “Authentication, Authorization and Accounting” and is common in the identity world, as it covers services who allow user login and privilege checks.

Authentication – User logins and approval
Authorization – Is the user have the right to use this resource?
Accounting – Logging and keeping track of the users authentication details

One of these processes are the Active Directory integrated LDAP (Lightweight Directory Access Protocol) functionality. When used correctly it’s per example used to allow access to VPN (Virtual Private Network) through a concentrator device like the SonicWALL SMA series using the username and password stored in Active Directory. However, the LDAP service in it’s basic configuration is not encrypted, making sniffing a simple attack vector for an attacker inside the network.

Using a certificate issued by Active Directory Certificate Authority or purchasing a public certificate you can encrypt the communication between these two devices, eliminating the sniffing vector. The two security settings look like this:

You’ll need to set the client settings signing requirement to enforced before you can require the Domain Controller policy to enforce signing. This makes sense because the other way around would break the LDAP service. Remember to install the public certificate in the service who need to encrypt the authentication too.

Activate Network Layer Authentication for Remote Desktop Protocol for servers
I can’t believe I have to say this, but please activate the NLA requirement on all the servers you can. The reason for this is to restrict the following:
– Service enumeration (an attacker will be able to read the Windows version)
– User enumeration (an attacker may be able to read out users in the system

But worse of all:
The attacker will be allowed to land on the login-page of the host, without providing any authentication details:

Picture collected from here

Going to Shodan.io we immediately find an open RDP port without NLA like this:

Simple search string: country:”NO” port:”3389″

Here you can see we can easily tell the name of the domain as well, with both TLS1.0 and TLS1.1 (deprecated) available as encryption options. Don’t make these mistakes. They will not serve you well, especially if you expose RDP on your firewall.

Believing a “hidden” share is a safe one
I’ve written about this before, but one of the gravest mistakes I see is when user privileges are not restricted on file shares. To compound this issue, there are often “hidden” shares where there are little to no security handled by the organization. The reason for this is because the administrator believes users “will never see it”. Problem is, a simple PowerShell command will easily list them out, even if you’ve marked them as hidden. The only difference between a hidden share and a visible share is how annoyed I’ll be when I need to write $ behind the share name to get it accessible. Please don’t do this.

In this picture you’ll see the “ADMIN$” share visible by just checking for it. Any user can look for it using the following PowerShell command: “net view /domain domain name /all” – that’s it.

Thing is, you’re just hiding it from users who don’t need to see it. An attacker will know how to find it. In the same line of discussion is the though of putting “Scripts” folder as a share. If you do, be very careful with who has write access to the share. If I can add myself as an administrator by just adding a few lines to a script you have running as “SYSTEM” through scheduled tasks – sweet, thanks. I can wait the 24 hours for you to trigger the “trash collection” script you have emptying all the user’s recycle bins.

Password policies

Do you remember a time where there were no expectations on your passwords? A time when grandma’s password was just granddad’s name? I remember my first password: “RunDMCbby”. I had just figured out Run DMC was cool (it was the 90’s) and taught myself how to use DC++ (old sharing platform where users could share their collected loot by joining community servers).

Ah, the gold of a bygone era. Sadly we’re not there anymore. In the late 2000’s we got complexity requirements where the user was required to meet at least two of the alphabets, both capital and normal: a-z and A-Z and a special character. I really appreciate Michael McIntyre’s tirade on the subject. Most users kept the same password they had and added an exclamation sign on the end.

This is actually where the default AD configuration is today:

This picture is collected from a customer Domain Controller, who is set up with the default password policy. The Policy requires the users to change passwords every 300 days, where the last 24 passwords are not allowed. The user may however change their password at any time between 24 hours after last set to 300 days. The password must at least contain 8 characters, with complexity requirement enforcing three out of five complexity categories:

1. Lowercase European letters: a-z
2. Uppercase European letters: A-Z
3. Base 10 digits: 0-9
4. Non-alphanumeric characters (special characters): ~!@#$%^&*_-+=`|\(){}
5. Any Unicode letter not found in option 1 or 2. Asian letters for instance are included in this group. Norwegian æ, ø or å is part of this group.

What’s wrong with this policy then?
Today we know a few more things than what we did back in the early 2000’s about how users behave and how to properly secure our user accounts and other objects. First thing is to stop requiring users to change their passwords regularly. Like I wrote in my “right to life” article: Any system not designed with a user-centric perspective will not be used. This means when obstacles are put in a user’s way, it will find a way around the obstacle instead of going the intended route. Ukrainians have a great word for this: People’s roads

Picture collected from here

Forcing users to change their passwords regularly only serves one purpose: Creating IT overhead. The users will chose easy to remember passwords, which lack proper complexity and you’ll end up with passwords like “Summer2020” or something akin to this. Last time we ran a password spray using a list of “Summer1990-2022” and similar, we had a hitrate of just above 15%. In addition, you’ll have a lot of users who require support to reset their passwords because they’ve been away from work and forgot what they set last time they were asked.

Side note: If you’re a Service Desk consultant, please don’t use these kinds of passwords. I want you to know most users don’t change the passwords they’re provided by the Service Desk. If you provide a user with this kind of password, you’re teaching your users they are acceptable.

This is why forcing users to change their passwords is a really bad idea. In addition you have the question of length. In the security business we’ve moved from passwords to pass-sentences. This changes the required length from 8 to 16 or 24, depending on who you’re listening to (Microsoft: 8, Pluralsight: 24, Nettvett (Norwegian IT resources group):16). The idea is to make it difficult for a computer to “guess” the password. Here’s a chart explaining the time it takes in 2022 to crack a password by random guessing.

Picture collected from here

As you can tell, the policy collected from the default configuration take the full time of 6 minutes to guess with modern hardware. However, if you follow MS best practices and setting a pass-sentence of 16 characters and four out of five complexity categories (last column). It’ll take more than 4 quadrillion years to beat. That’s a thousand in the power of 8, more time than we have left with our sun. As computational power increases, it’ll take less and less time, but either way it’s safe for now. If you feel like reading about just how long it is, check out Wikipedia’s article about large numbers.

Domain Controller isolation

What’s your domain controller to you? The domain controller is one of the most sensitive computers on your network, and the core to everything you’re doing. If you’ve read the MCSA (Deprecated Microsoft Server Administrator certification) course documentation you have read how the domain controller should be isolated form the internet in order to minimize it’s attack surface. In the small to medium business market, this is rarely done, and the Domain Controller is often used a the jump server because of the central tools you have available on it. The picture below show a customer site I visited not long ago:

There are several problems with this picture. First of all:

Never install Microsoft Azure AD Connect on a Domain Controller
This is a supported scenario, but it’s not best practice. The reason for this is because Azure AD Connect has it’s own SQL Express DB’s, which can interfere with the Active Directory database. At best it works, at worst you’ll end up with a corrupted AD database down the line. You should have Azure AD Connect set up in a High Availability (a single failure shouldn’t take it down) configuration and on different servers than the Domain Controller. A structure like this is best practices:

AADC in High Availability means you have one AADC server (or server with AADC installed, and an identical installation, which is simply maintaining communication with Azure AD without actually publishing anything. It’s in Staging Mode, allowing it to be kicked into action should the other one go down. This is especially important if you have configured Pass-Through authentication, where the actual authentication is done in the Domain Controller instead of Azure Active Directory.

Don’t install unnecessary software on the Domain Computers
There are Management servers for a reason. Most computer programs who communicate online for some reason or other ask the user to allow their communication in their Host-based Firewall (Host-based Intrusion Protection System, HIPS) as part of their installation process. If you look at the picture, you’ll see WinSCP, which is a FTP, SFTP and FTPS program. FTP in particular has been deprecated because the connection and authentication exchange is performed in clear text. This application and the opening of port 21 (FTP) should not be allowed in domain controllers residing in modern corporate networks. For every application you install, there’s more to maintain. Take Chrome for instance, which is updated to version 101, but how often those updates happen is difficult to describe. The company in question does not have a patching strategy explaining their stance. Just for reference, check out Mitre’s CVE list for Chrome here.

What domain to use

One of hardest things about moving to the cloud is watching customers make mistakes we haven’t made for years on-premises because of good best practices documentation and guides – but they are simply not available in the cloud the same way. Take for instance the Azure resource “Azure Active Directory Domain System”, a fully managed AD in the cloud, reverse synced from your Azure Active Directory tenant. The idea was to be able to use a domain in the cloud without having to maintain a domain controller in your application.

Picture collected from here

What could possibly go wrong? Customers make the root domain the domain name. This creates all manner of issues, especially for authentication which intermittently locks legitimate users out because of failed tries. On premises we know there’s a right way and an OK way to set up domains in an Active Directory setting.

The right way:
internal.customer.com

The OK way:
customer.local

The issue is the TLD (Top Level Domain – the part after customer.com). Because creating your own TLD is allowed by ICANN (the organization overseeing the Internet). You can find a overview on how to do it here. This means you never known when .local can be started as a publicly available top-level domain. If it is ever registered, your users will send DNS requests and maybe even authentication requests to the A-record of the root domain. Exactly this was done in Azure by registering an internal DNS Zone just a few years ago, allowing other tenants to rely on the record and devices to send information to the zone’s root A record directly. BleepingComputer wrote an article on it in August 2021 describing the issue in AWS and Google Cloud.

When you put anything on a public cloud – first know you have the understanding required or help available to architect your solution properly and make sure you trust the underlying company with your data.

There’s another major positive effect of choosing the “right way” is how you can use public wildcard certificates to authenticate internal services, without any need for a trusted certificate authority. Remember wildcards allow anything.company.com. It does not however support two layers deep, like this: anything.anything.company.com.

Azure AD password protection – please use it

This is just an added bonus I wanted to throw in because of how awesome I find it. In Azure Active Directory Premium Plan 1 or 2, you get access to Password Protection, which evaluates passwords options provided by your users against a banned (custom depends on your license) list of passwords like Summer2020 when the user requests the change. Microsoft drew it up in a not-so-considerate way like this:

Picture collected from here

First the administrator provides a password policy to Azure AD, who compiles it and runs normal substitution controls (Autumn2020 is the same as @utumn2O$0 for instance) before sending the list to a proxy agent installed on a server on premises. The user requests the password change, asking the Domain Controller to confirm the password option. The Domain Controller then evaluates the password option against the list found by asking the proxy agent to send it to the Domain Controller agent. If the password doesn’t hit any of the passwords in the banned list, or is long enough to get enough points to get through, it gets accepted, if not it’s rejected and the user is asked for another option.

Notice too how the Domain Controllers in the drawing are isolated from the internet by requesting the information through two proxy agents instead of communicating directly with AAD.

It’s sleek, simple and no hassle to set up. Please use it!

Thank you for reading

I promised you to always add my files. First, the pdf of the drawings:


Then the NetBIOS deactivation script in text: