Browse Source

Description for IMA finished, auditd missing

master
Michael Preisach 4 years ago
parent
commit
b40cfab8be
  1. 172
      thesis/04_implementation.tex
  2. BIN
      thesis/MAIN.pdf

172
thesis/04_implementation.tex

@ -89,15 +89,15 @@ Ubuntu installs Grub by default, and it is used as a fallback bootloader.
\section{Trusted Boot}
By default, every mainboard with support for TPM2.0 must support trusted boot.
When a TPM becomes available, the UEFI/BIOS itself takes all required measures until the boot process is handed over to the OS bootloader (e.g. GRUB).
Since Ubuntu uses GRUB 2.04 as bootloader which has TPM support by default, trusted boot just to be enabled in the GRUB configuration.
Since Ubuntu uses GRUB 2.04 as bootloader which has TPM support by default, trusted boot needs just to be enabled in the GRUB configuration.
In this case, GRUB will be measured from the BIOS to the PCRs 4 and 5, as shown in \autoref{tab:PCR}.
Grub itself uses PCR 8 for executed commands, the kernel command line and all commands forwarded to kernel modules.
PCR 9 is used to measure all files read by GRUB\cite{grub19}.
According to the documentation\cite{grub19}, Grub itself uses PCR 8 for executed commands, the kernel command line and all commands forwarded to kernel modules.
PCR 9 is used to measure all files read by GRUB.
Embedded systems like a productive version of the BS do not need several boot options.
Therefore we replace the bootloader EFI file with a blob containing all required information to load the kernel directly.
This kernel decrypts the disk and boots the remaining system.
Pawit Pornkitprasam \cite{pornkitprasan19-diskencryption}, \cite{pornkitprasan19-tpmtools} and Karl O from Tevora \cite{tevora-secureboot} introduced the concept of a \emph{Unified Kernel} for Ubuntu
Embedded systems like a productive version of the BS do not need several boot options, making Grub unnecessary.
Therefore we can replace Grub's bootloader EFI file with a blob containing all required information to load the kernel directly.
This kernel decrypts the disk and boots the remaining system autonomously.
Pawit Pornkitprasam \cite{pornkitprasan19-diskencryption}, \cite{pornkitprasan19-tpmtools} and the Tevora company \cite{tevora-secureboot} introduced the concept of a \emph{Unified Kernel} for Ubuntu
and Arch respectively.
This large EFI file contains the initramfs, kernel command line and the kernel itself.
@ -122,18 +122,42 @@ This large EFI file contains the initramfs, kernel command line and the kernel i
\end{table}
All binary resources are available as blobs which can be imported directly.
Only the command line parameters need to be defined manually.
The following shell scripts are tested on a Ubuntu 20.04 server minimal installation on all three devices.
These packages need to be installed beforehand on an Ubuntu minimal instance to run trusted boot:
\begin{enumerate}
Only the command line parameters need to be customized.
\subsection{Install and use Trusted Boot}
\label{ssec:install-and-use-trusted-boot}
The following shell scripts are available in the folder \texttt{trustedboot}.
They are tested on a Ubuntu 20.04 server minimal installation on all three devices.
These packages need to be installed beforehand on an Ubuntu minimal instance to install trusted boot:
\begin{itemize}
\item \texttt{binutils} for objcopy, generating unified kernel, and
\item \texttt{tpm2-tools} to interact with the onboard TPM,
\end{itemize}
Installing trused boot is done in three steps, assuming being root at the target system:
\begin{enumerate}
\item \emph{Execute \texttt{install.sh}}: It installs the shell scripts into \texttt{/usr/sbin} and adds a new random passphrase to LUKS. It furthermore adds TPM support to the initramfs and creates the unified kernel described above.
\item \emph{Reboot}: During reboot, the new PCR values are generated.
\item \emph{Execute \texttt{update-luks-tpm.sh}}: The new PCR values are used to seal the LUKS passphrase into the TPM.
\end{enumerate}
After finishing these steps, the system should be able to decrypt the FDE without user interaction and end up at the login prompt.
The automatic boot will now work as long as there are no updates affecting the unified kernel.
If a kernel update happens during upgrading the system, a new EFI blob must be generated and the TPM seal is to be renewed.
Similar to the installation procedure, this can be done in the following procedure:
\begin{enumerate}
\item \emph{Execute \texttt{update-kernel.sh}}: This includes the latest updates of kernel, its parameters and the initramfs into the EFI blob.
\item \emph{Reboot}: Again, the new PCR values need to be calculated.
\item \emph{Execute \texttt{update-luks-tpm.sh}}: Similar to the installation, the new seal is generated and replaces the old one.
\end{enumerate}
The result is a recent kernel with up-to-date configuration.
\subsection{Detailed description of the scripts}
\autoref{code:tbcommandlinetxt} shows the used command line which will be saved on \texttt{/boot/kernel-command-line.txt}.
The parameters activate also IMA which will be discussed later in this chapter.
\lstinputlisting[float,caption={\texttt{kernel-command-line.txt}: Command line for the Kernel}, label={code:tbcommandlinetxt}]{../../trustedboot/kernel-command-line.txt}
Relevant for trusted boot is the parameter where the root filesystem is located.
This example works for the default Ubuntu LVM on LUKS configuration.
The parameters activate also IMA which will be discussed later in this chapter.
If FDE is installed, the boot process need to be aware of how to decrypt the disk.
Therefore, the initramfs needs the luks binaries as well as the TPM software stack to unseal the passhrase with the PCR registers.
@ -141,14 +165,16 @@ The unseal operation itself is then done with \autoref{code:tbpassphrasesh}, whi
\lstinputlisting[float,language=bash, caption={\texttt{passphrase-from-tpm.sh}: Initramfs-script to ask the TPM for the LUKS key}, label={code:tbpassphrasesh}]{../../trustedboot/passphrase-from-tpm.sh}
We copy the script of \autoref{code:tbtpm2hooksh} to \texttt{/etc/initramfs-tools/hooks} to enable TPM access during boot after the next initramfs update.
\lstinputlisting[float,language=bash, caption={\texttt{tpm2-hook.sh}: Script copying required TSS files into the initramfs}, label={code:tbtpm2hooksh}]{../../trustedboot/tpm2-hook.sh}
Next, a new key for FDE is created by using the random number generator of the TPM.
Next, the script of \autoref{code:tbcreatelukssh} creates a new key for FDE by using the random number generator of the TPM.
It is saved in clear text in \texttt{/root/keys} to be able to update the sealing operation when new PCR values are used.
The passphrase needs to be available, when an update resulted in new PCR values.
In this case, the passphrase in the TPM would not be accessible anymore.
\autoref{code:tbcreatelukssh} shows the script for creating the LUKS passphrase.
When the new phrase is added to LUKS, the user is asked for an existing FDE password.
We keep the first password as backup when decryption via TPM fails.
Finally, \autoref{code:tbupdatekernelsh} shows how the unified kernel is created with the command \texttt{objcopy} and copied on the EFI disk partition.
Using a clear text password file in the \texttt{/root} directory is not per se considered insecure as the disk must be decrypted beforehand, meaning that the passphrase also exists unencrypted in memory.
Furthermore only root has access to the target directory.
The backup is needed for updating the system and when issues with the TPM appear.
When an updated kernel is booted, the seal cannot be opened anymore since the old PCR values cannot be restored anymore.
It is, of course possible to generate a new passphrase every time when the PCR values change intendedly.
In this case no passphrase need to be stored on the file system.
Finally, \autoref{code:tbupdatekernelsh} creates the unified kernel according to \autoref{tab:efilayout} using the command \texttt{objcopy} and copies it on the EFI disk partition.
The offset addresses need to be chosen according to the size of the included blobs.
All steps described above are summarized in \autoref{code:tbinstallsh}.
@ -161,41 +187,36 @@ The FDE decryption with the TPM will of course fail, since there is no sealed pa
This step is done now since the new unified kernel is measured the first time.
\autoref{code:tbupdatetpmsh} shows how the passphrase is sealed into the TPM with all relevant PCR registers.
\lstinputlisting[float,language=bash, caption={\texttt{update-luks-tpm.sh}: Script for updating the Sealing of the TPM Object with new PCR values},label={code:tbupdatetpmsh}]{../../trustedboot/update-luks-tpm.sh}
Line 15 of the script shows the unseal operation which is used to get the passphrase out of the TPM.
It should result in an exact copy of the original passphrase in \texttt{/root/keys}.
This finishes the installation of trusted boot resulting in an unattended disk decryption process during system boot.
The result is a trusted boot chain which ensures, that the system only has access to the encrypted disk when the kernel with its parameter is known---and therefore trusted.
This implementation also supports updating the linux kernel.
The required steps for keeping trusted boot intact are as follows:
\begin{enumerate}
\item \emph{System upgrade}: The system can be upgraded with the package tool of choice.
\item \emph{Updating unified kernel}: The EFI blob needs to be upgraded since a new kernel is installed by executing the script of \autoref{code:tbupdatekernelsh}.
\item \emph{Reboot}: The system needs to be rebooted to generate the new PCR values. The existing boot chain is, of course, broken and the optional FDE password need to be entered maually.
\item \emph{Update TPM}: The sealing of the LUKS password can be renewed with the new PCR values.
Since the existing seal cannot be opened anymore, the password must be available in clear text.
This step is done by the script in \autoref{code:tbupdatetpmsh}.
\end{enumerate}
\section{Integrity Measurement Architecture}
The result of trusted boot is a measured and therefore trusted kernel with its command line parameters and modules.
IMA extends this trust to the file system as described in \autoref{sec:integrity_measurement_architecture}.
All features of IMA are already implemented in the kernel sources and do not need additional packages.
The Gentoo wiki page about IMA\cite{gentoo19} describe which kernel compiler flags are related to IMA:
\begin{lstlisting}[float,language=bash,caption={Kernel compiler flags to enable IMA},label={code:kernelflags}]
CONFIG_INTEGRITY=y
CONFIG_IMA=y
CONFIG_IMA_MEASURE_PCR_IDX=10
CONFIG_IMA_LSM_RULES=y
CONFIG_INTEGRITY_SIGNATURE=y
CONFIG_IMA_APPRAISE=y
IMA_APPRAISE_BOOTPARAM=y
\end{lstlisting}
\begin{itemize}
\item \texttt{CONFIG\_INTEGRITY=y}
\item \texttt{CONFIG\_IMA=y}
\item \texttt{CONFIG\_IMA\_MEASURE\_PCR\_IDX=10}
\item \texttt{CONFIG\_IMA\_LSM\_RULES=y}
\item \texttt{CONFIG\_INTEGRITY\_SIGNATURE=y}
\item \texttt{CONFIG\_IMA\_APPRAISE=y}
\item \texttt{IMA\_APPRAISE\_BOOTPARAM=y}
\end{itemize}
According to their blog, Redhat\footnote{\url{https://www.redhat.com/en/blog/how-use-linux-kernels-integrity-measurement-architecture}, last visited on 9.7.2021} supports IMA since Enterprise Linux 8 and so would the Redhat clones like CentOS.
According to their blog, Redhat\footnote{\url{https://www.redhat.com/en/blog/how-use-linux-kernels-integrity-measurement-architecture}, last visited on 9.7.2021} supports IMA since Enterprise Linux 8 and so would the Redhat clones like CentOS, Rocky or Alma Linux.
Ubuntu enabled the required kernel compile flags by default on version 20.04 in the ubuntu kernel repository\footnote{\url{https://kernel.ubuntu.com/git/kernel-ppa/mirror/ubuntu-5.4-focal.git/tree/security/integrity/ima/Kconfig}, last visited on 9.7.2021}.
However, we found no official information on when IMA was introduced or whether IMA support will continue in future releases.
Every kernel supporting IMA creates a virtual file at \texttt{/sys/kernel/security/ima/ascii\_runtime\_measurements}.
Every kernel supporting IMA creates a virtual file at:
\begin{lstlisting}[numbers=none]
/sys/kernel/security/ima/ascii_runtime_measurements
\end{lstlisting}
When IMA is disabled, which is the default, this file has only one entry representing the boot aggregate.
By enabling IMA via kernel command line parameters, this file gets filled according to the policies defined.
By enabling IMA via kernel command line parameters, this virtual file gets filled according to the policies defined.
The first four parameters used in \autoref{code:tbcommandlinetxt} define the behavior of IMA and how the measurement log should look like.
\begin{itemize}
\item \texttt{ima\_appraise=fix} appends the filehash as an extended file attribute for every accessed file.
@ -204,14 +225,64 @@ The first four parameters used in \autoref{code:tbcommandlinetxt} define the beh
\item \texttt{rootflags=i\_version} must be enabled when mounting the filesystem since IMA is checking that number before re-hashing the resource.
\end{itemize}
Unfoortunately, the resulting IMA log is between 2000 and 3000 lines long when the system is freshly booted.
The log can blow up to several 10000 entries when uptime exceeds several days.
Unfortunately, the resulting IMA log is between 2000 and 3000 lines long when the system is freshly booted.
The log can blow up to several 10000 lines when uptime exceeds several days.
IMA has therefore a policy language rules for hashing files can be customized.
It might, for example, be useful to exclude log files from being hashed.
However, a thrid party can comprehend the state of the attesting system, when parsing the IMA log.
Together with the corresponding PCR value, where the hashes of all entries are chained the TPM can \texttt{certify} correctness of the log.
Together with the corresponding value of PCR 10, where the hashes of all entries are chained, the TPM can \texttt{certify} correctness of the log.
Besides the log entries, every hashed file gets an extended file attribute called \texttt{security.ima} holding current hash value in base64 encoding.
The apt package \texttt{attr} contains the binary \texttt{getfattr} which can show these additional attributes.
Now, the file attributes are shown with:
\begin{lstlisting}[numbers=none]
getfattr -m - -d trustedboot/install.sh
\end{lstlisting}
Having attributes for all relevant files allows IMA to enforce appraisal.
This means that the hash of every file is checked before it is accessed.
Before enforcing IMA, the root filesystem should be parsed to create attributes for every file.
Touching the file is not enough, the file must be openend for read, as shown in the following command:
\begin{lstlisting}[numbers=none]
time find / -fstype ext4 -type f -uid 0 -exec dd if '{}' of=/dev/null count=0 status=none \;
\end{lstlisting}
This command opens every file in an ext4 filesystem for read, causing the kernel to create/update the file attributes, but does not read any data.
It takes about fifteen minutes to parse the file system on a Ubuntu minimal server system given the hardware described above.
The final step is to enforce IMA appraisal via kernel command line parameter.
By changing the parameter \texttt{ima\_appraise=enforce} in
\texttt{/boot/kernel-command-line.txt}, IMA enforces the hash and will deny access if the hash is not correct.
The new parameters are activated by using the workflow for updating the kernel described in \autoref{ssec:install-and-use-trusted-boot}.
The result is a system which allows only resources with correct hash attribute to be read or executed.
An adversary may still create the file hash itself and overwrite the file with the hash.
Hence these hash values must be verified in some way before they can be trusted.
Two options are therefore available:
\begin{itemize}
\item \emph{Attest}: Let the complete IMA log be part of remote attestation and verify the hash values against a trusted known value database.
This makes the verification part very complex but the state of the attesting system is well documented.
\item \emph{Sign}: Sign hash values for static files like executables or libraries.
The host can directly check whether the file was tamepered with and act accordingly.
Linux kernels support this feature with the \emph{extended verification module} (EVM).
\end{itemize}
We implemented an attestation variant where the IMA log is part of the message.
Details about the message design will be discussed in \autoref{ssec:daa-network-protocol}
\section{Dynamic System Analysis}
IMA is a comprehensive tool for checking the integrity of a file or executable or library before it gets executed.
When access is allowed, IMA's job is done.
An executable can however change its behaviour during runtime, either intended with remote procedure calls or unintended with a remote code execution vulnerability.
One approach for runtime analysis is to create a log of syscalls for a certain process.
Syscalls are the only interface from the program to the OS when managing resources needed by the program.
Hence logging the trace of syscalls show which resources it needs and which files areaccessed or modified.
Any unusual behavior could be detected immediately given a good knowledge of the used resources when executing a good version of the program.
The trace logs are created with \texttt{auditd} which requires the corresponding apt package to be installed.
\section{Interaction with TPM2}
\subsection{Prove Certificate Chain}
\section{Prove TPM2 Certificate Chain}
Every TPM has a corresponding certificate which is part of a certificate chain maintained by the TPM manufacturer.
In our case, Infineon certifies its TPM with a number of intermediate CAs which itself are certified with Infineon's root CA.
The TPM certificate is available for RSA and ECC cryptofamilies respectively.
@ -289,12 +360,6 @@ IMA-Settings erklären.
Available on Ubuntu, RedHat and optionally Gentoo.
The kernel has the correct compile options set.
\subsection{Handling external hardware}
How can camera and fingerprint sensor be trusted?
What is the limitation of this solution?
\section{Using the DAA Protocol}
Direct anonymous attestation is a group signature scheme which uses the TPM as cryptoprocessor and key store.
The feature of identifiable instances of sensors is not required when interacting with the Digidow network.
@ -388,6 +453,7 @@ When all above steps are finished successfully, the demonstration setup is finis
\item picture taking program
\end{itemize}
\subsection{DAA Network Protocol}
\label{ssec:daa-network-protocol}
The network protocol provided by \texttt{ecdaa-network-wrapper} adds to the cryptographic implementation of Xaptum's ecdaa project a network communication layer.
It is designed to match the workflow of a Digidow transaction, affecting the decision which party is defined as listener and which as sender.

BIN
thesis/MAIN.pdf

Binary file not shown.
Loading…
Cancel
Save