Tuesday, 27 October 2020

Magnet Weekly CTF writeup - Week 3

 And we're on to week 3 of the Magnet Weekly CTF Challenge! This week's question still references the Android image from week 1:

Which exit did the device user pass by that could have been taken for Cargo?

This week's question had me stumped initially and added to the difficulty was the three answer attempt limit. Thankfully Magnet Forensics was generous enough to give a hint on Cache Up, which pointed players to one of their webinar on mobile artifact comparison.

From the webinar hint, my instinct tells me that this had to do with the Pixel equivalent of 'live photos' - a.k.a. motion photos - where the phone records and trims up to 3 seconds of video when taking a photo with motion enabled.

So I started looking at the MVIMG*.jpg files in the DCIM folder:

$ ls data/media/0/DCIM/Camera/ | grep MVIMG
MVIMG_20200305_145544.jpg
MVIMG_20200306_151636.jpg
MVIMG_20200307_130221.jpg
MVIMG_20200307_130237.jpg
MVIMG_20200307_130326.jpg
MVIMG_20200307_185225.jpg
MVIMG_20200307_201453.jpg
MVIMG_20200310_133405.jpg

There were 8 motion photos and I needed a way to extract the embedded video within. A quick Google search did not disappoint and I found a ready script by Jerry Peek on StackOverflow that does exactly what we needed.

#!/bin/bash
# extract-mvimg: Extract .mp4 video and .jpg still image from a Pixel phone
# camera "motion video" file with a name like MVIMG_20191216_153039.jpg
# to make files like IMG_20191216_153039.jpg and IMG_20191216_153039.mp4
#
# Usage: extract-mvimg MVIMG*.jpg [MVIMG*.jpg...]

for srcfile
do
  case "$srcfile" in
  MVIMG_*_*.jpg) ;;
  *)
    echo "extract-mvimg: skipping '$srcfile': not an MVIMG*.jpg file?" 2>&1
    continue
    ;;
  esac

  # Get base filename: strip leading MV and trailing .jpg
  # Example: MVIMG_20191216_153039.jpg becomes IMG_20191216_153039
  basefile=${srcfile#MV}
  basefile=${basefile%.jpg}

  # Get byte offset. Example output: 2983617:ftypmp4
  offset=$(grep -F --byte-offset --only-matching --text ftypmp4 "$srcfile")
  # Strip trailing text. Example output: 2983617
  offset=${offset%:*}

  # If $offset isn't an empty string, create .mp4 file and
  # truncate a copy of input file to make .jpg file.
  if [[ $offset ]]
  then
    dd status=none "if=$srcfile" "of=${basefile}.mp4" bs=$((offset-4)) skip=1
    cp -ip "$srcfile" "${basefile}.jpg" || exit 1
    truncate -s $((offset-4)) "${basefile}.jpg"
  else
    echo "extract-mvimg: can't find ftypmp4 in $srcfile; skipping..." 2>&1
  fi
done

Running the script against the MVIMG*.jpg files earlier and looking through the extracted videos, I noted an interesting frame extracted from MVIMG_20200307_130326.jpg:


The video appears to have captured a signboard on a highway, with the keyword 'Cargo' on it. Unfortunately the video quality isn't the best (or maybe it's just my screen) and I could not make out clearly what was on the signboard.

Checking the EXIF metadata of the image gives us the following information:

$ exiftool data/media/0/DCIM/Camera/MVIMG_20200307_130326.jpg 
ExifTool Version Number         : 12.00
File Name                       : MVIMG_20200307_130326.jpg
Directory                       : data/media/0/DCIM/Camera
File Modification Date/Time     : 2020:03:07 07:03:28-05:00
File Type                       : JPEG
File Type Extension             : jpg
MIME Type                       : image/jpeg
Make                            : Google
Camera Model Name               : Pixel 3
Modify Date                     : 2020:03:07 13:03:26
Date/Time Original              : 2020:03:07 13:03:26
Create Date                     : 2020:03:07 13:03:26
GPS Version ID                  : 2.2.0.0
GPS Altitude                    : 246.8 m Above Sea Level
GPS Date/Time                   : 2020:03:07 12:03:26Z
GPS Latitude                    : 60 deg 11' 38.70" N
GPS Longitude                   : 11 deg 5' 46.65" E

Looking up the GPS coordinates on Google Maps places us within Gardermoen Airport in Norway, next to Starbucks - not quite what I expected since the motion photo clearly showed the device user on the move outdoors.

Refusing to be daunted, I checked the EXIF of the images that were sequentially before and after the motion photo of interest and noted that MVIMG_20200307_185225.jpg places the user in Gamle Oslo, Norway. Since the motion photos suggests that the device user was on a bus, I used Google Maps for directions from Gardermoen Airport to Gamle Oslo and followed the route on street view. My persistence finally paid off when I found the signboard at 60°10'14.3"N 11°06'13.8"E.


