Friday, August 11, 2017

Week of Evading Microsoft ATA - Day 5 - Attacking ATA, Closing thoughts and Microsoft's response

This is Day 5 of Week of Evading Microsoft ATA. The week has been split in the following days:
Day 5 - Attacking ATA deployment, limitations of research and mitigation

Welcome to the last day of the Week of Evading ATA. We have seen how ATA can be bypassed and avoided during a security assessment. Today let's see how we can attack ATA deployment. We will also discuss limitations of the research against ATA, some closing thoughts and some general mitigation against AD attacks. 

Attacking ATA

Find ATA Installation
So how do we spot ATA? Before 1.8, it was possible to simply run banner grabbing against web services running on port 443 and look for "Microsoft Advanced Threat Analytics". An example PowerShell command for this:
But ATA 1.8 uses Single Sign-On and it is not possible to grab the banner without authenticatiob. But we are not out of options. We can simply look for certificate used by the ATA console. By default, ATA console uses a self-signed certificate issued to "ATACenter".
ATA uses local users and groups of the ATA Center, the ATA documentation suggests having three types of role groups ATA Administrators, ATA Users and ATA Viewers. If the target deployment uses the exact same group names as suggested, we should be able to enumerate ATA by enumerating local groups on machines in the domain using PowerView:
Also, I am quite sure that smart folks out there (like from nmap or metasploit) will soon include ATA in their service identification.

Admin Access
Once we know that there is an ATA deployment in a domain we may try attacking it. There are a number of interesting things which can be done with it. If the ATA Center is the part of the target domain and we have escalated privileges to domain admin or have got local admin access to the Center, we can have much fun. ATA subscribes to the concept of "if its admin its game over". By default, all the members of the local administrators group (local admins, domain admins) on the ATA Center have administrative access to the ATA console. We can resolve alerts, add exclusions, enumerate honey tokens etc. with that access.
While this is nothing ground shattering, since ATA specifically targets domain dominance and lateral movement, having the ability to add exceptions for our IP, users and attacks is very useful.

Backend MongoDB

ATA Center uses MongoDB to store entities, entity profiles, Kerberos requests, suspicious activities and more. It listens only on localhost but needs no authentication to connect to! This means if we have administrative access to the ATA Center we can do very interesting things. Let's see two of them:

Tampering with alerts
Let's say we want to tamper with suspicious activities from our foothold user, say, labuser. Let's first look for SourceAccountId from the UniqueEntity collection for labuser. I am using RoboMongo for accessing the mongodb:
Once we have the id of our account, let's have a look in the SuspiciousActivity collection for alerts for our user:
Let's have a look at the latest suspicious activity for labuser:
An unusual protocol alert, most probably an overpass-the-hash, going by the time stamp and other details, this is the alert in the ATA console:
Now, we can simply lookup for id of another user, say termadmin, and replace that by editing the SourceAccountId for that particular alert in the SuspiciousActivity collection. Let's do it not only for labuser but other two user's in the above alert as well for the sake of demonstration:
Sweet, isn't it :D

We can do the same for Computers as well to "frame" some other computer for attacks like Malicious replication of directory services and so on.

Hiding the alerts
Let's say we simply want to hide an alert. Entries in the SuspiciousActivity collection has a proeprty called "IsVisible". Set it to false and the alert vanishes from the console. Let's go after the latest DCSync alert:
Let's look for "TitleKey" : "DirectoryServicesReplicationSuspiciousActivityTitle" in the SuspiciousActivity collection and edit the latest one to change "IsVisible" : true to "IsVisible" : false:
And the result is:
Nice! This helps us in covering tracks in a post-DA lateral movement scenario.

Of course, no surprise, we modified the database and the console displays the modified values. But as these are security alerts, having access to just one box - ATA Center - drastically reduces the security posture of the entire organisation.

Limitations of the research
Copy paste from my BlackHat slides:
- Focus of all the bypasses is on Anomaly based detections.
- Many behavior based detections could not be replicated in the lab and are more powerful and useful in a real environment.
- Behavior based detection may detect lateral movement even if the anomaly based detection is bypassed – use the avoidance techniques (Day 4) in such cases.

Evading ATA forever
What happens when the bypasses we discussed are fixed? We modify our methods and techniques. I have seen fellow red teamers using Golden ticket or Skeleton key just to brag about it in their reports. No matter how frustrating they are, we as good attackers need to focus on the goals of the assessment. Not only it helps in meeting those deadlines, it also helps in avoiding pesky detection mechanisms ;) For example, there is no need to go for DA if the goal of the assessment can be completed without it, stay focused!

