Notifications
Clear all

Firefox 3 Forensics

7 Posts
4 Users
0 Likes
421 Views
(@jay_unistudent)
Posts: 5
Active Member
Topic starter
 

Does anybody know a good site or book that has file signatures for Firefox SQLite files. I'm trying to identify file signatures and offsets for places.sqlite. Any help would be much appreciated.

Thanks,
Jay

 
Posted : 05/02/2013 10:45 pm
keydet89
(@keydet89)
Posts: 3568
Famed Member
 

How about just opening some of the files in a hex editor, to start?

 
Posted : 05/02/2013 11:32 pm
Chris_Ed
(@chris_ed)
Posts: 314
Reputable Member
 

As far as I know, all sqlite database files start with the signature "SQLite" (0x53514C697465). If you're looking to identify places.sqlite in particular, bearing in mind that all SQLite files contain the statements to construct the databases, how about looking for some of those SQL statements specific to that database? For example, my places.sqlite contains the following string

CREATE TABLE moz_places ( id INTEGER PRIMARY KEY, url LONGVARCHAR, title LONGVARCHAR, rev_host LONGVARCHAR, visit_count INTEGER DEFAULT 0, hidden INTEGER DEFAULT 0 NOT NULL, typed INTEGER DEFAULT 0 NOT NULL, favicon_id INTEGER, frecency INTEGER DEFAULT -1 NOT NULL, last_visit_date INTEGER , guid TEXT)

Perhaps you could search for this, and if you find it then work backwards to try and carve the rest of the file? )

Also, check out what the tremendously clever Richard Drinkwater has to say about carving them in general. Here references the following offical documents from sqlite.org ([1] [2]) which deal specifically with the file format.

In terms of analysing your own places.sqlite, don't forget that there are many good, free hex editors you can use (such as HxD).

Good luck!

 
Posted : 06/02/2013 3:44 pm
(@jay_unistudent)
Posts: 5
Active Member
Topic starter
 

Chris_Ed, thanks for your help D

I'm using HxD to view places.sqlite and as you said I've managed to identify the database header. I've also identified the B-tree page header and the cell pointer arrays which point to the tables and fields you outlined. However, I am unable to find any pointers that identifies why the records which store the URL's start where they do?

I've created several virtual machines and created some test browsing activity to compare the places.sqlite files from these machines and all the records start in the same place. Does anybody know where in the places.sqlite file identifies why the records start here?

Thanks again )

 
Posted : 06/02/2013 8:24 pm
(@alexc)
Posts: 301
Reputable Member
 

The cell pointers give the offset of each record from the start of the current page, the cells themselves will consist of

- a VarInt giving the payload size (the length in bytes of the record)
- a VarInt give the cell's rowid (unique numeric value assigned to each row in a table)
- the record (which in turn is made up of…)
— the record header (made up of…)
—— a VarInt giving the length of the record header in bytes (including this value)
—— one or more VarInts which are serial type codes give the type (and implicitly the length) of the data in the record
— the record data (formatted according to the record header)

So to find the url you'd jump to the start of the cell by following the cell pointer, read (and for your purposes*, ignore) the payload and rowid values. That would bring you to the start of the record header, which you can then read, derive, based upon the table schema, where the URL will start relative to the end of the record header (assuming Chris's schema, this will be directly after the header) and the length of the url string (by decoding the serial type code in the record header).

EDIT if you're interested in deleted records, this won't be the best approach necessarily as you're at best going to target referenced records on freepages and at worst, well, live records.

Of course you could use an application like Epilog to do this for you, but I'm assuming from your user name that your interests are academic rather than practical?

Let me know if I can clarify any of that.

* actually, if the payload is big enough the record will overflow in which case you need to pay attention to the payload value in order to deal with this. But barring very long urls or page titles I doubt this table is likely to have overflowing records.

 
Posted : 06/02/2013 10:53 pm
(@alexc)
Posts: 301
Reputable Member
 

If you're asking how you know which pages contain data related to the "moz_places" table then you need to read (or just query) the "sqlite_master" table along the lines of

SELECT rootpage FROM sqlite_master WHERE "type"='table' AND tbl_name='moz_places';

The returned value (and there should only be 1) will give you the root page of the b-tree for that table. You'll then have to follow the tree to the leaf pages which contain the records for that table (I will get RSI typing out how to do that and http//sqlite.org/fileformat2.html Sections 1.5 and 2.0 describe it better than I will).

Of course, if you're interested in deleted records, it's probably best not to go about it like this, because they might not actually reside on the current leaf pages.

 
Posted : 06/02/2013 11:04 pm
(@jay_unistudent)
Posts: 5
Active Member
Topic starter
 

Thanks AlexC D

I've not had a chance to try it out yet but I will try it this weekend and let you know how I get on.

Thanks again )

 
Posted : 08/02/2013 5:51 pm
Share: