Monday, June 22, 2015

A first look at Windows 10 prefetch files


Windows 10 prefetch files (*.pf) show a different file format compared to previous ones.  At first glance you'll spot no textual strings inside, and this was the initial reason that make me try to understand how they changed.


quick&dirty journey



I guess that neither you nor I will run into Windows 10 DFIR cases for a while. That's what I thought when Claudia Meda (@KlodiaMaida) contacted me, showing me a couple of Windows 10 prefetch files. She then provided me some interesting clues that tickled the curious george monkey in me. Officially I do not have spare time, since it's already allocated, so I illegally used the non-existent spare time of spare time: please don't betray me... so I hope you'll tolerate any shortcuts in my quick&dirty journey into the entrails of windows (disgusting, isn't it?).


first lead


First, what a nude prefetch file has to say? Check the first bytes in the next figure, which shows a prefetch file for calc... sorry, now it's calculator (sad, I'll miss you dear calc!). They should remind you some other "prefetch folder" related file: can't you find your memo?


All kidding aside, what the MAM signature recalls is also used by the SuperFetch file format, which on Windows 7 exhibits the very similar MEMO MEM0 signature. A great old (gosh, 2011!) post addressing the SuperFetch file format (and so MEM[0|O] format) is "Windows SuperFetch file format – partial specification" by ReWolf, a worth reading. From there, you can get that the MEM files are, in the first instance, compressed containers and that the Windows API in charge to decompress them is RtlDecompressBuffer.


an actionable lead


I launched windbg inside a Windows 10 virtualized guest (Pro Insider Preview 10.0.10074) and I put a couple of bp on RtlDecompressBuffer and RtlDecompressBufferEx functions: the target process is the SuperFetch process, the svchosted sysmain.dll. To be short, I landed on the moon, which in the case is the sysmain!SmDecompressBuffer method: in the next picture you can see some green boxes (I signed following the decompression branch) and some yellow boxes (checksum check, more on this later).


The routine core is represented in the next picture, where you can (could, if I correctly re-sized the image) easily spot the call to the target method RtlDecompressBufferEx.


When applied to our MAM case, in the end you get three bytes with the magic signature 0x4d4d41, one byte that identifies the compression algorithm used and, eventually, the presence of a checksum: the next 4 bytes are the uncompressed size of the original buffer, then if checksum is in place, you'll get 4 more bytes preceding after [errata 22.06.2015] the uncompressed size that contain the checksum. The remaining data is what must be decompressed with RtlDecompressBufferEx. Which algorithm in used?

The followings are the compression package types and procedures as they are in ntifs.h.

//
//  Compression package types and procedures.
//
#define COMPRESSION_FORMAT_NONE          (0x0000)   // winnt
#define COMPRESSION_FORMAT_DEFAULT       (0x0001)   // winnt
#define COMPRESSION_FORMAT_LZNT1         (0x0002)   // winnt
#define COMPRESSION_FORMAT_XPRESS        (0x0003)   // winnt
#define COMPRESSION_FORMAT_XPRESS_HUFF   (0x0004)   // winnt

#define COMPRESSION_ENGINE_STANDARD      (0x0000)   // winnt
#define COMPRESSION_ENGINE_MAXIMUM       (0x0100)   // winnt
#define COMPRESSION_ENGINE_HIBER         (0x0200)   // winnt

So considering that the MAM signature usually is followed by 0x4 (or 0x84), the algorithm is COMPRESSION_FORMAT_XPRESS_HUFF.


decompress-ing


To replicate and double checking that findings, I created a small Python Windows native script: with native I pinpoint that you can't use on other OSes different from Windows, since it uses native api calls. Moreover you need Windows 8.1 at least, since the RtlDecompressBufferEx was introduced starting from that OS version. You could use the script to decompress prefetch files, if in need: but you'll get a better solutions at the end of the post. I tweeted about this script some days ago, pointing to a gist I made and that you can find at w10pfdecomp.py.


