GNU/Linux >> Linux Esercitazione >  >> Linux

Perché è necessario modificare le tabelle delle chiamate di sistema in Linux?

Puoi verificare se sono di sola lettura cercando i simboli del kernel. La "R" significa sola lettura.

$ grep sys_call_table /proc/kallsyms
0000000000000000 R sys_call_table
0000000000000000 R ia32_sys_call_table
0000000000000000 R x32_sys_call_table

Quindi lo sono di sola lettura e lo sono dal kernel 2.6.16. Tuttavia, un rootkit del kernel ha la capacità di renderli nuovamente scrivibili. Tutto ciò che deve fare è eseguire una funzione come questa in modalità kernel (direttamente o tramite gadget ROP sufficientemente flessibili, di cui ce ne sono molti) con ogni indirizzo come argomento:

static void set_addr_rw(const unsigned long addr)
{
    unsigned int level;
    pte_t *pte = lookup_address(addr, &level);

    if (pte->pte &~ _PAGE_RW)
        pte->pte |= _PAGE_RW;

    local_flush_tlb();
}

Questo cambia i permessi della tabella syscall e rende possibile modificarla. Se questo non funziona per qualsiasi motivo, la protezione da scrittura nel kernel può essere disabilitata globalmente con il seguente ASM:

cli
mov %cr0, %eax
and $~0x10000, %eax
mov %eax, %cr0
sti

Questo disabilita gli interrupt, disabilita il bit WP (Write-Protect) in CR0 e riabilita gli interrupt. L'uso dell'assembly consente di farlo funzionare nonostante write_cr0(read_cr0() & ~0x10000) in errore a causa della funzione predefinita per la scrittura su CR0 che ora blocca i bit sensibili. Assicurati di riattivare WP dopo, però!

Allora perché è contrassegnato come di sola lettura se è così facile da disabilitare? Uno dei motivi è che esistono vulnerabilità che consentono di modificare la memoria del kernel ma non necessariamente di eseguire direttamente il codice. Contrassegnando le aree critiche del kernel come di sola lettura, diventa più difficile sfruttarle senza trovare un ulteriore vulnerabilità per contrassegnare le pagine come scrivibili (o disabilitare del tutto la protezione da scrittura). Ora, questo non fornisce una sicurezza molto forte, quindi il motivo principale per cui è contrassegnato come di sola lettura è rendere più semplice l'arresto di accidentale sovrascrive dal causare un arresto anomalo del sistema catastrofico e irreversibile.

* L'esempio particolare fornito è per un processore x86_64. La prima tabella è per le chiamate di sistema in modalità nativa a 64 bit (x64). Il secondo è per le chiamate di sistema in modalità a 32 bit (IA32). Il terzo è per l'ABI x32 syscall raramente utilizzato che consente ai programmi di utilizzare tutte le funzionalità della modalità a 64 bit (ad es. SSE invece di x87 per le operazioni in virgola mobile) mentre utilizzano puntatori e valori a 32 bit.

† ​​L'API interna del kernel cambia continuamente, quindi questa funzione esatta potrebbe non funzionare su kernel più vecchi o più recenti. Disattivazione globale di CR0.WP in ASM tuttavia è garantito il funzionamento su tutti i sistemi x86 indipendentemente dalla versione del kernel.


Come notato da forest, il moderno Linux non lo consente, ma è facile da sovrascrivere.

Tuttavia, storicamente è stato utile (e forse lo è ancora) per motivi di sicurezza:patch a caldo contro le vulnerabilità. Negli anni '90 e nei primi anni 2000, ogni volta che veniva annunciata una nuova vulnerabilità per una chiamata di sistema di cui non avevo assolutamente bisogno (ptrace era molto comune allora), scriverei un modulo del kernel per sovrascrivere l'indirizzo della funzione nella tabella delle chiamate di sistema con l'indirizzo di una funzione che ha appena eseguito return -ENOSYS; . Ciò ha eliminato la superficie di attacco fino a quando non è stato disponibile un kernel aggiornato. Per alcune chiamate di sistema dubbie non avevo bisogno che presentassero ripetutamente vulnerabilità, l'ho fatto solo preventivamente per loro e ho lasciato il modulo sempre abilitato.


Linux
  1. Come controllare la versione del kernel su Linux

  2. Linux:perché non è presente alcun file system Rootfs sul sistema?

  3. Linux:perché gli utenti Linux non utilizzano una chiamata di sistema per ottenere l'ora corrente?

  4. Linux:metodi di chiamata di sistema nel nuovo kernel?

  5. Tabella delle chiamate di sistema Linux o cheatsheet per Assembly

Perché il mio bisogno di controllo mi ha fatto passare a Linux

Linux è un sistema operativo o un kernel?

Perché abbiamo bisogno di un bootloader in un dispositivo integrato?

Perché abbiamo bisogno del file .so.1 in Linux?

Come rimuovere un sistema Linux?

Fork vs Clone su 2.6 Kernel Linux