\addtocontents{toc}{\protect\vspace{\beforebibskip}} % Place slightly below the rest of the document content in the table

%************************************************
\chapter{Autopsy}
\label{ch:autopsy}
%************************************************

\begin{justify}
In this chapter, we briefly review the Autopsy digital forensic software, focusing on its main characteristics. The second half of the chapter details on one of our contribution to Autopsy: creation of an up-to-date package of Autopsy, so that it can be easily installed on Arch Linux and Debian, both Linux distributions.
\end{justify}

\section{The software}

\begin{justify}
Autopsy is an easy-to-use, \gls{gui}-based suite of software that allows efficient analysis on hard drives and smartphones. It has a plugin architecture that can be extended with add-on Java or Jython-based modules. Autopsy resorts to The Sleuth Kit Library\footnote{\url{http://sleuthkit.org/sleuthkit/}} to access different types of file formats and file systems to extract data from storage. The Sleuth Kit is a collection of command-line tools and a C library that allows analysis of disk images and recovery of deleted files \parencite{TheSleuthKit}.
\end{justify}

\section{Design}
\begin{justify}
This digital forensics software follows in its design some key aspects:

\begin{itemize}
    \item \textbf{Easy-to-use:} this software was designed to be intuitive. Wizards and navigation techniques help the user with everything he/she needs by making it easier to replicate steps without unnecessary reconfiguration \parencite{WikipediaAutopsy}. It tries to automate as much as possible, not only to facilitate its usage but to reduce the number of human errors that might occur otherwise \parencite{AutopsyIntuitive}.
    
    \item \textbf{Extensible:} one of the most important features is its plugin architecture. With this, any user can extend its capabilities by adding new functionality through non-native modules \parencite{WikipediaAutopsy}. Third-party add-ons can be found in the official Module Github repository of Autopsy\footnote{\url{https://github.com/sleuthkit/autopsy_addon_modules}}. Users can also create their add-on modules\footnote{\url{http://www.sleuthkit.org/autopsy/docs/api-docs/}}. Writing a custom module from scratch can lead to multiple advantages, even if a module that does the same already exists. This is because the user has the freedom to mold their creation the way it fits them better.
   
    \item \textbf{Fast:} a single device to analyse can hold many gigabytes of data. To be productive, the forensic practitioner must analyze the most amount of data in the least amount of time. Autopsy accomplishes this by running its tasks in parallel using multiple cores (except \path{sqlite3} modules because they do not support concurrency), hence shortening the time needed to analyze a drive's data. Although it might still take, in extreme cases, hours to finalize the analysis, the researcher does not have to wait that much time to start getting results. This is because Autopsy provides results in real-time as soon as they are found \parencite{AutopsyFast}.
\end{itemize}
\end{justify}

\begin{figure}[H]
 \centering
 \includegraphics[width=\linewidth]{imgs/AutopsyStartupScreenshot}
 \caption{Autopsy startup screenshot}
 \label{fig:AutopsyStartupScreenshot}
\end{figure}

\section{Features}

\begin{justify}
A great tool must have significant features that make it worth spending time learning and using it. Some of the features of Autopsy include the ability to collaborate with multiple forensic scientists in a large case, the capacity to analyze various format types, and an extensible report infrastructure. Collaborating with other researchers helps to spread the workload of a task making it more manageable to perform. Having a team working on a big case also ensures reliability on the outcome, as multiple examiners are looking for information and double-checking coworkers. Not only does the task get done a lot quicker, but it also becomes more trustworthy and less error-prone. Autopsy is capable of reading disk images, local drives, or a folder with local files. Different alternatives like these improve the usefulness of the software, as users stop feeling restrained to a single choice.
\end{justify}

\begin{justify}
Although Autopsy also has graphical interfaces that display timeline analysis, it also provides a way to bind a custom report. By default \gls{html}, \gls{xls}, and Body file reports are available and are configurable to display the information the user deems more valuable. The investigator is allowed to generate multiple reports at a time. The report functionality can be extended by adding special-purpose report modules. Likewise ingest modules, report modules can be coded in Java and Jython programming languages. This way, Autopsy can be customized according to the needs of the forensic practitioners \parencite{AutopsyFeatures}.
\end{justify}

\begin{figure}[H]
 \centering
 \includegraphics[width=\linewidth]{imgs/AutopsyReportsMenu}
 \caption{Autopsy interface to generate custom reports}
 \label{fig:AutopsyReportsMenu}
\end{figure}

\section{Linux package}

\begin{justify}
One of our goals was to have our GBoard4A software available for multiple OSes, namely Windows 10 and Linux, and to run under the latest versions of Autopsy. Also, we found out that Autopsy packages for the two Linux distributions we used for development (Arch Linux and Debian) were not up-to-date, severely lagging behind Autopsy current version (4.18). One solution was manually building Autopsy on every new release. Although this was a valid answer, it is only a short-term solution that would not help future developers and users. We wanted to maximize the limited time we had to develop this project by making every decision count.
\end{justify}

\begin{justify}
We decided to create a package with the latest version of Autopsy and a packager that generates packages for Arch Linux and Debian automatically. A package facilitates the groundwork required to have a workable Autopsy. The user simply needs its package manager to install the prebuilt package in its system.
\end{justify}

\subsection{Arch Linux}

\begin{justify}
We had experience with packaging for Arch Linux distributions, so creating a package for Arch Linux was straightforward. The package is in the official \gls{aur} and is named \path{autopsy-bin}\footnote{\url{https://aur.archlinux.org/packages/autopsy-bin/}}. Alternatively, the \path{autopsy} package\footnote{\url{https://aur.archlinux.org/packages/autopsy/}}, also stored in the \gls{aur}, can be installed.
\end{justify}

\subsection{Debian}

\begin{justify}
For Debian, we had to opt for a different approach. Debian packages are a bit more complex than Arch Linux, in our eyes, and we wanted to ensure everything was well executed and portable. Initially, we explored the documentation of Debian packages and how they are configured and organized \parencite{DebianPackaging}. The thought process was to create packages for both Arch Linux and Debian distributions and leave a well-document article in the LabCIF organization explaining how they work. This ensured that anyone could utilize the package and update it if needed. However, the structure of Debian packages quickly pushed us away from that path, and we decided to go with a tool to do it for us.
\end{justify}

\subsubsection{FPM}

\begin{justify}
By using an extern tool we assured the package was always going to be created correctly and future updates by different investigators would not mess up the package structure. FPM is a command-line program design to help building packages. With this program creating platform-native packages is simple, more trustworthy, and more reliable. It can generate a package for a distribution based on another package from a different one and tweak existing packages \parencite{GitHubFPM}. A usage example of FPM can be seen in figure \ref{listing:FPM usage}.
\end{justify}

\begin{listing}[H]
\begin{textcode}
fpm -s <source_type> -t <target_type> [list of sources]…
\end{textcode}
\caption{Building a package using FPM}
\label{listing:FPM usage}
\end{listing}

\begin{justify}
The \path{source_type} field is where the package is coming from. A directory \textit{(dir)}, a Rubygem \textit{(gem)}, an \gls{rpm} \textit{(rpm)}, a Python package \textit{(python)}, and a \gls{php} pear module \textit{(php)} are examples of source types. The \path{target_type} field defines the output package form. Some common examples are \gls{rpm} \textit{(rpm)} and Debian \textit{(deb)} \parencite{DocumentationFPM}.
\end{justify}

\begin{justify}
A real-world example is in the examples folder of the FPM GitHub repository \parencite{JRubyFPM}. Below, we can analyze the showcased Makefile \ref{listing:FPM jruby package} that creates the jruby package:
\end{justify}

\begin{listing}[H]
\begin{minted}[
    frame=lines,
    framesep=2mm,
    fontsize=\scriptsize,
    fontfamily=courier,
    linenos=true,
    breaklines=true,
    breakanywhere=true,
]{bash}
NAME=jruby
VERSION=1.6.1
DOWNLOAD=http://jruby.org.s3.amazonaws.com/downloads/$(VERSION)/$(TARBALL)
TARBALL=$(NAME)-bin-$(VERSION).tar.gz
TARDIR=$(NAME)-$(VERSION)

PREFIX=/opt/jruby

.PHONY: default
default: deb
package: deb

.PHONY: clean
clean:
	rm -f $(NAME)-* $(NAME)_* || true
	rm -fr $(TARDIR) || true
	rm -f *.deb
	rm -f *.rpm

$(TARBALL):
	wget "$(DOWNLOAD)"

$(TARDIR): $(TARBALL)
	tar -zxf $(TARBALL)

.PHONY: deb
deb: $(TARDIR)
	fpm -s dir -t deb -v $(VERSION) -n $(NAME) -d "sun-java6-bin (>> 0)" \
	    -a all -d "sun-java6-jre (>> 0)" --prefix $(PREFIX) -C $(TARDIR) .

.PHONY: rpm
rpm: $(TARDIR)
	fpm -s dir -t rpm -v $(VERSION) -n $(NAME) -d "jdk >= 1.6.0" \
	    -a all --prefix $(PREFIX) -C $(TARDIR) .

\end{minted}
\caption{Package creation using FPM}
\label{listing:FPM jruby package}
\end{listing}
 
\begin{justify}
To understand what the previous Makefile does, we need to look at the \path{name}, \path{version}, \path{download}, and \path{deb} fields. Starting from top to bottom, we first declare the \path{name} and \path{version} fields which are self-explanatory. Next, we define the \gls{url} that indicates the package version of jruby to download. This \gls{url} will download a \path{tar.gz} \path{tarball} containing the binary file needed for the package creation. Jumping to the \path{deb} section in line 26 is where the command-line expression for the Debian package creation is defined. The most important fields in this command are the same specified in the example above \ref{listing:FPM usage}. The \path{source_type} is a directory located at \path{jruby-1.6.1}, and the \path{target_type} is a Debian package. The following arguments define the dependencies needed and where the installation is going to take place. Running the command bellow should now generate the Debian package.
\end{justify}

\begin{textcode}
make package
\end{textcode}
 
\begin{justify}
Now it can be installed using the dpkg tool.
\end{justify}

\begin{textcode}
sudo dpkg -i jruby-1.6.0.RC2-1.all.deb
\end{textcode}

\begin{justify}
Just like that, FPM created a package for JRuby with a pretty intuitive configuration.
\end{justify}

\begin{listing}[H]
\begin{textcode}
% /opt/jruby/bin/jirb
>> require "java"
=> true
>> java.lang.System.out.println("Hello")
Hello
=> nil
\end{textcode}
\caption{JRuby installed using FPM running example}
\end{listing}

\subsection{Packager}

\begin{justify}
Now that we had a clear vision of the solution we wanted to go for, we needed to think about the next step. We could create the packages manually and updating them as needed, but this would not make it easier for future users. We wanted a solution that allowed updating the packages and making them available at the same time.
\end{justify}

\subsubsection{GitHub Actions}

\begin{justify}
The choice was to make use of GitHub Workflows and GitHub Actions. GitHub Actions helps to automate tasks within the software life cycle. GitHub Actions are event-driven, which means that a series of commands are executed after a trigger. GitHub Workflows are automated procedures that are added to a repository. A Workflow has one or more jobs that can be scheduled or triggered by an event \parencite{GithubActionsIntro}. We used GitHub Workflows as a \gls{ci} to build the Arch and Debian packages. The \gls{ci} configuration is a \gls{yaml} file, which makes it very intuitive to work with. When the \gls{ci} runs, it builds both packages and when done, releases them as artifacts. These packages are downloadable, but each is only available for 90 days. Users should not rely on the artifacts built by the \gls{ci} as they have an expiration time, and instead, they should go to the releases and pick the version they want to use.
\end{justify}

\subsubsection{Configuration}

\begin{justify}
\gls{yaml} is a human-readable data-serialization language. It is commonly used for configuration files and in applications where data is being stored or transmitted \parencite{YAML}. Listing \ref{listings:PackagerArchJob} shows a small portion of the \gls{ci} configuration\footnote{\url{https://github.com/labcif/autopsy-packager/blob/main/.github/workflows/packaging.yml}}.
\end{justify}

\begin{listing}[H]
\begin{yamlcode}
jobs:
  arch-packages:
    runs-on: ubuntu-latest
    container:
      image: archlinux
      options: --privileged # Needed for building in clean chroot
      volumes:
        - /sys/fs/cgroup:/sys/fs/cgroup # systemd nspawn needs cgroups
    steps:
      - name: Install required dependencies
        run: |
          pacman -Syu --noconfirm
          pacman -S git --noconfirm --needed --noprogressbar
      - name: Clone sleuthkit-java build repo from AUR
        run: |
          git clone https://aur.archlinux.org/sleuthkit-java.git $HOME/sleuthkit-java
          (cd $HOME/sleuthkit-java; git checkout $PACKAGE_SLEUTHKIT_JAVA_SHA)
      - name: Build sleuthkit-java
        uses: FFY00/build-arch-package@v1
        with:
          PKGBUILD: $HOME/sleuthkit-java/PKGBUILD
          OUTDIR: /tmp/artifacts
      - uses: actions/upload-artifact@v2
        with:
          name: arch-packages
          path: /tmp/artifacts/*.pkg.tar.zst
      - name: Clone autopsy-bin build repo from AUR
        run: |
          git clone https://aur.archlinux.org/autopsy-bin.git $HOME/autopsy-bin
          (cd $HOME/autopsy-bin; git checkout $PACKAGE_AUTOPSY_BIN_SHA)
      - name: Build autopsy-bin
        run: |
          chown user -R $HOME/autopsy-bin
          cd $HOME/autopsy-bin
          extra-x86_64-build -- -U user -I "$(find "/tmp/artifacts" -name 'sleuthkit-java-*.pkg.tar.zst')"
          mv *.pkg.* /tmp/artifacts
      - uses: actions/upload-artifact@v2
        with:
          name: arch-packages
          path: /tmp/artifacts/*.pkg.tar.zst
\end{yamlcode}
\caption{Packager - arch-packages job}
\label{listings:PackagerArchJob}
\end{listing}

\begin{justify}
The syntax of a \gls{yaml} file is pretty intuitive. In this sample, we can see the job of the \path{arch-packages}. The software image is defined, and then the steps are executed accordingly. The configuration file is structured to be scalable. If in the future an extra distribution is needed, then it can be added with another job.
\end{justify}

\subsubsection{Arch package}

\begin{justify}
The Arch Linux package generated by the \gls{ci} bases itself on the \path{autopsy-bin} \gls{aur} package. As shown in Listing \ref{listings:PackagerArchBuild}, the step execution clones the autopsy-bin package and builds it manually. This is the same process as installing the package locally using an \gls{aur} helper.
\end{justify}

\begin{listing}[H]
\begin{yamlcode}
- name: Clone autopsy-bin build repo from AUR
run: |
    git clone https://aur.archlinux.org/autopsy-bin.git $HOME/autopsy-bin
    (cd $HOME/autopsy-bin; git checkout $PACKAGE_AUTOPSY_BIN_SHA)
- name: Build autopsy-bin
run: |
    chown user -R $HOME/autopsy-bin
    cd $HOME/autopsy-bin
    extra-x86_64-build -- -U user -I "$(find "/tmp/artifacts" -name         'sleuthkit-java-*.pkg.tar.zst')"
    mv *.pkg.* /tmp/artifacts
\end{yamlcode}
\caption{Packager - Arch package build}
\label{listings:PackagerArchBuild}
\end{listing}

\subsubsection{Debian package}

\begin{justify}
As previously stated, the Debian package is generated using FPM. To keep the complexity much shorter, FPM supports receiving a package as its \path{source_type}. Our implementation uses this feature. GitHub Workflows allows having a job depending on another. This means we can have the Debian job depending on the Arch job, allowing the Arch package to be built first. Then in the Debian job, we can utilize that package to generate the other as seen in Listing \ref{listings:PackagerDebianBuild}.
\end{justify}

\begin{listing}[H]
\begin{yamlcode}
- name: Install Dependencies
run: |
    apt-get update -y
    apt-get install -y --no-install-recommends build-essential rubygems ruby ruby-dev curl git zstd locales
    sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen
    dpkg-reconfigure --frontend=noninteractive locales
    update-locale LANG=en_US.UTF-8
    gem install --no-document fpm
    fpm -t deb \
        -n "autopsy" \
        -v "${PACKAGE_AUTOPSY_BIN_VERSION}" \
        --iteration "$PACKAGE_SLEUTHKIT_JAVA_REL" \
        --no-auto-depends \
        -d "openjdk-8-jre" \
        -d "sleuthkit-java (>= ${PACKAGE_SLEUTHKIT_JAVA_VERSION})" \
        -d "testdisk" \
        -d "openjfx" \
        -a amd64 \
        -s pacman autopsy-bin-${PACKAGE_AUTOPSY_BIN_VERSION}-${PACKAGE_A    UTOPSY_BIN_REL}-x86_64.pkg.tar.zst
    mkdir -p /tmp/artifacts
    mv *.deb /tmp/artifacts

\end{yamlcode}
\caption{Packager - Debian package build}
\label{listings:PackagerDebianBuild}
\end{listing}

\subsubsection{Artifacts}

\begin{justify}
The built packages are then made available as artifacts in the Github Actions tab. Every time the \gls{ci} runs, it outputs new artifacts with the current version in the configuration file. This means that if different runs can provide identical package versions. Artifacts are available for download if not expired, as stated above. Figure \ref{fig:PackagerCIRuns} shows all packaging workflow runs. The most recent run is at the top of the list.
\end{justify}

\begin{figure}[H]
 \centering
 \includegraphics[width=\linewidth]{imgs/PackagerWorkflowsRuns.png}
 \caption{Packager CI runs}
 \label{fig:PackagerCIRuns}
\end{figure}

\begin{justify}
The latest run contains the information shown in Figure \ref{fig:PackagerLatestRuns} below. On this page,  users can analyze the logging of the selected \gls{ci} run. The displayed information is very straightforward. On the left, we can see the jobs ran, and in the middle, the order they executed. The \path{arch-packages} job ran first, and the \path{build-run} ran last. This information follows the \gls{ci} configuration analyzed above. Clicking on each, we can explore step by step how the execution performed. Each step contains a log detailing every command and action made.
\end{justify}

\begin{figure}[H]
 \centering
 \includegraphics[width=\linewidth]{imgs/PackagerLatestRun.png}
 \caption{Packager CI runs}
 \label{fig:PackagerLatestRuns}
\end{figure}

\begin{justify}
Lastly, the artifacts are placed at the bottom. If they are not expired, they are available for download. Simply clicking on the package downloads it.
\end{justify}

\begin{figure}[H]
 \centering
 \includegraphics[width=\linewidth]{imgs/PackagerLatestArtifacts.png}
 \caption{Packager CI runs}
 \label{fig:PackagerLatestArtifacts}
\end{figure}

\subsubsection{Releases}

\begin{justify}
Although artifacts are a good way of getting the most updated package versions (according to the configuration file), they are not reliable. Exploring the releases separator should be the priority. In the releases menu, not only is potentially available the latest version but also previously released versions. For instance, if the version needed was 2 or 3 minor versions older and was available as a release, it could be downloaded and installed like any package. The release for version \path{4.18.0-1} is shown in Figure \ref{fig:PackagerReleases}.
\end{justify}

\begin{figure}[H]
 \centering
 \includegraphics[width=\linewidth]{imgs/PackagerReleases.png}
 \caption{Packager release 4.18.0-1}
 \label{fig:PackagerReleases}
\end{figure}

\begin{justify}
In this chapter, we dealt with Autopsy, a well-known digital forensic open source software. Specifically, we first reviewed the main characteristics of Autopsy, and then described our contribution in providing packages for an easy installation of Autopsy under Arch Linux and Debian distributions. For this purpose, we detailed the followed methodology and the needed GitHub configurations. In the next chapter, we present our GBoard4A software tool and its coupling Autopsy software modules. 
\end{justify}