Saturday, October 20, 2007

An Overview Of Buffer Overflows / Buffer Overruns

Buffer Overflows (Buffer Overrun):

A buffer overrun condition occurs when a process tries to copy more data into a buffer than the buffer intended to hold. Buffer overruns can occur on the stack memory or on the heap memory. In buffer overflow attacks, the extra data may contain codes designed to trigger specific actions that could, damage the user's files, corrupt or overwrite the valid data, or disclose confidential information.

Buffer overflows are not easy to discover and even when one is discovered, it is generally extremely difficult to exploit. Buffer overflows found in widely used server products are likely to become widely known and can pose a significant risk to users of these products. It is very hard to discover these flaws in custom code of the application and risk is significantly moderate as the source code and detailed error messages for the application are normally not available to the attacker to perform further exploits other than to crash the application.

Attackers use buffer overflows to corrupt the execution stack of a web application. By sending specifically crafted input to a web application, an attacker can cause the web application to execute arbitrary code of their choice. With this attack an attacker can perform the following actions but not limited to:
  • Creating an unauthorized user or administrator accounts
  • Creating unprotected entry points into a system (“back-doors”)
  • Disabling protective devices such as firewalls or antivirus solutions
  • Running arbitrary code instead of legitimate code

Background:

In a classic buffer overflow exploit, the attacker sends data to a program that having this vulnerability, which it stores in undersized stack overwriting information on the call stack, including the function's return pointer. The attacker data sets the value of the return pointer in such a way that points back to the buffer that holds arbitrary code of the attacker, so that when the function returns, it transfers control to malicious code contained in the attacker's data. There are a variety of other types of buffer overflow, including Heap buffer overflow and Off-by-one Error among others. Another very similar class of flaws is known as Format string attack. All these conditions occur due to code not checking to see if the buffer being copied into has been allocated enough space for data being copied.

The application or component uses an unmanaged language, native code or some language that is not deemed “memory safe” for implementation is vulnerable to buffer overflows when user input is blindly copied into buffer structures without being validated first for length and type, opportunities. Managed languages such as C# and Java are generally not susceptible to buffer overrun conditions. Managed code makes buffer overruns extremely difficult to encounter however not impossible. For example, managed code can call into unmanaged code and overruns can occur there.

In Detail:

A buffer is a contiguous allocated chunk of memory. In many unmanaged languages, there are no automatic bounds checking on the buffer, which means a user can write past a buffer. Like, see the following example:

int main()
{
int stackbuff[20];
stackbuff[25] = 5;
}

The above program is a valid and doesn’t produce any errors. In the above the program writes data beyond the allocated memory for the buffer, you are allocated only 20 blocks of memory to the variable “stackbuff” of type integer but writing the value of 5 at 25th block that is beyond the allocation, which might result in unexpected behavior.

How the attacker exploits buffer overflows?

A Stack is a contiguous chunk of memory and a register called the stack pointer (SP) points to the top of the stack, the bottom of the stack is at a fixed address. Its size is dynamically adjusted at runtime. Whenever a function call is made, the following are pushed on to the stack in the specified sequence. First the function parameters, then the address to be executed after the function returns, then a frame pointer (FP), followed by local variables of the function. All these variables are cleaned up from the stack as the function terminates.

For example, see the following example code:

int sumofvalues(int x, int y, int z)
{
int sum=0;
sum = x+y+z;
return sum;
}

Whenever the above function is executed the stack will be like below:



First three function parameters x, y, z will be pushed onto the stack, then return address, then frame pointer, followed by local variable sum.

Suppose, your application is having a function looks like below:

void funccpy(char *source)
{
char destination[20];
strcpy(destination, source);
}

Later, this function is get called by passing string of characters that are to be copied into another string, well works fine if the passed characters are having length less than 20 characters. But, what happens if the passed value is having more number of characters than 20? The extra bytes run past the buffer allocated for “destination” variable causing overwrites the space allocated for the FP, return address and so on. Using this vulnerability an attacker can easily execute code of his choice by overwriting the return address. For example, attacker is able to place the arbitrary code to execute in the buffer's overflowing area and then overwrite the return address in such a way it points back to the buffer and executes the intended code. Such arbitrary code can be inserted into the program by using input parameters.

Recommendations/ Counter measures:

  • For each instance where user input is copied or concatenated into a buffer, perform input validation on the input for size prior to the buffer copy. If the user input exceeds the allocated space of the destination buffer, do not perform the copy and return with an error.
  • Source code and binaries should be scanned with source code analysis and binary analysis tools respectively to detect common buffer overrun conditions.
  • The choice of programming language can have a great effect on the occurrence of buffer overflows. Many programming languages provide runtime bounds checking which might send a warning or raise an exception when it would overwrite data.
  • Try to avoid usage of unmanaged code, if necessary, consider usage of secure functions instead of unsecure functions like strcpy(), strcat(), ...
  • Keep systems with most up to date security patches.
