CET - Intel Control-flow Enforcement Technology

Allikas: Imre kasutab arvutit
Redaktsioon seisuga 20. mai 2026, kell 21:32 kasutajalt Imre (arutelu | kaastöö) (→‎Tööpõhimõte)
Mine navigeerimisribaleMine otsikasti

Sissejuhatus

TODO

Mõisted

  • CET - control-flow enforcement technology
  • ROP - return oriented programming
  • SHSTK - shadow stack

Tööpõhimõte

CET algab protsessori toest, nt https://www.intel.com/content/www/us/en/products/sku/232391/intel-xeon-gold-6448h-processor-60m-cache-2-40-ghz/specifications.html puhul muu hulgas öeldakse

  • Intel® Control-Flow Enforcement Technology

ning töötava arvuti käest küsides

# lscpu | grep -i shstk
Flags:                                fpu vme de pse .. user_shstk ...

seejärel kerneli tugi, nt

# grep SHADOW /boot/config-6.17.0-23-generic
CONFIG_X86_USER_SHADOW_STACK=y
CONFIG_ARCH_HAS_USER_SHADOW_STACK=y
...

seejärel rakendustarkvara programmi tugi

# readelf -n /usr/sbin/nginx

Displaying notes found in: .note.gnu.property
  Owner                Data size 	Description
  GNU                  0x00000020	NT_GNU_PROPERTY_TYPE_0
      Properties: x86 feature: IBT, SHSTK
	x86 ISA needed: x86-64-baseline

Displaying notes found in: .note.gnu.build-id
  Owner                Data size 	Description
  GNU                  0x00000014	NT_GNU_BUILD_ID (unique build ID bitstring)
    Build ID: 9d51609b493789d993848c98e203e9a13dba3157

Displaying notes found in: .note.ABI-tag
  Owner                Data size 	Description
  GNU                  0x00000010	NT_GNU_ABI_TAG (ABI version tag)
    OS: Linux, ABI: 3.2.0

kusjuures kerneli ja programmi vahele jäävad teegid peavad ka toetama

# cat hu.sh
for lib in $(ldd /usr/sbin/nginx | grep -o '/lib[^ ]*'); do
    echo -n "$lib: "
    readelf -n "$lib" 2>/dev/null | grep -q "SHSTK" && echo "READY" || echo "MISSING HARDENING"
done

# sh hu.sh
/lib/x86_64-linux-gnu/libcrypt.so.1: READY
/lib/x86_64-linux-gnu/libpcre2-8.so.0: READY
/lib/x86_64-linux-gnu/libssl.so.3: READY
/lib/x86_64-linux-gnu/libcrypto.so.3: READY
/lib/x86_64-linux-gnu/libz.so.1: READY
/lib/x86_64-linux-gnu/libc.so.6: READY
/lib64/ld-linux-x86-64.so.2: READY

ning töötava protsessi juures on shstk aktiivne, see paistab nii

# ps U www-data
    PID TTY      STAT   TIME COMMAND
    920 ?        S      0:00 nginx: worker process
    921 ?        S      0:00 nginx: worker process
...

# cat /proc/921/status | grep -i thread_fe
x86_Thread_features:	shstk
x86_Thread_features_locked:	shstk wrss

Väited

  • tänapäeval on keeruline leida uut intel või amd protsessoriga arvutit mis ei toetaks cet tehnoloogiat
  • Ubuntu 24.04 platvormil on vaikimisi kõik cet jaoks vajalik olemas v.a. rakenduse systemd service seadistusest sisselülitamine
  • 2026 aasta kevade seisuga virtualiseerimise platvorm Proxmox PVE v. 9 kasutab qemu v. 11 ja seal on füüsilise protsessori kasutamisel virtuaalse arvuti protsessorine (valik 'host') kasutada cet tehnoloogia

Kasulikud lisamaterjalid

Haavatavuse näide

Haavatavuse ilmestamise programm rop_lab.c, tõenäoliselt on see märkimisväärne lihtsustus, aga ta illustreerib rop haavatavuse põhimõtet ning haavatavuse ärahoidmist

$ cat rop_lab.c
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

// This is our "Gadget". The program never calls this function honestly!
void malicious_gadget() {
    printf("\n⚡ [ATTACK SUCCESS] Control flow hijacked! Malicious code executing.\n");
    exit(0);
}

void vulnerable_function(char *str) {
    char buffer[16];

    // VULNERABILITY: strcpy does not check bounds.
    // It will overwrite the buffer, the frame pointer, and the Return Address!
    strcpy(buffer, str);

    printf("[CPU] Function executing normally inside buffer layout.\n");
}

