Tuesday, March 12, 2013

How to forensic examine a drive with PC Back / Rollback Rx and with an active Windows password.

Some computer vendors sell OEM copies of Windows with pre-build clean snapshots: if a customer wishes a full cleanup (after been infected by virus, for example), all he has to do is to press a key during boot, and the computer shortly becomes as it was when came from the store.

This is possible because they use a piece of software that applies rootkit techniques to mask the HD contents: the software remaps the disk sectors on the fly, so the disk Windows sees is not the same disk that would appear if the disk was plugged in as an external drive.

The effect of this in forensic is disastrous: when a examiner tries to use forensic tools to access the drive's filesystem, all he sees is the pre-build one, with no user created content.

But, when an image of the drive is booted in a virtualized enviroment (or as primary drive in a real computer), the more interesting user modified content appears, since the snapshot software is loaded in initialization and is allowed to do it's tricks.

Some copies of PC Back / Rollback Rx are shipped with a boot screen that allows to manage snapshots (activated with the Home key), but some vendors (like Positivo) uses copies with limited functionality in which the only available choice is to rollback to the factory default installation.

So, the first solution is to simply:

1-(not fully tested)-Try to access the management screen

  1. Image the drive.
  2. Boot the copy (virtually or in a real computer, your choice).
  3. Press 'Home' during boot.
  4. If the management screen appears, try to delete the factory snapshot.
I wasn't luck enough yet to pass step three, since the versions I came across were all limited and didn't offer the management screen at all.

Maybe this could be done buying a full version of the software. Or maybe not, who knows?
Well, let's include this as an untested solution:

2-(untested)-Buy the full program 

  1. Contact the developers and ask for free help.
  2. On failure, ask for payed help.
  3. On success, let us know that it worked.

The third, and natural (and tested), solution would be: 

3-Boot a copy of the drive and mirror itself from inside

  1. Image the drive.
  2. Boot the copy (virtually or in a real computer, your choice).
  3. From inside the running copy, use some program like FTKImager to copy the drive again.
This solution may present two problems:
  1. Prograns running at initialization may erase important evidence.
  2. If Windows is configured with a unknown password, you won't be able to run FTKImager or anything else. You would end up stuck in the login screen. Chntpwd won't help eider, since the registry it sees is from the factory-default system, not the user modified one.
Then we reach the fourth, and more complex (and also tested), solution:

4ยบ-The find-BCD-replace-it technique

  1. Make 3 images of the drive: A, B and C.
  2. Put A as primary drive and B as secondary. Boot that (virtually or in a real computer, your choice).
  3. Restore the system to the factory-default state (A will be modified).
  4. Boot A and B again.
  5. Install EasyBCD on A.
  6. Use EasyBCD to make a second entry in boot menu, pointing to B.
  7. Export the new BCD to a file outside A and B (a pendrive will do). It is important that new BCD isn't bigger than the old one.
  8. Restart the system, hit F10, and select this new second boot option, to boot B. The factory-default system should be installed automatically in B.
  9. Shutdown the system.
  10. In a forensic station, use WinHex, bgrep, or whatever to find where in C is the working BCD. To do that, search the disk for all occurrences of "NewStoreRoot". For each occurrence, locate the string "regf", a few bytes back (4000 or so). That's a possible BCD beginning position candidate.
    • Example using bgrep in linux: 
      • #bgrep '4e657753746f7265526f6f74' C.dd
      • Then find "regf" near each ocurrence:
      • #hexedit C.dd
      • Hit Enter, insert occurrence position, go up, find "regf", write down the position (be carefull with position truncation at the left column)
  11. For each BCD position candidate, copy the new BCD exported at step 7 over the candidate. This will replace the old BCD in the middle of the disk with the new one.
    • Example using linux (the candidate position here is 79951704064):
      • dd if=exportedBCD of=C.dd seek=79951704064 bs=1 conv=notrunc 
  12. After each try, prepare a system using C as primary drive and B as secondary.
  13. Boot C and B.
  14. At boot, hit F10 and check if the second boot option appears.
  15. If it does not appear, that's not the wright candidate yet. Go back to step 11 and try again.
  16. When the second boot option appears, select it. That will boot B, but will also work on C, so the user created content will be visible.
  17. B will boot, with a relatively clean OS, and no unknown password.
  18. C will show user created content.
  19. Use FTKImager or similar software to copy the first primary drive (C) to an external drive.
The find-BCD-replace-it technique could be adapted to find and replace sethc.exe or utilman.exe with cmd.exe, to just overcome the password problem. It would be a little simpler, but wouldn't avoid initialization of user installed programs.

Maybe this technique could work with other similar software, like COMODO Time Machine, Norton GoBack and RestoreIT, but I haven't tested it with those.

Tuesday, March 13, 2012

Chrome Forensics

Some times we need to get information from Google Chrome like History, Bookmarks and Downloads.

Using Google Chrome we can have this information typing "about:history", "about:bookmarks" and "about:downloads" in browser. For a list of Chrome URLs just type "about:about".

Another way is to look into Google Chrome database. Chrome stores the browser information in a SQLite database named "History". Take a look at:

    LINUX - /home/<USERNAME>/.config/<google-chrome or chromium>
    WINDOWS 7 - C:\Users\<USERNAME>\AppData\Local\Google\Chrome\Default\

To open the database file, we can use any SQLite Browser, like SQLiteStudio for Windows or sqlite3 for Linux. The database has the following tables: downloads, presentation, urls, keyword_search_terms, segment_usage, visits, meta and segments.

