Il 0% ha trovato utile questo documento (0 voti)
12 visualizzazioni77 pagine

Slide - Linux Kernel Exploitation 101 - Part 1 & 2

Copyright
© © All Rights Reserved
Per noi i diritti sui contenuti sono una cosa seria. Se sospetti che questo contenuto sia tuo, rivendicalo qui.
Formati disponibili
Scarica in formato PDF, TXT o leggi online su Scribd
Il 0% ha trovato utile questo documento (0 voti)
12 visualizzazioni77 pagine

Slide - Linux Kernel Exploitation 101 - Part 1 & 2

Copyright
© © All Rights Reserved
Per noi i diritti sui contenuti sono una cosa seria. Se sospetti che questo contenuto sia tuo, rivendicalo qui.
Formati disponibili
Scarica in formato PDF, TXT o leggi online su Scribd

Linux Kernel Exploitation 101

Spawn your uid=0 like ninja


Indice

- Introduzione teorica al kernel


- Kernel Debugging
- Vulnerabilità comuni
- Mitigation & Exploitation
Cos’è il kernel

Know your enemy


Comunicazione con HW e SW

HARDWARE KERNEL SOFTWARE


Esempio: Vuoi sentire musica da spotify

HARDWARE KERNEL SOFTWARE

linux-5.14
SOFTWARE KERNEL HARDWARE

curl https://target.com/

linux-5.14

WiFi/ethernet/..

SOFTWARE KERNEL HARDWARE

linux-5.14
Kernel-mode User-mode

HARDWARE KERNEL SOFTWARE


User-Mode vs Kernel-Mode

- User-Mode (aka User-Land / User-Space)


- Applicazioni software (Spotify, Browser (Chrome, Safari,..), Teams, ..)
- Privilegi limitati (ring 3)
- Comunica costantemente con il kernel (volontariamente e non)
- root user (root != kernel)
- Kernel-Mode (aka Kernel-Land / Kernel-Space)
- Ring 0
- Driver
- Interazione con l’hardware
- Schede grafiche/rete, chip Bluetooth/4G/, mouse, tastiere, periferiche audio
- Gestione dei privilegi
- Operazioni piú comuni
- Allocazione memoria per applicazione user-mode
- Comunicazione tra processi (IPC)
- Comunicazione network (TCP/IP, …)
- Ring 1 e 2 nativamente non utilizzati
- Ring 1 utilizzato da virtualizzazione (VirtualBox, VMWare, ..)
Kernel-mode User-mode
(ring 0) (ring 3)

HARDWARE KERNEL SOFTWARE

Come ??
User-mode => Kernel-Mode

- syscall
- Wrappers
- read, write, open, close
- socket, bind, connect, listen
- mmap, mprotect
- ioctl (Input Output ConTroL)
- https://filippo.io/linux-syscall-table/
Kernel-Mode => Hardware (Driver)

- Comunica direttamente con l’hardware tramite driver


- Un driver è un “modulo” aggiuntivo che stabilisce una comunicazione tra hardware e kernel
- Il driver viene scritto seguendo il “datasheet” della periferica
- Può fare da “ponte” per l’interazione tra user-mode e hardware
- Per esempio per la riproduzione di file musicali (sequenza di bit).
Kernel-Mode => Hardware - Esempio MRF24J40

- Implementazione del driver per il microchip MRF24J40 802.15.4


- Datasheet: https://ww1.microchip.com/downloads/en/DeviceDoc/39776C.pdf
- Driver: /drivers/net/ieee802154/mrf24j40.c
Hardware => Kernel-Mode

- L’HW si fa “notare” dal kernel utilizzando gli Interrupt


- Una periferica (e.g. una scheda di rete) manda un interrupt alla CPU
- Il kernel gestisce l’interrupt (Interrupt Handling) ed instrada l’informazione dove necessario
- Per esempio, se si tratta di un pacchetto arrivato ad una scheda di rete, questo dovrà essere elaborato in base
al tipo di protocollo.
- I tasti che premiamo sulla tastiera mandando un Interrupt all’Interrupt Handler
- Diversi tipi di Interrupt
- Maskable/Non Maskable
- Classificati per priority
Kernel Memory