Defences
More from my BlackHat slides:
- ATA even if can’t detect anomalies, provides interesting insight in the traffic exchanged with the         Domain Controller. Use that to detect the attackers. 
- Limit your DAs to login only to Domain Controllers. Remember prevention is better than cure. 


Microsoft's Response
Microsoft's ATA team is awesome! They contacted me (and MSRC contacted me as well) when my talk was scheduled and we worked together to address and understand each other. I always found them very open to the idea that researches like this actually make a product better. It was actually fun exchanging ideas with them!

That is all for the week of Avading Microsoft ATA. Hope you enjoyed it as much as I enjoyed writing it :) Please leave questions, feedback and comemnts :)



Week of Evading Microsoft ATA - Day 4 - Silver ticket, Kerberoast and SQL Servers

This is Day 4 of Week of Evading Microsoft ATA. The week has been split in the following days:
Day 4 - Bypasses/avoidance by reducing conversation with the DC
Day 5 - Attacking ATA deployment, limitations of research and mitigation

Day 4 is dedicated to those attacks which need minimum and normal communication with the domain controller and thus ATA. That is, after bypassing ATA on first three days, today we will discuss how ATA can be avoided.

Silver Ticket

If get our hands on NTLM hash of a service account, it is possible to create a TGS (Ticket Granting Service) and present it to the service to get access. As we would be creating a TGS, there is no communication with DC. Read more about silver ticket attack in this post. Now, if we are not talking to the DC, ATA can't read the traffic and thus, there is no detection. As simple as that!



What intrigued me during testing was even if a silver ticket is used for a service running on the DC, ATA still won't detect it.  We can use the NTLM/RC4 hash of the DC's machine account for some very interesting services like CIFS, WMI, PowerShell Remoting. LDAP etc. Since we already have DA access on Day 2, the ability to create a silver ticket for the DC is a decent persistence mechanism.

Why a silver ticket is not detected even for the DC? I think ATA is currently interested only in authentication requests.

Kerberoast

Kerberoast attack involves requesting a TGS from the DC for a service, save the TGS (which is encrypted using the NTLM hash of the target service account) to a file and brute-force the NTLM hash. Read this and this article for more information.

The only communication with the DC is when the TGS is requested from the DC. The DC gets TGS requests all day and spotting an anomaly in such a regular request is, well, not easy.

Actually, there is a chance for detection based on anomaly. Remember the encryption type we discussed on Day 3? A TGS request with encryption type 0x17 (RC4) may be used as an indicator of a ticket request for Kerberoasting. How? Let's use the below code to request a TGS for a service:
This is how it looks like in logs:
But there are many legit uses (legacy applications, service accounts, trusts etc.) which still use RC4, we can only hope that ATA starts detecting TGS requests using RC4 as malicious in a future release for those environments where AES is prevalent.

Kerberoast Variants

There are two Kerberoast variants which are helpful in active directory dominance.

AS-REP
Request a TGT for an account with Kerberos Pre-Authentication disabled (or force disable if we have sufficient rights), DC replies with TGT (AS-REP) which has a piece of information (emcrypted part) encrypted with the account's NTLM hash, save it to the disk and brute force offline. Please read this and this post for a detailed explanation.

ATA doesn't detect this. Is there any anomaly which can be seen? Yes!

After enumerating users with Pre-Auth disabled, send AS-REQ and receive AS-REP with encrypted part:
And this is how it looks like in Wireshark:
And this is how it is logged:
Hello RC4 we met again :)

As Will explains in this post, cracking AS-REP encrypted part which uses RC4 is much easier then the AES one so chances of an attacker using AES are not common. An anomaly, if ATA would like to spot it :)

Force SPN
If we have enough privileges, it is possible to set a user's SPN to anything, request a TGS for that made up SPN and then, brute-force the ticket offline.

Like in other TGS related attacks, a simple anomaly in this case could be use of RC4:
ATA doesn't detect it. ATA team commented that abnormal behaviour detection will catch this and AS-REP method when the brute-forced passwords are used to access a resource.

SQL Server

Targeting SQL servers and staying within the database server makes sure that there is no communication with the DC and therefore, avoids ATA. I wrote a post couple of months back on lateral movement within the database layer.

That is all for Day 4. Hope you enjoyed it!




Wednesday, August 9, 2017

