October 22, 2015

It has been far too long since I have covered something directly relating to IT Security, but today we will briefly go over a sometimes overlooked risk to a Windows Domain Controller's database file (NTDS.DIT), along with covering a potential mitigation for this risk.

What is NTDS.DIT and Why Should You Care?
To quote Microsoft, "Active Directory data is stored in the Ntds.dit ESE database file." This, unfortunately, doesn't really get the point across as to how important this file is both from a functionality perspective, but also that of security. Essentially, almost everything that is referenced by Active Directory is stored within this file. This includes User Objects, Groups, password hashes, etc. Yes, password hashes are stored in this file. Typically, this file is constantly locked by the SYSTEM user when the Operating System is running, and is not accessible by any other user whatsoever.

There are, however, a handful of ways for an attacker to obtain access to this file and its contents. Doing so allows them to copy down the file to a portable device, with which they can later extract and crack the password hashes stored within. One way would be for an attacker to boot the Domain Controller into a Linux environment, which allows the file to be easily accessed as it is no longer locked. This, however, would likely be noticed VERY quickly by an administrator of the system. Another way would be for the attacker to upload and run an application which would allow them to negate the file lock, but this might also be caught fairly easily by an administrator. There is, however, a fairly simple method, which is quite effective, that would allow the attacker to utilize a built-in feature in order to obtain the Active Directory database file... Volume Shadow Copy.

For sake of time, we will assume that the attacker has already obtained access to a Domain Administrator account, or some other account with the necessary permissions. Once they are able to log into the Domain Controller, they would essentially need to utilize the vssadmin utility to create a Shadow Copy of the C: Drive. Like so:

vssadmin create shadow /for=c:


Once the Shadow Copy is complete, they would merely need to copy the NTDS.DIT file and the Registry SYSTEM hive from within it. Using these, they could easily leverage one of the many freely-available tools in order to begin cracking all of the password hashes at their leisure.

How to Mitigate This Risk?
Fortunately, it isn't too incredibly difficult to provide a certain level of mitigation against this risk. In essence, you will need to remove the ability to start/stop the Volume Shadow Copy service from ALL users on the system(s), and to remove the ability to modify the security settings of the Volume Shadow Copy service from ALL users except for SYSTEM. In order to do so, you will need to follow the steps outlined below.

First, you will need a way with which you can easily deploy these changes and ensure that they remain in-place. For this, it is recommended to utilize a Group Policy. This should be a simple task for an administrator, and will therefore not be explained in detail. You will, however, need to do the following:
1. Create a Domain Group that this GPO will be applied to
2. Add your Domain Controllers into this Domain Group
3. Create a new Group Policy that will be applied ONLY to members of this Domain Group

Now that you have a Group Policy created, you can begin configuring the risk's mitigation. For this, you will first need to drill-down into the following location within your new Group Policy, Right-Click, and select Properties.

Computer Configuration -> Windows Settings -> Security Settings -> System Services -> VSS


Within the initial properties for VSS, you need to ensure that Define this policy setting is checked, and that the startup mode is set to Manual. Next, click Edit Security.



Within the Security for VSS screen, remove all Groups/Usernames from the list except for SYSTEM. After this, click Advanced in order to open the Advanced Security Settings options.



You will now need to ensure that SYSTEM has all permissions configured for DENY, except for Read Permissions and Change Permissions. After this, you can close out of the Permission Entry for VSS screen and return to the previous one.



Back in the Advanced Security Settings for VSS screen, you will need to click on the Auditing tab. From here, you will need to ensure that logging is enabled on ALL failures, and enabled for Successful starts of the service. Once this is complete, you can close out and save your changes.



After having done all of this, you may be wondering how exactly this all mitigates the risk that was previously presented. Essentially, what you have done is to force the Volume Shadow Copy service to only start manually, which prevents reboots of the Domain Controller from starting this service. You have also removed permission to start this service from ALL user accounts, including SYSTEM. This ensures that if an account happens to be compromised by an attacker, they cannot start the service. Auditing has also been enabled on this service, and will log any failures against it (e.g. someone attempting to start the service).

While the Volume Shadow Copy service is now restricted from being started by anyone, you did leave the ability to modify security permissions on this service to the SYSTEM account. This allows you, in the event that you utilize VSS for backups, to use the SYSTEM account to change the security permissions on the Volume Shadow Copy service to allow the service to be started by it. By doing this, you still retain a small risk, as someone could compromise the SYSTEM account and modify the security permissions, which is why Auditing was also enabled for any successful starts of the Volume Shadow Copy service.

At this point, you have greatly reduced the risk of someone obtaining your Active Directory database by leveraging the Volume Shadow Copy service, while retaining the ability to use it for your own Domain Controller backups.

October 1, 2015

Last week's article went over the steps of how to create a solution to determine the computer(s) a user logs into automatically. While this can be very useful information to have by itself, it also opens the door for other possibilities. One such possibility would be to have an automated process that forces a user to be automatically logged off of their computer(s) in the event that their domain account is disabled by an administrator.