Stack, Context, Heap (SLA|O|UB)


Stack vs Heap

Stack Heap
- Statico - Dinamico
- Le allocazioni sono determinate a - Allocazioni determinate runtime
compile-time - alloc/free manuali
- Size-limited - kmalloc/kfree

- Piú veloce - Frammentazione


- Salva variabili locali alla funzione
- I registri RSP & RBP delimitano lo stack
- Ogni funzione ha il proprio stack
Heap allocations / Memory Management

- SLAB
- Precursore
- EOL (verrà rimosso)
- Termine generico anche nell'implementazione di SLOB/SLUB
- SLOB
- Ottimizzato per sistemi Embedded
- SLUB
- Linux > 2.6.12
SLUB

- PAGE_SIZE allocations (4096)


- Divisione per grandezza
- 8, 16, 32, 64, 128 … 4k, 8k (x86_64)
- 128, 256, 512, .. 6k, 8k (ARM64)
- Divisione per tipo
- GFP_KERNEL / GFP_KERNEL_ACCOUNT
- kmalloc-16 / kmalloc-cg-16 / special caches
- Chunk
- Un oggetto in memoria
- slab/cache
- Un insieme di allocazioni dello stesso tipo
- e.g. kmalloc-8 puó avere N slabs che contengono ognuno (PAGE_SIZE / 8) chunks
SLUB / partial slabs

slab 1

slab 2

slab 3
SLUB / partial slabs

slab 1

slab 2

slab 3
SLUB / partial slabs
partial slab 1

slab 1

partial slab 2

slab 2

slab 3
SLUB / partial slabs

slab 1

partial slab 2

slab 2

slab 3
SLUB / partial slabs

slab 1

partial slab 2

slab 2

slab 3
SLUB / partial slabs

slab 1

partial slab 2

slab 2

slab 3
SLUB

- APIs
- kmalloc()
- flags: GFP_KERNEL | GFP_KERNEL_ACCOUNT | …
- kfree()
- Special-purpose caches
- kmem_cache_create()
- kmem_cache_alloc()
- struct kmem_cache / struct kmem_cache_cpu
- Struttura che descrive la cache
SLUB - Useful files

- /proc/slabinfo
- /sys/kernel/slab/
- /sys/kernel/slab/<CACHE>/partial
- /sys/kernel/slab/<CACHE>/objects_size
- /sys/kernel/slab/<CACHE>/objs_per_slab
Pointers: Kernel vs User

- Documentation/x86/x86_64/mm.rst
- 4-level page tables
- Più utilizzato su x86_64 (in base alla CPU)
- Userspace
- 0x0000000000000000 => 0x00007fffffffffff
- Kernel
- 0xffff800000000000 => 0xffffffffffffffff
- 5-level page tables
- Documentation/x86/x86_64/mm.rst#L75
- Configuration file: arch/x86/Kconfig
Kernel mapped on users process
0xffffffffffffffff

KERNEL-SPACE

0xffff800000000000

0x00007fffffffffff

USER-SPACE

0x0000000000000000
Kernel memory mapped on user-space

- È possibile dunque accedere alla memoria del kernel tramite user-mode?


- NO!
- Se si, è una vulnerabilità (o post-exploitation).
- Anche le operazioni da kernel-mode a user-mode sono controllate.
- https://elixir.bootlin.com/linux/v5.19-rc7/source/lib/usercopy.c#L10
- https://elixir.bootlin.com/linux/latest/source/include/asm-generic/access_ok.h#L31
copy_[from|to]_user

- copy_from_user
- unsigned long copy_from_user (void * to, const void __user * from, unsigned long n);

- “Copy a block of data from user space”


- __copy_from_user
- “Copy a block of data from user space, with less checking” (no access_ok)
- copy_to_user
- unsigned long copy_to_user (void __user * to, const void * from, unsigned long n);

- “Copy a block of data into user space.”


- __copy_to_user
- “Copy a block of data into user space, with less checking” (no access_ok)
copy_[from|to]_user checks