Week of Evading Microsoft ATA - Day 3 - Constrained Delegation, Attacks across trusts, DCSync and DNSAdmins

Welcome to Day 3 of Week of Evading Microsoft ATA. The week has been split in the following days:
Day 3 - Bypasses/avoidance using more Kerberos attacks and attacks across trusts
Day 5 - Attacking ATA deployment, limitations of research and mitigation

On Day 3, Let's see some more Kerberos attacks which can be used to bypass ATA. Also, since we already escalated to DA on Day 2, we will also discuss attacks across domain trusts which are not detected by ATA.

Constrained Delegation
Constrained delegation allows access to a service by impersonating *any* user if the service account is configured so (msds-allowedtodelegateto). You can read more about this attack here, here and here. All of the three are fantastic posts, please go through them to understand the attack.

ATA doesn't detect this attack.Why? Read on.

If we abuse unconstrained delegation with the help of Kekeo:

Request a TGT:
Request a TGS as Administrator using the above TGT:
Encryption type 0x17 means RC4-HMAC. See this article.

Now, is 0x17 an anomaly? Not really, even though AES has been introduced since Server 2008, service accounts, inter-domain tickets and inter-forest tickets still use RC4 encryption. So there is no downgrade for ATA to detect, by default, as far as TGS_REQ is concerned.

Once we have the TGS, it can be used in the current session to access the service:

Even if we force enable AES on the service account ATA doesn't detect it as we need to move the entire domain (trusts, legacy machines etc. still use RC4) to AES before 0x17 can be considered anomaly.

I think there is one chance of detection, while requesting a TGT, there is an encryption downgrade for the AS-REQ packet (see the screenshot above). But it is up-to the ATA team to tune-it and make the detection reliable.

Also, there is no detection for alternate tickets. It is possible to access any service running with the same service account as the service for which constrained delegation is enabled. See the section, "Server SPN target name validation level" in this article. That means, if we have access to a service like time on the domain controller using constrained delgeation we can request a TGS for a service like HOST (Schedule tasks and many others), RPCSS (WMI), CIFS (File server) and take over the DC completely and ATA won't detect it.

But please keep in mind that if we access the LDAP service and try to run DCSync attack (replication), ATA will detect it. In fact, during my testing, I found out that DCSync is one of those attacks which ATA rarely misses.
Above is based on my understanding of constrained delegation and service accounts. Please correct me if I messed up something :)

The ATA team commented that they are "currently working on detecting abnormal delegation usage".

Attacks Across Trusts

Let's discuss couple of attacks across domain trusts. Many attacks across domain trusts are not detected. That inter-domain tickets use RC4 is one of the reasons for this. We will discuss only two of most interesting attacks, escalation from domain to forest root and DCSync (replication) without detection.

Escalation from domain DA to forest root enterprise admin

It is well known that if we have DA access to one of the domains of a forest, it is possible to escalate privileges to the enterprise admin of the forest root. Read Sean's blog post here to understand the attack.

To use this attack, we just need the krbtgt hash of the current domain and some other information (domain SID, parent domain SID etc.) which is available to any normal user in active directory. We forge an inter-domain TGT, sign and encrypt with the krbtgt hash of child for validation and append SID history. When the parent DC receives this TGT for accessing a service in the parent domain, it reads the SID history and if it is set to Enterprise Admins, we are granted that privilege.

Now, this is how the network capture looks like on the child DC when the above attack is executed:
Because domain trusts use RC4 encryption by default what we see above is NOT a downgrade. To make this an anomaly, it will be required to enable the support of AES in the Trust properties in the Active Directory Domains and Trusts:
ATA currently does not take into account if AES is enabled for a trust.

DCSync across trust

As I stated earlier, DCSync is rarely missed by ATA. But if it is done from a chilld domain controller, DCSync is not detected by ATA which makes sense as domain controllers replicate stuff all the time. Since we escalated to Enterprise Admin above, we have sufficient privileges to do so.

First, using a golden ticket or overpass-the-hash, escalate privileges to DA on a member machine of child domain. Then run the below command from the member machine:
ATA does not detect this! :)

This makes it much easier to laterally move in the parent domain as we can extract AES keys and avoid detection later.

Abusing the DNSAdmins group membership

Another attack which is not currently detected by ATA is the ability to run remote code as SYSTEM on a Windows DNS server (or DC - if it works as DNS server as well). Read this post and this one by me for more details. Also, DNSAdmins is not a protected group :)

That is all for Day 3!




Tuesday, August 8, 2017

