Copyright © 2006 Flowgate Security Consulting
This software is licensed under the GNU General Public License.
FG-Injector Framework is a set of tools designed to help find SQL injection vulnerabilities in web applications, and help the analyst assess their severity. It includes a powerful proxy feature for intercepting and modifying HTTP requests, and an inference engine for automating SQL injection exploitation.
Often web developers think that by disabling error messages in their code, SQL injection vulnerabilities stop being dangerous. When a SQL injection vulnerability doesn't return errors messages it is known as a Blind Injection. The truth is that Blind Injections are just as dangerous as regular SQL Injections. By carefully selecting SQL sentences to inject, an attacker can retrieve information from the database of the vulnerable web application, one bit at a time. The end result is that the attacker can obtain the same data through the Blind SQL Injection that he/she would obtain from a regular -non-blind- SQL Injection.
The Inference Engine Module of the FG-Injector Framework automates the generation and injection of SQL statements needed for exploitation of a Blind SQL Injection. This module will work also for regular injections using the same method. It can produce blind injections on web/app servers using MS SQL Server, MySQL, and PostgresSql DBMSs.
There are several situations where SQL-Injection vulnerabilities show up. Depending on what the context is, the exploitation technique might be different.
A common situation is when the web application doesn't escape single quotes within an input string before applying it to build up a SQL sentence, as in the following PHP example:
$sql="SELECT * FROM employee WHERE
address='".$address."'"; |
where $address
is user input and single quotes are not
escaped.
Another situation is when the web application expects an integer value but doesn't check for the expected type. For example:
$sql="SELECT * FROM employee WHERE
id=".$id; |
where $id is user input and it is not sanity checked for illegal characters (any non-digit characters).
Moreover, the inserted value can be in different parts of the SQL sentence. In general, it will be in the WHERE section, but even in that case, it can be inside or outside a function call. For example in this line:
$sql="SELECT * FROM employee WHERE
id=cast('".$id."' as integer)"; |
the injected value is within a function call (cast).
Another relevant aspect in SQL-injection exploitation is the type of DBMS used in the back-end by the web application. Different DBMS vendors have slightly different SQL syntax, and sometimes there even exist changes between different release versions within the same DBMS.
Testing a web application for SQL-Injection vulnerabilities is facilitated by using a proxy that allows modifying HTTP headers and sending several times (in a trial-and-error style) the crafted request. The tester uses a proxy to intercept and modify the HTTP headers sent by the browser to the web application. The tester basically tries different characters in the parameter placeholders present in the HTTP header to modify the underlying semantics of the SQL sentence meant by the programmer of the application.
Sql-Injection vulnerabilities are easily detected when verbose error messages are present. Those messages might be very useful in a debugging stage, but when used in a production environment, they leverage the tester's chances to find vulnerabilities. In this case, after the tester injects an invalid SQL statement, the application will readily return a SQL error, unknowingly providing clues for the tester towards a successful exploitation.
When the web application doesn't return error messages, the tester uses an
indirect approach (A.K.A. Blind Injection). When he/she finds some HTTP
parameter that changes the returned HTML code when altered, he/she tries with
null SQL statements. For example if a parameter named 'id
' is an
integer and the application returns an item with a given id
number, but then returns another item when additional/different characters
are added, the tester will add %2b0
after the number (i.e. the
string "+0" url-encoded). If the return of the request contains the same item
he/she will know that there is a SQL-Injection at that point. Alternatively,
if the parameter is a string, the tester will then try with
'%2b
' after the string (the string "+" url-encoded). In this
case what the tester is doing is concatenating a null string after the
original string. If the returned HTML code is the same, the tester knows
there is a SQL injection at that place.
SQL-Injection vulnerabilities can be exploited to obtain data from the web application database, somehow subverting access control imposed by the programmer of the vulnerable application.
To obtain data using a blind SQL-Injection, valid SQL statements must be inserted. The FG-Injector framework provides an inference engine that generates valid SQL fragments for each DBMS, but the tester must know where exactly to insert those SQL fragments.
The Inference Engine Module can produce two types of SQL fragments: conjunctions and values.
Conjunctions are an "AND" word followed by a condition. All databases support this type of fragments, but they are only valid if the insertion is not within a function call argument.
For example, these are valid SQL conjunction injections:
SELECT * FROM employee WHERE id=2 AND password=123456 |
The second injection adds '1'='1 so the single quotes at the end don't produce an error (always-true condition).
Value-Injections are subselects. They can be inserted into function calls arguments, but are not supported by all DBMS versions (i.e. MySQL 4). For example, in this injection:
SELECT * FROM employee WHERE
id=cast(''+(select case when (select count(*) from
employee where id=2 and password=123456) then '2' else '3'
end)+'' as integer) |
the return of the web application will be the employee's record number 2 or 3 depending on whether the password of employee 2 is 123456 or not.
The examples illustrates the principle used by the Inference Engine to retrieve data from the database through blind SQL-Injections. Depending on whether the injected condition is true or false, the web application will return two different result pages. By testing one bit of the results of a query at a time, the Inference Engine can retrieve the complete results of the query. This sort of data leaking attack is only feasible when the application is vulnerable to SQL-Injections.
FG-Injector Framework is available for both Linux and MS-Windows platforms.
On Linux systems, you will need wxWidgets framework and a C++ compiler platform. To compile, just issue 'make' within the source directory.
On MS-Windows systems, you will just need a C++ compiler platform to compile from sources. Additionally, a binary installer version is provided.
The windows version is installed by running the supplied (or compiled) installer program.
The FG-Injector Framework Proxy listens on port 8888, and the web browser should be configured accordingly (to use localhost on port 8888 as a proxy).
In the configuration Options there is an option to use an external proxy as a gateway.
Using this option is necessary for testing vulnerabilities on SSL servers (URLs starting with “https”) as FG-Injector Framework doesn't have support for SSL. A proxy with SSL support (like The Proxomitron) should be used in this case for transforming the outgoing HTTP connections of the FG-Injector Framework into HTTPS connections to the web server.
On MS-Windows uninstall from Control Panel - Add/Remove Programs.
On Linux systems, uninstallation is not necessary since compiled binaries are neither copied nor linked into directories other than the source directory. In case you want to remove the wxWidgets libraries as well, please refer to the proper documentation.
The following list describes the steps typically followed by a tester using the the FG-Injector Framework:
The proxy allows to intercept and modify the requests sent by the browser to the server. It also allows selecting a request to use in the injection modules.
Forward button: forwards the request to the web server
Set as Injectable Request button: Selects the current request to use in the injection modules.
Intercept checkbox: Selects from either to intercept the request or to forward it directly.
Exclude non-html checkbox: Selects from either include or exclude non-html files from interception (it decides if a request is for a non-html file merely based on the extension, it does not do any further inspection.)
The Injector allows submitting the selected injectable request multiple times to the web server and displaying the web server response.
This module is intended to help find SQL-Injection vulnerabilities and to setup the inference engine options.
The place where the injection is made must be selected by the tester by writing the string '~~~' into the Injectable Request box.
To configure the Inference Engine the tester needs to know in which context the vulnerability exists. This module is useful for determining which type of injection the Inference Engine should use.
This modules configures the Inference Engine for different types of SQL-Injection vulnerabilities.
Add quotes at extremes checkbox: Selects if the inference engine adds quotes at the extremes of the inserted SQL fragments.
Target database: The DBMS type
Simultaneous Connections: The number of maximum requests that the Inference Engine is allowed to do at the same time
Injection Type: The type of SQL fragment that the Inference Engine must generate. If the DMBS is MySQL the Injection Type should be Conjunctions.
Inject Values: In case that Injection Type "Inject Values" was selected, these are the values inserted in case of a true or a false condition. This values must create two different pages when inserted by themselves, and should not contain single quotes.
Inference Type: The method used by the Inference Engine if an inserted condition were evaluated to true or false. If "Automatic" is selected, the "Initialize Injection" button should be pressed so the Inference Engine detects which are the differences between true and false conditions requests. If "keyphrase" is selected, the "true keyphrase" textbox should contain an HTML fragment returned by the application only when a true condition is inserted. This second method is more sensitive but the first one is easier to use.
Inference Engine Status: Shows the status of the Automatic Inference Type detection engine.
This modules extracts information from the database using inference. It can exploit Blind SQL-Injection vulnerabilities.
Predefined Queries: Same useful queries to extract the list of tables, the fields of specific tables, and the username/s of the database user/s.
Query: SQL fragment that the inference engine will try to get the value off the DBMS. It should be a select statement or an expression.
Result Type: Should be "Single" in case the query is an expression and "list" if the query is a select statement.
Index: Used only when the query is a select statement. Primary key or unique index of the table after the "FROM" in the query string.
Note:
A select statement can not be an arbitrary select. It should have the
following format:
select field1,field2,field3(etc) from
tablename [where condition] |
Examples:
select name from users where id=2
|
select name, password from users
|
The index of both examples is id
This module shows the latest request and its corresponding response.