Saturday, May 3, 2008

Fun with DCE-RPC Fuzzing

I recently finished working on an interesting project that was a mix of architecture assessment and penetration testing.  One of our key tasks was to analyze the effectiveness of a firewall that they had configured to perform layer 7 inspection of Windows DCE-RPC traffic within their environment.  The firewall was designed to enforce a white-list of allowed RPC services (based on UUID) and deny all others.  It also did some fancy dynamic port management, automatically opening/closing high-number ports for permitted RPC connections.  The client, naturally concerned about how common RPC exploits are in Windows environments, wanted to see if this functionality worked as advertised.
Our pen-tests usually don't entail a significant amount of packet crafting and manipulation, since we're more typically working at the OS or application level.  So testing this firewall's RPC filtering mechanism was a fun challenge.  We ended up relying on two tools to perform fuzzing attacks, primarily manipulating the UUID and function call fields in the RPC packets:
  • Impacket - A collection of Python classes developed by the Core Security guys.  Includes support for DCE-RPC v4 and v5.  I used this to write up a number of scripts for each test case.
  • SPIKE - Popular fuzz testing framework based in C - it includes a pre-built msrpc fuzzing tool.
I initially wanted to use Scapy, but it unfortunately doesn't have native support for DCE-RPC and I didn't have the time (or skill) to build out the protocol.  Of course, we also heavily relied upon Wireshark since it decodes DCE-RPC v5 very nicely, and Metasploit to launch a few known RPC exploits.
Our team's results were mixed.  After extensive brainstorming and failed attempts with my colleague, we were able to trick the firewall into opening RPC ports by spoofing valid RPC sessions - but only for white-listed UUIDs.  I was more interested in getting the firewall to choke on malformed endpoint mapper requests or other RPC packets, and possibly create denial of service conditions (or get packets with disallowed UUIDs past the filtering mechanism).  No luck there, mostly due to how the RPC endpoint mapper and firewall work together to dynamically open ports.  The specific port opened for an RPC service is dictated by the endpoint mapper response and cannot be defined by the initial request - which makes sense, the client shouldn't have any say in what port the server chooses for the service. 
Despite failing to completely own the firewall, designing and implementing our testing approach was a great experience - especially coding the Python test scripts with Impacket.  It certainly was a nice change of pace from our traditional Windows penetration tests.

Labels: , , ,

Thursday, August 23, 2007

Pass the hash, NTLM style

Way back in 1997, a Windows exploit named "NT Pass the Hash" was posted on Bugtraq. This Unix-based tool was a modified SMB client that lets you use captured LanMan hashes, without having to decrypt them first.

After a mere ten years, someone has finally modernized this concept into a much more potent attack. Core Security has released Pass-The-Hash Toolkit, which runs on Windows and works with NTLM hashes. It's comprised of two key modules:
  • IAM.EXE - This tool "injects" another user's NTLM credentials into your current Windows logon session, given their username, Windows domain, and NTLM hash. You can then use the 'net' tools or any other Windows software that authenticates via NTLM, all under the assumed privileges of the compromised user account.
  • WHOSTHERE.EXE - Lists the usernames and NTLM hashes of all users logged on to a system.
No password cracking required! So if you own other systems on the network, you can just run whosthere.exe on them until you snag a domain admin's hashes. Or you could use a man-in-the middle attack, like the WPAD proxy exploit. As I discussed a few posts ago, the Metasploit guys covered several methods for grabbing NTLM hashes in their Tactical Exploitation presentation at BlackHat.

Labels: ,

Wednesday, July 4, 2007

Why is it still so easy to hack Windows networks?

The other day, a few of us at work were discussing how internal Windows penetration tests have remained ridiculously easy, irrespective of the client, since we first started in this field. Between the four of us, we've done at least twenty or thirty Windows internal pen-tests in the last few years, against both gigantic and small networks. Regardless of the target's size and complexity, we can usually get domain administrator control of the environment within one day, or even a few hours, and it's not through any fancy attack techniques either. The progression is almost always the same:
  1. Compromise standalone servers/workstations through a handful of common attacks.
  2. Run LSAdump to obtain LSA secrets, run PWdump to crack local account hashes.
  3. Use recovered credentials to gain access to domain accounts.
Step #1 usually is accomplished by finding SQL servers with blank or weak 'SA' passwords and gaining local admin through xp_cmdshell. Yes, this is still a problem, even in highly sensitive environments where you'd never expect it. We also often find old IIS servers permitting anonymous FrontPage authoring, load up hostile ASP to pass-through commands, and pop the server that way. A third approach is to enumerate users on Windows hosts via anonymous NetBIOS, and test them for blank passwords & password=username. Local accounts are almost always neglected on at least a few hosts. These are the "low-hanging-fruit" for which we'll immediately scan, before attempting more involved attacks. They are incredibly old issues (MS SQL 2005 won't let you give SA a blank password, and anonymous authoring hasn't been enabled by default in FrontPage for years) but in a big environment you'll always find some susceptible systems that were "missed" for some reason or other.

Once we've got Local Admin on a box (one way or another), PWdump gives us the local user password hashes and LSAdump gives us the LSA secrets. It's especially fun to crack the Local Admin account password with PWdump and then realize they're using the same password for Local Admin on every other Windows box. Typical excuse: "It's too hard to manage the Local Admin accounts on so many machines, so we just use the same password on all of them."

But I usually have the best luck with passwords in the LSA secrets - there's almost always some service account running as a domain administrator with the same credentials. It's absolutely ridiculous how liberally some organizations assign AD privileges - "Oh, XXX service didn't run right, so we had to make the account a domain admin." Horrible reasoning. And sometimes you just get a local user account that has the same password for his or her equivalent domain account.

In some cases, we'll get a domain admin account but it won't be allowed to establish Terminal Services connections. That's really not much of a security control when you can still shuttle files on and off the machine with NetBIOS and execute commands with psexec (or schedule commands on the remote host with "at", or remotely start/stop services and edit the registry, etc.).

The bottom line is that although these attack techniques and vulnerabilities are old and easy to fix, they persist year after year, client after client. I think there are a few contributing factors:

  • It is difficult to create and maintain an accurate inventory of all systems active in an environment. If you don't know it's there, you can't make sure it's secure.
  • Many organizations already know about the vulnerabilities we find, but had assumed them to be acceptable risks. Sometimes it takes a penetration test to really drive home the "real-world" impact of an issue before management will understand and act on it. In other cases, risks are accepted because developers or sys-admins successfully argue that correcting the flaw would "break" key functionality - often because they didn't feel like going through the trouble of making it work.

  • Applying the principle of least-privilege to Windows domains and their user accounts is exponentially more difficult as an environment grows in size and complexity.

  • (potentially controversial point) The barrier to entry for Windows system administrators is lower than that for Unix or networking admins, simply because at a superficial level, it is easier to stand up and maintain a Windows environment. As a result, many are often less technically proficient than they need to be. This is based purely on my anecdotal observations, but other some of my other colleagues agree.
I certainly acknowledge that it must be hell to be on the other end of a pen-test, even if you are a diligent administrator - it's much easier to break down one door rather than defend hundreds of them. I just get frustrated when I see really basic security vulnerabilities that are obviously the product of poor controls, organization, and leadership. It shouldn't be That easy for any unprivileged user to own your environment.

Thoughts/comments are welcome.

Labels: ,