Week of Evading Microsoft ATA - Day 2 - Overpass-the-hash and Golden Ticket

Welcome to Day 2 of Week of Evading Microsoft ATA. The week has been split in the following days:

We left Day 1 with admin access to the box where a domain admin (DA) token is available. The next step is to get access to the credentials of the DA. Here, credentials could be clear text password, NTLM hash, AES keys, user token etc. 

Overpass-the-hash
Let's pull hashes for the DA "tempDA" using Invoke-Mimikatz:
Once we have access to the NTLM hashes, we can use Overpass-the-hash attack to create a Kerberos ticket and access resources and services as tempDA. From an administrative shell:
We now have DA privileges! Nice, isn't it? Not really! ATA caught us:
What now? If we read the detection, it says "The encryption method of the Encrypted_Timestamp field of AS_REQ message from OPS-USER11 has been downgraded based on previously learned behavior." Ok. Let's investigate this!

Let's see how the Encrypted_TimeStamp (in the PreAuthentication Data) field of AS-REQ message looks like when normal authentication (cleartext password) is used:
Now, below is how the same filed looks like when we use NTLM hash for Overpass-the-hash:
So, the encryption type downgrade is quite evident from the screenshots above. How to avoid this downgrade? By using AES keys! Use below command to extract AES keys from a remote computer:
And then use the below command to use it for Overpass-the-hash (note that we can use whatever AES128 keys if they are not available). It is always advisable to use all the hashes:

Bingo! We have elevated our privileges to DA and this doesn't get detected by ATA!

Please note the following from Benjamin's post: "AES keys can be replaced only on 8.1/2012r2 or 7/2008r2/8/2012 with KB2871997, in this case you can avoid NTLM hash."

Another detection of Overpass-the-hash, as seen in the screenshot above, is "Unusual protocol implementation". I _believe_ that this detection is because of another field (supported encryption) in the AS-REQ packets. Can't confirm this and will welcome more research and comments on this:
Another interesting thing to notice is, we can use Overpass-the-hash for generating false alerts on ATA! Failure events can be generated for any user, even a non-existing user, in the domain. Any made-up NTLM hash can be used for this.


Golden Ticket
Once, we have access to DA, let's establish persistence in the domain. We can create a Golden Ticket for that. Let's pull the RC4/NTLM hash of krbtgt account from the domain controller to create a golden ticket.
Let's create a golden ticket and inject it in memory. As soon as a resource in the domain is accessed, ATA will detect the golden ticket as:
Similar to Overpass-the-hash, ATA looks for encryption downgrade. Since golden ticket is a TGT, the focus is on TGS-REQ packet. Let's have a look at the encryption method of the TGT field of a TGS-REQ in case a user accesses a resource normally:
And this is how a golden ticket generated using NTLM hash of krbtgt looks like:
Clearly a downgrade. How to make a golden ticket appear normal? Right! AES keys once again!

Let's use "/inject" option of the lsadump::lsa module in mimikatz:
"/inject" provides additional credentials. How? Why? See this post.

Once we have the AES keys, a golden ticket can be generated and used without detection:

Another Golden Ticket Bypass
Previous one is not the only golden ticket bypass! When I found out the next one, I couldn't believe it!

We can actually avoid golden ticket detection while still using RC4/NTLM hash of the krbtgt account by using a non-existent username!
In ATA 1.8, ticket lifetime based detection was introduced. "If a Kerberos ticket is used for more than the allowed lifetime, ATA will detect it as a suspicious activity" - What's new in ATA version 1.8

Now, let's hold our horses and think. Why should we save a golden ticket to disk at all? It is the no-change of krbtgt hash which provides the persistence and NOT the golden ticket. We can always create a golden ticker whenever there is a need to access a resource, just keep the krbtgt hash handy!

Also, we can set lifetime of the ticket while creating a golden ticket. Enumerate the Kerberos policy using (Get-DomainPolicy)."Kerberos Policy" from PowerView. The default ticket lifetime is 10 hours. In the lab, it is setup as 1 hour. To avoid using a ticket beyond lifetime we can use the following options. The golden ticket create in the below command is valid for one hour after two hours from the time of creation and can be renewed during 7 days (10080 minutes):
Make sure that you purge the golden ticket from the target box otherwise ATA will detect it.

That is all for Day 2. Hope you liked it! :)



Monday, August 7, 2017

Week of Evading Microsoft ATA - Announcement and Day 1

