Installing Autopsy 4.6.0 on linux



Autopsy is a digital forensics tool that needs no introduction. It has a ton of capabilities such as registry analysis, email analysis, media analysis, android analysis etc. The fact that it's open source and is bundled with the ability to analyze android images is just super awesome.

I had previously tried to compile Autopsy for linux but i had little luck. I decided to try again with this version, that's packaged for linux. Here is how to go about it.

Update and install dependencies

  • apt-get update
  • apt-get install libafflib-dev libbfio-dev libc3p0-java libewf-dev libpostgresql-jdbc-java sleuthkit-java

Install and configure Java 8

Add Java repository and install the Java 8 installer 
  • sudo add-apt-repository ppa:webupd8team/java
  • sudo apt-get install oracle-java8-installer
Check for the Java version:
  • java -version
  • javac -version
Confirm the Java path
  • sudo update-alternatives --config java
Add path to environment
  • sudo nano /etc/environment
  • JAVA_HOME="/opt/jdk1.8.0_101"
  • export JAVA_HOME
Initialize environment:
  • source /etc/environment
Test Java HOME variable:
  • echo $JAVA_HOME

Download and setup Autopsy

Create working directory:
  • mkdir autopsy-4.6.0-linux
  • cd autopsy-4.6.0-linux/
Download Autopsy:
  • wget -nc -cq --show-progress https://github.com/sleuthkit/autopsy/releases/download/autopsy-4.6.0-linux1/sleuthkit-java_4.6.0-1_amd64.deb
  • wget -nc -cq --show-progress https://github.com/sleuthkit/autopsy/releases/download/autopsy-4.6.0-linux1/autopsy-4.6.0-linux1.zip