checksum-ing


In the first instance I ignored the checksum assembly branch, but then I realized that SuperFetch Windows 10 files show the same MAM signature: by applying the previous script, decompression fails. Previously I introduced the fact that a checksum could be present in the prefetch file, when in the third byte (algorithm) you get the most significant bit set: in those cases you see 0x84 as the byte value.

Reconsidering the checksum branch, here is it what happens: the (prefetch|superfetch) file will have 4 more bytes set to the calculated checksum, those bytes stored after the decompresion size (so, bytes 8-11, starting to count from 0): that bytes must be skipped during the decompression phase.

The checksum is a simple CRC32, calculated on the whole file, zeroing out the current file checksum: you can then realize why in the dis-assembly  RtlComputeCrc32 is called three times. I'll updated my Python script to consider that checksum, both on the gist and on the hotoloti github repository.


yaJUl


No, I'm not drunk. yajul (it sounds nice) means Yet Another Joachim Uber Library. Joachim Metz published and currently maintains, among many others, the "Windows Prefetch File (PF) format" document, where he describes the various formats those file use: if you couple it with his "Windows SuperFetch database format", you'll get all the intimate details of Prefetch and SuperFetch files, compression containers included.

Moreover, his libssca (Prefetch files) and libagdb (SuperFetch files) libraries, with the help of libfwnt, are able to correctly handle the decompression and parsing of MAM compression containers (well, the libraries handles all the variants), and that is damned cool!

I want to personally thank Joachim for his prompt support when I reached him with my findings: among other things I got very good suggestions and observations on my short research. I want to share with you an interesting link he provided to me, link to a work made by Jeff Bush on Microsoft Compression Formats.


conclusions


In the end we get that starting from Windows 10, Prefetch and SuperFetch files are compressed with the XPRESS HUFFMAN algorithm, actually a.k.a. the MAM format. Which is not new: Windows 8.1 uses it to compress SuperFetch files, but not Prefetch files. Moreover from what I see checksum is present only for SuperFetch files and never for Prefetch files.

It remains unclear why Prefetch and SuperFetch files are compressed. Usually compression means space saving (IO reduction?) and computational effort, but it could mean obfuscation too: if you have any clue, I'd be happy to get it.

Anyway with the excellent work made by Joachim we'll be able to understand and to handle those file without any problem. Last but not least, his work his Open Source: not bad, especially in the DFIR world, isn't it?

If you'd need my Python script you can download it from hotoloti or from the gist.


Wednesday, June 3, 2015

iOS 8.3: the end of iOS Forensics?

The latest iOS update (iOS 8.3) is a real nightmare for digital forensics specialists. This article will try to clarify what can you really obtain from an iOS device with iOS 8.3.

As we already know from Jonathan Zdziarski blog, with the introduction of iOS 8 is no longer possible to obtain a so called "Advanced Logical" acquisition based on lockdown service.

However, when we find a device without passocode it is still possible to obtain a backup, although it may be password protected if the user has previously set a password for the local backup.

In the same way we can perform a backup if we find a turned on and locked device, but only if we are able to find a pairing lockdown certificate and the device has been unlocked at least once by the user before the seizure. The same problem about an eventual backup password previously set by the device owner applies to this case too.

The real nightmare is when, and this is the most common case, we have to acquire a device that was turned off.

In this case, also with the lockdown certificate, it is not possible to obtain a backup before unlocking at least once the device. In practical it means that we need to know the passcode to create a backup.

Moreover iOS 8.3 added a new security measure that prevents external tools (not only forensics tools but also iDevice browsing tools like iFunBox) from accessing third party applications sandbox. It means that the only way to read third party contents is to create a backup....but as we already noticed to create a backup you need an unlocked device or a locked device not turned off and a lockdown certificate.


So the question is: what can we really obtain from a locked and turned off device?

It depends, of course, if we are able or not to find a lockdown certificate.