- Puntatori
- Che i due parametri “to” e “from” siano validi (tramite access_ok())
- copy_from_user
- from: user pointer ( < 0x00007fffffffffff )
- copy_to_user
- to: user pointer ( < 0x00007fffffffffff )
- CONFIG_HARDENED_USERCOPY
- Controlli sulla grandezza dei chunk
Common vulnerabilities
Common vulnerabilities (memory corruptions)

- Stack Overflow
- Heap Overflow/Underflow
- Large overflows / off-by-one / Integer Overflow...
- Use-After-Free
- UAF read/write
- UAF self-referencing pointer (linked lists)
- Double Free
- Race Conditions / refcount
- => UAF/Hep ovf/..
Weird machine

- Che cos’è una corruzione di memoria?


- Si accede (r|w|x) ad una zona di memoria in maniera non prevista dal programma
- Mancati controlli (e.g. di una size)
- Errati controlli (assunzioni non corrette)
- Come si sfrutta?
- GIOCANDO e MANIPOLANDO la memoria ed il programma
- Creando una Weird Machine
- Far fare ad un programma ció per cui non è stato progettato (e.g. eseguire uno shellcode/ROP =>
RCE).
- Bypass mitigazioni correnti
Common Mitigations

- Comuni
- kASLR
- SMAP
- SMEP

- Extra
- CONFIG_FG_KASLR
- CONFIG_STATIC_USERMODEHELPER
- CONFIG_SLAB_FREELIST_RANDOM/HARDENED
- CONFIG_DEBUG_LIST
- CONFIG_HARDENED_USERCOPY
- CONFIG_ARM64_UAO
- CONFIG_FORTIFY_SOURCE
- CONFIG_MEMCG
- ..
Mitigazioni == Impossibile scrivere exploit ?

- NO !
- Ma ci sono dei cambiamenti
- Ogni singola vulnerabilità fa caso a se
- Stack Overflow => Overwrite RIP => shellcode => PWN
- Heap Overflow => Unlinking => RIP control => PWN
- Sempre piú difficile (nuove mitigation appaiono ogni anno)
- Ma anche piú divertente =) (e stressante)
Heap Overflow
Heap Overflow

- Concetto base
- Oggetto A sovrascrive oggetto B (allocato successivamente all’oggetto A)
- In memoria, oggetto prende il nome di chunk

Heap Overflow
A = kmalloc(32);

chunk A

Heap Overflow
A = kmalloc(32);
B = kmalloc(32);

chunk A chunk B

Heap Overflow
A = kmalloc(32);
B = kmalloc(32);
.. kmalloc(...)... // Altre allocazioni

chunk A chunk B

… …

Heap Overflow
A = kmalloc(32);
B = kmalloc(32);
.. kmalloc(...)... // Altre allocazioni
memset(A, 0x41, 32);

chunk A chunk B

… AAAAAAAAAAAAAAA …

Heap Overflow
A = kmalloc(32);
B = kmalloc(32);
.. kmalloc(...)... // Altre allocazioni
memset(A, 0x41, 32);
memset(A, 0x41, 64);

chunk A chunk B

… AAAAAAAAAAAAAAA AAAAAAAAAAAAAAA …

Heap Overflow
A = kmalloc(32);
B = kmalloc(32);
.. kmalloc(...)... // Altre allocazioni
memset(A, 0x41, 32);
memset(A, 0x41, 64);
B->function() // => Corrupted from chunk A => RIP = 0x4141414141414141

chunk A chunk B

… AAAAAAAAAAAAAAA AAAAAAAAAAAAAAA …

A => Target object Target object


B => Victim object - Oggetto dove si presenta la vulnerabilità
Victim object
Heap Overflow - Oggetto scelto arbitrariamente dall’attaccante
(per essere corrotto ad-hoc)
Use-After-Free

- Concetto base
- Un oggetto, precedentemente de-allocato (free), viene riutilizzato

Use-After Free
A = kmalloc(32);

chunk A

Use-After Free
A = kmalloc(32);
free(A);

chunk A

Use-After Free
A = kmalloc(32);
free(A);
B = kmalloc(32);

