Showing posts with label sqlite injection. Show all posts
Showing posts with label sqlite injection. Show all posts

Saturday, 23 March 2013

SQLite injection - beyond SELECT

I work a lot with mobile and that means whenever I see SQLinjection vulns, chances are that they're in SQLite. This is a massive pain because:
a) no-one really writes guides/tools for SQLite injection
b) It's really limited (as we'll see)

Unfortunately this post is about what is not possible in SQLite injection. Hopefully it will give you a guide to where to focus attacks/defence.

SQL injection as my previous post mentioned is a subset of regular SQL. There's no command execution, file reading/writing or anything particularly cool. You can't even stack queries unless the developer is using less orthodox functions (like rawquery). In essence it normally boils down to information disclosure (i.e. reading from tables that you shouldn't).

Select Statements in Mobile SQLite

With Android you (as the attacker) will hopefully be able to inject on 'projection' variable, that is the part that goes in the "SELECT ____ FROM". This obviously allows you to redirect the statement to go to anywhere else. The ideal test is to try projection=" * FROM SQLITE_MASTER; -- ". If you can get to the master table, you can get anywhere else (unless the programmer has some custom code ready to black list you out of having fun).
Failing this you could try on the 'selection' variable and try a union statement. (see my previous post for more details

This week has been spent looking at the other commands (insert,update,delete). The goal for the attacker is to change values in other tables in the .db file. The big issue here is the table to be queried is selected before your variables get included.

Inject into INSERT statements


insert into TABLENAME(field1,field2) values (val1,val2)
 
Here you can maybe control field1 & 2 and val1 & 2. The problem is that you can't jump tables. SQLite doesn't permit UNIONs or JOINs in anything other than select statements. You can use CASE to hide SELECT statments in the middle of this but that doesn't get you much in the way of altering data powers. You also can't use table.field in the query. Essentially you are stuck altering the data within that table.

It is therefore possible for SQL injection through inference of values being changed with CASE statements to read data from a table, but it's not possible to jump to and attack other tables.

 Inject into UPDATE or DELETE statements

UPDATE table SET (val1 = val2) WHERE condition
DELETE FROM table WHERE condition

Similarly the update query permits field names (val1), updated values (val2) and where clauses (condition), but no changing of the table name. The delete function is similarly limited.

I'm scratching my head finding a more useful attack vector that somehow nests more useful things inside statements. All comments are welcome. In the meantime, this should make for some useful reading: http://www.sqlite.org/syntaxdiagrams.html

Wednesday, 25 April 2012

SQLite Injection

There does seem to be a lack of information regarding SQLite injection. This is probably because SQLite is so limited compared to other SQL databases. However, it does seem that given Android (and iOS?) interest in using them, there is something to be said for writing up some basics and findings that I've had so far.

 I will try to write this from a more general SQLite injection angle rather than OS specific. First enumeration. Getting out the master database is fairly straight forward as long as your injection is early on. If you can get results posted to the screen the enumerating the database structure is easy:

"* FROM SQLITE_MASTER; --"

The SQLITE_MASTER database holds descriptions of all the tables so is a quick win for enumeration. From there, more select statements will get you the rest.

If the injection point is not at the WHERE or SELECT clause then things may get a little more difficult. More particularly interesting when the injection is at the ORDER BY clause. This means that not only can you not add in the table to select from, but you also can't use a UNION statement to join it to a fresh select statement. I've yet to find a good way to solve this one so please, answers on a postcard.

This is just an introductory post. I want to cover effective manual blind SQLite injection but this will have to wait until next time.

The other area that I want to look into is the use of the "." commands. SQLite seems to have many extra functions, which I'm guessing can not be used through API calls. Perhaps the PHP exec() function might? It would certainly be good to know where, if anywhere, these values could be used, as it would allow inclusions of other files.

Finally I want to take a look at whether the values can be overwritten with long/specially formatted strings. The .db file could then be manipulated into becoming something else (okay so this one's a long shot, but worth taking a look at).

Stay tuned