Command Execution

The Command Execution section covers attacks designed to execute remote commands on the web site. All web sites utilize user-supplied input to fulfill requests. Often this user-supplied data is used to create construct commands resulting in dynamic web page content. If this process is done insecurely, an attacker could alter command execution.

Buffer Overflow

Buffer Overflow exploits are attacks that alter the flow of an application by overwriting parts of memory. Buffer Overflow is a common software flaw that results in an error condition. This error condition occurs when data written to memory exceed the allocated size of the buffer. As the buffer is overflowed, adjacent memory addresses are overwritten, causing the software to fault or crash. When unrestricted, properly-crafted input can be used to overflow the buffer, resulting in a number of security issues.

A Buffer Overflow can be used as a Denial of Service attack when memory is corrupted, resulting in software failure. Even more critical is the ability of a Buffer Overflow attack to alter application flow and force unintended actions. This scenario can occur in several ways. Buffer Overflow vulnerabilities have been used to overwrite stack pointers and redirect the program to execute malicious instructions. Buffer Overflows have also been used to change program variables.

Buffer Overflow vulnerabilities have become quite common in the information security industry and have often plagued web servers. However, they have not been commonly seen or exploited at the web application layer itself. The primary reason is that an attacker needs to analyze the application source code or the software binaries. Because the attacker must exploit custom code on a remote system, he would have to perform the attack blind, making success very difficult.

Buffer Overflow Example

Buffer Overflow vulnerabilities most commonly occur in programming languages such as C and C++. A Buffer Overflow can occur in a CGI program or when a web page accesses a C program. An example of a Buffer Overflow occurring in a web application was discovered in Oracle iAS version 9 release 2. Within iAS is a web interface to execute SQL queries called iSQL*Plus. iSQL*Plus requires a username and password to be entered before connecting to the database. If the username passed to the form was longer than 1024 bytes, the saved return address on the stack is overwritten. This results in the program flow being redirected and arbitrary opcodes to be executed. A simple example of code resulting in a Buffer Overflow is demonstrated next:

In this example, when the function is called, the return address of the caller is written to the stack. This is used to return control to the proper place after the function is completed. The bottom of the stack is then moved down 20 bytes to accommodate the local variable buffer. The important part to understand is that if you fill up the buffer variable and continue writing, the return address that was saved on the stack will be overwritten.

A successful exploit will be able to overwrite this saved return address with a value that points back into the memory address of the local variable buffer. In this local variable buffer will be included shell code to perform malicious actions. When the function completes, it will attempt to grab the return address from the stack and continue executing at that address. Because we have replaced that saved return address, we are able to change where it continues executing.

Apache Countermeasures

The Center for Internet Security's Apache Benchmark document has a Level 2 section (L2.9) that helps to combat Buffer Overflow attacks. See Appendix C for an example httpd.conf file with both Level 1 and Level 2 settings.

LimitRequestBody. This setting will limit the total size of the HTTP request body that is sent to the Apache web server. These parameters usually come into effect during HTTP PUT and POST requests where the client is sending data back to the web server from a form, or sending data into a CGI script. The setting below will restrict the request body size to be no more than 100K. You will need to increase this size if you have any forms that require larger input from clients.

LimitRequestFields. Limits the number of additional headers that can be sent by a client in an HTTP request, and defaults to 100. In real life, the number of headers a client might reasonably be expected to send is around 20, although this value can creep up if content negotiation is being used. A large number of headers may be an indication of a client making abnormal or hostile requests of the server. A lower limit of 40 headers can be set with the setting below.

LimitRequestFieldsize. Limits the maximum length of an individual HTTP header sent by the client, including the initial header name. The default (and maximum) value is 8,190 characters. We can set this to limit headers to a maximum length of 1,000 characters with the setting below.

LimitRequestline. Limits the maximum length of the HTTP request itself, including the HTTP method, URL, and protocol. The default limit is 8,190 characters; we can reduce this to 500 characters with the line below. The effect of this directive is to effectively limit the size of the URL that a client can request, so it must be set large enough for clients to access all the valid URLs on the server, including the query string sent by GET requests. Setting this value too low can prevent clients from sending the results of HTML forms to the server when the form method is set to GET. With these directives, you could add the following entries to your httpd.conf file:

This will certainly help with placing adequate restrictions on the size of these portions of the client's request; however, these LimitRequest directives listed previously are a bit too broad to handle individual buffer overflow vulnerabilities in application parameters. We can, however, leverage Mod_Security's granularity capabilities to place proper restrictions on specific application parameters.

Restrict Input Size and Type
Taking the example listed previously with Oracle 9iAS, we can place restrictions on the username parameter to verify that it will only accept alpha characters and that the total size is less than 1,024 bytes.

Verify Encodings and Force ByteRange
Often, a Buffer Overflow attack will include random binary data in order to fill up the buffer and then to execute the desired shellcode.Mod_Security has a few different directives that will help to identify and prevent this data from executing. Both of the Encoding checks will help to filter out bogus encodings. The SecFilterForceByteRange directive will also restrict the allowed character set to non-meta characters.

In order to test these settings, I decided to use the torture.pl script created by Lincoln Stein. This PERL script will send data to a web server in order to test how it handles different loads. Next is the help menu of the script.

I then ran the script in order to send random data to the web server and test the Mod_Security filters.

As you can see, Mod_Security generated a 403 status code for this request. Let's take a look at the audit_log data to see exactly what data the torture.pl script sent to the web server.

As the mod_security message indicates, this request was denied due to the SecFilterForceByteRange restrictions.