it-swarm-eu.dev

Monitoraggio delle chiamate di sistema (in modo affidabile e sicuro)

Esiste un metodo affidabile per "monitorare" le chiamate di sistema su Linux?

C'è strace per esempio per monitorare chiamate e segnali di sistema. C'è un modo per evitare un processo da strace? Se sì, esiste un altro metodo affidabile e sicuro per "monitorare" le chiamate di sistema (e, forse, ricevere segnali), dal quale un processo non può sfuggire (presupponendo una corretta implementazione di Linux)?

15

Su Linux, è possibile monitorare in modo affidabile una selezione di chiamate di sistema o accessi ai file con sottosistema di controllo . Assicurati che il demone auditd sia in esecuzione, quindi configura ciò con cui vuoi accedere auditctl . Ogni operazione registrata viene registrata in /var/log/audit/audit.log (su configurazioni tipiche).

Troverai semplici esempi di auditctl use su questo sito , su Server Fault e su nix Stack Exchange .

strace o programmi associati che utilizzano ptrace sono modi affidabili per monitorare le chiamate di sistema, ma diffiderei di usarle su un programma dannoso. Non saprei dirti come mi è venuto in mente, ma dovrebbe essere possibile per un programma monitorato effettuare le giuste chiamate ptrace per eludere il monitoraggio.

Si noti che un programma dannoso potrebbe generare un processo che non è stato verificato e può eseguire codice che non verrà registrato. Ad esempio, potrebbe usare mmap per scrivere su un file senza che il contenuto del file non compaia mai come argomenti delle chiamate di sistema, rendere questo file eseguibile e generare un processo che lo esegue. Il processo generato in genere può interrompere l'albero del processo con qualcosa come ssh localhost. Se controlli tutti i processi eseguiti da un determinato utente (al contrario di un solo processo e dei suoi discendenti), sarai in grado di registrare tutto.

In caso affermativo, esiste un altro metodo affidabile e sicuro per "monitorare" le chiamate di sistema (e, forse, ricevere segnali), che il processo non può interrompere (presupponendo una corretta implementazione di Linux)?

Reiterare in modo leggermente diverso ciò che D.W. ha già detto, ptrace è una chiamata di sistema che strace, gdb e simili fanno per monitorare le azioni di un processo. Ci sono due problemi con questo approccio:

  1. Come probabilmente saprai, l'aggancio delle chiamate di sistema è una tecnica preferita degli autori di rootkit. È del tutto possibile sostituire ptrace, fornire l'output di un altro processo o qualche altro malfunzionamento.
  2. I processi non sono sempre scritti per essere inviati volontariamente ai debugger. Potresti leggere questo set di sfide (focalizzato su win32 - vedi la prima voce e continua a leggere per renderlo difficile) da un'azienda di appsec (non ho collegamenti con loro). Mentre focalizzato sul meccanismo IsDebuggerPresent(), simile esistono soluzioni per ptrace . Se vuoi vederlo in natura e avere skype installato su un box Linux, prova a eseguire il debug.

    Ripetendo queste tecniche qui, ci sono due chiari meccanismi anti-ptrace:

    if (ptrace(PTRACE_TRACEME, 0, 0, 0) < 0) {
        printf("being ptraced\n");
        exit(1);
    }
    

    Questo metodo si basa sul fatto che un processo non può essere tracciato due volte. Se non riesci a rintracciarti, verrai rintracciato.

    struct timespec spec;
    
    signal(SIGALRM, SIG_IGN);
    alarm(1);
    spec.tv_sec = 2;
    spec.tv_nsec = 0;
    if (nanosleep(&spec, NULL) < 0) {
        /* EINTR */
        printf("being ptraced\n");
        exit(1);
    }
    

    Per spiegarlo, dai un'occhiata a nanosleep() e leggi l'articolo originale. In termini semplici, nanosleep() è una chiamata di sistema non riavviabile e tornerà presto quando un segnale viene gestito dal processo. Questo particolare processo, quando non verrà eseguito il debug, non gestirà quel particolare segnale e quindi non verrà risvegliato. Tuttavia, un processo ptraced lo gestirà, facendo sì che nanosleep ritorni presto. Un altro esempio in cui ciò accade è la chiamata di sistema select().

In definitiva, puoi mitigare gli effetti di 1 assicurando l'integrità del tuo sistema prima di avviare e applicare misure di sicurezza sufficienti e un kernel opportunamente configurato.