The more interesting table is the urls table. It has the columns: id, url, title, visit_count, typed_count, last_visit_time, hidden and favicon_id.

Other tables that we can be interested in are the download and keyword_search_terms tables.

The download table has the columns: id, full_path, url, start_time, received_bytes, total_bytes, state, end_time and opened.

And the keyword_search_terms has the following columns: keyword_id, url_id, lower_term, term.

The timestamps stored in the database are in Webkit Format and its base time is 01/01/1601 00:00:00. For more information you can go here.

So, to obtain the history from Google Chrome browser we can create a select query like this (Atila, thanks for the improvement!):

    urls.url AS URL,
    urls.title AS "Page Title",
    urls.visit_count AS "Number of Visits",
    urls.typed_count AS "Typed Count",
    datetime(( urls.last_visit_time /1000000)-11644473600, 'unixepoch') AS "Last Visit (UTC)",
    urls.hidden AS Hidden,
    datetime(( visits.visit_time /1000000)-11644473600, 'unixepoch') AS "First Visit (UTC)",
    visits.from_visit AS "From Visit",
    visitsold.url AS "From Visit URL",
    CASE (visits.transition & 255)
    WHEN 0 THEN 'User clicked a link'
    WHEN 1 THEN 'User typed the URL in the URL bar'
    WHEN 2 THEN 'Got through a suggestion in the UI'
    WHEN 3 THEN 'Content automatically loaded in a non-toplevel frame - user may not realize'
    WHEN 4 THEN 'Subframe explicitly requested by the user'
    WHEN 5 THEN 'User typed in the URL bar and selected an entry from the list - such as a search bar'
    WHEN 6 THEN 'The start page of the browser'
    WHEN 7 THEN 'A form the user has submitted values to'
    WHEN 8 THEN 'The user reloaded the page, eg by hitting the reload button or restored a session'
    WHEN 9 THEN 'URL what was generated from a replacable keyword other than the default search     provider'
    WHEN 10 THEN 'Corresponds to a visit generated from a KEYWORD'
    END AS Comment
    FROM urls, visits
    LEFT OUTER JOIN (SELECT visits.id, urls.url FROM visits, urls WHERE urls.id=visits.url) AS     visitsold
    ON visits.from_visit = visitsold.id
    WHERE urls.id = visits.url
    ORDER BY 5

The transition column describes how the URL was loaded in the browser. We need to apply a 0xFF mask to the value found inside the database to correspond to one of the 10 types of transitions.

And to obtain the Downloads from Chrome we can:

    url AS URL,
    full_path AS "Full Path",
    received_bytes AS "Receveid Bytes",
    total_bytes AS "Total Bytes",
    datetime(( start_time /1000000)-11644473600, 'unixepoch') AS "Start Time (UTC)",
    datetime(( end_time /1000000)-11644473600, 'unixepoch') AS "End Time (UTC)"
    FROM downloads

The same procedure we can use to the keyword_search_terms table.

The Bookmarks are stored in the file Bookmarks in the same directory we found the History database.

The Bookmark file is plain text and you will find a structure like this:

       "checksum": "7f7d7ff1d022fca5cad656c796845993",
       "roots": {
          "bookmark_bar": {
             "children": [ {
                "children": [ {
                   "date_added": "12975699777642745",
                   "id": "5",
                   "name": "Forensics & Incident Response",
                   "type": "url",
                   "url": "http://forensir.blogspot.com/"
                }, {
                   "date_added": "12975699777777745",
                   "id": "6",
                   "name": "Windows Incident Response",
                   "type": "url",
                   "url": "http://windowsir.blogspot.com/"
                } ],


       "version": 1

The timestamps of the Bookmark file are also in Webkit Format and to translate to a readable format (UTC) we can use the SQLite query:

    SELECT datetime(( "TIME" /1000000)-11644473600, 'unixepoch')

where TIME is the integer number in the Bookmark file timestamps.

Good Luck with your queries!!!

Tuesday, March 6, 2012

How to make a vmdk disk that points to a dd image.

This procedure does not require any conversion, and thus, no waiting time or extra disk space.

It was tested in VirtualBox, but it's expected to work in VMWare as well. And it works both on Windows and Linux hosts.

First, check how many sectors your dd image have. It's the image size in bytes divided by 512.

$ ls imagem.dd  -l
-rw-r--r-- 1 root root 1500301910016 2012-02-17 11:36 imagem.dd
1500301910016/512 is 2930277168, so 2930277168 is what we want

Next, create a file with the following contents and save it with a '.vmdk' extension (edit the file to use your image path and size):

# Disk Descriptor File

# Extent description

#DDB - Disk Data Base
ddb.adapterType = "ide"
ddb.virtualHWVersion = "3"
In this example, we would change the line after Extend description to:
RW 2930277168 FLAT "imagem.dd" 0

You can use relative or absolute paths.

After including your new VMDK in a virtual machine, you can take a snapshot before turning it on, to keep the image file intact. If your image file is read-only, the snapshot is required in order to make the vmdk work, otherwise there will be access errors and the virtual machine will not start. Your new vmdk file, on the other hand, always has to be writable.

OBS: two common errors when trying to virtualize an otherwise not-virtual Windows are:

  • Blue Screen of Death, with error 0x7B. Caused by required disk device drivers not been loaded during boot. You can try to change how your virtual machine connects your drive (IDE PIIX4,PIIX3,ICH6,SATA). If that doesn't help, the solution may require a registry edit, with a different procedure from XP to Vista/7.
  • Black screen followed by repeating reboot. Are you sure you're not trying to virtualize a 64bit OS guest on a 32bit OS host?