Add to Technorati Favorites

Wednesday, October 17, 2007

One Of The Code Injection Attack: LDAP Injection

LDAP Injection:

LDAP Injection is an attack technique used to exploit web sites that construct LDAP statements from invalidated user supplied input. Using this attack, the attacker can execute arbitrary statements against the directory services. Simply, LDAP injection attack exploits vulnerabilities in input validation to run arbitrary LDAP statements against information directories. LDAP Injection is possible when an application constructs dynamic LDAP statements by using invalidated/un-sanitized user input to access directory services.

What Is LDAP?

Lightweight Directory Access Protocol (LDAP) is an open-standard protocol for both querying and manipulating directory services running over TCP/IP. LDAP was designed at the University of Michigan to adapt a complex enterprise directory system (called X.500) to the modern Internet. Just like any Database Management System is used to process queries and updates to a relational database, an LDAP server is used to process queries and updates to an LDAP information directory. LDAP session starts whenever a client connects to an LDAP server. After establishing a connection with the LDAP server the client sends operation requests to the server, and the server sends responses in turn. The server may send the responses in any order and with few exceptions the client need not wait for a response before sending the next request. The LDAP protocol is both cross-platform and standards-based and LDAP directory servers store their data hierarchically, LDAP directories are heavily optimized for read performance. LDAP allows you to securely delegate read and modification authority based on your specific needs using Access Control Instances(ACIs).

In Detail:

LDAP Injection attacks are not as common as the other types of injection attacks like SQL Injection. But, an LDAP Injection could occur anywhere that the underlying code could use some type of invalidated user input for any LDAP searches, or queries.

The most widely use of LDAP in web applications is to enable users to easily search for specific data on the Internet. For Example, LDAP-enabled Web application searches specific information about a user by accepting the user name from the user and uses it in a search query. The underlying code would take this search query information and generate the LDAP query dynamically that will be used to search the LDAP database. The search query within the code may like below:

String uName = txtSearch.Text
String searchQuery = "(cn=" + CStr(uName) + ")"
ldapObj.DN = "ou=customers,dc=example,dc=com"
ldapObj.SearchFilter = searchQuery