If we haven't got a lockdown certificate we can only recover information about the device and in particular:

  • Device class (iPhone, iPad, iPod)
  • Device name
  • Device color
  • Hardware model
  • iOS version
  • Unique Device ID (UDID)
  • Wi-Fi Address
We can use the tool ideviceinfo that is available in libimobiledvice.

If we have a lockdown certificate there are some more information that we can recover by using the AFC protocol. In particular:

  • Device information
    • IMEI (for devices with telephony capability)
    • Bluetooth Address
    • Language
    • Date and time
    • Timezone
    • Battery charge level
    • Total NAND memory size
    • Empty space size
  • Backup configuration
    • Local vs. iCloud
    • For local backup we can verify if it is password protected
    • Last backup date
  • Installed application list
  • Application distribution on Springboard
  • File contained inside applications that are using iTunes File Sharing. During our test we were able to successfully recover files from:
    • Adobe Reader
    • iZip
    • WinZip
    • File App
    • Office Plus
    • Smart Office
    • USB Disk
  • iBooks folder, containing all the books (both ePub or PDF) saved by the user in the application
  • Downloads folder, containing downloaded files or, in some cases, applications updates
  • iTunes_Control folder
    • iTunes subfolder, containing the iDevice iTunes library list
    • Music subfolder, containing audio files loaded into iTunes library. Files that were originally loaded into iTunes from a PC/MAC are also available
  • Videos loaded into the Device from a PC/MAC
For other folders we can obtain the file name list. For example you can recover it from the DCIM folder and know, at least, if and how many images are stored in the iDevice.

In our test we were able to obtain filename list from:
  • DCIM
  • PhotoStramsData
  • PhotoData
  • Purchases
  • Radio
In the end a short recap:
  • Unlocked device
    • You can always create a local backup
    • If the user has previously set a backup password you need to crack it
  • Locked device
    • Turned on and with lockdown certificate
      • You can create a local backup
      • The same problem as the previous case applies if the user has previously set a backup password
      • Be sure that the device keep charging during the backup process
    • Turned off device and with lockdown certificate
      • Use AFC protocol and recover the most information that you can, as explained in this article
    • Turned on/off device without a lockdown certificate
      • Only device information (name, UDID, etc.)
So, in the end, a suggestion: if you find a turned on device try to isolate it and DO NOT TURN IT OFF before searching for a lockdown certificate on a synced PC/MAC.

For more information on this topic we suggest our book "Learning iOS Forensics", published by PacktPub in March 2015 and authored by Mattia Epifani and Pasquale Stirparo.



Thursday, May 21, 2015

UnDesXing


In my own vocabulary, undesxing is the action of decrypting something encrypted with the Microsoft version of the DESX algorithm: a bit obfuscated title but I liked to make a scenographic use of it.

DESX is a variant of the Data Encryption Standard in that a XOR step is added to the plaintext before and after the encryption: you can find a description on wikipedia. So, what is the issue with it? Let me provide the context.

windows lsass


The Windows Local Security Authority (LSA) Subsystem Service (lsass) process is in charge, among other things, to authenticate and log users on to the local system: see Microsoft info here. It's well known that it keeps some sensitive information regarding the logon sessions: for example users' passwords and tokens. This kind of storage - basically due to the SSO capability - is exploited by the never-loved-enough mimikatz, which is able to provide some cool passive (not considering its active operation modalities) information.

This gold mine is kept in lsass process memory, but not all stuffs are in cleartext form. Lsass likes to encrypt some of its (definitely ours!) secrets: obviously lsass has all the data needed to decrypt them. If lsass has that data, we have it too.

Starting from Windows Vista, lsass uses the AES and 3DES to protect that data, without any change to the original algorithms: if you're able to grab the key and the iv (init vector) from the memory (live or dump) you can use any implementation of those algos to decrypt the data.