int main() {
    // We are crafting a malicious payload payload manually.
    // 16 bytes to fill the buffer + 8 bytes to smash the saved frame pointer
    // + 8 bytes containing the exact memory address of malicious_gadget()
    char payload[32];

    // Fill the padding area with 'A's (0x41)
    memset(payload, 'A', 24);

    // Get the exact memory address of our target gadget
    unsigned long target = (unsigned long)malicious_gadget;

    // Append the target address onto the end of our overflow payload
    memcpy(payload + 24, &target, 8);

    printf("[Lab] Target Gadget Address is at: %p\n", (void*)target);
    printf("[Lab] Launching attack payload against vulnerable function...\n");

    vulnerable_function(payload);

    printf("[CPU] Returned safely to main. (This should not happen if hacked!)\n");
    return 0;
}

kus

  • malicious_gadget() on protsessi mälus olev nö ärakasutatav järgnevus - et ära kasutada, tuleb sattuda sobivale aadressile - võib olla see järgnevus pole üldse algselt programmeeritud isesesiva funktsioonina, aga ta nii praktiliselt toimib kui sobivalt pöörduda-kasutada
  • vulnerable_function - haavatav funktsioon - asutakse ära kasutama tema potensiaali kirjutada üle rohkem stack mälu sisu kui on ette kujutatud
  • main() - programmi töö algus, valmistatakse ette sobiva sisuga payload (mälu sisu) ja paigutatakse kohale
  • tulemusena funktsioonist vulnerable_function tagasi pöördudes ei saabuta main() 'printf ...' juurde, aga gadget juurde

Väljakutsuvalt liberaalse binary kompileerimiseks sobib öelda

$ gcc -fno-stack-protector -z execstack -fcf-protection=none rop_lab.c -o lab_unhardened

kus

  • -fno-stack-protector - ei moodustata nö tarkvarapõhist stack kaitset
  • -z execstack - lisaks lülitatakse sisse stack'is oleva koodi käivitamise võimalus
  • -fcf-protection=none - lülitatakse välja igasugune hardware-assisted st cet põhine stack kaitse

cet põhine kaitse

$ gcc -fno-stack-protector -fcf-protection=full rop_lab.c -o lab_hardened

kus

  • -fcf-protection=full - sisse on lülitatud maksimaalne võimalik hardware-assisted st cet põhine stack kaitse
  • -fno-stack-protector - ei moodustata nö tarkvarapõhist stack kaitset selleks, et katses pääseks mõjule cet põhine kaitse

Kui käivitada cet-võimestatud binary't nö tavalisel viisil ning cet riistvara toega arvutis, siis ta töötab haavatavalt

$ lscpu | grep shstk
Flags:               .. user_shstk ...

$ ./lab_hardened
[Lab] Target Gadget Address is at: 0x6552a7afc1c9
[Lab] Launching attack payload against vulnerable function...
[CPU] Function executing normally inside buffer layout.

⚡ [ATTACK SUCCESS] Control flow hijacked! Malicious code executing.

Kui lülitada sisse cet kaitse, siis hoiab kernel ära haavatavuse mõjulepääsu

$ export GLIBC_TUNABLES=glibc.cpu.hwcaps=SHSTK

$ ./lab_hardened
[Lab] Target Gadget Address is at: 0x59f889ed41c9
[Lab] Launching attack payload against vulnerable function...
[CPU] Function executing normally inside buffer layout.
Segmentation fault (core dumped)

Samal ajal kirjutatakse kerneli logisse

# dmesg -T | tail -n 1
[Wed May 20 20:31:35 2026] lab_hardened[2872] control protection ip:59f889ed421e sp:7ffe4f9f7648 ssp:76edde5fffe0 error:1(near ret) in lab_hardened[121e,59f889ed4000+1000]

kus

  • sp - stack pointer väärtus
  • ssp - shadow stack pointer väärtus
  • nad ei klapi

Kasutamine - Ubuntu 24.04 ja zabbix agent2

Näiteks zabbix agent kaudu haavatavuse esilekutsumine ja haavatavuse vältimine. Moodustada UserParameters abil kontroll

# cat /etc/zabbix/zabbix_agent2.d/misc.conf
UserParameter=rop_hardened,/home/imre/20260520/lab_hardened 1>>/home/tmp/rop_hardened.log 2>&1

# systemctl restart zabbix-agent2

# zabbix_get -k rop_hardened -s 127.0.0.1

Tulemusena programmi ja seal sisalduva nö eksploidi käivitamine

# tail -n 5 /home/tmp/rop_hardened.log
[Lab] Target Gadget Address is at: 0x616af0eed1c9
[Lab] Launching attack payload against vulnerable function...
[CPU] Function executing normally inside buffer layout.