The following will outline the solution to have a user's domain account be logged off of any computer(s) that they are currently logged into utilizing a scheduled PowerShell script. This process has been designed to work on Windows Server 2008 and later versions.

The first part of the PowerShell script should look similar to what was used in the Creating AD User Account Alerts article, as we will also need to get the most recent instance of Event ID 4725 which is caused from a domain account being disabled.

$Event = Get-EventLog -LogName Security -InstanceId 4725 -Newest 1

With the most recent instance of this Event ID, we now need to parse out the domain account name that has been disabled and then store it into a usable variable.

[String]$String = $Event.ReplacementStrings
$UserName = ($String).split()[0]


Next, we need to get the corresponding Distinguished Name of this user account from Active Directory.

$DN = dsquery user -samid $UserName
$DN = $DN -replace '"',""


Using this information, we can now query the ManagedBy attribute within Active Directory in order to determine what computer(s) this particular user is currently logged into.

$ComputerDNs = dsquery * -filter "(&(objectCategory=computer)(managedBy=$DN))"
ForEach ($ComputerDN in $ComputerDNs)
{
    $Computers+= ($ComputerDN -split ",")[0].substring(4) + ","
}


Due to how we have extracted this information, we now need to perform some cleanup of the output so that we have a usable Array containing the computer(s).

$Computers = $Computers.Split(",",[System.StringSplitOptions]::RemoveEmptyEntries)

With all of this information, we can now loop through the list of computers that this user is logged into and force their logoff.

ForEach ($Computer in $Computers)
{
    IF (Test-Connection -ComputerName $Computer -Count 4 -Quiet)
    {
        (gwmi win32_operatingsystem -ComputerName $Computer).Win32Shutdown(4)
        $SuccessList+= $Computer + "<br/>"
    } ELSE
    {
        $FailList+= $Computer + "<br/>"
    }
}


As a final touch, let's setup an E-Mail confirmation that will let yourself, and any other administrators, know what computer(s) this user has been logged off of, along with any that were unreachable (e.g. not connected to the network).

$Body = @"
The Domain User $UserName has been successfully logged out of the following computer(s): <br/>
$SuccessList <br/>
The Domain User $UserName has NOT been logged out of the following computer(s), please verify: <br/>
$FailList <br/>
"@
Send-MailMessage -to "[Your E-Mail Address or Distribution List]" -from "[UserID Running the Scheduled Task]" -subject "Disabled User Logged Out of Computer(s)" -body $Body -SmtpServer [SMTP Server IP] -BodyAsHTML


When it is all put together, your PowerShell script should look something like this.

$Event = Get-EventLog -LogName Security -InstanceId 4725 -Newest 1

[String]$String = $Event.ReplacementStrings
$UserName = ($String).split()[0]

$DN = dsquery user -samid $UserName
$DN = $DN -replace '"',""

$ComputerDNs = dsquery * -filter "(&(objectCategory=computer)(managedBy=$DN))"
ForEach ($ComputerDN in $ComputerDNs)
{
    $Computers+= ($ComputerDN -split ",")[0].substring(4) + ","
}

$Computers = $Computers.Split(",",[System.StringSplitOptions]::RemoveEmptyEntries)

ForEach ($Computer in $Computers)
{
    IF (Test-Connection -ComputerName $Computer -Count 4 -Quiet)
    {
        (gwmi win32_operatingsystem -ComputerName $Computer).Win32Shutdown(4)
        $SuccessList+= $Computer + "<br/>"
    } ELSE
    {
        $FailList+= $Computer + "<br/>"
    }
}

$Body = @"
The Domain User $UserName has been successfully logged out of the following computer(s): <br/>
$SuccessList <br/>
The Domain User $UserName has NOT been logged out of the following computer(s), please verify: <br/>
$FailList <br/>
"@
Send-MailMessage -to "[Your E-Mail Address or Distribution List]" -from "[UserID Running the Scheduled Task]" -subject "Disabled User Logged Out of Computer(s)" -body $Body -SmtpServer [SMTP Server IP] -BodyAsHTML


Just like with the previous article on Creating AD User Account Alerts, you will now need to schedule this PowerShell script within Task Scheduler on your Active Directory server using a Domain Account with the appropriate access. In order for this script to execute immediately whenever a user account is created, and therefore log them out of any computer(s) they are logged into, you will need to configure the task to be triggered whenever Security Event ID 4725 occurs.

By creating this PowerShell script and scheduling it to run on your Active Directory server, you now have an automated solution in-place to logoff any disabled domain accounts from the computer(s) that they are logged into. You also have an E-Mail that will be sent to you whenever this script is triggered to notify you of the computer(s) that the domain account was logged off of, along with any that were unreachable at the time of execution. While this should not be used as a replacement for proper business practices for employee termination, it can be a helpful backup for instances where their domain account has been disabled before corporate security, human resources, or their direct manager have made it to their desk in order to escort them out.
Subscribe to RSS Feed Follow me on Twitter!