chunk B

Use-After Free
A = kmalloc(32);
free(A);
B = kmalloc(32);
A->function(32); // Access undefined values => RIP: ????

chunk B

Use-After Free
A = kmalloc(32);
free(A);
B = kmalloc(32);
A->function(32); // Access undefined values => RIP: ????

A => Target object


chunk B
B => Victim object

Target object
- Oggetto dove si presenta la vulnerabilità
Victim object
- Oggetto scelto arbitrariamente dall’attaccante
Use-After Free (per essere corrotto ad-hoc)
Common Mitigations

KASLR, SMAP, SMEP


KASLR

- Randomizzazione degli indirizzi


- Richiede, quasi sempre, la necessità di una Information Disclosure
- Per ottenere altri indirizzi
- Esempio
- Un leak di un pointer nella sezione .text del kernel permette di ottenere tutti gli altri indirizzi
- Scenario
- Pre-ASLR
- Arbitrary Write => Write ad un indirizzo conosciuto => uid=0
- ASLR
- Arbitrary Write
- Se possibile trasformarlo in un Arbitrary/OOB read =>uid=0
- Oppure necessità di un’altra vulnerabilità che permette Information Disclosure => uid=0
SMAP / SMEP (x86_64)

- SMAP (Supervisor Mode Access Prevention)


- Genera un “fault” se si accede alla memoria user-space
- “Allows supervisor mode programs to optionally set user-space memory mappings so that access to those
mappings from supervisor mode will cause a trap” (Wikipedia)
- SMEP (Supervisor Mode Execution Prevention)
- Genera un “fault” se si esegue dalla memoria user-space
- Gestito dal registro CR4
KERNEL-SPACE

USER-SPACE
Come fa copy_from|to|user a funzionare?

- Disabilitando temporaneamente SMAP (dal registro CR4)

STEPS (esempio)

1. copy_from_user()
2. Disable SMAP (ASM_STAC)
3. Interazione con user-space
4. Enable SMAP (ASM_CLAC)
SMEP / Supervisor Mode Execution Prevention

Kernel-land

User-land
SMEP / Supervisor Mode Execution Prevention

Kernel-land
RIP control

User-land
SMEP / Supervisor Mode Execution Prevention

Kernel-land
RIP control

User-land

Shellcode
SMEP / Supervisor Mode Execution Prevention

Kernel-land
RIP control
RIP

User-land

Shellcode
SMEP / Supervisor Mode Execution Prevention

Kernel-land
RIP control userspace_address()
RIP

User-land
SMEP

Shellcode
SMEP / Supervisor Mode Execution Prevention

Kernel-land
RIP control userspace_address()
RIP

User-land
SMEP

Shellcode Conosciuto come ret2usr


SMAP / Supervisor Mode Access Prevention

Kernel-land
RIP control

0xffffff5eaa7bc000

0xffffff5eaa7bc034
User-land
0xffffff5eaa7bc983

0xffffff5eaa530f10

ROP chain
SMAP / Supervisor Mode Access Prevention

Kernel-land
RIP control

0xffffff5eaa7bc000

0xffffff5eaa7bc034
Stack Pivot User-land
0xffffff5eaa7bc983

0xffffff5eaa530f10

ROP chain
SMAP / Supervisor Mode Access Prevention

Kernel-land kernel_ptr = * (user_ptr)


RIP control
copy_from_user(kernel_ptr, user_ptr, size);

0xffffff5eaa7bc000

0xffffff5eaa7bc034
SMAP Stack Pivot User-land
0xffffff5eaa7bc983

0xffffff5eaa530f10

ROP chain
SMAP/SMEP

- SMAP/SMEP sono mitigation Intel


- e.g. anche Windows
- ARM ha il corrispettivo PXN/PAN
- Stesso concetto, implementazione kernel/cpu diversa
Exploitation techniques

Attack kernel structures


Exploitation strategies

- Dipende dalla vulnerabilità


