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:
// A function declares a 20 byte buffer on the stack char buffer[20]; // the function take a buffer which was user defined char input[] = argv[0]; // then tries to copy the user-defined buffer into the 20 byte buffer strcpy( buffer, input );
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:
LimitRequestBody 10240 LimitRequestFields 40 LimitRequestFieldsize 1000 LimitRequestline 500
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.
<Directory /patch/to/apache/htdocs/login> SecFilterSelective Arg_username "!^[a-zA-Z]+$" SecFilterSelective Arg_username ".{1024,}" </Directory>
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.
# Make sure that URL encoding is valid SecFilterCheckURLEncoding On SecFilterCheckUnicodeEncoding On # Only allow bytes from this range SecFilterForceByteRange 32 126
In order to test these settings, I decided to use the torture.pl script created by Lincoln Stein (http://stein.cshl.org/~lstein/torture/). 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.
# ./torture.pl Usage: ./torture.pl -[options] URL Torture-test Web servers and CGI scripts Options: -l <integer> Max length of random URL to send [0 bytes] -t <integer> Number of times to run the test [1] -c <integer> Number of copies of program to run [1] -d <float> Mean delay between serial accesses [0 sec] -P Use POST method rather than GET method -p Attach random data to path rather than query string -r Send raw (non-escaped) data
I then ran the script in order to send random data to the web server and test the Mod_Security filters.
# ./torture.pl -l 102400 -p -r http://localhost/ ** torture.pl version 1.05 starting at Fri Apr 22 15:13:39 2005 Transactions: 1 Elapsed time: 0.323 sec Bytes Transferred: 84485 bytes Response Time: 0.28 sec Transaction Rate: 3.10 trans/sec Throughput: 261875.68 bytes/sec Concurrency: 0.9 Status Code 403:1 ** torture.pl version 1.05 ending at Fri Apr 22 15:13:39 2005
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.
======================================== UNIQUE_ID: 8dUAbH8AAAEAAGZPCQsAAAAA Request: 127.0.0.1 - - [21/Apr/2005:01:52:29 --0400] "GET /?c\x9f\xb0\xf7,;\xe4\xc0\xb3\xfc\xf5\xa7\x86\x0e\x1a\x12 \xdc\x9a8\xb0\xd5\xbbBJ%Q\
xcc\x92c\xc1a\xd0\x8bn\xb0\x97\xf0M;\x938T\xfaGL""\x07RjE\x9f\xedK\x1d\x83\x9b\xd5\x97
!\x01&\xb8\xa1\xc0-\xe2>U\xeav;\x90\x94'\xef\x11o\x05B\xc9\xb7\x7f\xefD6\xc6\xfc\xee\
xcdl\xe8\x85+p\x8b\xe93\x81 HTTP/1.1" 403 729 Handler: cgi-script -------------------------------------------------------------------- GET /?c\x9f\xb0\xf7,;\xe4\xc0\xb3\xfc\xf5\xa7\x86\x0e\x1a\x12 \xdc\x9a8\xb0\xd5\ xbbBJ%Q\xcc\x92c\xc1a\xd0\x8bn\xb0\x97\xf0M;\x938T\xfaGL"\x07RjE\x9f\xedK\x1d\x83\x9b\
xd5\x97!\x01&\xb8\xa1\xc0-\xe2>U\xeav;\x90\x94'\xef\x11o\x05B\xc9\xb7\x7f\xefD6\xc6\
xfc\xee\xcdl\xe8\x85+p\x8b\xe93\x81 HTTP/1.1 Host: localhost mod_security-message: Error normalizing REQUEST_URI: Invalid character detected [159] mod_security-action: 403 Ü8°Õ»BJ%QÌcÁa?n°∂M;8TúGL"RjEíK!&¸¡À->Uêv;'ïoBÉ·ïD6ÆüîÍlè +pé3 HTTP/1.1 403 Forbidden Content-Length: 729 Connection: close Content-Type: text/html; charset=ISO-8859-1 ========================================
As the mod_security message indicates, this request was denied due to the SecFilterForceByteRange restrictions.
References
"Inside the Buffer Overflow Attack: Mechanism, Method and Prevention" By Mark E. DonaldsonGSEC http://www.sans.org/rr/code/inside_buffer.php
"w00w00 on Heap Overflows" By Matt Conoverw00w00 Security Team http://www.w00w00.org/files/articles/heaptut.txt
"Smashing the Stack for Fun and Profit" By Aleph OnePhrack 49 http://www.insecure.org/stf/smashstack.txt
Format String Attack
Format String Attacks alter the flow of an application by using string formatting library features to access other memory space. Vulnerabilities occur when user-supplied data is used directly as formatting string input for certain C/C++ functions (e.g., fprintf, printf, sprintf, setproctitle, syslog, etc.). If an attacker passes a format string consisting of printf conversion characters (e.g., "%f", "%p", "%n", etc.) as parameter value to the web application, they may:
- Execute arbitrary code on the server.
- Read values off the stack.
- Cause segmentation faults / software crashes.
Format String Attack Example
Let’s assume that a web application has a parameter emailAddress, dictated by the user. The application prints the value of this variable by using the printf function:
printf(emailAddress);
If the value sent to the emailAddress parameter contains conversion characters, printf will parse the conversion characters and use the additionally supplied corresponding arguments. If no such arguments actually exist, data from the stack will be used in accordance to the order expected by the printf function. The possible uses of the Format String Attacks in such a case can be as follows:
- Read data from the stack: If the output stream of the printf function is presented back to the attacker, he may read values on the stack by sending the conversion character "%x" (one or more times).
- Read character strings from the process’ memory: If the output stream of the printf function is presented back to the attacker, he can read character strings at arbitrary memory locations by using the "%s" conversion character (and other conversion characters in order to reach specific locations).
- Write an integer to locations in the process’ memory: By using the "%n" conversion character, an attacker may write an integer value to any location in memory (e.g., overwrite important program flags that control access privileges, overwrite return addresses on the stack, etc.).
In the previous example, the correct way to use printf is
printf("%s",emailAddress);
In this case, the "emailAddress" variable will not be parsed by the printf function. The following examples were taken from real-world format string vulnerabilities exploits against HTTP-based servers:
The Format String Attack 1 is as follows:
GET / HTTP/1.0 Authorization: %n%n%n%n
While this second example of a Format String Attack is also valid:
GET /%s%s%s HTTP/1.0
Apache Countermeasures for Format String Attacks
Similar to how we handled the buffer overflow issues, we can utilize the same Mod_Security directives that will check the encodings and byte ranges of the request. A key component of a format string attack is the inclusion of the percent sign (%) in the request. If you are sure that certain client headers will not legitimately need to use this parameter, then you can create additional Mod_Security filters to check for the presence of the % sign. This is needed since the decimal number for the % sign is 25, which is within the allowed range specified by the SecFilterForceByteRange setting of 20 126. The following filter will identify the presence of a % sign in the host client header:
SecFilterSelective HTTP_HOST "\x25"
The reason why this filter is needed is that Mod_Security will perform the URL decoding of the request prior to applying these filters. If the % sign is still present, then it will be denied. This concept could be expanded to inspect other client request headers.
References
"(Maybe) the first publicly known Format Strings exploit" http://archives.neohapsis.com/archives/bugtraq/1999-q3/1009.html
"Analysis of format string bugs" By Andreas Thuemmel http://downloads.securityfocus.com/library/format-bug-analysis.pdf
"Format string input validation error in wu-ftpd site_exec() function" http://www.kb.cert.org/vuls/id/29823
LDAP Injection
LDAP Injection is an attack technique used to exploit web sites that construct LDAP statements from user-supplied input.
Lightweight Directory Access Protocol (LDAP) is an open-standard protocol for both querying and manipulating X.500 directory services. The LDAP protocol runs over Internet transport protocols, such as TCP. Web applications may use user-supplied input to create custom LDAP statements for dynamic web page requests.
When a web application fails to properly sanitize user-supplied input, it is possible for an attacker to alter the construction of an LDAP statement. When an attacker is able to modify an LDAP statement, the process will run with the same permissions as the component that executed the command (e.g., database server, web application server, web server, etc.). This can cause serious security problems where the permissions grant the rights to query, modify, or remove anything inside the LDAP tree.
LDAP Injection Examples
Vulnerable code with comments:
line 0: <html> line 1: <body> line 2: <%@ Language=VBScript %> line 3: <% line 4: Dim userName line 5: Dim filter line 6: Dim ldapObj line 7: line 8: Const LDAP_SERVER = "ldap.example" line 9: line 10: userName = Request.QueryString("user") line 11: line 12: if( userName = "" ) then line 13: Response.Write("<b>Invalid request. Please specify a valid user name</b><br>") line 14: Response.End() line 15: end if line 16: line 17: line 18: filter = "(uid=" + CStr(userName) + ")" ' searching for the user entry line 19: line 20: line 21: 'Creating the LDAP object and setting the base dn line 22: Set ldapObj = Server.CreateObject("IPWorksASP.LDAP") line 23: ldapObj.ServerName = LDAP_SERVER line 24: ldapObj.DN = "ou=people,dc=spilab,dc=com" line 25: line 26: 'Setting the search filter line 27: ldapObj.SearchFilter = filter line 28: line 29: ldapObj.Search line 30: line 31: 'Showing the user information line 32: While ldapObj.NextResult = 1 line 33: Response.Write("<p>") line 34: line 35: Response.Write("<b><u>User information for : " +ldapObj.AttrValue(0) + "</u></b><br>") line 36: For i = 0 To ldapObj.AttrCount -1 line 37: Response.Write("<b>" + ldapObj.AttrType(i) +"</b> : " + ldapObj.AttrValue(i) + "<br>" ) line 38: Next line 39: Response.Write("</p>") line 40: Wend line 41: %> line 42: </body> line 43: </html>
Looking at the code, we see on line 10 that the userName variable is initialized with the parameter user and then quickly validated to see if the value is empty. If the value is not empty, the userName is used to initialize the filter variable on line 18. This new variable is directly used to construct an LDAP query that will be used in the call to SearchFilter on line 27. In this scenario, the attacker has complete control over what will be queried on the LDAP server, and he will get the result of the query when the code hits line 32 to 40 where all the results and their attributes are displayed back to the user.
Attack Example
http://example/ldapsearch.asp?user=*
In the preceding example, we send the * character in the user parameter, which will result in the filter variable in the code to be initialized with (uid=*). The resulting LDAP statement will make the server return any object that contains a uid attribute.
Apache Countermeasures for LDAP Injection Attacks
This scenario falls into the input validation category. Our mitigation strategy will be similar to how we combated XSS attacks, except that instead of looking for JavaScript tags, we will restrict the character sets allowed for the particular parameter. Here is a Mod_Security filter that will restrict the "user" parameter character set to only allow alpha characters:
SecFilterSelective ARG_user "!^[a-zA-Z]+$"
If this filter were in place when the attacker submitted the example attack listed previously, then it would have been rejected, due to the "*" character not being listed in the allowed character set.
References
"LDAP
Injection:
Are
Your
Web
Applications
Vulnerable?"
By
Sacha
FaustSPI
Dynamics
http://www.spidynamics.com/whitepapers/LDAPinjection.pdf
"A
String
Representation
of
LDAP
Search
Filters"
http://www.ietf.org/rfc/rfc1960.txt
"Understanding LDAP" http://www.redbooks.ibm.com/redbooks/SG244986.html
"LDAP Resources" http://ldapman.org
OS Commanding
OS Commanding is an attack technique used to exploit web sites by executing Operating System commands through manipulation of application input. When a web application does not properly sanitize user-supplied input before using it within application code, it may be possible to trick the application into executing Operating System commands. The executed commands will run with the same permissions of the component that executed the command (e.g., database server, web application server, web server, and so forth).
OS Commanding Example
Perl allows piping data from a process into an open statement, by appending a '|' (pipe) character onto the end of a filename. Pipe character examples:
# Execute "/bin/ls" and pipe the output to the open statement open(FILE, "/bin/ls|")
Web applications often include parameters that specify a file that is displayed or used as a template. If the web application does not properly sanitize the input provided by a user, an attacker may change the parameter value to include a shell command followed by the pipe symbol (shown previously). If the original URL of the web application is
http://example/cgi-bin/showInfo.pl?name=John&template=tmp1.txt
Changing the template parameter value, the attacker can trick the web application into executing the command /bin/ls:
http://example/cgi-bin/showInfo.pl?name=John&template=/bin/ls|
Most scripting languages enable programmers to execute Operating System commands during run-time, by using various exec functions. If the web application allows user-supplied input to be used inside such a function call without being sanitized first, it may be possible for an attacker to run Operating System commands remotely. For example, here is a part of a PHP script, which presents the contents of a system directory (on UNIX systems). Execute a shell command:
exec("ls -la $dir",$lines,$rc);
By appending a semicolon (;), which is URL encoded to %3D, followed by an Operating System command, it is possible to force the web application into executing the second command:
http://example/directory.php?dir=%3Bcat%20/etc/passwd
The result will retrieve the contents of the /etc/passwd file. This is similar to the PHF exploit that was shown in Chapter 2.
Apache Countermeasures for OS Commanding Attacks
There are three different ways that we can potentially mitigate OS Commanding attacks.
- Restrict Permissions on OS Commands.
- Whitelist Allowed Characters.
- Filter Out Command Directory Names.
If you remove the execution bit from the everyone group (-rwxrwzrw-) of OS commands, then the web server user account will not be able to execute the targeted command even if an attacker is able to trick the web application into attempting to execute it.
In order to bypass validation mechanisms of the target web application, the attacker will usually need to insert different meta-characters to alter the execution. You can therefore create a Mod_Security filter for the target application so that it will only allow acceptable characters.
SecFilterSelective SCRIPT_FILENAME "directory.php" chain SecFilterSelective ARG_dir "!^[a-zA-Z/_-\.0-9]+$"
This chained ruleset will only allow letters, numbers, underscore, dash, forward slash, and period in the dir parameter.
Instead of focusing on the meta-character exploit, we change our focus to the target of the attack, which is the OS command itself. We could list out every possible OS-level command; however, the resulting Mod_Security rule would be huge and our filter would also probably not be comprehensive. An alternative method that I use is to list the parent directories of the OS commands. For example, the following filter would block the example attack listed previously for the /etc/passed file since it would match on the "/etc/" regular expression:
SecFilterSelective THE_REQUEST "/^(etc|bin|sbin|tmp|var|opt|dev|kernel)$/"
References
"Perl
CGI
Problems" By
RFPPhrack
Magazine,
Issue
55
http://www.wiretrip.net/rfp/txt/phrack55.txt
(See "That
pesky
pipe" section.)
"Marcus Xenakis directory.php Shell Command Execution Vulnerability" http://www.securityfocus.com/bid/4278
"NCSA Secure Programming Guidelines" http://archive.ncsa.uiuc.edu/General/Grid/ACES/security/programming/#cgi
SQL Injection
SQL Injection is an attack technique used to exploit web sites that construct SQL statements from user-supplied input. Structured Query Language (SQL) is a specialized programming language for sending queries to databases. Most small and industrial-strength database applications can be accessed using SQL statements. SQL is both an ANSI and an ISO standard. However, many database products supporting SQL do so with proprietary extensions to the standard language. Web applications may use user-supplied input to create custom SQL statements for dynamic web page requests.
When a web application fails to properly sanitize user-supplied input, it is possible for an attacker to alter the construction of back-end SQL statements. When an attacker is able to modify an SQL statement, the process will run with the same permissions as the component that executed the command (e.g., database server, web application server, web server, and so forth). The impact of this attack can allow attackers to gain total control of the database or even execute commands on the system.
SQL Injection Examples
A web-based authentication form might have code that looks like the following:
SQLQuery = "SELECT Username FROM Users WHERE Username = '" & strUsername & "' AND Password = '" & strPassword & "'" strAuthCheck = GetQueryResult(SQLQuery)
In this code, the developer is taking the user-input from the form and embedding it directly into an SQL query. Suppose an attacker submits a login and password that looks like the following:
Login: ' OR ''=' Password: ' OR ''='
This will cause the resulting SQL query to become
SELECT Username FROM Users WHERE Username = '' OR ''='' AND Password = '' OR ''=''
Instead of comparing the user-supplied data with entries in the Users table, the query compares '' (empty string) to '' (empty string). This will return a True result, and the attacker will then be logged in as the first user in the Users table.
There are two commonly known methods of SQL injection: Normal SQL Injection and Blind SQL Injection. The first is vanilla SQL Injection, in which the attacker can format his query to match the developer's by using the information contained in the error messages that are returned in the response.
Normal SQL Injection
By appending a union select statement to the parameter, the attacker can test to see if he can gain access to the database:
http://example/article.asp?ID=2+union+all+select+name+from+sysobjects
The SQL server then might return an error similar to this:
Microsoft OLE DB Provider for ODBC Drivers error '80040e14' [Microsoft][ODBC SQL Server Driver][SQL Server]All queries in an SQL statement
containing a UNION operator must have an equal number of expressions in their target lists.
This tells the attacker that he must now guess the correct number of columns for his SQL statement to work.
Blind SQL Injection
In a Blind SQL Injection attack, instead of returning a database error, the server returns a customer-friendly error page informing the user that a mistake has been made. In this instance, SQL Injection is still possible, but not as easy to detect. A common way to detect a Blind SQL Injection is to put a false and true statement into the parameter value. Executing the following requests to a web site should return the same web pages because the SQL statement 'and 1=1' is always true:
http://example/article.asp?ID=2 http://example/article.asp?ID=2+and+1=1
Executing the following request to a web site would then cause the web site to return a friendly error or no page at all:
http://example/article.asp?ID=2+and+1=0
This is because the SQL statement "and 1=0" is always false. Once the attacker discovers that a site is susceptible to Blind SQL Injection, he can exploit this vulnerability more easily, in some cases, than by using normal SQL Injection.
Apache Countermeasures for SQL Injection Attacks
SQL Injection is best solved through two practices: Input Validation and Stored Procedures with parameterized queries. Input validation is a practice that will prevent SQL Injection exploits as well as a multitude of other application attacks. This process should be followed for all applications, not just those that use SQL queries. Using stored procedures for SQL queries ensures that the user input is not executed as part of the SQL query. (Note: Make sure to use parameterized queries to ensure that the stored procedure itself is not vulnerable to SQL Injection.) The following recommendations will help prevent successful SQL Injection attacks.
User-Input Sanitization Checking
The best way to filter data is with a default-deny regular expression that includes only the type of data the web application expects to receive.
Character-Set and Length Restriction
Restrict the valid types of characters a user may submit to a web application. Using regular expressions, make the input filters as strict as possible with anchors at the beginning and end. Table 7.1 lists some example regular expressions and their meaning.
Table 7.1 Example Regular Expressions and Their Meaning
Purpose of Expression |
Regular Expression |
Only allow letters with a length restriction between 1 and 10 characters. |
/^[a-zA-Z]{1,10}$/ |
Allow letters and numbers with a length restriction between 1 and 10 characters. |
/^[a-zA-Z0-9]{1,10}$/ |
Allow letters, numbers, and some punctuation with a length restriction between 1 and 10 characters. |
/^[a-zA-Z0-9\.@!]{1,10}$/ |
The following is an example of using these regular expressions with Mod_Security to protect the ID parameter for the article.asp page from earlier:
SecFilterSelective SCRIPT_FILENAME "article.asp" chain SecFilterSelective ARG_ID "!^[a-zA-Z0-9\.@!]{1,10}$"
If for some reason you cannot take that approach and must instead use a "deny-what-is-bad" method, then at minimum remove or escape single quotes ('), semicolons (;), dashes, hyphens(-), and parenthesis("()").
Prevent Common SQL Commands
SQL commands should never be taken directly from user input, regardless of whether they are valid SQL commands in and of themselves. Here are some Mod_Security filters that will deny many of the common SQL commands targeted by attackers:
SecFilter "delete[[:space:]]+from" SecFilter "insert[[:space:]]+into" SecFilter "select.+from" SecFilter xp_cmdshell SecFilter xp_regread SecFilter xp_regwrite SecFilter xp_regdeletekeySecFilter xp_enumdsn SecFilter xp_filelist SecFilter xp_availablemedia
References
"SQL Injection: Are Your Web Applications Vulnerable"SPI Dynamics http://www.spidynamics.com/support/whitepapers/WhitepaperSQLInjection.pdf
"Blind SQL Injection: Are Your Web Applications Vulnerable"SPI Dynamics http://www.spidynamics.com/support/whitepapers/Blind_SQLInjection.pdf
"Advanced SQL Injection in SQL Server Applications" By Chris AnleyNGSSoftware http://www.nextgenss.com/papers/advanced_sql_injection.pdf
"More Advanced SQL Injection" By Chris AnleyNGSSoftware http://www.nextgenss.com/papers/more_advanced_sql_injection.pdf
"Web
Application
Disassembly
with
ODBC
Error
Messages"
By
David
Litchfield@stake
http://www.nextgenss.com/papers/webappdis.doc
"SQL Injection Walkthrough" http://www.securiteam.com/securityreviews/5DP0N1P76E.html
"Blind SQL Injection"Imperva http://www.imperva.com/application_defense_center/white_papers/blind_sql_server_ injection.html
"SQL Injection Signatures Evasion"Imperva http://www.imperva.com/application_defense_center/white_papers/sql_injection_ signatures_evasion.html
"Introduction to SQL Injection Attacks for Oracle Developers"Integrigy http://www.net-security.org/dl/articles/IntegrigyIntrotoSQLInjectionAttacks.pdf
SSI Injection
SSI Injection (Server-side Include) is a server-side exploit technique that allows an attacker to send code into a web application, which will later be executed locally by the web server. SSI Injection exploits a web application’s failure to sanitize user-supplied data before they are inserted into a server-side interpreted HTML file.
Prior to serving an HTML web page, a web server may parse and execute Server-side Include statements before providing it to the user. In some cases (e.g., message boards, guest books, or content management systems), a web application will insert user- supplied data into the source of a web page. If an attacker submits a Server-side Include statement, he may have the ability to execute arbitrary operating system commands, or include a restricted file’s contents the next time the page is served.
SSI Injection Example
The following SSI tag can allow an attacker to get the root directory listing on a UNIX-based system:
<!--#exec cmd="/bin/ls /" -->
The following SSI tag can allow an attacker to obtain database connection strings, or other sensitive data contained within a .NET configuration file:
<!--#INCLUDE VIRTUAL="/web.config"-->
Apache Countermeasures for SSI Injection Attacks
The best way to prevent SSI injection attacks is to create a Mod_Security filter to block any requests that have SSI format syntax. For example, the following filter would trigger on all SSI injections:
SecFilter "\<\!--\#"
References
"Server-Side Includes (SSI)"NCSA HTTPd http://hoohoo.ncsa.uiuc.edu/docs/tutorials/includes.htm
"Security Tips for Server Configuration"Apache HTTPD http://httpd.apache.org/docs/misc/security_tips.html#ssi
"Header-Based Exploitation: Web Statistical Software Threats"CGISecurity.com http://www.cgisecurity.net/papers/header-based-exploitation.txt
"A practical vulnerability analysis" http://hexagon.itgo.com/Notadetapa/a_practical_vulnerability_analys.htm
XPath Injection
XPath Injection is an attack technique used to exploit web sites that construct XPath queries from user-supplied input. XPath 1.0 is a language used to refer to parts of an XML document. It can be used directly by an application to query an XML document, or as part of a larger operation such as applying an XSLT transformation to an XML document, or applying an XQuery to an XML document.
The syntax of XPath bears some resemblance to an SQL query, and indeed, it is possible to form SQL-like queries on an XML document using XPath. For example, assume an XML document that contains elements by the name user, each of which contains three subelements—name, password, and account. The following XPath expression yields the account number of the user whose name is "jsmith" and whose password is "Demo1234" (or an empty string if no such user exists):
string(//user[name/text()=’jsmith’ and password/text()=’Demo1234’]/account/text())
If an application uses run-time XPath query construction, embedding unsafe user input into the query, it may be possible for the attacker to inject data into the query such that the newly formed query will be parsed in a way differing from the programmer’s intention.
XPath Injection Example
Consider a web application that uses XPath to query an XML document and retrieve the account number of a user whose name and password are received from the client. Such application may embed these values directly in the XPath query, thereby creating a security hole. Here's an example (assuming Microsoft ASP.NET and C#):
XmlDocument XmlDoc = new XmlDocument(); XmlDoc.Load("..."); XPathNavigator nav = XmlDoc.CreateNavigator(); XPathExpression expr = nav.Compile("string(//user[name/text()='"+TextBox1.Text+"' and password/text()='"+TextBox2.Text+ "']/account/text())"); String account=Convert.ToString(nav.Evaluate(expr)); if (account=="") { // name+password pair is not found in the XML document - // login failed. } else { // account found -> Login succeeded. // Proceed into the application. }
When such code is used, an attacker can inject XPath expressionsfor example, provide the following value as a username:
' or 1=1 or ''='
This causes the semantics of the original XPath to change, so that it always returns the first account number in the XML document. The query, in this case, will be
string(//user[name/text()='' or 1=1 or ''='' and password/text()='foobar']/account/text())
which is identical (since the predicate it evaluates to is true on all nodes) to
string(//user/account/text())
yielding the first instance of //user/account/text(). The attack, therefore, results in having the attacker logged in (as the first user listed in the XML document), although the attacker did not provide any valid username or password.
Apache Countermeasures for XPath Injection Attacks
XPath Injection is closely related to SQL Injection from a preventative standpoint. We need to filter out client data and disallow both the single quote (‘) and double quote (") characters. This Mod_Security filter will do the trick:
SecFilterSelective THE_REQUEST "(\’|\")"
References
"XML Path Language (XPath) Version 1.0"W3C Recommendation, 16 Nov 1999 http://www.w3.org/TR/xpath
"Encoding a Taxonomy of Web Attacks with Different-Length Vectors" By G. Alvarez and S. Petrovic http://arxiv.org/PS_cache/cs/pdf/0210/0210026.pdf
"Blind XPath Injection" By Amit Klein http://www.sanctuminc.com/pdfc/WhitePaper_Blind_XPath_Injection_20040518.pdf