commit df90539b9e7ee75c206d5b77d4f1b94882d090c7
parent 039144b8e7f7fb4074883e8037787d420e86f70c
Author: Louis Burda <quent.burda@gmail.com>
Date: Wed, 1 Feb 2023 16:57:26 -0600
Add guest provisioning scripts and instructions
Diffstat:
9 files changed, 156 insertions(+), 42 deletions(-)
diff --git a/.gitmodules b/.gitmodules
@@ -4,3 +4,6 @@
[submodule "cachepc-linux"]
path = linux
url = git@github.com:Sinitax/cachepc-linux.git
+[submodule "cachepc-AMDSEV"]
+ path = AMDSEV
+ url = git@github.com:Sinitax/cachepc-AMDSEV.git
diff --git a/AMDSEV b/AMDSEV
@@ -0,0 +1 @@
+Subproject commit a3c82f656a1364b11d61bf493742a3f7cb91e500
diff --git a/README b/README
@@ -14,75 +14,75 @@ tests
Several test-cases were used to verify parts of the exploit chain separately:
test/eviction:
- Demonstrate that performance counters & our setup are accurate enough
- to detect a single eviction in L1 cache and infer its cache set
- through PRIME+COUNT
+ Demonstrate that performance counters & our setup are accurate enough
+ to detect a single eviction in L1 cache and infer its cache set
+ through PRIME+COUNT
test/kvm-eviction:
- Demonstrate that the cache set of a memory access instruction can be
- inferred in non-SEV / SEV / SEV-ES / SEV-SNP -enabled vms respectively.
+ Demonstrate that the cache set of a memory access instruction can be
+ inferred in non-SEV / SEV / SEV-ES / SEV-SNP -enabled vms respectively.
test/kvm-step:
- Demonstrate that SEV-SNP enabled vms can be single-stepped using local
- APIC timers to interrupt the guest and increment the interrupt interval
- while observing the RIP+RFLAGS ciphertext in the VMSA for changes to
- detect that a single instruction has been executed.
+ Demonstrate that SEV-SNP enabled vms can be single-stepped using local
+ APIC timers to interrupt the guest and increment the interrupt interval
+ while observing the RIP+RFLAGS ciphertext in the VMSA for changes to
+ detect that a single instruction has been executed.
test/kvm-pagestep:
- Demonstrate that a SEV-SNP enabled vm can be quickly single-stepped
- and analyzed by tracking a single page at a time. This type
- of tracking creates a page-wise profile of the guests execution,
- which can be used to infer what the guest is doing and to begin
- fine-grained single-stepping.
+ Demonstrate that a SEV-SNP enabled vm can be quickly single-stepped
+ and analyzed by tracking a single page at a time. This type
+ of tracking creates a page-wise profile of the guests execution,
+ which can be used to infer what the guest is doing and to begin
+ fine-grained single-stepping.
test/qemu-pagestep:
- Replicate result from kvm-pagestep on a qemu-based vm running debian.
+ Replicate result from kvm-pagestep on a qemu-based vm running debian.
test/qemu-eviction:
- Replicate result from kvm-eviction on a qemu-based vm running debian
- using a specially crafted guest program to signal when measurement
- should take place to infer the accessed set.
+ Replicate result from kvm-eviction on a qemu-based vm running debian
+ using a specially crafted guest program to signal when measurement
+ should take place to infer the accessed set.
test/qemu-aes:
- Demonstrate that AES encryption keys can be leaked from a
- modified qemu-based linux guest.
+ Demonstrate that AES encryption keys can be leaked from a
+ modified qemu-based linux guest.
test/qemu-poc:
- Demonstrate that AES encryption keys can be leaked from an
- unmodified qemu-based linux guest.
+ Demonstrate that AES encryption keys can be leaked from an
+ unmodified qemu-based linux guest.
-modes
------
+track modes
+-----------
The kernel module employs a few different modes of tracking described
in more detail below:
CPC_TRACK_FAULT_NO_RUN:
- Tracks access to all guest pages and lets the guest page fault over and over
- without untracking / handling any page faults. This results in a decent
- baseline measurement when we dont want to step the vm.
+ Tracks access to all guest pages and lets the guest page fault over and over
+ without untracking / handling any page faults. This results in a decent
+ baseline measurement when we dont want to step the vm.
CPC_TRACK_EXIT_EVICTION:
- Set apic timer such that for any reasonably short KVM_RUN no local apic
- interrupts will occur to cause exits. Good for collecting PRIME+COUNT
- measurements over a clean run to a guest-invoked exit such as KVM_EXIT_HLT.
+ Set apic timer such that for any reasonably short KVM_RUN no local apic
+ interrupts will occur to cause exits. Good for collecting PRIME+COUNT
+ measurements over a clean run to a guest-invoked exit such as KVM_EXIT_HLT.
CPC_TRACK_PAGES:
- Track execution of all guest pages. While the guest is running, untrack
- a single executable page at a time based on page-faults. Allows tracking
- which guest pages are executed and how long using retired instructions.
+ Track execution of all guest pages. While the guest is running, untrack
+ a single executable page at a time based on page-faults. Allows tracking
+ which guest pages are executed and how long using retired instructions.
CPC_TRACK_STEPS:
- Single-step guest exection. For each step, collect either only instruction
- or instruction and data page-faults. Allows tracking not only which sets were
- evicted but what gfns were involved in the access. A target page can
- be set, such that we will first page-step until the page is reached,
- then single-step while running instructions on that page.
+ Single-step guest exection. For each step, collect either only instruction
+ or instruction and data page-faults. Allows tracking not only which sets were
+ evicted but what gfns were involved in the access. A target page can
+ be set, such that we will first page-step until the page is reached,
+ then single-step while running instructions on that page.
-setup
------
+host setup
+----------
Testing was done on a Supermicro H12SSL-i V1.01 motherboard and AMD EPYC 72F3
(Family 0x19, Model 0x01) cpu. The motherboard bios version is 2.4 and was
@@ -97,8 +97,8 @@ sev-snp-devel at commmit a480a51. Install the host kernel by running:
# ./install.sh
-For the build to complete the following packages needed to be installed
-following a clean install of debian linux-5.10.0-21:
+For the build to complete the following packages were needed following
+a clean install of debian linux-5.10.0-21:
git build-essential flex dpkg bc rsync libelf-dev libssl-dev bison ninja-build
pkg-config libglib2.0-dev libpixman-1-dev python3 coda nasm uuid-dev iasl
@@ -136,6 +136,27 @@ $ cp $(AMDSEV_REPO)/linux/host/.config linux/.config
$ make linux
+guest setup
+-----------
+
+Generate a guest image and install debian by running qemu/install.sh.
+The virtual machine can either be controlled via vnc, or once the guest os
+is installed via ssh, port forwarded to localhost:8000.
+
+Once debian is installed, launch the guest by running qemu/launch.sh and
+copy over the compiled guest kernel packages from AMDSEV/linux on the host
+and install them. Reboot the guest, make sure that `uname -r` matches
+the expected version and copy that versions initrd and vmlinuz out of
+/boot on the guest to qemu/ on the host. Also copy the guests /proc/cmdline
+contents to qemu/cmdline on the host.
+
+Finally, run qemu/launch-victim.sh to launch a qemu guest ready to
+be attacked.
+
+
+troubleshooting
+---------------
+
In case SEV-SNP initialization fails due to a low firmware version, the
firmware can be updated to v1.51 by running:
diff --git a/cachepc/macro.S b/cachepc/macro.S
@@ -4,6 +4,8 @@
.macro barrier
mfence # memory barrier
rdtsc # serializing
+ # mov $0x80000005, %rax
+ # cpuid # serializing (cpuid alone does not work)
.endm
# clobbers rax, rbx, rcx, rdx, (out)
diff --git a/qemu/.gitignore b/qemu/.gitignore
@@ -0,0 +1,7 @@
+monitor
+stdout.log
+*.fd
+*.qcow2
+*.iso
+initrd.img-*
+vmlinuz-*
diff --git a/qemu/cmdline b/qemu/cmdline
@@ -0,0 +1 @@
+BOOT_IMAGE=/boot/vmlinuz-5.19.0-rc6-snp-guest-d9bd54fea4d2 root=UUID=a0bc580b-fe27-4aa9-b795-6bde981ba954 ro quiet
diff --git a/qemu/install.sh b/qemu/install.sh
@@ -0,0 +1,31 @@
+#!/bin/sh
+
+set -ex
+
+gitroot=$(git rev-parse --show-toplevel)
+cd "$gitroot/qemu"
+
+DISK="debian11.qcow2"
+DEBIANISO="debian-11.4.0-amd64-DVD-1.iso"
+
+if [ ! -e "$DISK" ]; then
+ echo "Creating guest disk.."
+ qemu-img create -f qcow2 "$DISK" 20G
+fi
+
+if [ ! -e "$DEBIANISO" ]; then
+ echo "Downloading debian DVD image.."
+ wget "https://cdimage.debian.org/mirror/cdimage/archive/11.4.0/amd64/iso-dvd/debian-11.4.0-amd64-DVD-1.iso" -O "$DEBIANISO"
+fi
+
+sudo LIBVIRT_DEBUG=1 virsh net-start default 2>&1 | grep -i warning || true
+
+sudo PREFIX="$gitroot/AMDSEV" "$gitroot/AMDSEV/launch-qemu.sh" \
+ -hda "$DISK" \
+ -console serial \
+ -vnc 1 \
+ -mem 2024 \
+ -smp 1,cores=4,threads=2 \
+ -allow-debug \
+ -cdrom "$DEBIANISO"
+
diff --git a/qemu/launch-victim.sh b/qemu/launch-victim.sh
@@ -0,0 +1,31 @@
+#!/bin/sh
+
+set -ex
+
+gitroot=$(git rev-parse --show-toplevel)
+cd "$gitroot/qemu"
+
+if [ ! -e cmdline ]; then
+ echo "Missing qemu/cmdline.."
+ exit 1
+fi
+
+if [ ! -e debian11_encrypted.qcow2 ]; then
+ echo "Copying disk.."
+ rsync -a --info=progress2 debian11.qcow2 debian11_encrypted.qcow2
+fi
+
+sudo LIBVIRT_DEBUG=1 virsh net-start default 2>&1 | grep -i warning || true
+
+sudo PREFIX=$gitroot/AMDSEV $gitroot/AMDSEV/launch-qemu.sh \
+ -hda debian11_encrypted.qcow2 \
+ -console serial \
+ -vnc 1 \
+ -mem 2024 \
+ -smp 1,cores=1,threads=1 \
+ -allow-debug \
+ -initrd initrd.img-5.19.0-rc6-snp-guest-d9bd54fea4d2 \
+ -kernel vmlinuz-5.19.0-rc6-snp-guest-d9bd54fea4d2 \
+ -append "$(cat cmdline)" \
+ -sev-snp
+
diff --git a/qemu/launch.sh b/qemu/launch.sh
@@ -0,0 +1,17 @@
+#!/bin/sh
+
+set -ex
+
+gitroot=$(git rev-parse --show-toplevel)
+cd "$gitroot/qemu"
+
+sudo LIBVIRT_DEBUG=1 virsh net-start default 2>&1 | grep -i warning || true
+
+sudo PREFIX=$gitroot/AMDSEV $gitroot/AMDSEV/launch-qemu.sh \
+ -hda debian11.qcow2 \
+ -console serial \
+ -vnc 1 \
+ -mem 2024 \
+ -smp 1,cores=4,threads=2 \
+ -allow-debug
+