Cosa puoi fare in modo affidabile su 2? Non molto senza modificare il codice binario originale, poiché qualsiasi tecnica per il debug introdurrà incoerenze osservabili o problemi di implementazione da qualche parte.

tl; dr ptrace ti aiuterà se il processo di destinazione non è stato scritto pensando ai debugger.

10
user2213

Linux Audit Framework supporta il monitoraggio di syscall - credo che sia quello che stai cercando.

5
john

Sì. strace è un modo ragionevole per monitorare le chiamate di sistema e i loro argomenti, purché il processo monitorato non sia dannoso. Se il processo monitorato è dannoso ed è stato scritto per sfuggire alla strage, mi aspetto che possa farlo. strace non è stato scritto come uno strumento di sicurezza e posso ipotizzare diversi modi in cui il processo potrebbe sconfiggerlo. Vedere, ad esempio, Robert Watson, Sfruttare le vulnerabilità della concorrenza nei wrapper di chiamate di sistema o Tal Garfinkel, Trappole e insidie: problemi pratici negli strumenti di sicurezza basati sull'interposizione di chiamate di sistema .

Se sei preoccupato per il codice dannoso, ti consigliamo di utilizzare un sandbox progettato per la sicurezza, piuttosto che uno strumento come strace non progettato per la sicurezza. L'approccio generale alla costruzione di un tale sandbox consiste nell'utilizzare l'interposizione delle chiamate di sistema sia per contenere il processo monitorato, sia per monitorarne le azioni. Un metodo portatile consiste nell'utilizzare ptrace, sebbene ciò possa introdurre un sovraccarico prestazionale non banale poiché forza un cambio di contesto ad ogni chiamata di sistema. Su Solaris, è possibile utilizzare/proc;/proc consente di specificare il sottoinsieme di chiamate di sistema che si desidera includere nel wrapping, che consente di ottenere prestazioni migliori a spese della compatibilità.

Dai un'occhiata a Plash, Systrace e Subterfugue, per vedere alcuni sistemi funzionanti che usano questo tipo di metodi. Guarda anche il sandbox di Chrome, che utilizza una varietà di meccanismi (incluso seccomp su Linux).

4
D.W.

Che dire del monitoraggio delle chiamate di sistema sul lato del kernel usando un'istanza gdb esterna.

Questo potrebbe essere fatto impostando una macchina virtuale configurata per eseguire il codice di interesse. Quindi QEMU e KVM (per quanto ne so) devono essere configurati per aprire una porta per il debug gdb del kernel. (Vedi le guide blow).

Se this VM viene avviato gdb potrebbe essere collegato al suo kernel durante l'avvio.

Il prossimo passo è impostare le proprietà gdb e i punti di interruzione in modo che vengano attivati ​​su ogni esecuzione (e console) che imposta il codice di interesse come nuovo programma. Quindi lascia correre gdb fino a quando non raggiunge questo punto di interruzione. A questo punto durante l'esecuzione del programma è possibile estrarre il pid del processo che esegue il codice di interesse e impostare punti di interruzione in gdb che vengono colpiti (nel codice del kernel) su qualsiasi chiamata di sistema di questo processo (incluso fork ed execve chiamate che potrebbero portare a ulteriori processi da osservare).

In teoria questa dovrebbe essere una buona soluzione che è difficile da doge.

Un problema è che tutto nel sistema guest diventa orribilmente lento e potresti ricevere un'enorme quantità di chiamate indesiderate come catture accessorie (che devi filtrare usando gdb ...). Potrebbe essere necessario estendere gdb aggiuntivo usando python per far funzionare i breakpoint condizionali con le condizioni richieste (specialmente per un rilevamento automatico dei processi secondari).

Guida su come collegare gdb al guest: Whamcloud Wiki , ReadHat Helpdesk , Stackoverflow

(Non ho provato queste guide. Ho usato gdb alcuni anni fa per eseguire il debug di alcuni dettagli del kernel per un progetto studentesco. Lì ho usato una semplice condizione su un breakpoint per rilevare le chiamate fork di un processo specifico.)

Inoltre ci sono alcune altre tecniche per debug di un kernel .

PS: tieni presente che ci sono modi per sfuggire a una macchina virtuale (un vecchio esempio ).

0
msebas