Command execution is the process of using a web interface in order to execute OS commands on a web server.  This article will discuss how to detect and block several of these types of attacks.  It will also illustrate how to properly deal with encoded characters. Other articles in the series:


Background

For a command execution attack, the end user includes system level commands that are passed through as part of a HTTP request to the target web server.  By executing commands on the server, the end user can install viruses or remotely retrieve sensitive information.

Specifying commands directly

First let's pick on the windows platform.  Executable extensions are delimited by a .exe extension.  Certain web servers will also allow calling of code withing application libraries which have the .dll extension. 

http://someserver//c:/windows/system32/shutdown.exe

While there may be some instances where .exe's or .dll's are desired (CGI or ISAPI for instance), it is fairly simple to put an iRule together to block all requests to these types of objects.  For the cases that you desire certain objects to be allowed, you could add special cases to the switch to allow them through.

 

when HTTP_REQUEST {
  switch -glob [string tolower [HTTP::uri]] {
    "*.exe*" -
    "*.dll*" {
      log local0. "ATTACK ([HTTP::uri]) - Attempt made to call a system level command"
      reject;
    }
  }
}

The reason the "string tolower" is in there is to cover requests like "http://somserver//c:/windows/system32/shutdown.ExE"?

Piping and Command Chaining

To be fair, this exploit will work on various flavors of Unix as well as Windows.  In this case, the user makes use of a way to append a command to what would look like a valid request.  Here's one example that will execute what looks like a perfectly fine cgi application of processRequest.pl passing it a GET variable of doc=/bin/ls. 

http://someserver/cgi-bin/proccessRequest.pl?doc=/bin/ls|

Whoa...  What's that pipe symbol at the end of the request?  Well, this will actually tell perl to execute the previous command of "/bin/ls".  This will return a file listing which is probably not what was intended for processRequest.pl.

Here's another example of a request to a PHP page.

http://someserver/something.php?dir=%3Bcat%20/etc/passwd

At a first glance, this looks fine.  Well, except for the /etc/passwd is kind of a red flag.  In this case, the caller has done some encoding on the URI to try to bypass any filters that did straight string comparisons.  The HTTP spec allows for ascii encoding of characters in the request.  Taking a look at a handy ASCII table (http://www.asciitable.com/), the decoded version of this request is

"http://someserver/something.php?dir;cat /etc/passwd"

Ahhh, now that doesn't look too good.  A semi-colon tells php to terminate it's command and execute the following command after the specified semi-colon.  In this case, this request would cat "echo" the contents of the local passwd file.  Definitely not something you want to happen.

Here is how you would check for these cases with an iRule.

when HTTP_REQUEST {
  switch -glob [string tolower [URI::decode [HTTP::uri]]] {
    "*.pl*|" {
      log local0. "ATTACK ([HTTP::uri]) - Attempt to execute a perl based pipe"
      reject
    }
    "*.php*;*" {
      log local0. "ATTACK ([HTTP::uri]) - Attempt to chain a command to a php script"
      reject
    }
  }
}

Notice the "URI::decode" command that will take the input URI and decode all encoded characters in the request.

Putting it all together

Here's a combined iRule with the above examples.

when HTTP_REQUEST {
  switch -glob [string tolower [URI::decode [HTTP::uri]]] {
    "*.exe*" -
    "*.dll*" {
      log local0. "ATTACK ([HTTP::uri]) - Attempt made to call a system level command"
      reject;
    }
    "*.pl*|" {
      log local0. "ATTACK ([HTTP::uri]) - Attempt to execute a perl based pipe"
      reject
    }
    "*.php*;*" {
      log local0. "ATTACK ([HTTP::uri]) - Attempt to chain a command to a php script"
      reject
    }
  }
}

Conclusion

This article is meant to show some common ways to protect against remote command execution.  It is by no means covers every exploit out there and we recommend using a application firewall to fully protect against this type of attack.  But in the rare case where you find yourself being attacked and need a way to quickly protect your website, these techniques will likely come in handy.

Get the Flash Player to see this player.