Before Vista? Lsass processes coming out from the Windows XP family uses different algorithms for the same purpose: RC4 and DESX. Nothing to say about RC4, a couple of caveats about the latter.

some info


Trying to get more technical, when lsass needs to encrypt part of its memory it uses the function LsaEncryptMemory provided by the lsasrv.dll module: the same when it needs to decrypt that data, by simply specifying the modality to use (0 is decrypting, 1 is encrypting). The LsaEncryptMemory has three parameters: the input buffer, the input buffer length and the modality. At this point, both pre-Vista and post-Vista Windows exhibit a similar behaviour: if the input buffer length is not multiple of 8 bytes, RC4 (pre-Vista) and AES  are used; otherwise DESX (pre-Vista) and 3DES.

Let's see what happens inside the Windows XP LsaEncryptMemory in the DESX case: in the following example I used an lsasrv.dll module version 5.1.2600.6058 and GUID FC6285E5-A654-4781-BD4C-BA9E9A0B69E.


There is a call to the CBC function, providing the encryption method as a parameter, desx in figure. The CBC (Cipher Block Chaining mode of operation) method is a bit branched, and I isolated only the relevant path, based on how LsaEncryptMemory initialize its parameters and based on testing.


The "call edx" in the previous figure is a call to the function parameter, desx. In the following the desx decryption branch is reported.


