01.09.2015 Views

4.0

1NSchAb

1NSchAb

SHOW MORE
SHOW LESS
  • No tags were found...

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

130<br />

Web Application Penetration Testing<br />

possible to extract the first character of the username on a specifically<br />

selected row. As the inner query returns a set of records, and not just<br />

one, it is not possible to use it directly. Fortunately, we can combine<br />

multiple functions to extract a specific string.<br />

Let’s assume that we want to retrieve the username of the 10th row.<br />

First, we can use the TOP function to select the first ten rows using<br />

the following query:<br />

SELECT TOP 10 username FROM users<br />

Then, using this subset, we can extract the last row by using the<br />

LAST function. Once we have only one row and exactly the row<br />

containing our string, we can use the IFF, MID and LAST functions<br />

to infer the actual value of the username. In our example, we employ<br />

IFF to return a number or a string. Using this trick, we can<br />

distinguish whether we have a true response or not, by observing<br />

application error responses. As id is numeric, the comparison with<br />

a string results in a SQL error that can be potentially leaked by 500<br />

Internal Server Error pages. Otherwise, a standard 200 OK page<br />

will be likely returned.<br />

For example, we can have the following query:<br />

http: /www.example.com/index.php?id=’%20AND%20<br />

1=0%20OR%20’a’=IIF((select%20MID(LAST(username),1,1)%20from%20(select%20TOP%2010%20username%20from%20users))=’a’,’a’,’b’)%00<br />

that is TRUE if the first character is ‘a’ or false otherwise.<br />

As mentioned, this method allows to infer the value of arbitrary<br />

strings within the database:<br />

[1] By trying all printable values, until we find a match<br />

[2] By inferring the length of the string using the LEN function,<br />

or by simply stopping after we have found all characters<br />

Time-based blind SQL injections are also possible by abusing<br />

heavy queries.<br />

References<br />

• http: /nibblesec.org/files/MSAccessSQLi/MSAccessSQLi.html<br />

• http: /packetstormsecurity.com/files/65967/Access-Through-<br />

Access.pdf.html<br />

• http: /seclists.org/pen-test/2003/May/74<br />

• http: /www.techonthenet.com/access/functions/index_<br />

alpha.php<br />

• http: /en.wikipedia.org/wiki/Microsoft_Access<br />

Testing for NoSQL injection<br />

Summary<br />

NoSQL databases provide looser consistency restrictions than<br />

traditional SQL databases. By requiring fewer relational constraints<br />

and consistency checks, NoSQL databases often offer<br />

performance and scaling benefits. Yet these databases are still<br />

potentially vulnerable to injection attacks, even if they aren’t using<br />

the traditional SQL syntax. Because these NoSQL injection attacks<br />

may execute within a procedural[1] language , rather than in<br />

the declarative[2] SQL language, the potential impacts are greater<br />

than traditional SQL injection.<br />

NoSQL database calls are written in the application’s programming<br />

language, a custom API call, or formatted according to a<br />

common convention (such as XML, JSON, LINQ, etc). Malicious<br />

input targeting those specifications may not trigger the primarily<br />

application sanitization checks. For example, filtering out common<br />

HTML special characters such as < > & ; will not prevent attacks<br />

against a JSON API, where special characters include / { } : .<br />

There are now over 150 NoSQL databases available[3] for use<br />

within an application, providing APIs in a variety of languages and<br />

relationship models. Each offers different features and restrictions.<br />

Because there is not a common language between them,<br />

example injection code will not apply across all NoSQL databases.<br />

For this reason, anyone testing for NoSQL injection attacks will<br />

need to familiarize themselves with the syntax, data model, and<br />

underlying programming language in order to craft specific tests.<br />

NoSQL injection attacks may execute in different areas of an application<br />

than traditional SQL injection. Where SQL injection would<br />

execute within the database engine, NoSQL variants may execute<br />

during within the application layer or the database layer, depending<br />

on the NoSQL API used and data model. Typically NoSQL injection<br />

attacks will execute where the attack string is parsed, evaluated,<br />

or concatenated into a NoSQL API call.<br />

Additional timing attacks may be relevant to the lack of concurrency<br />

checks within a NoSQL database. These are not covered under<br />

injection testing. At the time of writing MongoDB is the most<br />

widely used NoSQL database, and so all examples will feature<br />

MongoDB APIs.<br />

How to Test<br />

Testing for NoSQL injection vulnerabilities in MongoDB:<br />

The MongoDB API expects BSON (Binary JSON) calls, and includes<br />

a secure BSON query assembly tool. However, according to MongoDB<br />

documentation - unserialized JSON and JavaScript expressions<br />

are permitted in several alternative query parameters.[4]<br />

The most commonly used API call allowing arbitrary JavaScript<br />

input is the $where operator.<br />

The MongoDB $where operator typically is used as a simple filter<br />

or check, as it is within SQL.<br />

db.myCollection.find( { $where: “this.credits == this.debits”<br />

} );<br />

Optionally JavaScript is also evaluated to allow more advanced<br />

conditions.<br />

db.myCollection.find( { $where: function() { return obj.credits<br />

- obj.debits < 0; } } );<br />

Example 1<br />

If an attacker were able to manipulate the data passed into the<br />

$where operator, that attacker could include arbitrary JavaScript<br />

to be evaluated as part of the MongoDB query. An example vulnerability<br />

is exposed in the following code, if user input is passed

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!