Internal networks are rife with lurking threats that often manifest in unexpected ways. Among these, logon scripts, a seemingly innocuous component of user and computer management, are one of the most subtle potential attack vectors. These scripts, intended to streamline user access and automate various tasks during login, can inadvertently become the Achilles’ heel of an organization’s security posture if not properly managed.
It seems counterintuitive, but I promise you, In an age where cyber threats continue to evolve, and adversaries continue to develop novel attack methods, it’s never been more important to get the basics right. Because of the “path of least resistance,” these and many other seemingly benign vulnerabilities could be the difference between an attacker fully compromising your environment versus deciding to move on to an easier target.
In this blog post, we will:
- Discuss what a logon script is and what its purpose is
- Describe four common logon script misconfigurations and how they can be used as an attack platform
- Share a free tool I created to help identify these issues
- Offer recommendations for remediating and mitigating risks with logon scripts
Finally, in the mitigation section for each use case, I will talk about a free tool I created to help find misconfigured and dangerous logon scripts called ScriptSentry. If you’re more of a listener than a reader, check out the podcast episode I did where I talk about this exact issue: https://offsec.blog/episode-54-misconfigured-and-dangerous-logon-scripts/
As with all the tools I write, the first and most important part is the logo and ASCII art. 😎 Let’s get into it!
What is a Logon Script?
So if you’re reading this, I assume you have some idea what a logon script is. If you’re already familiar with them, feel free to skip to the next section, where I dig into the common misconfigurations.
A logon script is a script that is executed under the context of a given user when that user logs into a computer in an Active Directory environment. That bit about running as the user who logs in will be important later on. Logon scripts can be configured in Group Policy and/or through the scriptPath attribute in the user’s Active Directory profile.
Logon scripts are great because they can be used to do all sorts of fun things like map file shares, add printers, update software, delete temp files, log login times, run commands, set background wallpapers, etc.
Identifying Common Logon Script Misconfigurations
Now that we know what a logon script is and what its purpose is, your gears may already be turning on how they could potentially be not only misconfigured but abused for network dominance. Let’s talk through some common misconfigurations in order of most to least commonly seen in the wild.
Logon Script Misconfiguration Summary
- Use case #1 – Plaintext credentials
- Use case #2 – Mapping file shares/deploying files that have unsafe permissions
- Use case #3 – Logon scripts with insecure permissions
- Use case #4 – Mapping non-existing shares
Use case #1 – Plaintext credentials
This is by far the most common misconfiguration we see on internal assessments. The way this issue manifests is as a result of configuring a logon script to map a file share with explicit credentials. This is typically when the file share has limited permissions, but IT Admins still want a user or several to have access to the share. Here’s an example of what that may look like:
With ScriptSentry, finding plaintext credentials in logon scripts is a breeze! There are multiple regex patterns that ScriptSentry uses to find credentials, and it can search in all the various logon script formats (bat, cmd, vbs, ps1).
It’s never a good idea to put plaintext credentials in any file or script for a number of reasons. The recommended way to handle this scenario is to delegate permissions on the file share itself for the users/groups that need access. Whether IT Admins realize it or not, logon scripts are readable by all domain users (and sometimes even anonymous users), so if credentials are left in these scripts, they can be seen by anyone that can open the file.
Use case #2 – Mapping file shares/deploying files that have unsafe permissions
The next most common misconfiguration we see is when there is a logon script that’s either mapping a file share, deploying a file, installing a program, or something similar but the share where the resource is located has unsafe permissions. In the example below, the run.vbs logon script is running a batch file located on fileshare1. If we look at the permissions of fileshare1 we see that the “Everyone” group has Full control. Yikes!
What’s the impact, you may be asking? Well, everyone, including all Domain Users and potentially even Anonymous users, can modify it. That means that through this innocuous little logon script, any user can execute commands or code anywhere this logon script is run. In most environments, we typically see a small number of logon scripts that get deployed to the organization’s entire user base. So, imagine if an attacker on the network is able to execute commands on every computer (and server) in your environment without ever needing admin privileges. That would certainly be a bad day.
This one is pretty bad and very risky, but the good news is, like the previous issue, it’s very straightforward to remediate. First, you want to review all of your logon scripts to ensure that any mapped file shares do not have unsafe permissions like this. Unsafe groups that tend to have elevated rights on file shares include Domain Users, Authenticated Users, and Everyone. Then you should review the permissions on all scripts and programs that are being run from file shares. Many times these permissions issues occur first on the parent directories, but not always. I’ve seen situations where the file share was configured properly, but a mistake was made on a batch file that allowed all users to modify it.
Here is ScriptSentry coming in the clutch because it can identify not only misconfigured file shares but also files themselves. ScriptSentry is great because it will show you the type of issue it found, the file or folder it found the issue on, the user(s) that have misconfigured permissions, and the rights they have been granted. In large environments, it can take some time to run, but the results speak for themselves.
Use case #3 – Logon scripts with insecure permissions
The next two use cases are a bit more under the radar and innocuous, but once you see the risk, I promise you will agree you have to go run ScriptSentry in your environment immediately after reading this blog post. This issue occurs when the logon script itself, or perhaps the NETLOGON share, is misconfigured such that it allows Authenticated Users, Everyone, and/or Domain Users write or modification rights. You can imagine that if any given user can modify any given logon script, the results could be pretty bad. This would allow for code execution, lateral movement, and even privilege escalation, all with built-in tools and very little in the way of out-of-the-box detection.
The screenshot above shows that Domain Users do in fact have Modify and Write permissions on this logon script. You may remember from the previous use case that run.vbs is being used to execute a batch file. Since any Domain User can modify this logon script itself, any non-admin user could modify this VBScript file to do pretty much anything. An attacker on the network could abuse this to achieve lateral movement or even to elevate their privileges.
To mitigate this issue, audit the permissions on all of your logon scripts. Ensure that unsafe groups such as Everyone, Authenticated Users and Domain Users do not have elevated permissions on these logon scripts. Furthermore, check the NETLOGON and SYSVOL shares themselves to ensure there are no upstream permissions issues. ScriptSentry makes this quick and easy to check. ScriptSentry is able to find these pesky misconfigured logon script permissions.
Use case #4 – Mapping non-existing shares
This issue occurs when a file share that’s being mounted in a logon script no longer exists. Specifically, the server the share resides on no longer exists. Now take this up one more notch. Imagine that this logon script is being used by Domain Admins. I think you may be able to sense where this is going.
The reason this is dangerous is because, by default, Authenticated Users can create new DNS entries, and in some situations, Authenticated Users can update existing DNS entries. In these configurations, an attacker on the network (running under the context of a non-admin) could create a DNS entry for this non-existing server, point it to a host they control, and from there could either 1) steal plaintext credentials/hashes or 2) relay authentication from one host to another. As we will see in the next example, the worst-case scenario of this is extremely dangerous.
In the screenshot above, a low-privilege user creates a new DNS entry for the non-existing server. The DNS entry points to an attacker-controlled host on the network. The screenshot below shows using a security tool called Inveigh to capture, spoof and respond to requests made to the attacker-controlled host. Since ITAdmin has a logon script set that attempts to map this non-existing share, the attacker is able to obtain the NTLMv2 password hash for the ITAdmin account once the account logs in.
To resolve this issue and defend against this type of abuse, you first want to audit all your logon scripts. Check to make sure there are no file shares being mapped that no longer exist. Next, you will want to ensure that Authenticated Users cannot create new DNS entries nor modify existing DNS entries. The best mitigation is to create the DNS records manually as part of the domain join process and to revoke the permission granted to Authenticated Users. However, if that’s unrealistic in your environment, you can replace the identity that has been granted the right to create DNS records from Authenticated Users to Domain Computers.
Then, create a wild card DNS entry as an Administrator that points to a sinkhole, such as 0.0.0.0. Creating this static wildcard DNS entry as an administrator will prevent non-administrators from creating their own wildcard entry. Furthermore, this wildcard entry will also help mitigate LLMNR/NBNS spoofing.
Lastly, audit all of your user accounts that are members of privileged groups (Domain Admins, Enterprise Admins, Account Operators, etc.) and 1) check to see if the scriptPath attribute is set and 2) if there is a logon script set, review it for the misconfiguration above. I would highly recommend NOT allowing admin accounts to have logon scripts applied. Instead, use Group Policy or even Intune for management.
Again, ScriptSentry is an incredibly valuable tool because it will identify all the Admins in your environment that have logon scripts set. That way, you can manually verify that there are no misconfigurations with the logon scripts that are configured for those admins.
The silver lining of the issues described in this blog post is that they are all low effort to fix. Even if you have a big environment with a lot of logon scripts and a lot of mapped file shares, remediation should be straightforward.
If you’ve gotten this far in the blog post, I thank you and salute you. I appreciate you taking the time to read about this issue. I sincerely hope the ScriptSentry tool I created, combined with this blog post helps you discover and fix these issues in your environment. If you do give ScriptSentry a try, I would encourage you to leave me feedback on Twitter and/or LinkedIn, and if you run into any issues, have any questions, or have any ideas for new features, don’t hesitate to create an issue on GitHub.