In the next figure a partial view of des decryption branch is reported (truly long, since the loop it's unrolled).



So basically there is a Microsoft interpretation of DES-X algorithm, and that is the first issue to be considered. The second one is the key, which is not present inside the memory. Wait, let me elaborate. During the LsaInitializeProtectedMemory execution the (pseudo)random DES (X) key is created and lost, since the key is exploded in its corresponding rounds-subkeys (key scheduling). So what you will find in memory are the 16 round subkeys, 128 bytes, plus two 8 bytes whitening vectors, for a 144 bytes blob. This is exactly what the debug symbol lsasrv!g_pDESXKey is pointing to, coupled with the lsasrv!g_Feedback symbol (used as the first XOR in CBC function).

LsaEncryptMemory XP transposition ... LsaDecryptXp


Mimikatz reuse the decryption capability offered by the Windows OS: to be able to decrypt DESX encrypted secrets without native Windows features, you need to reverse the algorithm. That's the reason I wrote LsaDecryptXP Python module. I opted for a quick&dirty approach: if you take a look at the code, you'll understand why I used the word transposition. Anyway, a quite good effort/time result. You can find LsaDecryptXP on github.com/dfirfpi/lsadecryptxp.

who cares?


It depends: one question and one tip. The question: did you known that the awesome Rekall has a mimikatz plugin? The tip: in the next weeks you could check the Rekall code reviews for some cool refactoring of that plugin, and it will use this addon.


Tuesday, January 13, 2015

Happy DPAPI!

Last October, I participated as speaker at the SANS DFIR Summit in Prague. It was a great meeting and I am very happy to have been able to participate. My speech was focused on DPAPI, the Windows Data Protection API, and how it could be used during a post-mortem digital investigation to access protected information: overcoming system's security it's sometimes necessary to access data otherwise not available. I like to call this "process" ODI, Offensive Digital Investigations.

I want to be brief, skipping any DPAPI introduction and only providing some links for readers who don't know what DPAPI might be. Consider simply the fact that the technology was introduced with Windows2000(!!) and you and/or your system/applications use it every day... Moreover, if you wonder how wifi passwords are protected, how IE or Chrome treats saved credentials, how Dropbox encrypts its databases, how iCloud protects user credentials, how EFS (Encrypting File System) gets unlocked and so how your private asymmetric key is safeguarded... then you need to know what DPAPI is and how it works. You can download my slides "Give Me the Password and I'll Rule the World" from here and this is the links list:


The last work is an awesome research made by Elie Bursztein and Jean-Michel Picod, who first published DPAPI intimate details. They even provided dpapick, an Open Source Python tool able to offline decrypt DPAPI blobs (aka the encrypted information) up to Windows Vista. Their work is a milestone to deeply understand this technology, and it was my entrance and reference when I started to dig inside DPAPI. For this reason I decided to try improving dpapick by adding Windows7 and Windows 8.1 support: after some nights inside WinDbg, I was able to decrypt blobs coming from these systems, just in time for the SANS conference. Then Jean-Michel took my patch, refactored the code and added some other cool features, releasing the dpapick version 0.3 in the middle of October: check the new features added in his blog post here.

Just a note on Windows 8.1: DPAPI decryption is supported only for local accounts, not for online accounts. As you can read here, "[DPAPI is] used to encrypt and decrypt static data on a single computer. Cloud computing, however, often requires that content encrypted on one computer be decrypted on another": so Microsoft introduced DPAPI-NG to allow sharing of secrets/whatever on different computers, after proper authentication and authorization. DPAPI-NG is used when working with online user accounts, and it's not currently supported by dpapick.

Ideally this post should have been published few days after the meeting, anyway it's here: some examples on how you can use dpapick to access data protected by DPAPI tech.

prerequisites


First, you must download the dpapick version 0.3 from bitbucket (the zip file or the mercurial clone) or (cool news) install from pypi! The pro with the installation option is that it will take care of dependencies, otherwise you must set the correct PYTHONPATH and provide the 3rd part packages: dpapick itself is pure Python, so no issues with the OS you're using. In the post examples, I used both Linux and Windows.

Second, you should have a Windows OS mounted somewhere: I'll use the vmdk virtual disk files coming from the Windows 8.1 and Windows 7 VmWare guests I used during the reverse engineering phase. Alternatively you should extract the needed files from your target Windows and place them wherever you prefer.

Besides that, you should know that user's login password is the main key that unlocks user's masterkeys and allows later blobs decryption; that the system has its own secrets protected with a system password. In the first case the password should be only in user mind; in the second case the password must be inside (or, at least, known to) the system, so no security at all...

no more (lsa) secrets


One of the cool features added is the capability to decrypt Windows7-8.1 LSA secrets (credits to mimikatz too): this feature is needed to grab the system key (DPAPI_SYSTEM) used by Windows to dpapi-protect some info. Moreover it could expose some other interesting info. Let's use the script lsasecrets in dpapick folder "examples": in the first instance use '--hex' to avoid unpleasant string conversion errors, it's not all a string there (note that command and parameters used are splitted on more lines to ease reading).

./lsasecrets
--system=/media/win81/Windows/System32/config/SYSTEM
--security=/media/win81/Windows/System32/config/SECURITY
--hex

NL$KM              CurrVal     bc8b5abe12a6b772114c7f3902b25cb20813be04493f9d84...
NL$KM              CupdTime    2014-09-29 19:44:25
NL$KM              OldVal   
NL$KM              OupdTime    2014-09-29 19:44:25
DPAPI_SYSTEM       CurrVal     01000000c78f09ee4f1c5d6ccc29280313c0a63f6c83b478...
DPAPI_SYSTEM       CupdTime    2014-09-14 21:31:04
DPAPI_SYSTEM       OldVal      01000000962d3a6c963627caa8c0725b56ce7dfbe8050007...
DPAPI_SYSTEM       OupdTime    2013-08-22 14:45:11
DefaultPassword    CurrVal     66007500660066006100
DefaultPassword    CupdTime    2014-09-14 21:32:24
DefaultPassword    OldVal      52004f004f0054002300310032003300
DefaultPassword    OupdTime    2013-08-22 14:45:44

The DPAPI_SYSTEM value it's the data needed to unlock system masterkeys and to decrypt system blobs. Then we were able to get NL$KM value, used by Windows to encrypt domain cached credentials, and... what? DefaultPassword (aka user auto-logon password)? I can't figure out why it's there, perhaps VmWare easy-install? Anyway, let's get only those values.

./lsasecrets
--system=/media/win81/Windows/System32/config/SYSTEM
--security=/media/win81/Windows/System32/config/SECURITY
--secret=DefaultPassword

fuffa
ROOT#123

Ok, 'fuffa' is the current user password and 'ROOT#123' the old password. That's a windfall, since getting the user password in this way it's too easy... and so we'll able to unlock DPAPI for the user. Later we'll see another way to unlock user DPAPI.

wifi credentials


Let's see an example of system's secret, wifi credentials. As you should know, when you connect to a wifi network with the right password, this data will be saved inside your os (together with other info) for later reuse: a sort of SSO. This storage is not per-user, but system wide and the passwords are protected with DPAPI: you need the DPAPI_SYSTEM "secret" to decrypt them.

I just realized the current dpapick has not scripts to handle this task, so I wrote the following one which will provide wifi credentials (just wifi name and password): I called it wiffy, to train my talent in providing cool names... As is as usual, just quick&dirty coding.


#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
# Author: dfirfpi - francesco.picasso@gmail.com
#

from DPAPI.Core import blob
from DPAPI.Core import masterkey
from DPAPI.Core import registry
from optparse import OptionParser

import re
import os
import sys

if __name__ == "__main__":
  parser = OptionParser()
  parser.add_option("--masterkey", metavar="DIRECTORY", dest="masterkeydir")
  parser.add_option("--system", metavar="HIVE", dest="system")
  parser.add_option("--security", metavar="HIVE", dest="security")
  parser.add_option("--wdir", metavar="WIFIDIR", dest="wifi_dir")

  (options, args) = parser.parse_args()

  reg = registry.Regedit()
  secrets = reg.get_lsa_secrets(options.security, options.system)
  dpapi_system = secrets.get('DPAPI_SYSTEM')["CurrVal"]

  mkp = masterkey.MasterKeyPool()
  mkp.loadDirectory(options.masterkeydir)
  mkp.addSystemCredential(dpapi_system)
  mkp.try_credential_hash(None, None)

  for root, _, files in os.walk(options.wifi_dir):
    for file in files:
      filepath = os.path.join(root, file)
      with open(filepath, 'r') as f:
        file_data = f.read().replace('\x0a','').replace('\x0d','')
        wifi_name = re.search('<name>([^<]+)</name>', file_data).group(1)
        key_material = re.search(
            '<keyMaterial>([0-9A-F]+)</keyMaterial>', file_data).group(1)
        wblob = blob.DPAPIBlob(key_material.decode('hex'))
        wifi_pwd = '<not decrypted>'
        mks = mkp.getMasterKeys(wblob.mkguid)
        for mk in mks:
          if mk.decrypted:
            wblob.decrypt(mk.get_key())
            if wblob.decrypted:
              wifi_pwd = wblob.cleartext
              break
        print 'Wifi:{} Password:{}'.format(wifi_name, wifi_pwd)

Let's execute wiffy (it sounds like a name for dogs... but it's inside the urban dictionary... no copyright then...) against my real windows8.1 installation, so results will be offuscated (you too curious).