I have been playing with Microsoft Advanced Threat Analytics (ATA) for past few months. I found it useful for Blue Teams and scary as a Red Teamer as it detects many Active Directory (AD) tools and techniques. Naturally, I needed ways to bypass it and that is something which motivated me to spend weekends and nights looking for ways out. I found some methods to bypass ATA, some to avoid it and some to attack the ATA installation. 

I gave a talk about Evading Microsoft ATA for Active Directory Dominance at Black Hat USA last week (slides at the end of the post) and would speak at 44CON and BruCON on some of the additional research I am doing. 

What I found mostly during my research was it is not really difficult to evade detection by ATA as long as we are not running tools blindly without understanding what they do. So, to generate interest on using offensive tools more wisely and modifying techniques based on the detection mechanisms, in addition to my talks at multiple conferences, I announce a Week of Evading Microsoft ATA beginning from 7th of August 2017.

We will see interesting stuff the whole week which includes whatever discussed in my talk and more:

Day 1 - Introduction, detection and bypassing/avoiding Recon and Brute-force detection
Day 2 - Detection and bypass of overpass-the-hash and golden ticket

Let's get started with Day 1:

What is ATA?
ATA is a platform which listens to certain protocols going to the Domain Controllers (DC) of a domain. It can integrate with syslog, SIEM etc. It can detect attacks based on anomaly and user behaviour. AFAIK, for anomaly detection there is no learning period for some attacks (one week for certain attacks) and for behavioural detection there is a learning period of 21 days. We are going to focus only on the anomaly based attacks.

ATA Architecture
ATA needs to see the traffic being sent to the DC. Here is how it looks like:

ATA Gateway is that part which reads the traffic and parses it. ATA Center is that part which stores the parsed traffic, do analysis, stores everything in a mongodb and hosts ATA console where we can see alerts. The Gateway can either be a separate box or a lightweight one which can be installed on to a DC. More on architecture here.

Lab Setup
The lab setup uses a Lightweight ATA Gateway with ATA 1.8 (started with 1.7) which is the latest at the time of writing - 30th July 2017.  I use this installation in my PowerShell and Active Directory training and therefore, the installation has been tested by more than 400 hackers and infosec professionals in last 7 months. 

What attacks can ATA detect?
Many! Have a look at this link: What threats does ATA look for?
The attacks which we are interested in:

Recon
- Account enumeration
- NetSession enumeration
- Directory services enumeration. 
Above attacks result in enumeration of users, computers, group membership, sessions etc. 

Compromise Credentials
- Brute-force
- Unusual protocol implementation

Lateral Movement
- Pass the ticket
- Pass the hash
- Overpass-the-hash

Domain Dominance
- Golden Ticket
- Malicious replication requests

Once we understand the architecture, let's jump in and have a look at various attacks. We will follow a simple "attack chain" where we begin with a normal domain user privileges and then work our way up to domain dominance. We will see ATA detects us and how it can be bypassed at each step.

Recon

We assume that we have a normal domain user privileges. We start with the domain enumeration and try to list computers, group membership of domain admins etc. This enumeration is fine with ATA most of the times. But for some enumeration there are alerts. For example, if you enumerate all users and groups in a domain using PowerView, there are no alerts but if the native net.exe is used that may be detected as "Reconnaissance using directory services enumeration":

Why so? Because ATA currently detects such enumeration done using SAMR protocol which is used by net.exe. PowerView uses LDAP queries which ATA does not care about currently for enumeration. In fact, ATA is mostly interested in the authentication related data when it comes to LDAP.

To avoid detection WMI queries can also be used. This was covered by Chris Thompson (@retBandit) in his DEF CON talk:

Get all users in the domain "opsdc"
Get all domain groups:
Get membership of the Domain Admins group:
Because we have enough information now, let's move ahead with some more enumeration. Let's start hunting for local admin privileges on other boxes.
Let's hunt for a machine where a DA token is available and we have local admin privileges:
Both the above activities are detected by ATA as Reconnaissance using SMB session enumeration:
Now, if we look at the alert closely. ATA complains about Recon against only the DC. What does that mean? That means, if we gather the information from the DC but do not run user hunting against the DC it would be possible to bypass this detection. To avoid running user hunting against the DC, we need to use the -ComputerFile parameter of Invoke-UserHunter or Find-LocalAdminAccess and provide a list of computers which does not contain the name or IP of the DC.


This is how it looks like in the lab:
And above will not be detected by ATA! A simple but effective bypass ;) As long as we keep our communication with the DC minimum, chances of detection would be low.