Answer: E16

Fun fact: E16 is actually the route and not exit, unlike what the question suggests. From Wikipedia: European route E16 is the designation of a main west-east road through Northern Ireland, Scotland, Norway and Sweden.

Tuesday, 20 October 2020

Magnet Weekly CTF writeup - Week 2

Magnet is hosting a weekly DFIR challenge until the end of 2020. Head on over to https://magnetweeklyctf.ctfd.io to sign up if you haven't already done so!


This week's question:

What domain was most recently viewed via an app that has picture-in-picture capability?

This question is based off the Android image we were given in week 1. To start, we have to determine which apps supports picture-in-picture (PIP). Per the Android Developers' guide, apps have to declare support for PIP by registering video activity in their manifest by setting android:supportsPictureInPicture to true.

I unpacked the MUS_Android.tar image given and used apkanalyzer from the Android SDK to print out the manifest files from all the Android packages (apks) in data/app.

$ find data/app -name "base.apk" -print0 | xargs -0 -i apkanalyzer manifest print {} > manifest-all

Stringing a bunch of grep commands together to search for packages with android:supportsPictureInPicture="true" from the printed manifests in the previous step gives us the following 7 out of 79 packages with PIP capability:

$ grep -E "package=|PictureInPicture=\"true\"" manifest-all | grep -B 1 "PictureInPicture" | grep package
    package="com.google.android.apps.maps"
    package="com.facebook.orca"
    package="com.google.android.apps.tachyon"
    package="com.google.android.youtube"
    package="com.android.chrome"
    package="com.google.android.videos"
    package="com.google.android.gms"

Of the above, the most likely candidate to start with is Chrome, as the other apps are not known for being used to view other domains. The Chrome app history is located in the database at data/data/com.android.chrome/app_chrome/Default/History. Opening up the History SQLite database with DB Browser for SQLite, a quick join and sort of the visits and urls table by visit_time gives us:


Answer: malliesae.com

Friday, 16 October 2020

Installing Android SDK command-line tools on Linux

 Recently I had to use some tools from the Android SDK on Linux and it was surprisingly not as straightforward as I thought it'll be. Perhaps Google was trying to convince folks to use Android Studio...

Anyways, the first step is to download the command-line tools from Android Developers. (Click on "Download Options" for more options.) Grab the zip file for command-line tools and unzip it to a folder of choice. You should see a tools folder, with the necessary binaries in the bin subfolder.

If you get a Warning: Could not create settings error when trying to run tools/bin/sdkmanager, that's because the tools directory hierarchy has been changed starting from Android SDK Command-line Tools 1.0.0 (6200805). (Refer to the excellent answer by Jing Li on Stack Overflow here.) The solution therefore, is to move the unzipped tools folder into the cmdline-tools subfolder, and add cmdline-tools/tools/bin to your path.

Assuming the sdkmanager is located at /home/<username>/cmdline-tools/tools/bin/sdkmanager, one would add the following to their bash profile (~/.bashrc):

export PATH=$PATH:/home/<username>/cmdline-tools/tools/bin

Exit and restart the terminal, and the Android SDK command-line tools should work now. Some useful commands:

$ sdkmanager --help
$ sdkmanager --list
$ sdkmanager --install <package>

Note: to use certain tools such as apkanalyzer, one would also need to install the necessary packages with sdkmanager.

Tuesday, 13 October 2020

Magnet Weekly CTF writeup - Week 1

Magnet Forensics has recently launched a weekly capture-the-flag (CTF) challenge that will run through the last quarter of 2020! Head on over to their blog for more details on the challenge and how to sign up.

For challenge one, we are provided with an Android image which is a tar file containing what appears to be a filesystem extraction of an Android phone.The challenge question was:

What time was the file that maps names to IP's recently accessed?
(Please answer in this format in UTC: mm/dd/yyyy HH:MM:SS)

I had to first figure out which is the file that maps names to IP addresses on Android. According to this answer on StackOverflow, it is no different than on a standard Linux system - i.e. the /etc/hosts file. However I could not find an /etc/hosts file in the given Android tar image.

Running a search for an "etc/hosts" file in the tarball points me to data/adb/modules/hosts/system/etc/hosts.

$ tar -tvf MUS_Android.tar | grep "etc/hosts"
-rw-r--r-- 0/0                85 2020-03-05 05:50 data/adb/modules/hosts/system/etc/hosts

A quick check of the contents of the file after extracting confirms it to be the one we are after.

$ cat data/adb/modules/hosts/system/etc/hosts
127.0.0.1       localhost
::1             ip6-localhost
184.171.152.175 malliesae.com

Based on the above output, the file was last modified on 5th March 2020 at 05:50 UTC but we also need the seconds for the answer. A quick search on the internet indicates that the --full-time option is available for both the ls and tar commands, giving us timestamp information in ISO format.