Extract sleuthkit and manual install:
  • dpkg -x sleuthkit-java_4.6.0-1_amd64.deb sleuthkit
  • sudo cp -r sleuthkit/usr/* /usr/
Extract Autopsy:
  • mkdir autopsy-4.6.0-linux
  • unzip autopsy-4.6.0-linux1.zip -d autopsy-4.6.0-linux
Configure Autopsy:
  • cd autopsy-4.6.0-linux/
  • chmod +x unix_setup.sh
  • ./unix_setup.sh
Start autopsy:
  • cd bin/
  • ./autopsy
If all goes well, you should get your nice and simple GUI, as shown below. 


I will work on a follow up blog post, that will highlight how to create android images and analyze them using Autopsy.

References



A gentle introduction into ARM assembly


Computer architecture 101

There are two main types of microprocessor architectures i.e. Complex Instruction Set Computing (CISC) and Reduced Instruction Set Computing (RISC). The term instruction set by definition is a group of instructions that are given in order to execute a program and direct the computer on manipulating or processing it. CISC is the typical x86 computer with a complex set of instructions while RISC is used in portable devices and embedded systems due to it's power efficiency and the fact that instructions can be executed more quickly.

ARM is an assembly language that is used to build software that ships as a System On Chip (SoC) which is an integrated circuit which contains all the components of a computer system on a single chip. An example of ARM systems are mobile devices, routers, and various assortment of Internet of Things (IoT) devices.

The smallest unit of data in a computer is a binary digit or a bit. A bit can have a value of 0 or 1. This is because the microprocessor understands binary numbers which is either 0 or 1, which translates to either Off or On or 0V or 5V respectively. Each 0 and 1 represent a bit of information to the microprocessor. 8 bits make 1 byte, 4 bits make 1 nibble and 2 nibbles make 1 byte. To a computer, data is basically a combination of binary digits.

Users interact with computers by providing alphanumeric or special character inputs which the computer does not directly understand. It has to convert them into bits. A detailed overview of the number systems is out of scope of this blog post. In order to grasp how computers convert numbers, alphanumeric and special characters, it is important to understand binary, hexadecimal and natural numbers conversations from one system to another. Not to mention, how to perform mathematical operations on them such as adding, subtracting, multiplication and division is a compulsory requirement. It is advisable to go through video tutorials on YouTube to acquire some insight on the above.

When it comes to representing integers, the following table is a really good reference on how to convert between binary, hex and decimal number systems for the first 16 digits.

Word length 

ARM device ship with either a 32bit or 64 bit ARM CPU. A 32 bit CPU processes 4 bytes of instruction blocks at a go, which makes up a word.  A 64 bit CPU on the other hand processes 8 bytes of  instruction blocks, at a go. In this case, the 8 bytes make up a word.  Remembering that 8 bits make 1 byte, it's easy to see how the bits that each CPU can  process, adds up to 32 and 64 respectively. 

32 bit CPU:
 0x01234567 ==> 0x67 = 1 byte (8 bits)
 0x01234567 ==> 0x01234567 = 4 bytes (32 bits)

64 bit CPU:
 0x0123456789ABCDEF ==> 0xEF = 1 byte (8 bits)
 0x0123456789ABCDEF ==>  0x0123456789ABCDEF  = 8 bytes (64 bits)

It's worth mentioning that the most significant bits are to the left and the least-significant bits are to the right. The most significant bit of a word for the ARM CPU, is located at bit 31, hence a carry is generated in the event an overflow occurs there. 

32 bit CPU:
 0x01234567 ==> 0x67 = least significant bits
 0x01234567 ==> 0x01 = most significant bits 

64 bit CPU:
 0x0123456789ABCDEF ==> 0xEF = least significant bits
 0x0123456789ABCDEF ==>  0x01 = most significant bits 

The ARM processor sees memory in word blocks i.e. every 4 bytes. The memory address at the start of a word is known as the word boundary and it is divisible by 4. Here is a quick illustration:

32 bit CPU:
0x00000000 ==> word boundary 
0x00000004 ==> word 1
0x00000008 ==> word 2
0x0000000C ==> word 2
0x0000000F ==> word 4

64 bit CPU:
0x0000000000000000 ==> word boundary 
0x0000000000000008 ==> word1
0x0000000000000010 ==> word2
0x0000000000000018 ==> word3
0x0000000000000020 ==> word4

The number of bytes in a word, vary from architecture to architecture. Some examples of ARM architectures are ARM v4, ARM v5, ARM v6, ARM v7-A. ARM v7-R and ARM v7-M. So it is always a good idea to keep in mind the architecture you are dealing with because instructions could vary in length. Understanding how the processor fetches and executes instructions is a very important concept in reverse engineering. 

ARM CPU instruction sets

ARM CPU Processors operate in 3 states i.e. ARM, thumb or thumb-2. ARM instructions are 32 bits long, thumb instructions are 16 bits long, while thumb-2 instructions on the other hand are 32 bits long. Thumb is a subset of ARM, hence not all the instructions in ARM are available in thumb. Thumb-2 is a super set of thumb with more instructions. Thumb-2 in essence, is a combination of 16 bit and 32 bit instructions. 

Modern processors can execute operations using either 16 bit thumb, 32 bit thumb-2 or 32bit ARM instructions. Processors can switch between ARM and thumb states, in order to optimize execution and processing especially so for embedded devices. A section of code can be compiled as either ARM or thumb. When compiling code in C or C++ you can set compiler options to assist in the use of these states. 

ARM Registers

A Register is the smallest and most fundamental storage area on a chip. The ARM processor provides 13 general purpose registers from R0-R12. Each register can store 32 bits of data. There are also 3 special purpose registers i.e. R13-R15 and the CPSR register. It's worth mentioning that the first four arguments of a function are stored in registers R0-R3 as per the specifications of the ARM function calling convention.

A majority of ARM chips work as a load and store machine. This is where a register is loaded with contents of another register or memory location or a register stores contents of another register or memory location.

LDR instructions load a register with a value from memory while the STR instructions store a register value into memory.

ldr , r3, [r5] @ load r3 with the contents of the memory address in r5
str, r3, [r5]  @ store value of r3 into memory address in r5

Azeria made some really awesome register images shown below, especially the ARM vs x86 register comparison.You should definitely check out her site here for some great tutorials, challenges and download her pre-configured ARM lab. 





The Frame Pointer (R11) is used to track the current stack frame. This register points to local variables stored on the stack frame. It's also used as a base pointer to local variables on the stack.

The Intra Procedural Call Register (R12) may be used by a linker as a scratch register between a routine and any subroutine it calls. It can also be used within a routine to hold temporary values between subroutine calls.

The Stack Pointer (R13) holds the address of the stack in memory. It is commonly referred to the top of the stack. The stack grows downwards and increases by 4 bytes.The stack uses the Last In First Out (LIFO)  principle. When we push a value to the stack, it goes into the stack pointer and when it's popped off the stack, it removes the value from the stack and into a register of your choice. When the instruction pop{ r7} is executed, what happens is that you are taking the data on the stack and storing it into the r7 register. 


The Link Register (R14) is used to hold the return address for subroutines/function calls. Some instructions such as Branch with Link (BL), copies the next instruction to be executed from where the function was branching from, into the link register before performing the branch. Branch means moving to specific location of a program.  This allows the program to copy the link register back into the program counter.

This is how subroutines/functions are called and how they return and resume execution at the next instruction after the one that was called. Given that program execution is from top to bottom, line by line. The link register does not need to write to the stack, hence can save a lot of execution time with repeated calls to subroutine/functions. 

The Program Counter (R15) that is used to store the currently executing instruction. It is also used by the C library when calling functions in dynamically linked libraries. Their content may change at random e.g. when a function such as printf is called. In x86 the program counter stores the address of the next instruction to be executed.

In the event of a branch instruction, it contains the address the next instruction to be executed which is the address of the destination it is branching to. This register should be treated with care else an entire program can crash if manipulated incorrectly. When hacking or reverse engineering, inspecting the program counter is essential, as it can help you understand how functions are being executed and how the program flows. Being able to control it, can help you make a program run your own code. Hint! Hint! :D

The Current Program State Register (CPSR) stores information about the program and the results of the operation. This register has 32 bits and the first 4 most-significant bits are the condition flags. The remaining bits are used by the operating system. The CPSR also contains the current mode (USR/SVC) and state (ARM/Thumb) as illustrated in the image below. 


Whenever an instruction is completed, the CPSR is updated accordingly. If any of the above conditions occurs, the respective bit is set to 1. 


Some of the instructions that directly affect the CPSR are Compare (CMP) and Compare negative (CMN). CMP and CMN compare register values and update the condition flags on the result but do not place the result in any register. Below is in an example illustrates this:
CMP r1, r0 ==> translates to subtract r0 from r1 (r1-r0) and if the result is zero, the 30th bit is set to 1
CMN r1, r0 ==> translates to add r1 to r0 and if the result is negative, the 31st bit will be set to 1

It is worth mentioning that add (ADD) and subtract (SUB) operations do not update the CPSR but ADDS and SUBS update the respective CPSR flags . On the other hand BEQ which stands for Branch if Equal to Zero, means that if the zero flag was set, it branches to another function within the code.

Disclaimer: A majority of the images used in the blog are the property of Azeria and Azeria Labs. I am not affiliated to Azeria Labs in any way. I have used them in the blog as a point of reference. However, i do use her blog content to learn ARM assembly.

References:

Portable mobile app traffic analysis


One of the phases of mobile application pentesting is to analyze network traffic, usually in order to inspect the kind of data exchanged between the mobile app and the end point its connecting to. It can be used to identify insecure mobile app communication, potential mobile app or server side vulnerabilities, or even insecure mobile app or server-side configurations to name a few.  


Some background info...

There are two types of network traffic analysis approaches i.e. Passive analysis and Active analysis. Passive analysis is where traffic is collected and analyzed at a later point in time.  Its where you dump network packets usually in PCAP (Packet Capture) or PCAP-NG (Packet Capture - Next Generation Dump File) format and proceed analyze them using network protocol analysis tools such as wireshark

On the other hand Active analysis, is where network traffic is intercepted and the packets are modified on the fly before they are forwarded to the respective intended destination. Ideally, this is a network based MiTM (Man In The Middle) attack, some examples of the such modifications that could be performed are injecting scripts into web pages, packet injection, media replacement. spoofing etc This can be done using tools such as Bettercap/Bettercap-ng, MITMf, Charles proxy, Burp Suite etc 

My network analysis setup...

On this blog post, i will focus on passive analysis, however, in the near future i will look into an active network analysis setup. My goal was to monitor mobile network traffic from any specific app of interest. This means that i need an access point to provide internet access, the device that the app resides on, a tactic to capture/dump network packets and lastly the ability to analyze the packets in near real-time or passively. 

I also needed the setup to be easy to install, configure, highly portable, such that i can easily setup and analyze the network traffic of any app of interest at a moments notice, and can work anywhere that i have access to my laptop.  

The network packet capture and analysis setup that i came up with, is as shown below. It might look a little complicated but it really isn't, as i shall illustrate its components and how to replicate it. I took a couple of tries to get it right, especially piping out the network traffic from the hotspot as well as analyzing the packet in real-time but it was definitely worth the effort. You tend to learn a lot more from setup failures. 


The setup is very far from perfect, but it gets the job done. There are a few changes i will definitely make to the setup. Any suggestions are welcome. I will now head over to illustrate how to replicate the above setup for your own passive network traffic monitoring or in real-time. 


Choosing an access point...

I started with trying to figure out the kind of access point to use. My first thought was an external USB Wireless adapter such as the TP-LINK WN722N or the ALFA Networks AWUS036 variant either the NEH, NHA or NH adapters.  I did some digging online on setting up access points using USB adapters and the process seemed a bit tedious and time consuming to get up and running on a linux machine.

 I also considered a portable WiFi Router such as the TL-MR3020 flashed with OpenWRT. Flashing the WiFi router seemed like a good alternative however, i will need a power source for the router. So that won't work for me as well. I eventually settled on creating an access point on my rooted nexus 5 android device and used it as a hotspot. The android device used to create the hotspot must be rooted, so that you are able to dump network packets from the created hotspot’s interface.

Pro tip: It's wise to disable any automatic app updates on the device that will connect to the access point (the device running the app you are pentesting). This will also definitely include temporarily disabling any app updates over WiFi, so as to conserve your mobile data. 


Setting up the analysis station...

One thing i knew from the get go, is that i needed a suitable virtual machine with a wide variety of network analysis tools, to dissect the packets i will be collecting. What better distro to use other than Security Onion. It ships with a ton of network analysis tools at your disposal. All i needed to do is install it on VirtualBox using the ISO available on their github page here. Be sure to install the Virtualbox extension pack on Virtualbox.

I needed the following Virtual Machine network configurations setup before starting the Security Onion installation process.
  • Adapter 1 - Internal network (monitor interface)
  • Adapter 2 - Bridged (management interface)
  • Adapter 3 - NAT (internet access)
How to install Security Onion is beyond the scope of this blog post, there are a couple of videos by Doug Burks on his YouTube channel showing how to go about it, alongside other neat videos on the variety of tools it ships with. A very important step while running the Security Onion setup, is to ensure the network interfaces are configured as indicated below.
  • eth0 - sniffing (monitor) interface
  • eth1 - management interface
  • eth2 - internet access interface
Once Security Onion was fully installed and the network interfaces properly setup. I needed a way to send network packets from the access point to the Security Onion VM for analysis. I decided to do this via the android USB cable. So i needed to enable a USB device filter for the Security Onion VM via the settings, so that when i connect the USB cable to the device and laptop (host machine), it would connect directly to the VM as opposed to the laptop (host machine). You may need to go to Devices > USB on the Security Onion virtualbox instance menu, to select the specific device after plugin in the USB cable.

Pro tip: Be sure to use a reliable and genuine USB cable that can consistently transmit data and current. Some android USB cables, mostly 3rd party ones, tend to only pass current used to charge the device but cannot transmit data reliably, which is a requirement for adb to work properly between the device and the VM. 

To ensure the device can send packets to the Security Onion VM, i decided to reverse port forward a specified port that the access point will be sending traffic to. So that on the Security Onion VM, i can listen for packets on the same port. The communication channel sending the packets between the access point and the laptop would be via the USB cable, that was setup earlier. So i had to be careful it doesn't unplug while the hotspot was active.

The newer android debug bridge(adb) binary has the capability to implement reverse port forwarding using the command "adb reverse <local> <remote>" This is the logical opposite of 'adb forward', i.e. the ability to reverse network connections from the device to the host. in this case, <local> corresponds to the socket on the device and <remote> corresponds to the socket on the host.

The Security Onion package repository has a very old version of adb that does not support reverse port forwarding, so i needed to download the standalone Android SDK Platform-Tools. It contains the most recent version of adb alongside other useful binaries such as fastboot. To run adb, all you need to do is unzip the file, change directory into the folder, make the binary executable if need be and then execute it.

To setup the reverse port forwarding from the access point to the security onion VM, you run the following command inside the Security Onion VM:
  • ./adb reverse tcp:1337 tcp:1337 
I also needed to setup the Security Onion VM to listen to the port specified above, and then pipe out network packets to the tool i wish to inspect the packets with. I started of with tshark for the test run, using this command:
  • nc -l -v -s 127.0.0.1 -p 1337 | tshark -i -
You can also forward incoming packets to either wireshark or tcpreplay at interface eth0 so that you can utilize tools such a Bro IDS to parse them. Here are the sample commands to use:
  • nc -l -v -s 127.0.0.1 -p 1337 | wireshark -k -S -i -
  • nc -l -v -s 127.0.0.1 -p 1337 | tcpreplay -i eth0 -


Getting some network packets...

I needed a target device where my app of interest resides. This means the ability to dump the network packets for my app of interest and forward them to the Security Onion VM for analysis. In this case, i had two options, either to dump the packets on the device itself using a packet capture app or directly from the access point. Both these options had their benefits and drawbacks. i'll start with the option of capturing packets on the device running my app of interest. 

Option 1: 

The SSL packet capture app for android is pretty neat. It sets up a VPN to capture network packets from the device. It also allows you to capture packets from the device itself or from a specific app of interest. This option is great when pentesting a specific app or a specific set of apps on the device. Since the app installs a user security certificate, the device will give a notification prompt that "Network may be monitored by an unknown third party". This is because by default the device only trusts system security certificates, so this should not worry you.

I did tests on some banking, payment and social media apps just to get a feel of the kind of data i would get. I got a mix of encrypted and unencrypted traffic on the payment and banking apps. Including some great info as to the URLs where data is sent and retrieved from. Including some insight of the server side directory structure.  Not to mention being able to see the structure of the soap request. On one app, i could even see the raw data being fetched from an enterprise cloud server alongside the API key for my requests. Here are some screenshots of the packets captured from some of the messaging apps i ran some tests on.

Whatapp screenshots


Telegram screenshots


 

Viber screenshots

 




On a particular social media app, it was interesting to note that i could send and receive chats but sending or receiving media was not successful because the app was doing some sort of certificate validation before facilitating any media requests. It was kind of weird for the app to do the certificate validation on media only and not on chats, which are also equally important.

The downside of this  approach is that a number of client side mitigation can be setup within the app to ensure that either the device does not communicate with the end point provided that the VPN is up and running or if the packet capture app is trying to dump packets.

I came across Net Monitor (Privacy Friendly) that shows active network activity of installed apps on the mobile device. It provides connection information which includes local and remote socket information along with resolved hostnames and a protocol evaluation based on well-known ports. Known unencrypted and encrypted protocols are automatically marked. A detailed mode offers additional technical information of the connections. This is as per the app's description. I liked the fact that the app is privacy focused, so minimal permissions, no ads, no tracking and data collection from the device.

Whatapp screenshots

Telegram screenshots

Viber screenshots


Both these apps provide the ability to see which IP addresses the app is communicating with, alongside the protocol and even the encryption status, where applicable. It also makes it much easier to later analyze the collected packets as they are app specific. As you can filter the packets based on the desired destination IP addresses.

Option 2: 

A better alternative is dumping network packet is at the access point. The advantage of this approach is that the application will communicate with the end point as it normally would. Given that at this stage you are only mirroring off the packets passing through the access point. The disadvantage is that you will be dumping all the packets from the device the app is running. You will have to analyze the pcaps and focus on packets to and from the end points of interest. This means that you will need to find a way of identifying IP addresses of the end point the app of interest in communicating with, beforehand or on the fly.

Provided that i am using a rooted nexus 5 as my access point, all i needed to do is, get shell access the device via the android debug bridge(adb) and determine the interface responsible for the WiFi hotspot. First you need to enable the WiFi hostspot under the device settings menu and then proceed to look for the interface using the netcfg or the ifconfig command via the adb shell. The IP address of the access point is usually 192.168.43.1/24 and the corresponding interface name will be either ap0 or wlan0.

In order to capture packets from the nexus device, we will need both the tcpdump and busybox binaries. The tcpdump binary for android can be obtained here and the busybox binaries can be obtained from here or installed via the play store. Its important to validate which arm version of the busybox binary works on the respective device you will use as an access point.

To prepare the access point setup, simply install busybox or use the binary provided above. Copy tcpdump to the device at /data/local/tmp (this is the default temp folder in android).
  • adb push tcpdump /data/local/tmp
  • adb  shell "chmod  777  /data/local/tmp/tcpdump
  • adb push busybox-armvxx /data/local/tmp
  • adb  shell "chmod  777  /data/local/tmp/busybox-armvxx
Once this is done, i can now dump network packets from my hotspot interface and proceed to pipe it out to netcat using the command below:
  • adb shell
  • cd /data/local/tmp/
  • su
  • ./tcpdump -i wlan0 -s0 -w - | ./busybox-armvxx nc 127.0.0.1 1337 
If you installed busybox from the play store, use this command instead. 
  • ./tcpdump -i wlan0 -s0 -w - | nc 127.0.0.1 1337
If all went well, you should see come packets on the Security Onion VM, either on the terminal via tshark or on wireshark. If you use tcprelay you can view the raw bro logs that have been generated or simply use the Kibana dashboard.

I'll definitely write a follow up blog post on how to slice and dice the network packet collected using this setup, and maybe even give an overview on my tools of trade and how i utilize them in mobile app penetration tests.

A huge shout-out to Ruby for her invaluable assistance in writing this blog post, validating the research findings as well as providing some great pointers on designing the packet analysis architecture.

References


Mounting an encrypted hard disk (LUKS) using Kali Linux live USB


Problem Statement 

My sister attempted to upgrade her laptop from Ubuntu 14.04 to 16.04. During the upgrade, there was a prompt that requested for a new encryption password setup. Of which she obliged and continued with the upgrade. All went well, until she rebooted the laptop. The grub menu loads up, then gets stuck on loading the kernel. Any Linux user knows that, if this happens, you either messed up badly of something went terribly wrong. In this case, unfortunately, the upgrade broke ☹.
The laptop was fully encrypted and contained tons of invaluable data both my sister’s and mine, which we both couldn't afford to lose. In terms of backup, the data was not fully backed up, i only had bits and pieces of my data that i really needed regularly, on an external hard drive. So basically, we both didn’t have a full or incremental data backup.
Now back to the problem. At this point, the laptop seems inaccessible with data that we both would like to gain access to. So, what now?? Let's see how i worked around this, to regain access to the encrypted hard drive and the data.
Disclaimer: Some of the images on the blog might not be as clear, please bear with me. My phone doesn't have the best of cameras.

Fact Finding

Now it was time to try and figure out how bad the situation really is. I boot up the machine and the grub menu loads up the grub menu. By default, the operating system will boot into the first option after a few seconds, if you don't select any of the other two options.
C:\Users\xtian\AppData\Local\Microsoft\Windows\INetCache\Content.Word\grub.jpg
It then proceeds to this screen and gets stuck trying to load the kernel 4.4.0-83-generic, as mentioned earlier. The cursor stays there for a very long time, which shouldn't be the case. 
C:\Users\xtian\AppData\Local\Microsoft\Windows\INetCache\Content.Word\boot_3.jpg

At this point, I couldn't do much, so I reboot the laptop by pressing down the power button. This is the only way I could turn off the laptop. It usually feels like this.
This time, I decide to select Advanced options for Ubuntu to see what options are available.

These are the options available under that section.
C:\Users\xtian\AppData\Local\Microsoft\Windows\INetCache\Content.Word\grub_3.jpg
Now this is good news. There are two kernels available i.e. 4.4.0-83-generic and 3.13.0-123-generic.  This is great, because I can select the other kernel and hope that Ubuntu can load into it and initiate the rest of the boot process.

I select Ubuntu, with Linux 3.13.0-123-generic and it successfully loads the kernel and boots up till the point it asks for the password to decrypt the hard drive. 
C:\Users\xtian\AppData\Local\Microsoft\Windows\INetCache\Content.Word\boot_5.jpg

Now this is where things get interesting. I enter the new password that my sister set up and it constantly failed. I honestly tried the password so many times, at one point I even thought maybe the keyboard local settings might have even changed. At one point, I was even trying the old password, just in case the upgrade had not altered it yet. Some wishful thinking but still no luck.

At this point, I figured, maybe I could try boot up using a Live USB running Linux, and try mount the hard drive again from the live USB. I decided to use Kali Linux as the distribution of choice. You can download Kali Linux here.

In order to make the flash disk bootable, I used unetbootin, which can be downloaded here. I prefer unetbootin as it's very reliable and someone rarely has any issues with the Linux OS refusing to boot up from the USB drive. I highly recommend using it to create Live USB drives. 

To create a bootable Kali Linux USB drive, simply download the Kali Linux ISO file of your choice and unetbootin for your respective distribution from the links above. After downloading unetbootin, execute it and select the Disk Image option, the ISO you downloaded and confirm that you have selected the correct flash drive. Below is a screenshot of unetbootin on my setup, running on a windows laptop. Your mileage may vary on Linux and Mac. Click OK, sit back and let unetbootin do its thing. It should be done in a few minutes.
Before booting the Live USB, you will need to edit your BIOS options to boot from USB drive. On the HP Envy, hitting F10 as the laptop just boots up, gives you access to the menu below.
I hit F10 to get to get the BIOS setup screen, shown below. I played around with both the EUFI and legacy boot order.
After selecting the desired boot option and setting the USB drive as the first device in the boot order, you should be good to go, once you save the changes.
I had lots of trouble getting the laptop to boot from the USB in EUFI boot mode. It would not detect the USB drive, when selecting the device to boot from but it eventually worked when I re-enabled secure boot and disabled legacy boot. The legacy boot mode, worked just fine.
To get into the Boot Device menu, press F9 as the laptop boots up, after saving the changes above. You should see the several devices you can boot from, as shown below.

I selected the USB Hard drive option and the laptop successfully booted from the flash drive into the unetbootin menu screen below.
I selected the Live USB Encrypted Persistence option and it the kernel was successfully loaded from the USB drive and the boot initialization started. 
At this point, I entered the original encryption and it accepted it, yaaaay! 😊 Then the kali desktop showed up soon after. 
I opened the terminal to check if the hard drive and its partitions are recognised, using the fdisk command. 
The partition of interest is /dev/sda3. I then mounted the encrypted drive, using the commands below.
  • Install the necessary requisite tools
    • apt-get install lvm2 cryptsetup
  • Create directory to mount the drive to
    • mkdir /media/test
  • Load the dm-crypt kernel module
    • modprobe dm-crypt
  • Open the partition using cryptsetup and enter the encryption password
    • cryptsetup luksOpen /dev/sda3 test
  • Activate all volume groups available
    • vgchange -ay
  • Mount the partition to the directory created earlier
    • mount /dev/ubuntu-vg/root /media/test
  • Access the hard drive on the mounted location
    • cd /media/test
The screenshot below highlights the output of the commands above.
Now I had full access to the encrypted hard drive partition 😊. I then backed up all the necessary data on my external hard drive and formatted the laptop with an up to date Linux distro, and copied the required data back to the laptop.

Lessons Learnt

  • Always keep an updated backup of your data. This goes without say. It's basically the first unwritten rule of computing.
  • Keep within reach a live USB flash drive running Linux. You can never know when it can come in handy
  • Never forget your encryption password, EVER. If you ever do, it's basically GAME OVER.
  • Don't be too quick to format your machine, there would just be a way to get access your data, that you haven't thought about.

References