No description
- TeX 94.8%
- HTML 3.4%
- Rust 1.5%
- Shell 0.2%
- Assembly 0.1%
| document | presentation: remove captions | |
| project | submodule update | |
| .gitignore | presentation: add inkscape svg cache to .gitignore | |
| .gitlab-ci.yml | Update .gitlab-ci.yml file | |
| .gitmodules | Fix link to D30S repository | |
| README.md | thesis: countermeasures, D3OS | |
📓 Aufgabenbeschreibung
Hier den erstellten Entwurf einfügen
Recherche
Links
- https://docs.kernel.org/core-api/protection-keys.html
- https://www.youtube.com/watch?v=QA9HgdlOha4
- https://github.com/Kianenigma/meltdown-spectre
- https://meltdownattack.com/
- https://arxiv.org/abs/1801.01207
- https://arxiv.org/abs/2310.04192
- https://core.ac.uk/outputs/578691973/?source=2
- https://github.com/IAIK/meltdown
- https://en.wikipedia.org/wiki/Meltdown_(security_vulnerability)
- https://gms.tf/check-cpu-microcode-version-on-linux.html
- https://askubuntu.com/questions/704640/how-to-detect-in-runtime-is-kaslr-enabled-or-disabled
KPTI, KAISER, KASLR
- https://www.phoronix.com/search/KPTI
- https://www.phoronix.com/news/Linux-4.15-Release-Coming-Today
- https://www.phoronix.com/news/Linux-4.16-KPTI-Improvements
- https://www.phoronix.com/review/linux-416-changes
- https://www.phoronix.com/news/KPTI-PCID-Global-Pages-4.17
- https://en.wikipedia.org/wiki/Address_space_layout_randomization
- https://en.wikipedia.org/wiki/Kernel_page-table_isolation
- https://www.phoronix.com/search/KASLR
- https://lwn.net/Kernel/Index/#Security-Meltdown_and_Spectre
- https://lwn.net/Articles/738975/
Performance
- https://www.phoronix.com/review/if-amd-kpti
- https://www.phoronix.com/review/linux-kpti-pcid
- https://www.phoronix.com/search/Meltdown
Videos
- Moritz Lipp on YouTube
- USENIX '18 Talk by Moritz Lipp
- Paper review by Sudip Maitra
- Paper reproductio by Sudip Maitra
- Meltdown Attack explained
- Meltdown and Spectre Attack Lab
- Spectre & Meltdown - Computerphile
- The spectre of hardware bugs
- X-Factor: Das Unfassbare - Die Geschichte von Meltdown und Spectre by Michael Schwarz
- A Christmas Carol - The Spectres of the Past, Present, and Future
- Meltdown and Spectre... ... for normal people
Stack handling
- https://stackoverflow.com/questions/12911841/kernel-stack-and-user-space-stack
- https://signalshore.github.io/blog/2020-09-20-Stack-Frames-in-x86.html
- https://stackoverflow.com/questions/3699283/what-is-stack-frame-in-assembly
- https://wiki.osdev.org/Scheduling_Algorithms
- https://wiki.osdev.org/Continuation_Systems
- https://www.linuxjournal.com/article/3985
- https://web.archive.org/web/20130926005901/http://users.actcom.co.il/~choo/lupg/tutorials/signals/signals-programming.html
- https://wiki.osdev.org/Signals
- https://en.wikipedia.org/wiki/Call_stack
- https://wiki.osdev.org/Stack
Signal handling
- Kernel stack gets reset for each interrupt using
rsp0, therefore, the bottom(top) of the stack is defined- Use bottom(top) of the stack to access return address in first stack frame (constant offset)
- Or use InterruptStackFrame parameter of interrupt handlers to modify return address
Linux investigation
Reproduction results
| CPU | OS | Kernel version | VM | KASLR | Method | ./test |
time sudo taskset 0x1 ./kaslr |
offset | /proc/direct_physical_map |
sudo taskset 0x1 ./reliability |
sudo taskset 0x1 ./reliability <offset> |
sudo ./secret & taskset 0x1 ./physical_reader <addr> <offset> |
taskset 0x1 ./memdump 0x240000000 -1 <offset> |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| i7-9750H | Arch Linux | 6.12.10-arch1-1 |
no | yes? | meltdown_nonull |
0m0.259s |
fail | - | 0xffff928640000000 |
Success rate: 0.00% (read 6 values) |
Success rate: 0.00% (read 16 values) |
unreadable ascii | mostly 00, only 2 rows after ~1h |
| i5-2450M | Debian 7 | 3.2.0-4-amd64 |
no | no? | meltdown_nonull |
0m0.240s |
0m0.271s |
0xffff880000000000 |
0xffff880000000000 |
Success rate: 99.89% (read 87592 values) |
Success rate: 99.89% (read 7951 values) |
unreadable ascii | mostly 00 |
| i5-2450M | Debian 7 | 3.2.0-4-amd64 |
no | no? | meltdown_nonull |
0m0.240s |
0m0.269s |
0xffff880000000000 |
0xffff880000000000 |
Success rate: 99.88% (read 19560 values) |
Not tested | some successful results | Not tested |
| i7-9750H | Debian 7 | 3.2.0-4-amd64 |
yes | no? |
Next steps
- Record reproduction results using asciinema
- Which conditions influence the success of
./physical_reader?- Parallel computer usage? Sometimes, the attack worked significantly better when using GUI applications in parallel to the attack.
- Simulate with stress, as recommended in PoC README?
- Some strings work better than others?
- Parallel computer usage? Sometimes, the attack worked significantly better when using GUI applications in parallel to the attack.
Physical machine
KASLR
KASLR enabled
lukas@Lukas-TP-Arch2:meltdown$ sudo head -n 10 /proc/kallsyms
0000000000000000 A fixed_percpu_data
0000000000000000 A __per_cpu_start
0000000000001000 A cpu_debug_store
0000000000002000 A irq_stack_backing_store
0000000000006000 A cpu_tss_rw
000000000000b000 A gdt_page
000000000000c000 A exception_stacks
0000000000018000 A entry_stack_storage
0000000000019000 A espfix_waddr
0000000000019008 A espfix_stack
KASLR disabled
- Boot with
nokaslrincmdline - How to detect?
Microcode
Microcode version in current boot
lukas@Lukas-TP-Arch2:~$ sudo journalctl -k -b 0 --grep='microcode:'
Jan 21 08:48:55 Lukas-TP-Arch2 kernel: microcode: Current revision: 0x000000f8
Jan 21 08:48:55 Lukas-TP-Arch2 kernel: microcode: Updated early from: 0x000000f0
lukas@Lukas-TP-Arch2:~$ grep 'microcode' /proc/cpuinfo
microcode : 0xf8
Microcode version in past boot
lukas@Lukas-TP-Arch2:~$ sudo journalctl -k -b -1 --grep='microcode:'
Jan 20 14:39:13 Lukas-TP-Arch2 kernel: microcode: Current revision: 0x000000f0
Available microcodes
lukas@Lukas-TP-Arch2:~$ iucode_tool -lS /usr/lib/firmware/intel-ucode/
iucode_tool: system has processor(s) with signature 0x000906ea
microcode bundle 1: /usr/lib/firmware/intel-ucode/06-05-03
...
microcode bundle 149: /usr/lib/firmware/intel-ucode/06-66-03
selected microcodes:
098/001: sig 0x000906e9, pf_mask 0x2a, 2023年09月28日, rev 0x00f8, size 108544
019/001: sig 0x000906ea, pf_mask 0x22, 2024年02月01日, rev 0x00f8, size 105472
060/001: sig 0x000906eb, pf_mask 0x02, 2024年02月01日, rev 0x00f6, size 106496
042/001: sig 0x000906ec, pf_mask 0x22, 2024年02月01日, rev 0x00f8, size 106496
061/001: sig 0x000906ed, pf_mask 0x22, 2024年02月05日, rev 0x0100, size 106496
lukas@Lukas-TP-Arch2:~$ lsinitcpio /boot/intel-ucode.img
kernel
kernel/x86
kernel/x86/microcode
kernel/x86/microcode/.enuineIntel.align.0123456789abc
kernel/x86/microcode/GenuineIntel.bin
None in initramfs:
lukas@Lukas-TP-Arch2:~$ lsinitcpio --early /boot/initramfs-linux.img | grep microcode
lukas@Lukas-TP-Arch2:~$
Microcode loaded by BIOS:
lukas@Lukas-TP-Arch2:~$ sudo dmidecode --type bios
# dmidecode 3.6
Getting SMBIOS data from sysfs.
SMBIOS 3.1.1 present.
Handle 0x0013, DMI type 0, 26 bytes
BIOS Information
Vendor: LENOVO
Version: N2NET53W (1.38 )
Release Date: 07/08/2022
Address: 0xE0000
Runtime Size: 128 kB
ROM Size: 32 MB
Characteristics:
PCI is supported
PNP is supported
BIOS is upgradeable
BIOS shadowing is allowed
Boot from CD is supported
Selectable boot is supported
EDD is supported
3.5"/720 kB floppy services are supported (int 13h)
Print screen service is supported (int 5h)
8042 keyboard services are supported (int 9h)
Serial services are supported (int 14h)
Printer services are supported (int 17h)
CGA/mono video services are supported (int 10h)
ACPI is supported
USB legacy is supported
BIOS boot specification is supported
Targeted content distribution is supported
UEFI is supported
BIOS Revision: 1.38
Firmware Revision: 1.12
Memdump test results
Runtime: ~2h
lukas@Lukas-TP-Arch2:meltdown$ taskset 0x1 ./memdump 0x240000000 -1 $(cat /proc/direct_physical_map)
[+] Physical address : 0x240000000
[+] Physical offset : 0xffff928640000000
[+] Virtual address : 0xffff928880000000
240004700: | bb 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ |
2400916d0: | 00 15 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ |
24009c740: | 00 00 00 00 00 00 00 00 00 00 00 02 00 00 00 00 | ................ |
24009c8e0: | 00 00 00 00 00 00 00 00 02 00 00 00 00 00 00 00 | ................ |
24009d250: | 00 00 00 00 00 00 00 02 00 00 00 00 00 00 00 00 | ................ |
24009e160: | 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 00 | ................ |
24009f340: | 00 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ |
24009f3b0: | 00 00 00 02 00 00 00 00 00 00 00 00 00 00 00 00 | ................ |
24009f730: | 00 00 00 00 00 00 02 00 00 00 00 00 00 00 00 00 | ................ |
24009fc90: | 00 00 00 00 00 00 00 00 00 00 00 00 02 00 00 00 | ................ |
2400a0e10: | 00 00 00 00 00 00 00 00 00 00 00 00 00 02 00 00 | ................ |
2400a2350: | 00 00 00 00 00 00 00 00 02 00 00 00 00 00 00 00 | ................ |
2400a23e0: | 00 00 00 00 00 00 00 02 00 00 00 00 00 00 00 00 | ................ |
2400a2f30: | 00 00 00 00 00 00 00 00 00 00 00 00 02 00 00 00 | ................ |
2400a4080: | 00 00 00 00 00 00 00 00 02 00 00 00 00 00 00 00 | ................ |
2400a8640: | 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ |
2400af320: | 00 00 00 00 00 02 00 00 00 00 00 00 00 00 00 00 | ................ |
2400afa10: | 00 00 00 00 00 00 00 02 00 00 00 00 00 00 00 00 | ................ |
2400b5cf0: | 00 02 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ................ |
2400b6a10: | 00 00 00 00 00 00 00 00 00 00 00 00 02 00 00 00 | ................ |
Virtual machine
Pin VM to physical cores
- In virt-manager, edit the XML for the CPU settings
- Add the
cpuset-parameter to thevcpusetting:<vcpu placement="static" cpuset="4-7">4</vcpu>- This seems to pin all 4 guest CPUs to any of the four host CPUs:
lukas@Lukas-TP-Arch2:~$ sudo virsh vcpuinfo debian9 VCPU: 0 CPU: N/A State: N/A CPU time N/A CPU Affinity: -------yyyyy VCPU: 1 CPU: N/A State: N/A CPU time N/A CPU Affinity: -------yyyyy VCPU: 2 CPU: N/A State: N/A CPU time N/A CPU Affinity: -------yyyyy VCPU: 3 CPU: N/A State: N/A CPU time N/A CPU Affinity: -------yyyyy - Or even better, specify
vcpupinparameters in thecputuneconfiguration:<vcpu placement="static">4</vcpu> <cputune> <vcpupin vcpu="0" cpuset="0"/> <vcpupin vcpu="1" cpuset="1"/> <vcpupin vcpu="2" cpuset="2"/> <vcpupin vcpu="3" cpuset="3"/> </cputune>- This pins the CPUs individually:
lukas@Lukas-TP-Arch2:~$ sudo virsh vcpuinfo debian7 VCPU: 0 CPU: 0 State: running CPU time: 222.6s CPU Affinity: y----------- VCPU: 1 CPU: 1 State: running CPU time: 0.6s CPU Affinity: -y---------- VCPU: 2 CPU: 2 State: running CPU time: 0.6s CPU Affinity: --y--------- VCPU: 3 CPU: 3 State: running CPU time: 0.6s CPU Affinity: ---y-------- - Verify CPU affinity using
sudo virsh vcpuinfo <VMName> - Documentation: https://libvirt.org/formatdomain.html#cpu-allocation
- Apparently not sufficient?
Arch Linux VM
physical Arch Linux on deprecated CPU
- Dual boot with Debian difficult, as os-prober does not assign the correct root partition arguments to the Debian menuentry
- Add original Debian GRUB configuration via
/etc/grub/40-custom
- Add original Debian GRUB configuration via
- Old packages (kernel) in Arch Linux Archive
- Only dates back to January 2019 (5 years from now), post-meltdown, kernel 4.19.15-lts
- Arch Linux Historical Archive in the Internet Archive, not complete, incorrect time stamps
- Building old kernel versions fails due to various issues
- This invalid escaping of special characters in Build.include which needs to be adapted (use literal
#instead of$(pound)) - Probably this use-after-free issue due to updated GCC 12
- This invalid escaping of special characters in Build.include which needs to be adapted (use literal
deprecated Debian
Installation
- Create VM with virt-manager
- Choose "network install" and use the following operating system install URL: https://archive.debian.org/debian-archive/debian/dists/stretch/main/installer-amd64/
- Alternatively, download the ISO from https://archive.debian.org/debian-archive/debian/dists/stretch/main/installer-amd64/current/images/netboot/mini.iso
- For physical installation, download a live iso from https://cdimage.debian.org/mirror/cdimage/archive/, e.g. https://cdimage.debian.org/mirror/cdimage/archive/7.11.0-live/amd64/iso-hybrid/?C=S;O=A
- For installing Debian versions which apt keys have already expired (installation will fail when installing grub after specifying mirror, for netinstall earlier), pass the following kernel options either by pressing TAB in the GRUB menu, or by adding them to the URL options when specifying the netboot URL in virt-manager:
debian-installer/allow_unauthenticated=true apt-setup/allow-unauthenticated=true - In the installation process, when asked for a debian archive mirror, scroll to the top to enter a mirror manually
- Use https://archive.debian.org/debian-archive/debian/ as mirror URL
Debian 9 VM Results
user@debian9:~/meltdown$ sudo taskset 0x1 ./kaslr We trust you have received the usual lecture from the local System Administrator. It usually boils down to these three things: #1) Respect the privacy of others. #2) Think before you type. #3) With great power comes great responsibility. [sudo] password for user: [+] Direct physical map offset: 0xffff884900000000 user@debian9:~/meltdown$ sudo taskset 0x1 ./test Expect: Welcome to the wonderful world of microarchitectural attacks ^C user@debian9:~/meltdown$ sudo taskset 0x1 ./reliability 0xffff884900000000 [+] Setting physical offset to 0xffff884900000000 [\] Success rate: 0.39% (read 2321019 values) ^C user@debian9:~/meltdown$ taskset 0x1 ./physical_reader Usage: ./physical_reader <physical address> [<direct physical map>] user@debian9:~/meltdown$ taskset 0x1 ./physical_reader 0x171401d78 0xffff884900000000 [+] Physical address : 0x171401d78 [+] Physical offset : 0xffff884900000000 [+] Reading virtual address: 0xffff884a71401d78 ^[[A^C user@debian9:~/meltdown$ taskset 0x1 ./memdump -1 0xffff884900000000 Error converting physical to virtual address user@debian9:~/meltdown$ taskset 0x1 ./memdump 0 -1 0xffff884900000000 [+] Physical address : 0x0 [+] Physical offset : 0xffff884900000000 [+] Virtual address : 0xffff884900000000 0: | 02 02 02 02 02 02 02 02 02 03 02 02 02 02 02 02 | ................ | 10: | 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 | ................ | 20: | 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 | ................ | 30: | 03 02 02 03 02 02 02 02 02 02 02 02 02 02 02 02 | ................ | 40: | 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 | ................ | 50: | 02 02 02 03 02 02 02 02 02 02 02 02 02 02 02 02 | ................ | 60: | 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 | ................ | 70: | 03 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 | ................ | 80: | 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 | ................ | 90: | 02 02 02 02 03 02 02 02 02 02 02 02 02 02 02 02 | ................ | a0: | 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 | ................ | b0: | 04 04 02 02 02 02 02 02 02 02 02 02 02 02 02 02 | ................ | c0: | 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 | ................ | d0: | 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 | ................ | e0: | 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 | ................ | f0: | 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 | ................ | 100: | 02 02 03 02 02 02 02 02 02 02 02 02 02 02 02 02 | ................ | 110: | 02 02 03 02 02 02 02 02 02 02 02 02 02 02 02 02 | ................ | 120: | 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 | ................ | 130: | 04 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 | ................ | 140: | 03 02 02 02 02 02 02 02 02 02 02 02 02 02 02 02 | ................ |
Debian 7 physical results
- Installation fails when installing GRUB, due to failure to install packages from apt, due to expired keys. For fix, see deprecated Debian/Installation above. Logs obtained through web method (starts a local web server) in the "Save debug logs" step of the graphical installer.
Spectre-Meltdown-Checker
- git repository
- Similar resources:
Implementation
Signal handler
- Interrupt handler macht bei GPF nicht panic! sondern setzt Flag in Thread
- Wenn Thread gescheduled wird, prüft der Scheduler Flags
- Falls Flags gesetzt, prüfe ob Serviceroutine registriert, ansonsten panic
- Falls Serviceroutine registriert, Stackframe bauen und anspringen
- Falls Serviceroutine zurückkehrt, Ausführung an derselben Stelle fortsetzen, wo der Fault aufgetreten ist
- Rücksprungadresse?
- Falls Fault wieder auftritt, panic
Allgemein:
- Grafik erstellen
- nur das Nötige implementieren (z.B. zurückkehren muss nicht unterstützt werden)
- http://wiki.osdev.org/Exceptions
- https://www.man7.org/linux/man-pages/man7/signal.7.html
Aufschreiben
- CPU yield between memory accesses
Performance degradation of meltdown attack
- Meltdown attack does not work after merging development in commit 121b73dbd65ac802b68136793a328e1c25529e8c
- Performance degradation after merging parts of dda646692ebde274f20959f29493df0276319ab9 in 5a9bd742c5ea6235aeaf1066dc8434db65808e5a
- Performance degradation a bit better when commenting the init cpu info in boot.rs
Gegenmaßnahmen
- Process ID Flags?
- Bei jedem Adressraumwechsel den TLB flushen?
- Microcode-Updates in D3OS?
Kernel-Adressraum im Usermode minimieren
Zwei Optionen beim Syscall:
- Den Usermode Adressraum klonen, damit andere Usermode-Threads unverändert weiterlaufen (und nicht parallel ebenfalls ggf. per Meltdown auf den Kernel-Adressraum zugreifen können) und darin Teile des Kernels einblenden
- Im Usermode-Adressraum müsste dann nur der Syscall-Handler eingeblendet sein, welcher dann den temporären Adressraumwechsel vornehmen kann
- Den Kernel Adressraum klonen, und darin Teile des Usermode einblenden
- z.B. Buffer, die übergeben werden etc.
Linux
KASLR (2014)
- https://en.wikipedia.org/wiki/Address_space_layout_randomization
- Kernel address space layout randomization
- Kernel mappings hidden from user space
- Can be leaked using side channels
KAISER / KPTI (2017? / 4.15)
- https://en.wikipedia.org/wiki/Kernel_page-table_isolation
- https://lwn.net/Articles/738975/
- Kernel Address Isolation to have Side-channels Efficiently Removed
- Kernel page-table isolation
- KPTI: Linux implementation, relation to KAISER?
- Apparently KAISER not suitable, got modified
- Completely separate user and kernel page tables
- kernel page tables as before
- user mode page tables: only minimal set of kernel mappings (system calls & interrupts)
The minimal kernel page tables try to map only what is needed to enter/exit the kernel such as the entry/exit functions, interrupt descriptors (IDT) and the kernel trampoline stacks. This minimal set of data can still reveal the kernel's ASLR base address. But, this minimal kernel data is all trusted, which makes it harder to exploit than data in the kernel direct map which contains loads of user-controlled data.
- Copy only top level of page tree
- Initially: 32bit 3GB Userspace, 1GB Kernel
- Limited memory for both Kernel and Userspace, but no need to flush TLB
- 4G/4G mechanism solved some problems, but slow, not into mainline
PCID
- https://en.wikipedia.org/wiki/Translation_lookaside_buffer#PCID
- Process-condext identifies
- Avoid TLB flush
- 12bit PCID since 2010 Westmere Intel-64?
Vorgehen
- Page Table auf oberster Ebene klonen, in Usermode-Kopie darf nur der Syscall- und Interrupt-Handler vorhanden sein (reicht das?)
- Syscall-Handler (und Interrupt-Handler?) muss an einer höheren Adresse (dedizierte VMA?) gemappt werden, damit dieser aus dem Usermode verfügbar bleibt
- Syscall-Handler (Interrupt-Handler?) schaltet Adressräume um
- TLB Flushen wenn in den Usermode-Adressraum zurückgewechselt wird
- PCID verwenden?
Schwierigkeiten
pages::copy_tableklont die Wurzeltabelle und legt neue Tabellen auf den niedrigeren Ebenen an, wir brauchen aber genau das Gegenteil, eine neue Tabelle auf oberster Ebene und Referenzen auf die Tabellen niedriger Ebenen.b