Wednesday, April 30, 2014

Custom Properties and Descriptions in AD

One of the first things I like to do when I land on a domain-joined machine is enumerate the domain. Sometimes I do this even before attempting to privilege escalate. Sometimes a few LDAP queries is all you need to accomplish your goal.

During the planning phase of an engagement, I try to ascertain at least three data points that the organization feels are critical to their business and would be devastating if it fell into the wrong hands. That data is my ultimate goal and sometimes that data is stored in the database known as Active Directory (AD). I don't know if there is a single reason why organizations choose to store sensitive information in AD, but I have found it several times. PowerShell v2 introduced a type accelerator which makes enumerating AD quite simple and allows us to use PowerShell to manipulate the results without diving to deep into LDAP queries:

$LdapFilter = #Query Goes Here
([adsisearcher]"$LdapFilter").Findall()
view raw gistfile1.ps1 hosted with ❤ by GitHub
A simple way to enumerate all domain users from any user or machine account (this works great in situations where the "net" utility is deleted or restricted and returns much more digestible output):

([adsisearcher]"objectCategory=User").Findall() | ForEach {$_.properties.cn}
view raw gistfile1.ps1 hosted with ❤ by GitHub
Additionally, we can wrap that into a simple one-liner to be run from cmd.exe (or your favorite shell). For example, if we wanted to enumerate all machines in the domain:

powershell.exe -com '([adsisearcher]'objectCategory=Computer').Findall() | ForEach {$_.properties.cn}'
view raw gistfile1.ps1 hosted with ❤ by GitHub
Unfortunately, that pipe ("|") is going to give us problems. We can easily encode it from within PowerShell:

(cmd /c echo {([adsisearcher]'objectCategory=Computer').Findall() | ForEach {$_.properties.cn}}).split(' ')[1]
view raw gistfile1.ps1 hosted with ❤ by GitHub
Now we can run our query:

powershell.exe -enc KABbAGEAZABzAGkAcwBlAGEAcgBjAGgAZQByAF0AJwBvAGIAagBlAGMAdABDAGEAdABlAGcAbwByAHkAPQBDAG8AbQBwAHUAdABlAHIAJwApAC4ARgBpAG4AZABhAGwAbAAoACkAIAB8ACAARgBvAHIARQBhAGMAaAAgAHsAJABfAC4AcAByAG8AcABlAHIAdABpAGUAcwAuAGMAbgB9AA==
view raw gistfile1.ps1 hosted with ❤ by GitHub
Nothing earth-shattering there, but where it gets interesting is if you discover customer properties that the organization has added to the account objects. To find that, we simply enumerate the 'PropertyNames' of any of the accounts returned in the array:

powershell.exe -com "((([adsisearcher]"objectCategory=User").Findall())[0].properties).PropertyNames"
view raw gistfile1.ps1 hosted with ❤ by GitHub


Being able to dump the social security numbers of every employee or user is obviously a critical finding, but sometimes the other data can come in handy for further social engineering attacks or to demonstrate the risk of single link clicked. I have found employee IDs, cell phone numbers, supervisor information, number of disciplinary actions, which user's internet activity was being monitored, hourly rate and salary information. In one case, the information available in AD was what was needed to request VPN credentials and remotely reset their password.

Since most administrators interact with AD with a MMC snapin, they mistakingly believe that custom fields can't be viewed by other users. Fortunately, they can easily adjust the permissions on those properties to only be viewed by members of specific groups. At least then an attacker would have to privilege escalate or laterally compromise a member of one of the privileged groups. Even then, I wouldn't recommend storing sensitive information within AD.

One of the default properties that I like to check is the description field. Most of the time there are just notes about the account, but other times there are passwords. Passwords are obviously valuable, but the notes can be pretty valuable as well. For example, a trend I see in many high-security enterprises is to obfuscate user account common names. This protects from account guessing attacks from open-source information, but is little protection from any legitimate or illegitimate user on the domain if the real name of the user is used in the comment field. To enumerate properties:



It is also worthwhile to enumerate the properties of the computer accounts as well.

-Chris