Showing posts with label Penetration Testing. Show all posts
Showing posts with label Penetration Testing. Show all posts

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!




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.

Tuesday, November 22, 2016

Exfiltration of User Credentials using WLAN SSID

I was playing with Windows Hosted Network feature couple of days back. A hopefully useful idea which came to my mind was using the name of the hosted SSID for exfiltration. Since, SSID names support maximum 32 bytes the choice of data to exfiltrate is not really wide. Something like user credentials is small enough to fit in this limited space.

I wrote a PowerShell script which allows use to exfiltrate data using only SSID names. I give you Invoke-SSIDExfil.ps1. Here is the source code. This script provides for multiple options to exfiltrate data. Since, we are mostly after user credentials, the script uses logic from Invoke-CredentialsPhish to show a credentials prompt to the user to capture credentials in clear text. The captured credentials are then encoded using ROT13 (not going to call ROT13 encryption though that may be the technically correct term) and a Windows Hosted Network is created and started with SSID name set as to the encoded value in the form Domain:Username:Password. Below is the script in action. Please note that the script must be executed from an elevated shell:
And this is how  - if we are in physical proximity of the target - the SSID looks like:
Now, we can decode the user credentials using Invoke-SSIDExfil script's -Decode option.

Neat! From my past experience, such scripts are useful for impressive demonstrations.

The script can be used as a payload in targeted client side attacks, Human Interface Devices (Kautilya), authenticated command execution and other techniques.

Using the -StringToExfiltrate and -ExfilOnly parameters, it is also possible to exfiltrate a small piece of data without showing a credential prompt to the user.

An update to the Gupt-Backdoor

While working on this script, I revisited Gupt-Backdoor. That backdoor is quite impressive as well when it comes to demonstrations. I blogged about it here. An improvement to that backdoor has been added which allows to pass a one line PowerShell downloand and execute cradle for PowerShell v3 onwards. Also, ROT13 encoding has been implemented to make SSID names less suspicious. Below command can be used to start the backdoor on a target and tell that an encoded command will be provided to it:
And this is how a Wireless AP can be started to send instructions to the backdoor.

And the execution looks like below. The backdoor downloads and executes Get-WLAN-Keys from Nishang:
Small but useful improvements!

Hope you enjoyed the post! Please leave feedback and comments.

Wednesday, May 25, 2016

Practical use of JavaScript and COM Scriptlets for Penetration Testing

I have been following Casey Smith's brilliant work on JavaScript and COM Scriptlets. After looking at his work, I started playing with the code. I was interested in developing easy and customizable ways to use JavaScript, SCT files, rundll32 and regvr32 for...well...interesting things. After using some weeknights and weekends, I give you following PowerShell scripts (all available in Nishang):

 

Invoke-JSRatRundll

Based on JSRAT by Casey, Invoke-JSRatRundll uses rundll32.exe to execute JavaScript on a target which provides a Reverse PowerShell Shell over HTTP. Why? Because it is so cool. Also, it is file-less, the client part is just a single command and most importantly, another method to pwn targets :) The script and the client part are intelligent enough to figure out if there is a proxy in use and also to use first proxy from multiple proxies from Internet Explorer settings. Also, based on the method mentioned here, Invoke-JSRatRundll doesn't leaver rundll32.exe running on the target, when "exit" command is used from the spawned reverse shell, so a clean exit. 

The listener, on the attacker's machine, needs to be run from elevated PowerShell session.
This is how it looks like in action:

Start the listener
The above listener provides the following command to be run on a target. Please note that will need to remove newlines:
When the command is executed on the target:
We get a connect back on the listener:
Nice! A proxy aware,  file-less, Reverse PowerShell Session.

The client part (one-line command) can be used whenever we have the ability to execute a command on the target. Below is an example of using the client part with Out-Word from Nishang. Note that the the double quotes in client part need to be escaped by using double-quotes two times.
When a target user opens the Word file and chooses to enable Macros, the listener will receive a connect back from the target machine. Bingo!