Another enumeration technique, not caught by ATA right now, is using SPN scanning. Read this article to know more about SPNs. We will touch SPN scanning on Day 4.

Brute-Force
Once we know a machine where token of a DA is available, we may like to have local admin access to it so as to possibly extract credentials (hashes, keys or passwords) for the DA and use that. There are so many ways to achieve it. Since we already have a list of users, let's try brute-force attack against all the users in the domain. This is how a detection looks like:

We will use only one password and therefore, a single attempt against all the users. This is a well known technique. We will use Invoke-BruteForce from Nishang for this:


And this doesn't get detected! I have another brute-force bypass under research and I will present that during my talk at BruCON.

Once we have local admin credentials (brute-force) or access (Find-LocalAdminAccess) to the box where DA tokens are available, we will pull the credentials for DA. That will be covered on Day 2 :)

Hope you enjoyed the post!

The slides of the BlackHat talk are below:
https://www.slideshare.net/nikhil_mittal/evading-microsoft-ata-for-active-directory-domination





Wednesday, May 10, 2017

Abusing DNSAdmins privilege for escalation in Active Directory

UPDATE (November 2021) - After more than 4 years, Microsoft has acknowledged this is as a vulnerability and released a patch. This is now CVE-2021-40469!
 
Yesterday, I read this awesome post by Shay Ber here which details a feature abuse in Windows Active Directory (AD) environment.  I rely heavily on feature abuse during my red team engagements and always recommend them over memory corruption exploits during my training as well. Feature abuses are as lethal as exploits and are almost always ignored.

The post details a feature abuse in AD where a user who is member of the DNSAdmins group or have write privileges to a DNS server object can load an arbitrary DLL with SYSTEM privileges on the DNS server. Since, many enterprise setups use the Domain Controller (DC) as a DNS server as well, this is a very interesting find. Let's try to  see the practical usage of this feature.

This is the lab setup. We have initial access as a normal domain user (labuser) on one of the boxes in our lab AD.


Let's first enumerate users who are part of the DNSAdmins group using PowerView.
In a real red team or pentest, the next step would be to target the buildadmin user. We can find a box where token of buildadmin is available using Invoke-UserHunter from PowerView.
To keep the discussion on the topic at hand, let's assume that we found a box where a ticket of buildadmin is available and our current user (labuser) has local admin access as well (derivative admin). So, we have privileges of the user who is a member of the DNSAdmins group.

Now, there could be two scenarios - one where the DC is the DNS server as well and second, where a separate server acts as the DNS server.

For the first scenario, where the DNS Server service is running on the DC we can simply use dnscmd as mentioned in the post by Shay to load a dll. There is also a PowerShell module - dnsserver - for this but it is not well documented.

Before we discuss the dll to be used, there is a catch which the above referenced post didn't address. If we have a look at the MS-DNSP protocol specification, the ServerLevelPluginDll needs an absolute pathname. That means, it is not possible to load a DLL from a UNC path. We must load the DLL from the local machine. I tried UNC paths, HTTP etc. without any success. This actually spoils the attack to much extent as we will need write privileges on the DC :/ I actually though of not writing this post after discovering this but decided to write it anyway so that others do not spend time looking for the same thing. Also, that is how one learns :) I will be glad if someone smarter than me finds out a way to do this remotely.

UPDATE: Benjamin confirmed that it is possible to load the DLL from UNC path. The 'C$' in my UNC path was the problem!

We can use the below command to load the DLL. The path \\ops-build\dll should be readable by the DC:
For debugging (admin rights required on the target), below command can be used to check if DLL was added successfully on the target