If the variable uName is not properly validated, an LDAP injection could be possible. Suppose an attacker can use this vulnerability in any one of the following ways, but not limited to:
  • If an attacker enters * as an input, then the resulting LDAP statement will make the server return any object that contains a “cn” attribute, simply this will return every username in the LDAP database.
  • If an attacker enters the input as xxx)((acno=*), this results the underlying LDAP search query like (cn=xxx)((acno=*) ) which would reveal the users xxx account number.
There are so many other possibilities that an attacker can perform depending on the way the LDAP query constructed and the resulting actions by that query. An attacker can start the attack by sending a few requests with unusual characters to know how the application reacts to them and to identify the type of validation performed within the code of the target application. Later the attacker continues his attack by reverse-engineering the structure of the LDAP query to determine how the user-supplied data is used to perform the search. Few applications use LDAP queries to authenticate users, in such a case the authentication mechanism can be easily bypassed.

Countermeasures / Preventions:

LDAP Injection can be prevented in the same way as other code injection attacks since LDAP injection attack is one of the code injection attacks.
Input Validation: It is the best measure to defend applications from LDAP injection attacks. The underlying code needs to verify the correct input using a white list to ensure that the application does accept only legitimate input. If the input is verified against a white list using a regular expression then the malicious input could be rejected.
Also, all data returned to the user should be validated and the amount of data returned by the queries should be restricted as an added layer of security.
Please refer to my previous posting on
Input Validation for more details.
LDAP Server Configuration: Implementing tight access control on the data in the LDAP directory is vital when configuring the permissions on user objects. The access level used by the Web application to connect to the LDAP server should be restricted to the minimum required. In addition, the LDAP server should not be directly exposed on the Internet, thereby reducing the attack surface area.

Add to Technorati Favorites

Wednesday, October 10, 2007

Code Injection: XPath Injection

XPath Injection:

SQL is the most popular type of code injection attack, there are several others that can be just as dangerous to your applications and your data, including LDAP injection and XPath injection. An ‘XPath injection’ attack is similar to an SQL injection attack, but its target is an XML document rather than an SQL database. ‘XPath Injection’ is an attack technique used to exploit web sites that construct XPath queries from user-supplied input.

What is XML?

XML stands for Extensible Markup Language and was designed to describe data. It allows programmers to create their own customized tags to store data. In XML the data is stored in nodes in a tree form. XML Path or XPath language is used for querying information from the nodes of an XML document. Please refer to XML Tutorial for more details on XML.

What is XPath?

“XML Path” or “XPath” 1.0 is a language used to refer to parts of an XML document. Path expressions are used to access elements and attributes in an XML document, which return a node-set, a string, a Boolean or a number. It can be used directly to query an XML document by an application, 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. Please refer to
XPath Tutorial for more details on XPath.

In Detail:

Code Injection is a technique to Inject code into a program or application code by taking advantage of the unchecked assumptions the application makes about its inputs to bypass or modify the originally intended functionality of the code. All code injection attacks work in a same way; an attacker injects malicious code into the application code through an input field of the application. So, to perform such attacks there must be entry points that are not performing adequate validation.
Consider a Web application that uses XPath to query an XML document to retrieve the social security number of a customer by passing name and password values that are supplied by the user of the application. If the application embeds these values directly in the XPath query then it is vulnerable to XPath Injection.

For Example:

An application is using “CustProfile.xml” to store the customer related data and is like below:

<? xml version = " 1.0" encoding =" utf-8" ?>
<Customers>
<Customer>
<CLogIn> Malapati </CLogIn>
<CName> Pradeep Malapati </CName>
<Email> pradeep.malapati@malapaticorp.com </Email>
<Pwd> Malapati2020 </Pwd>
<SSN> xxxxxxxxxxxx </SSN>
<ACNO> 11111111111 </ACNO>
</Customer>

<Customer>
<CLogIn> Vijaya </CLogIn>
<CName> Vijaya Gavuji </CName>
<Email> Vijaya.Gavuji@vigavinc.com </Email>
<Pwd> Vigav1010 </Pwd>
<SSN> xxxxxxxxxxxx </SSN>
<ACNO> 99999999999 </ACNO>
</Customer>
--------
--------
</Customers>

In application, the code is written like below to retrieve Social Security Number of the customer:

XmlDocument XmlDoc = new XmlDocument();
XmlDoc.Load("CustProfile.xml");
...
XPathNavigator custnav = XmlDoc.CreateNavigator();
XPathExpression xexpr = custnav.Compile("string(//Customers/Customer[CLogIn/text()='"+TextBox1.Text+ "' and Pwd/text()='"+TextBox2.Text+ "']/SSN/text())");
String ssn=Convert.ToString(custnav.Evaluate(xexpr));
if (!ssn=="")
{
// some logic using ssn or return ssn
}
else
{
// return with error message
}


In the above sample code application is allowing its users to retrieve and perform operations on SSN based on the invalidated values supplied by them. Now, this code is vulnerable to XPath Injection! If user enters legitimate values like Malapati and Malapati2020 in Login and password fields respectively then the Query will be looks like below:

// Customers/Customer[CLogIn/text()='Malapati’ and Pwd/text()= 'Malapati2020']/SSN/text()

Works well. But, suppose a user/ attacker enters the following value in the text box provided for customer Login and a blank value in password field.
' Or 1=1 Or 'a'='a
Now, what will be the actual XPath query?

// Customers/Customer[CLogIn/text()=' ' Or 1=1 Or ‘a’ = ‘a’ and Pwd/text()=' ']/SSN/text()

The above expression CLogIn/text() = ‘ ’ Or 1=1 Or ‘a’ = ‘a’ and Pwd/text() = ‘ ’ can be simply represented as below:
(CLogIn/text() = ‘ ’ Or 1=1) Or (‘a’ = ‘a’ and Pwd/text() = ‘ ’) as logical operator AND has higher precedence than OR. So if either first or second condition is true the expression will evaluate to true. In this case the attacker input is having 1=1 is always returns true thus making first condition always becomes true. Now the above query is identical to //Customers/Customer/SSN/text() that results first record’s/node SSN number.

Countermeasures / Preventions:

XPATH Injection can be prevented in the same way as SQL injection since XPath injection attacks are much like SQL injection attacks. Most of these preventative methods are the same as well to prevent other typical code injection attacks.
Input Validation: is one of the best measures to defend applications from XPATH injection attacks. The developer has to ensure that the application does accept only legitimate input. Please refer to my previous posting on Input Validation for more details.
Parameterization: Use parameterized queries to prevent XPATH injection. In Parameterized queries, the queries are precompiled and instead of passing user input as expressions, parameters are passed. For example:
//Customers/Customer[CLogIn/text() = $login and Pwd/text() = $password]/SSN/text()
Please refer to the Mitigating XPath Injection Attacks in .NET for more details.
Add to Technorati Favorites