./wiffi.py
--masterkey=/mnt/win81/Windows/System32/Microsoft/Protect/S-1-5-18/User/
--system=/mnt/win81/Windows/System32/config/SYSTEM
--security=/mnt/win81/Windows/System32/config/SECURITY
--wdir=/mnt/win81/ProgramData/Microsoft/Wlansvc/Profiles/Interfaces/\{9420B7D3...\}/

Wifi:MyUberWifi Password:notUberTheCarButUberTheUber
Wifi:monkey Password:CuriousGeorge
Wifi:wannabe Password:lamer


from system to user secrets


If getting the system password is expected, what about the user password, needed to decrypt user's secrets? Ruled out the DefaultPassword LSA secret, you can try cracking the password hash or... you could find it in cleartext inside a RAM dump, for example an hibernation file. The awesome mimkatz is the tool, thanks to the number-one-lsass-enemy© Benjamin Delpy: refer to his blog and to my previous posts. I think this topic is already well known, but there is something more...
Our goal is not the user password, but to unlock user's DPAPI masterkeys: actually, if you have a memory dump (whatever contains the lsass process), you'll be able to (almost) always unlock user DPAPI. Sounds cool... but stay grounded. Let's recall the mimikatz matrix, next figure


As you can see in the Primary column, the SHA1 hash is always there with only one exception, the domain protected users. That SHA1 is the SHA1(UTF16LE(user_password)), which is exactly the only secret part of the pre-key needed to unlock masterkeys (refer to the slides)!

