1
0
Fork
You've already forked masterarbeit
0
No description
  • TeX 94.8%
  • HTML 3.4%
  • Rust 1.5%
  • Shell 0.2%
  • Assembly 0.1%
2025年11月21日 11:52:00 +01:00
document presentation: remove captions 2025年11月21日 11:52:00 +01:00
project submodule update 2025年11月21日 09:40:12 +01:00
.gitignore presentation: add inkscape svg cache to .gitignore 2025年11月19日 13:38:13 +01:00
.gitlab-ci.yml Update .gitlab-ci.yml file 2025年09月18日 09:41:51 +02:00
.gitmodules Fix link to D30S repository 2025年11月18日 22:56:04 +01:00
README.md thesis: countermeasures, D3OS 2025年08月18日 16:46:53 +02:00

📓 Aufgabenbeschreibung

Hier den erstellten Entwurf einfügen

Recherche

KPTI, KAISER, KASLR

Performance

Videos

Stack handling

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?

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 nokaslr in cmdline
  • 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 the vcpu setting: <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 vcpupin parameters in the cputune configuration:
    <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

Arch Linux VM results

physical Arch Linux on deprecated CPU

deprecated Debian

Installation
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

Implementation

Signal handler

  1. Interrupt handler macht bei GPF nicht panic! sondern setzt Flag in Thread
  2. Wenn Thread gescheduled wird, prüft der Scheduler Flags
  3. Falls Flags gesetzt, prüfe ob Serviceroutine registriert, ansonsten panic
  4. Falls Serviceroutine registriert, Stackframe bauen und anspringen
  5. Falls Serviceroutine zurückkehrt, Ausführung an derselben Stelle fortsetzen, wo der Fault aufgetreten ist
  • Rücksprungadresse?
  1. Falls Fault wieder auftritt, panic

Allgemein:

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)

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

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_table klont 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