So listing the specific file in our tarball with the --full-time option gives us:

$ tar --full-time -tvf MUS_Android.tar 'data/adb/modules/hosts/system/etc/hosts'
-rw-r--r-- 0/0              85 2020-03-05 05:50:18 data/adb/modules/hosts/system/etc/hosts

While the challenge technically asked for recently accessed (i.e. last accessed) instead of last modified, I could not find any other timestamp. Checking with 7zip also revealed only a single modified timestamp.


Answer: 03/05/2020 05:50:18

Friday, 15 May 2020

Installing Volatility 2.x on Windows 10

Quick documentation on getting Volatility 2.x set up on Windows 10.

Volatility Foundation (https://www.volatilityfoundation.org/) offers pre-compiled binaries for Volatility 2.6 on Windows but the executable was last updated in 2016 and missing much of the newer Windows memory profiles. Google search revealed plenty of folks having trouble getting Volatility to work on Windows 10 from source and the closest I've found is Mike Cary's post on Installing Volatility on Windows. There's still a bunch of errors from his steps when I followed it, so here's a quick documentation of what I did to get Volatility 2.6.1 working.

Step 1: Download and install Python 2.7 from https://www.python.org/downloads/.

Step 2: Download and install Microsoft Visual C++ Compiler for Python 2.7 from https://www.microsoft.com/en-us/download/details.aspx?id=44266.

Step 3: Install Volatility 2.6.1 dependencies per https://github.com/volatilityfoundation/volatility/wiki/Installation:
  • Distorm3: install version 3.3.4 as newer versions don't seem to support Python 2 nor work with Volatility 2.
    pip install distorm3==3.3.4
  • Yara: I tested version 3.8.1 which works. You can also try with other versions but note that there was an error about missing 'stdbool.h' for version 4.0.0.
    pip install yara-python==3.8.1
  • PyCrypto: no major issues encountered for current versions of pycrypto 2.6.1 and pycryptodome 3.9.7 with Python 2.
    pip install pycrypto pycryptodome
  • OpenPyxl: again, no issues with Python 2 support for current version 2.6.4.
    pip install openpyxl
  • ujson: it seems they have stopped supporting Python 2 for newer releases so I installed version 1.35.
    pip install ujson==1.35

Step 4: Finally, download (or git clone) Volatility 2 from https://github.com/volatilityfoundation/volatility.


Now you should have a working version of Volatility 2 on Windows 10 with the latest profiles included. Refer to the Volatility Usage wiki for additional plugins. (E.g. memory baseline plugin by csababarta)

Last but not least, with end of support for Python 2, do consider switching to Volatility 3!

Saturday, 17 November 2018

Convert VDI image

Some quick notes on virtual machine formats.

There was a VirtualBox VDI file which EnCase and FTK Imager couldn't mount - EnCase v8.05 was unable to even read the partitions while FTK Imager v4.1.1.1 could read the partitions but not the filesystem in the partitions.

Initially I tried to convert to VMDK format using VirtualBox's vboxmanage internalcommands:
vboxmanage internalcommands converthd -srcformat VDI -dstformat VMDK <inputfile> <outputfile>

but it produced the following error:
VBoxManage.exe: error: Cannot copy the image: VERR_VD_INVALID_TYPE


Subsequently, thanks to the post by Namareba食べたい, I successfully converted the image file with the following command:
vboxmanage clonemedium disk <inputfile> <outputfile> --format VMDK

and the resultant VMDK file was read and mounted successfully by EnCase.

Tuesday, 18 September 2018

Weekly roundup - 16 Sep 2018

Quick roundup of two articles read last week:

  1. https://www.magnetforensics.com/blog/android-messaging-forensics-sms-mms-and-beyond/
    Jamie McQuaid at Magnet Forensics blogged about the various databases on Android from which SMS/MMS data can be found, with a brief mention of Samsung logs and the newer "Android Messages" application. I do wish there was more information about the icing_mmssms.db database though, such as how and when messages will differ between icing_mmssms.db and the normal mmssms.db.


  2. https://www.magnetforensics.com/blog/qualcomm-phone-edl-mode/
    Magnet Forensics put up a post on getting Qualcomm phones into Emergency Download (EDL) mode via three options, with a link to Aleph Security's detailed post on exploiting EDL programmers.


In other news, Apple launched the new iPhone XS, XS Max, and XR at the iPhone event 2018 which goes up to 512GB of storage. This is going to be a headache for acquisitions and e-discovery...

Saturday, 4 August 2018

Windows folder deletion

It is pretty well known that when files are deleted in Windows Vista or later, two files are created in the Recycle Bin - the $I file and $R file. Most forensic tools are smart enough to piece the two files together to present the examiner with the original filename, original path, and deletion date. What happens when it is not a file but a folder that is deleted?

To test, I created a folder with 3 text files in it, then deleted the entire folder. The following shows the artefacts found in my Recycle Bin:

Ignore the .ORF and .JPG files for now. Note the matching $I and $R 'files' highlighted in red (the $R 'file' is actually a directory).
paladin@paladin:<redacted>$ ls -l
total 9
-rwxrwxrwx 1 root root  129 Nov 20  2017 desktop.ini
-rwxrwxrwx 1 root root  108 Jul  4 13:35 $I5SL57R.ORF
-rwxrwxrwx 1 root root  108 Jul  5 06:44 $I6O696O.ORF
-rwxrwxrwx 1 root root   66 Jul 27 06:09 $IBN1JFG
-rwxrwxrwx 1 root root  108 Jul  4 13:35 $IFXKF3C.JPG
-rwxrwxrwx 1 root root  108 Jul  4 13:35 $IJP866D.JPG
-rwxrwxrwx 1 root root  108 Jul  4 13:35 $IK0XWGY.ORF
-rwxrwxrwx 1 root root  108 Jul  4 13:34 $IRBWPPL.JPG
-rwxrwxrwx 1 root root  108 Jul  4 13:34 $IWMRGZO.ORF
drwxrwxrwx 1 root root 4096 Jul 27 06:03 $RBN1JFG

As expected, the $R 'file' contained the contents of the deleted folder, without the accompanying $I files.
paladin@paladin:<redacted>$ ls -l \$RBN1JFG
total 2
-rwxrwxrwx 2 root root 76 Jul 27 06:02 file_copy.txt
-rwxrwxrwx 2 root root 75 Jul 27 06:02 file_move.txt
-rwxrwxrwx 2 root root 70 Jul 27 06:01 file_orig.txt

Looking at the $I file, we can see the original path of the folder, as well as the deleted date of "D0 8D 9F 64 70 25 D4 01" which corresponds to 27 July 2018 06:09:35 UTC+0.
paladin@paladin:<redacted>$ hexdump -e '8/1 "%02X ""\t"" "' -e '8/1 "%c""\n"' \$IBN1JFG
02 00 00 00 00 00 00 00   
DD 00 00 00 00 00 00 00  �
D0 8D 9F 64 70 25 D4 01  Ѝ�dp%�asdasd
13 00 00 00 43 00 3A 00  C:
5C 00 54 00 65 00 6D 00  \Tem
70 00 5C 00 66 00 6F 00  p\fo
6C 00 64 00 65 00 72 00  lder
5F 00 64 00 65 00 6C 00  _del

The above short experiment explains why certain files in the Recycle Bin are not displayed with their corresponding deletion times in a certain tool, as the tool was not able to match the parent folder's deletion time to the files contained within.

Separately, the .ORF and .JPG $I files were files that I had previously deleted and restored. It would appear that Windows leaves the $I files in the Recycle Bin for restored files and only deletes them if the file in the Recycle Bin was deleted. However that bears more testing/research for another day.

*Update*
Read more on the testing of residual $I files by Phill Moore at ThinkDFIR and Yogesh Khatri.

Sunday, 18 February 2018

Installing SIFT

SANS Investigative Forensics Toolkit (SIFT): https://github.com/sans-dfir

The current recommended way is to install via SIFT commandline (sift-cli) as opposed to using the older bootstrap method or saltstack.

The following steps are what I did on my installation of Ubuntu 16.04 (Xenial Xerus):

1) Download the latest release files
Note: grab the latest release files from https://github.com/sans-dfir/sift-cli/releases/latest (version 1.5.1 at the time of writing).
$ wget https://github.com/sans-dfir/sift-cli/releases/download/v1.5.1/sift-cli-linux
$ wget https://github.com/sans-dfir/sift-cli/releases/download/v1.5.1/sift-cli-linux.sha256.asc


2) (Optional) Verify downloaded files
Grab the PGP key and verify the signed SHA256 signature.
$ gpg --keyserver pgp.mit.edu --recv-keys 22598A94
$ gpg --verify sift-cli-linux.sha256.asc
$ shasum -a 256 -c sift-cli-linux.sha256.asc OR sha256sum -c sift-cli-linux.sha256.asc


3) 'Install' sift-cli
$ sudo mv sift-cli-linux /usr/local/bin/sift
$ chmod 755 /usr/local/bin/sift


4) Use sift-cli to install latest SIFT
$ sudo sift install


Wait for it to finish (took pretty long on my installation) and you're done!

Some other useful commands for keeping your SIFT installation up to date:

Update existing VM:
$ sift update

Upgrade to new release:
$ sift upgrade

Magnet Summit 2022 Virtual CTF - Windows

Magnet Forensics recently concluded their Virtual CTF for the Magnet Summit 2022.  Participants were provided with the following three image...