So despite the fact the Microsoft hardened Windows by removing default user password presence in some SSPs (Security Support Providers) or despite the user configuration (see this great post from Mike Pilkington) the SHA1 will allow DPAPI decryption even if the user password is not known. To the best of my knowledge you can't configure/remove (aka harden) the primary SSP (msv1_0). Result: grab that hash and enjoy with dpapick, which handles it wonderfully.

Consider the following mimikatz output, coming out from a Windows 8.1 with one local user account


As expected, no cleartext password but... the SHA1 is there! Since I know my password (do you remember the previous 'fuffa'?), that SHA1 is exaclty the SHA1(UTF16LE('fuffa'))... Rememeber, with virtualization you must know the user password to access DPAPI protected data (you can't reset the user's password): here, with dpapick, you only need the "always present" SHA1.

iCloud


Since I'm talking about ODI, I'd like to show how dpapick usage could help during a digital forensics investigation. Recalling the slides, if you face an "unbreakable" (something to say here...) turned off iPhone, with no passcode provided... you will not be able to access its data. Suppose you have the suspect's laptop (but no Apple LockDown certificates) too, and iCloud installed... or suppose you have only a laptop with iCloud installed... This scenario could be called "Access to otherwise inaccessible data".

The iCloud Windows application allows the users to backup their idata on the (i)cloud (too many 'i'...), a well-known feature with some well-known issues too... but it's another story. During the installation, iCloud asks for the user credentials once and then it starts doing its job every time the computer is powered on. In other terms, single sign on in action (and autorun, btw).

The iCloud credentials are kept inside the com.Apple.AOSKit.plist file, in "\Users\<username>\AppData\Roaming\Apple Computer\Preferences\". This file contains a data section which is a large DPAPI blob: to be short, it's enough to execute the icloud.py script inside dpapick/examples folder to get the job done. For any detail, refer to slides and to the icloud.py code.

./icloud
--sid=S-1-5-21-2128076315-4144300488-3078399761-1001
--credhist=/mnt/win81/Users/user/AppData/Roaming/Microsoft/Protect/CREDHIST
--masterkey=/mnt/win81/Users/user/AppData/Roaming/Microsoft/Protect
            /S-1-5-21-2128076315-4144300488-3078399761-1001/
--hash=74b87ba1e12734f71fe4737990e2c420bd145bf4
--aoskit=/mnt/win81/Users/user/AppData/Roaming/Apple\ Computer/Preferences/com.apple.AOSKit.plist
--fout=../aoskit.plist


iCloud Apple token decryption
Binary PLIST file for account iFooFooFoo@icloud.com decrypted!
Decrypted plist written in file "../aoskit.plist.plist" 

(ERRATA: when using the --hash parameter instead of --password, as I do, a quick fix is needed in icloud.py code... add at line 65  "options.h.decode('hex')"... sorry, I forgot it, and it will be fixed).

icloud.py ERRATA

CURRENT LINE 65>
datablob.try_decrypt_with_hash(options.h, mkp, options.sid, aoskit=options.aoskit)

MUST BE>
datablob.try_decrypt_with_hash(options.h.decode('hex'), mkp, options.sid, aoskit=options.aoskit)