⚡ [ATTACK SUCCESS] Control flow hijacked! Malicious code executing.

Programmis sisalduva eksploidi töötamise takistamiseks sobib kasutada zabbix agent2 systemd service unit seadistustes GLIB_TUNABLES abil

# systemctl edit zabbix-agent2

[Service]
Environment="GLIBC_TUNABLES=glibc.cpu.hwcaps=SHSTK"

# systemctl restart zabbix-agent2

Tulemusena ütleb kernel segmentation fault rikkumise avastamisel

# tail -n 6 /home/tmp/rop_hardened.log
[Lab] Target Gadget Address is at: 0x616af0eed1c9
[Lab] Launching attack payload against vulnerable function...
[CPU] Function executing normally inside buffer layout.

⚡ [ATTACK SUCCESS] Control flow hijacked! Malicious code executing.
Segmentation fault (core dumped)

# dmesg -T | tail -n 1
[Wed May 20 20:50:28 2026] lab_hardened[3417] control protection ip:62ee74e0421e sp:7ffeadc19f28 ssp:7e27011fffe0 error:1(near ret) in lab_hardened[121e,62ee74e04000+1000]

coredump

süsteemi logisse kirjutatakse

2026-05-20T20:50:28.063977+03:00 zabbix-pub-01 kernel: lab_hardened[3417] control protection ip:62ee74e0421e sp:7ffeadc19f28 ssp:7e27011fffe0 error:1(near ret) in lab_hardened[121e,62ee74e04000+1000]
2026-05-20T20:50:28.073376+03:00 zabbix-pub-01 systemd[1]: Started systemd-coredump@11-3418-0.service - Process Core Dump (PID 3418/UID 0).
2026-05-20T20:50:28.134245+03:00 zabbix-pub-01 systemd-coredump[3420]: Process 3417 (lab_hardened) of user 111 dumped core.#012#012Stack trace of thread 3417:#012#0  0x000062ee74e0421e n/a (/home/imre/20260520/lab_hardened + 0x121e)#012ELF object binary architecture: AMD x86-64
2026-05-20T20:50:28.136589+03:00 zabbix-pub-01 systemd[1]: systemd-coredump@11-3418-0.service: Deactivated successfully.
2026-05-20T20:50:28.139121+03:00 zabbix-pub-01 systemd[1]: systemd-coredump@11-3418-0.service: Triggering OnSuccess= dependencies.
2026-05-20T20:50:28.145170+03:00 zabbix-pub-01 systemd[1]: Starting apport-coredump-hook@11-3418-0.service...
2026-05-20T20:50:28.274024+03:00 zabbix-pub-01 systemd[1]: apport-coredump-hook@11-3418-0.service: Deactivated successfully.
2026-05-20T20:50:28.274268+03:00 zabbix-pub-01 systemd[1]: Finished apport-coredump-hook@11-3418-0.service.
2026-05-20T20:52:17.413974+03:00 zabbix-pub-01 kernel: NOTICE: Automounting of tracing to debugfs is deprecated and will be removed in 2030

ning

# coredumpctl list lab_hardened
TIME                          PID  UID  GID SIG     COREFILE EXE                               SIZE
Wed 2026-05-20 15:08:59 EEST 1080 1000 1000 SIGSEGV present  /home/imre/20260520/lab_hardened 18.5K
Wed 2026-05-20 15:09:26 EEST 1165 1000 1000 SIGSEGV present  /home/imre/20260520/lab_hardened 18.5K
Wed 2026-05-20 15:45:00 EEST 1677  111  112 SIGSEGV present  /home/imre/20260520/lab_hardened 18.0K
Wed 2026-05-20 15:45:01 EEST 1696  111  112 SIGSEGV present  /home/imre/20260520/lab_hardened 18.0K
Wed 2026-05-20 15:45:55 EEST 1811  111  112 SIGSEGV present  /home/imre/20260520/lab_hardened 18.0K
Wed 2026-05-20 15:45:57 EEST 1827  111  112 SIGSEGV present  /home/imre/20260520/lab_hardened 18.0K
Wed 2026-05-20 15:51:15 EEST 1908  111  112 SIGSEGV present  /home/imre/20260520/lab_hardened 18.0K
Wed 2026-05-20 15:52:54 EEST 1939 1000 1000 SIGSEGV present  /home/imre/20260520/lab_hardened 18.5K
Wed 2026-05-20 20:31:35 EEST 2872 1000 1000 SIGSEGV present  /home/imre/20260520/lab_hardened 18.5K
Wed 2026-05-20 20:43:23 EEST 2976  111  112 SIGSEGV present  /home/imre/20260520/lab_hardened 18.0K
Wed 2026-05-20 20:43:31 EEST 2994  111  112 SIGSEGV present  /home/imre/20260520/lab_hardened 18.0K
Wed 2026-05-20 20:50:28 EEST 3417  111  112 SIGSEGV present  /home/imre/20260520/lab_hardened 18.0K