Now, since our user is a part of the DNSAdmins, we can restart the DNS service. While, this is NOT the default configuration, it makes sense for such a user to have the rights to restart the DNS service. But, the service restart must be done from the local box, that is, DC in the current scenario. We need administrator rights to do it remotely  - the attack gets more typical and hard to execute :(

So what do we get after successfully executing the above commands? Benjamin quickly updated mimilib to be used with this attack. The updated version of mimilib when used in this attack logs all DNS queries to C:\Windows\system32\kiwidns.log
We can make changes to kdns.c to include capability of command execution. I included a simple line of code to execute a reverse PowerShell shell encoded using Invoke-Encode from Nishang. The payload gets executed for each query to the DNS service and the kiwidns.log will still be created and populated.
 
On our listener:
Neat! SYSTEM on the domain controller. We own this domain and possibly the entire forest :D

For our second scenario, if DNS service was not running on the DC we can still get SYSTEM access on the box with 'only' the privileges of DNSAdmins and restarting the DNS service.

How to detect the attack? 

To prevent the attack, audit ACL for write privilege to DNS server object and membership of DNSAdmins group. 

Obvious indicators like DNS service restart and couple of log entries:
DNS Server Log Event ID 150 for failure and 770 for success


Microsoft-Windows-DNS-Server/Audit Log Event ID 541 for both success and failure.
Monitoring changes to HKLM:\SYSTEM\CurrentControlSet\services\DNS\Parameters\ServerLevelPluginDll will also help.


Hope you liked the post. Please leave feedback and comments.

Thursday, March 23, 2017

Using SQL Server for attacking a Forest Trust

Recently I started playing with the awesome PowerUpSQL tool by guys at NetSPI. I was interested in the ability to attack an Active Directory (AD) environment using access to a SQL Server, that is, not leaving the database layer as long as possible. Fortunately, during a Red team engagement few weeks back, I had a chance to play with PowerUpSQL extensively. Turns out that it is very much possible to enumerate and attack not only the current domain but a trusting forest in a Two-Way External Trust as well from the database layer. Let's have a look at it!

Network Diagram
I have mapped the client network to my lab on a much smaller scale.  We have access to the SQL Server ops-sqlsrvone where we have public privileges and can communicate to only selected machines on the defensiveps.com forest. 

Cross Forest Enumeration
It is possible to enumerate the current domain accounts using PowerUpSQL using interesting fuzzing methods. In our lab setup we know that there is a trust relationship from offensiveps with a forest called defensiveps (we can use PowerView, netdom or Get-ADTrust). But PowerUpSQL does not provide a way of specifying an alternate domain to enumerate accounts. We can change a single variable in the code to use an alternate domain.
Now, it is possible to enumerate interesting information from the target domain which is in a different forest. After modifying the value of $Domain variable, import the PowerUpSQL module and run the below command:
Neat! We got a list of target domain's users, groups, computers etc.

The enumeration done above helped in listing SQL Servers in the defensiveps domain. Now, mimicking the network I encountered during the assessment, it is possible to access only dps-sqlsrvdev, couple of DCs and some terminal servers in the defensiveps network directly. So, let's enumerate dps-sqlsrvdev:

Database logins
Note that our current user is listed as a login above and that is why it is possible to enumerate the above. Let's check the current privileges we have:
No sysadmin privileges. We can check it manually as well (I am using HeidiSQL as a client):

We can go ahead with a brute-force attack as there are some interesting SQL server logins and generally, account lockouts are not enabled in SQL Server databases and nobody really looks at the logs of authentication failure in SQL Server, at least, on non-production servers. But we are not going to do that right now.

Linked Servers
We can also enumerate linked servers for dps-sqlsrvdev. Let's do it:
Nice! A server, dps-sqlsrvtwo, in the defensiveps domain - which we enumerated earlier as well - is linked to the current database. Note that it is possible to run arbitrary SQL queries on the linked database even if we have only public privileges on both the initial and destination servers with the privileges configured in the link. Read more about hacking SQL Server links in the amazing blog by Antti. Link enumeration can be done manually as well:
So, dps-sqlsrvdev has a linked server dps-sqlsrvtwo.

Now, to execute queries on the destination server (dps-sqlsrvtwo) we can use Openquery as suggested by Antti in the blog linked above. Let's see our current user and if we have sysadmin privileges:

Turns out that we have only public privileges with a user called dbuser and the target server is SQL Server 2016 SP1.

Now, we can try various methods from PowerUpSQL for privilege escalation on SQL Server. The problem is we can't access dps-sqlsrvtwo directly and AFAIK, there is no way to execute these commands on a linked server using the tool. So, we need to try the methods manually, one by one. During the Red Team assessment, I found out a user which we can impersonate on a linked server. So, let's use that in our lab setup as well. To list all the users which we can impersonate from our current user can be listed using the following SQL query stolen directly from this amazing blog by Scott. We are going to use the query inside Openquery so that it can be executed on the linked server:
Looks like we can impersonate a user called "reportsuser". But a command like below is most likely to fail:
Why? Because, apparently, it is not possible to use EXECUTE AS without getting our privileges revert to the original 'dbuser'. I tried WITH NO REVERT option as well but soon realized that it may work only when sending the query directly to a database. Please see this MSDN documentation on EXECUTE AS.

No luck there! Let's look for another interesting privilege escalation avenue - trustworthy database. Read this very useful blog, once again by Scott, to understand more about trustworthy database. We can use the following query - taken from the blog referenced above -  to enumerate trustworthy databases on the target linked server:
A trustworthy database 'reports_db'! Let's list users with db_owner role on the server:
Now, let's see if our current user - dbuser - is db_owner of reports_db on the linked server. In place of checking the role, let's try to create a stored procedure in the reports_db database which can help us in privilege escalation. Please note that to create a stored procedure RPC Out must be enabled for the linked server - which is not enabled by default but quite common in case of linked servers. The idea is to create a stored procedure which gets executed as OWNER which is the user 'sa'. Use below query to create a stored procedure on the linked database.
Our stored procedure makes dbuser a sysadmin. Now, let's execute the stored procedure.

Neat! Now we can access all databases and tables on the target server. PowerUpSQL provides very useful commands for pillaging a database (and that is what I used first in the assessment to capture some juicy data) but we are not going to use them. See this blog post for details about that.

In many cases, this is one of the major goals of red team assessments, staying within the database layer we have access to multiple SQL servers across forest trust and juicy information stored within them. Since we have not done anything very unusual or noisy up to now, there are very low chances of detection. In fact, in my lab I have Microsoft Advanced Threat Analytics (ATA) set up and there was no detection of the attack. Obviously, because we did not communicate to the domain controller at all and ATA looks at only the DC traffic. Take that ATA!

Since, RPC Out is enabled on the linked server and we have sysadmin privileges, it is possible to enable xp_cmdshell and achieve OS command execution! Please note that if xp_cmdshell was already enabled on the linked server, we could execute OS commands without RPC Out while using only Openquery! Use below to enable xp_cmdshell
And let's see the privileges of the database process:

Great! Looks like the SQL server process is running with a domain user (sqlprodadmin) privileges. We can now hunt for a DA token from the normal domain user privileges we have on dps-sqlsrvtwo. Let's use the awesome PowerView for the DA token hunting. Remember that we cannot access our linked server dps-sqlsrvtwo directly and we do not have command execution on dps-sqlsrvdev. To load PowerView on dps-sqlsrvtwo, we can download and execute it in memory using PowerShell one-liner.
The one-liner needs to be encoded so that the URL doesn't mess up with the syntax of SQL query. Also, make sure that PowerView is modified a bit to include call to functions in the script itself and to receive the output the function calls must be piped to Out-Host.
And let's execute the encoded command:
Awesome! Looks like on the server dps-srvjump a DA token is available and our current user has local admin access. Let's dump NTLM hash of the DA - Administrator from dps-srvjump using Invoke-Mimikatz.
Finally, let's use these hashes with Invoke-Mimikatz to run a command on the DC of defensiveps. The DC of defensiveps is accessible from our machine in the offensiveps forest.

Bingo! DA access in the target forest!

We started with a non-admin domain user and worked our way to multiple SQL Servers while staying only at the database layer. We also got domain admin/enterprise admin in a trusting forest! :)