What you get is a new decrypted plist file, which contains a lot of useful and interesting info (mailToken, cloudKitToken, etc.). The iCloud token is the pair [dsPrsID, mmeToken]: with this token you can access the user's iDevices iBackups ('i' again...) stored online. For this last task I use Elcomsoft Phone Password Breaker (see here), simply because it's the only tool providing such a cool feature in the way I like. Anyway, you could also try with another iCloud by re-encrypting the decrypted token with your current Windows user DPAPI (not providing code, but it's simple).

dropbox


Dropbox obfuscated Python code it's an hard reverse engineering quest. There are at least three notable works on it, but here I want to cite the awesome one made by Nicolas Ruff and Florian Ledoux, "A critical analysis of Dropbox software security", more than two years ago! They even provide the useuful code to obtain the encrypted dbx decryption key, which is protected by DPAPI. Being brief, check their work on https://github.com/newsoft: the dpapick dropbox script is based on their findings.

So, to get that decryption key, just run dpapick dropbox script, as shown in the next example (note: the same errata as icloud applies if using the '--hash' parameter), where I used dpapick from a Windows machine.


python dropbox
--sid=S-1-5-21-2128076315-4144300488-3078399761-1001
--masterkey=G:\Users\user\AppData\Roaming\Microsoft\Protect\S-1-5-21-2128076315-4144300488-3078399761-1001 --credhist=G:\Users\user\AppData\Roaming\Microsoft\Protect\CREDHIST --hash=74b87ba1e12734f71fe4737990e2c420bd145bf4
--ntuser=G:\Users\user\NTUSER.DAT
 
Dropbox DBX password
2bc4bfd30e10dd3ec3256bf5715f8c64

Then? As reported in my slides, you need EE Sqlite (Encryption Extension, see here), which is not publicly available. Newsoft provided a 3.7.0 sqlite3 source code with EE, so you can grab it from their github space and use it with the extracted password.

find your blobs


If you are curious as I suppose, you can even try to find out how many DPAPI blobs you have inside your Windows. To the best of my knowledge, actually there is only one crypto provider used, whose GUID is "df9d8cd0-1501-11d1-8c7a-0c04fc297eb": so, with a simple hex-searching you will be able to spot them. Then, with a next-to-come dpapick script, it will be easy to verify the bytes found and, in case, decrypt them.

conclusions


There are many secrets protected with DPAPI, for example Windows Vaults (lazy wip here). So feel free to write to me and/or to Jean-Michel providing some info regarding the usage of CryptProtectData in your target app, your scripts or whatever could help improving dpapick.

As you read, dpapick needs some tunings and addings, but it's an invaluable tool when you need to access protected data to go on with the investigation. So, Happy DPAPI(ck)!


[bonus track]


If you reached this last part of the post (without directly scrolling here, cheater!), then you deserve a bonus. When exploring LSA secrets, I pointed out the presence of the DefaultPassword old value, which surprised me.

I did some more tests on 6 different installations of Windows 7, 3 Windows 8.1 and 1 Windows Vista. All but Vista contained that DefaultPassword old value set, without having the auto-logon feature enabled: this password seems to be the first one inserted during the Windows installation and, by changing the current one, it does not change (not tested the auto-logon enabling and disabling).

The conclusion? Hardly definitive due to reduced dataset (please share your findings), but it could be said that starting from Windows 7, Windows keeps in the old DefaultPassword value your first password (assumed auto-logon disabled). The risk? It depends on you. The opportunity? It depends on them. Anyway, from today, I'll always check this value.

Sunday, June 15, 2014

Digital Forensics Tools Bookmarks

We want to share with you a list of bookmarks related to hardware and software tools for Digital Forensics acquisition and analysis. The bookmark file is in Mozilla Firefox, so it can be directly imported into it.

You can download the file from

http://www.realitynet.it/bookmarks.html

If you are interested in adding a tool to our list, please contact me at mattia @ realitynet.it.