- L'obiettivo (di solito e se possibile) è costruirsi una primitiva R/W
- Se hai r/w sul kernel, la root é (generalmente) solo questione di tempo (e di bypass di mitigation)
- Caso comune
- Si parte da una vuln con r/w limitato per arrivare ad una arbitrary R/W
- Da un primitiva write è possibile costruirsi una R/W
- Se controlli il RIP (e.g. tramite la corruzione di una funzione kernel)
- Possibile costruire una ROP/JOP a seconda delle mitigation
- Si ha quasi sempre bisogno di un information leak
- Per bypassare KASLR
- Chaining di piú vulnerabilità
A = kmalloc(32);
free(A);
B = kmalloc(32);
A->function(32); // Access undefined values => RIP: ????

A => Target object


chunk B
B => Victim object

Target object
- Oggetto dove si presenta la vulnerabilità
Victim object
- Oggetto scelto arbitrariamente dall’attaccante
Use-After Free (per essere corrotto ad-hoc)
A = kmalloc(32);
B = kmalloc(32);
.. kmalloc(...)... // Altre allocazioni
memset(A, 0x41, 32);
memset(A, 0x41, 64);
B->function() // => Corrupted from chunk A => RIP = 0x4141414141414141

chunk A chunk B

… AAAAAAAAAAAAAAA AAAAAAAAAAAAAAA …

A => Target object Target object


B => Victim object - Oggetto dove si presenta la vulnerabilità
Victim object
Heap Overflow - Oggetto scelto arbitrariamente dall’attaccante
(per essere corrotto ad-hoc)
Victim Object

- Un oggetto che viene utilizzato per ottenere altre primitive


- R/W/X
- link 1 / link 2
- shm_file_data
- msg_msg
- Tty_struct
- …
- Utilizzi
- Heap Overflow
- Oggetto che viene allocato adiacente all’oggetto vulnerabile per essere sovrascritto
- UAF
- Oggetto che viene rimpiazzato
Victim Object

- Un oggetto che viene utilizzato per ottenere altre primitive


- R/W/X
- link 1 / link 2
- shm_file_data
- msg_msg
- Tty_struct
- …
- Utilizzi
- Heap Overflow
- Oggetto che viene allocato adiacente all’oggetto vulnerabile per essere sovrascritto
- UAF
- Oggetto che viene rimpiazzato
A = kmalloc(32);
B = kmalloc(32);
.. kmalloc(...)... // Altre allocazioni
memset(A, 0x41, 32);
memset(A, 0x41, 64);
B->function() // => Corrupted from chunk A => RIP = 0x4141414141414141

chunk A chunk B

… AAAAAAAAAAAAAAA AAAAAAAAAAAAAAA …

A => Target object Target object


B => Victim object - Oggetto dove si presenta la vulnerabilità
Victim object
Heap Overflow - Oggetto scelto arbitrariamente dall’attaccante
(per essere corrotto ad-hoc)
Victim Object
- Un oggetto che viene utilizzato per ottenere altre primitive
- R/W/X
- link 1 / link 2
- Shm_file_data / msg_msg / tty_struct / ..
- Utilizzi
- Heap Overflow
- Oggetto che viene allocato adiacente all’oggetto vulnerabile per essere sovrascritto
- UAF
- Oggetto che viene rimpiazzato
- Prerequisito
- L’oggetto deve essere allocato nella stessa cache
- Target obj = kmalloc-32
- Victim obj = kmalloc-32 (must)
- Altrimenti cross-cache attacks
- https://duasynt.com/blog/linux-kernel-heap-feng-shui-2022
- Non essere de-allocati prima di sfruttare la vulnerabilità
kmalloc-32

Heap Overflow (Read)


kmalloc-32

chunk A shm_file_data

Heap Overflow (Read)


kmalloc-32

read(A, 64); // Read chunk A and shm_file_data


// => leak vm_ops (kernel .data) => ASLR DEFEATED

chunk A shm_file_data

… READING

Heap Overflow (Read)


kmalloc-32

read(A, 64); // Read chunk A and shm_file_data


// => leak vm_ops (kernel .data) => ASLR DEFEATED

chunk A shm_file_data

… READING

Stesso concetto per Write Overflow

Heap Overflow (Read)

Potrebbero piacerti anche