One thing to note in Invoke-JSRatRundll is that a window pops-up temporarily whenever a command is executed on the target. It is because of the use of Exec method of WScript. The Run method which provides for silent execution could not be used as it did not return the output without storing the output temporarily somewhere on the target.

 

Invoke-JSRatRegsvr

This script utilizes regsvr32.exe for providing a Reverse PowerShell session over HTTP. Use of regsvr32, the technique which has been termed as "Squiblydoo", has added benefits. regsvr32.exe takes care of proxy by itself, the execution is file-less and AFAIK, leaves no traces on the target after a clean exit. 

The listener needs to be run from an elevated PowerShell on the attacker's machine. This is how it looks like in action:
 The above listener provides the following command to be run on the target:
As soon as the command is executed on a target, using a client side attack, or any other method:
Great!

This script also shows a window momentarily on the target machine for the same reason as Invoke-JSRatRundll

 

Out-RundllCommand

Use this script to generate rundll32.exe one line commands. The generated command can be used on a target to run PowerShell commands and scripts or a reverse PowerShell session over TCP.

Here is how to generate a command. 
Now, if the rundll32 command is executed on a target using client side attack or other methods, the payload will get executed.

During testing it was not possible to execute larger scripts (specially the encoded ones due to the increased length). The added advantage with this script is it can be used with a simple netcat listener on a Linux machine as well. There is no need to run a special listener unlike in the above two scripts.
Start a netcat/Powercat listener. Run Out-RundllCommand with the -Reverse switch:
 When the generated rundll32 command is executed on the target:
Nice!

Also, the execution is silent on the target machine. Please note that this script leaves rundll32.exe running on the target machine.

 

Out-JS

This script is useful for client side attacks. Using this script, we can create "weaponized" JavaScript files which can be sent to a target user to execute PowerShell scripts and commands. Once a user executes the file (a double click opens the file using Windows Script Host, wscript.exe), the specified payload gets executed on the target with the privileges of the current user. The default name of the generated file is Style.js. 

Once again, it was not possible to execute large scripts, therefore, there is no option of specifying a script path. An example is included in the script to execute a reverse PowerShell session over TCP.

Out-SCT

This script generates a SCT file which can be used with regsvr32.exe to execute PowerShell scripts and commands. The default name of the generated file is UpdateCheck.xml. This file needs to be hosted on a web server and the one-liner regsvr is to be executed on the target.  Note that, in case a PayloadURL is provided, two connections are made from the target environment. This first one to pull the SCT file and the second one to download the PowerShell script.

Like Out-JS only small scripts can be executed using Out-SCT. An example is included in the help of this script which explains usage of a Reverse PowerShell session over TCP without having to download a script. 

Usage with metasploit

Some of the above scripts can be used to get a meterpreter session in the following ways:

Create a PowerShell meterpreter payload using msfvenom:

Host the generated payload on a web server.

Using Out-SCT
Pass the URL where meterprer PowerShell script is hosted to Out-SCT.
Now, host the generated SCT file on a web server. When the generated regsvr32 command is executed on a target, this will happen:

Awesome! A reverse HTTPS meterpreter from a file-less execution which is also helpful in avoiding Applocker!

Using Out-JS
Pass the URL to Out-JS.
When the generated Style,js is executed on a target, we will get a connect back on msfconsole!

Using Out-RundllCommand
Pass the URL to Out-RundllCommand.
Once again, when the generated rundll32 command is executed on a target, a meterpreter will pop-up in the msfconsole.

That is all for this post, all the scripts are available in the GitHub repository of Nishang. Hope you liked it. Please leave feedback and comments.

Join me for a two days training "Offensive PowerShell for Red and Blue Teams" at Shakacon, Honolulu (2 days - July 11th - 12th, 2016) - https://www.shakacon.org/trainings/offensive-powershell-for-red-and-blue-teams-by-nikhil-mittal/