# coredumpctl dump lab_hardened --output=lab_crash.core
           PID: 3417 (lab_hardened)
           UID: 111 (zabbix)
           GID: 112 (zabbix)
        Signal: 11 (SEGV)
     Timestamp: Wed 2026-05-20 20:50:28 EEST (8min ago)
  Command Line: /home/imre/20260520/lab_hardened
    Executable: /home/imre/20260520/lab_hardened
 Control Group: /system.slice/zabbix-agent2.service
          Unit: zabbix-agent2.service
         Slice: system.slice
       Boot ID: 3c8da9f759024317bf94b1831190ee44
    Machine ID: b5cb741b1516242b193018946930aed8
      Hostname: zabbix-pub-01
       Storage: /var/lib/systemd/coredump/core.lab_hardened.111.3c8da9f759024317bf94b1831190ee44.3417.1779299428000000.zst (present)
  Size on Disk: 18.0K
       Message: Process 3417 (lab_hardened) of user 111 dumped core.

                Stack trace of thread 3417:
                #0  0x000062ee74e0421e n/a (/home/imre/20260520/lab_hardened + 0x121e)
                ELF object binary architecture: AMD x86-64
More than one entry matches, ignoring rest.

# ls -ld /var/lib/systemd/coredump/*
-rw-r-----+ 1 root root 19024 May 20 15:08 /var/lib/systemd/coredump/core.lab_hardened.1000.3c8da9f759024317bf94b1831190ee44.1080.1779278939000000.zst
-rw-r-----+ 1 root root 19025 May 20 15:09 /var/lib/systemd/coredump/core.lab_hardened.1000.3c8da9f759024317bf94b1831190ee44.1165.1779278966000000.zst
-rw-r-----+ 1 root root 19016 May 20 15:52 /var/lib/systemd/coredump/core.lab_hardened.1000.3c8da9f759024317bf94b1831190ee44.1939.1779281573000000.zst
-rw-r-----+ 1 root root 19014 May 20 20:31 /var/lib/systemd/coredump/core.lab_hardened.1000.3c8da9f759024317bf94b1831190ee44.2872.1779298295000000.zst
-rw-r-----  1 root root 18468 May 20 15:45 /var/lib/systemd/coredump/core.lab_hardened.111.3c8da9f759024317bf94b1831190ee44.1677.1779281100000000.zst
...

core uurimiseks sobib öelda

# gdb ./lab_hardened lab_crash.core
GNU gdb (Ubuntu 15.1-1ubuntu1~24.04.1) 15.1
Copyright (C) 2024 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.
Type "show copying" and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<https://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.

For help, type "help".
Type "apropos word" to search for commands related to "word"...
./lab_hardened: No such file or directory.
[New LWP 3417]

This GDB supports auto-downloading debuginfo from the following URLs:
  <https://debuginfod.ubuntu.com>
Enable debuginfod for this session? (y or [n]) y
Debuginfod has been enabled.
To make this setting permanent, add 'set debuginfod enabled on' to .gdbinit.
Downloading executable for /root/lab_crash.core
...

(gdb) info registers
rax            0x38                56
rbx            0x7ffeadc1a088      140731813568648
rcx            0x0                 0
rdx            0x0                 0
rsi            0x62ee74e05050      108776302596176
rdi            0x7e2701405710      138705989818128
rbp            0x4141414141414141  0x4141414141414141
rsp            0x7ffeadc19f28      0x7ffeadc19f28
r8             0x7e2701403b20      138705989810976
r9             0x0                 0
r10            0x1                 1
r11            0x3                 3
r12            0x1                 1
r13            0x0                 0
r14            0x62ee74e06da0      108776302603680
r15            0x7e2701611000      138705991962624
rip            0x62ee74e0421e      0x62ee74e0421e
eflags         0x10202             [ IF RF ]
cs             0x33                51
ss             0x2b                43
ds             0x0                 0
es             0x0                 0
fs             0x0                 0
gs             0x0                 0
fs_base        0x7e27015c5740      138705991653184
gs_base        0x0                 0
(gdb)

kus

  • TODO

Kasulikud lisamaterjalid

  • teksti koostamisel on kasutatud ohtralt gemini google abi