Whenever any list of the biggest computing risks is compiled, it’s almost guaranteed that one or more injection attacks will vie for the top position. Injection attacks are commonly associated in news reports with SQL, but they can pop up in a variety of different places. There are injection-related vulnerabilities associated with headers, logs and a sizable list other attack points. In brief, an injection attack can be defined as any attack wherein an attacker is able to misuse an application by feeding it values that are different than what it expected.
In this article, we will first look at four of the most well-known types of injection attacks (SQL, LDAP, XML, and command), and then use some images from a simplistic example to try to differentiate between the various categories. Knowing and understanding the basics of injection attacks will help you in your pursuit of security certifications.
As mentioned above, the most popular injection attack today, at least from the standpoint of making the news, involves SQL, the de facto programming language used for communicating with online (and other relational) databases. A SQL injection attack is also commonly — and more appropriately — called a SQL insertion attack. The reason for this is that an attacker manipulates the database code to take advantage of a weakness in it. For example, if the interface is expecting the user to enter a string value, but has not been specifically coded that way, then the attacker can enter a line of code, and that code will then execute instead of being accepted as a string value.
Several types of exploits use SQL injection, and the most common fall into the following categories:
- Escape characters not filtered correctly
- Type handling not properly done
- Conditional errors
- Time delays
SQL is used to communicate with a database, so it is common to have SQL statements executed when someone clicks a logon button. The SQL statements take the username and password entered, and they query the database to see whether those credentials are correct. The problem begins with the way websites are written. They are written in some scripting, markup or programming language, such as HTML (Hypertext Markup Language), PHP (PHP: Hypertext Preprocessor), ASP (Active Server Pages), and so on. These languages don’t understand SQL, so incoming SQL statements are usually put into a string and whatever the user inputs in the username and password boxes is appended to that string. Here is an example:
“SELECT * FROM tblUSERS WHERE UserName =’” + txtUserName + “‘”AND ~CA Password = ‘”+password +”‘”
Notice that single quotes are inserted into the text, meaning that whatever the user types into username and password text fields is enclosed in quotes within the SQL query string, like this:
SELECT * FROM tblUSERS WHERE UserName =’admin’ AND Password = ‘password”;
Now the attacker will put a SQL statement into the username and password fields that is always true, like this:
‘ or ’1′ =’1
This results in a SQL query like this:
‘SELECT * FROM tblUSERS WHERE UserName =” or ’1′ =’1′ AND Password = ” or ’1′ =’1”
So now it says to get all entries from table = tblUsers if the username is ” (blank) OR IF 1 =1. And if password = ” (blank) OR IF 1=1! Since 1 always equals 1, the user is logged in.
The way to defend against this attack is always to filter input. That means that the website code should check to see if certain characters are in the text fields and, if so, to reject that input.
Just as SQL injection attacks take statements that are input by users and exploit weaknesses within, an LDAP injection attack exploits weaknesses in LDAP (Lightweight Directory Access Protocol) implementations. This can occur when the user’s input is not properly filtered, and the result can be executed commands, modified content, or results returned to unauthorized queries.
One of the most common uses of LDAP is associated with user information. Numerous applications exist — such as employee directories — where users find other users by typing in a portion of their name. These queries are looking at the cn value or other fields (those defined for department, home directory, and so on). Someone attempting LDAP injection could feed unexpected values to the query to see what results are returned. All too often, finding employee information equates to finding usernames and values about those users that could be portions of their passwords.
The best way to prevent LDAP injection attacks is to filter the user input and to use a validation scheme to make certain that queries do not contain exploits.
When a user enters values that query XML (known as XPath) with values that take advantage of exploits, it is known as an XML injection attack. XPath works in a similar manner to SQL, except that it does not have the same levels of access control, and taking advantage of weaknesses within can return entire documents.
The best way to prevent XML injection attacks is to filter the user’s input and sanitize it to make certain that it does not cause XPath to return more data than it should.
A common goal of an injection attack is to be able to access a directory other than the one the application is supposed to be limited to. Known as directory traversal, one of the simplest ways to perform this is by using a command injection attack that carries out the action. For example, exploiting a weak server implementation by calling up a web page along with the parameter cmd.exe?/c+dir+c:\ would call the command shell and execute a directory listing of the root drive (C:\). With Unicode support, entries such as %c%1c and %c0%af can be translated into / and \ respectively.
The ability to perform command injection is rare these days. Most vulnerability scanners will check for weaknesses with directory traversal/command injection and inform you of their presence. To secure your system, you should run such a scanner and keep the web server software patched.
Looking at Various Categories
Bear in mind that injection attacks work by “injecting” in something that wasn’t expected so that the application behaves in a way that the programmer never intended for it to behave. As a simplistic example of this, imagine that you are a programmer writing — from scratch — a program to allow a robot to play the game of Blackjack with real cards and against an actual player
Blackjack is a card game in which a player draws cards from a standard deck of playing cards and tries to get the numerical value of the cards in his hand as close to 21 as he can without going over. With normal play, the player starts with two cards and then chooses to stand on that or draw another one (and another one, and another one … ) as they try to get closer and closer to the desired number without going over it. If the cards total 22 or more, this results in an immediate loss. The code that you write needs to let the robot look at the cards the player has and calculate their value, and we’ll assume that only a single deck is in use.
Figure One shows the player’s hand at the beginning of play. A six of spades and a seven of hearts total thirteen, and that is a pretty simple piece of code to write. Based on this value, it would not be unreasonable to expect another card to be taken by the player.
Figure One: The player’s beginning hand totals 13.
Suppose that after the next card, the player’s hand resembles Figure Two. Jokers are not used in this game, and now the new card represents an unexpected value. The player could be using this card to try to trick the program into executing unintended commands or allowing access to unauthorized data — thus constituting the very definition of an injection attack by the Open Web Application Security Project (OWASP).
Figure Two: The unexpected card injected into the deck can trick the interpreter.
As a programmer, you would need to write a routine to filter the input to prevent any unintended consequences — make sure that every card is of a value that can be found in a standard deck. That still leaves open the possibility depicted in Figure Three, however. Here, the player has slipped in a card from a second deck. They are trying to increase their chances of winning (with cards that total 19), and are cheating to make it happen by using a second six of spades.
Figure Three: The player is pulling cards from a second, unauthorized deck
This type of attack is often referred to as a union attack because, with databases, the union command can be used to return query values from another table. As a programmer, you would need to write a routine to make sure that only cards from this deck are used and that you can account for all 52 cards. If you tried to solve the problem by only making sure there were no duplicate cards, the card borrowed from the second deck might be an eight of diamonds and its pair could still be in the deck so you would never know this type of attack was being implemented.
Figure Four shows another type of attack. If you look closely at the seven of hearts, you’ll note the edge of a 10 card being concealed beneath it. The player, with 23, has busted and the round should be over. They are, however, trying to make it look as if they have fewer cards and thus are able to keep drawing more and playing. If the results of the attack are not visible to the player themselves (they know they have a card they are hiding, but don’t what card it is), this can be called a blind attack.
Figure Four: The player is hiding cards from view to make it look as if it is an earlier round in the game than it actually is
A similar strategy of pretending it is earlier than it really is can be played out by feeding a program dot-slash sequences (“../”) to get to the parent directory from the current directory. As a programmer, you would obviously need to include code that prevents it from happening and the list of what you need to specifically look for — and prevent — increases in size exponentially.
Summing It Up
Injection attacks are a major threat to application security. The examples discussed here barely skim the comprehensive ocean of possibilities. The examples do, however, illustrate the basics of the attacks and provide a foundation upon which to build.