Mitigations

SQL Server Level
Multiple common mitigations like having limited linked databases and not enabling RPC Out on linked servers would have helped. Also, restricted allocation of privileges, even the public login, will help. One of the databases we encountered later on was running with a domain user's privileges. This is disastrous as it opens up many opportunities for privilege escalation on the domain level! Restricting privileges with which the database processes run is always desired.

Forest Level
Many improvements can be made. Allowing a local administrator on a box where a Domain Admin can log in is very very dangerous and results in disastrous situations like the one we saw above. If there is a box where DAs' privileges are required no other administrative account should be present. Logs will also tell you about a successful DA authentication from a forest if someone is looking for such information. Also, Selective Authentication can help in forest trust scenarios.

A note on ATA
I have Microsoft ATA setup in the lab where all the attacks took place. Since, ATA is the new sheriff in town let's discuss it a bit. ATA detect anomalies by looking at the traffic destined to the DC(s) by port mirroring. If we can limit ourselves to those attacks and techniques where there is no or minimal interaction with a DC, it is possible to avoid ATA and still get access to the most interesting machines and information. ATA thrives on Red Teamer/attacker's desire of going for DA rights as soon as possible. It is not always necessary to go after DA and use Golden ticket/Skeleton key/Credentials replay attacks for achieving the goal of an assessment unless, of course, you want to brag about it in your report :D Of course, there are bypasses for ATA as well but why bypass it when you can avoid it :)

Hope you enjoyed the post. Please leave comments, feedback and questions.