Tracciabile eseguibile senza permessi di lettura


17

Ho trovato alcuni comportamenti sorprendenti su Ubuntu 14.04 durante l'utilizzo stracesu un eseguibile, su cui non ho i permessi di lettura. Mi chiedo se si tratti di un bug o se alcuni standard impongano questo oscuro comportamento.

Per prima cosa vediamo cosa succede quando avvio un normale eseguibile in background e vi allego. Come previsto, funziona:

$ /bin/sleep 100 &
[2] 8078
$ strace -p 8078
Process 8078 attached
restart_syscall(<... resuming interrupted call ...>

Quindi provo con un eseguibile, sul quale non ho autorizzazioni di lettura su:

---x--x--x 1 root root 26280 Sep  3 09:37 sleep*

Non è consentito collegarsi a questo processo in esecuzione:

$ ./sleep 100 &
[1] 8089
$ strace -p 8089
strace: attach: ptrace(PTRACE_ATTACH, ...): Operation not permitted

Questo è anche quello che mi aspetterei. Concedere l'autorizzazione di esecuzione senza autorizzazione di lettura non farebbe molto bene, se potessi semplicemente collegare un debugger al processo e disporre effettivamente delle autorizzazioni di lettura sull'eseguibile in quel modo.

Ma se avvio l'eseguibile con un processo già tracciato, sono autorizzato a farlo:

$ strace ./sleep 100
execve("./sleep", ["./sleep", "100"], [/* 69 vars */]) = 0
brk(0)                                  = 0x9b7a000

Questo è inaspettato per me. Si tratta di un bug di sicurezza o è una funzione obbligatoria di uno standard?


3
@ StéphaneChazelas: Il punto è che può affrontarlo, semplicemente usandolo come argomento per stracciare. La causa principale sembra essere che nelle execvechiamate, le autorizzazioni di lettura del file eseguito non vengono ricontrollate se il processo è già tracciato. La sua domanda è se che è un bug di sicurezza o di una funzione di mandato (in quest'ultimo caso, sarei ancora considero un bug di sicurezza, solo un bug di sicurezza della specifica).
Celtschk,

@celtschk, scusa, ho letto la domanda troppo in fretta.
Stéphane Chazelas,

1
Il EPERMsembra provenire da get_dumpable()(utilizzato anche per controllare se un core dumping è permesso, quindi "dumpable") chiamato da __ptrace_may_access()chiamata da ptrace_attach()sopra kernel/ptrace.c.
ninjalj,

Quando un programma è in esecuzione, saranno disponibili al debugger informazioni sufficienti per generare un eseguibile eseguibile contenente il suo codice o il caricatore del programma scarterà cose come le correzioni di rilocazione che sarebbero necessarie per far funzionare effettivamente un programma?
Supercat,

@supercat Per quanto ne so, il debugger ha accesso a un singolo passaggio attraverso tutto il codice della modalità utente in esecuzione, incluso il codice di trasferimento. Con quel livello di accesso non dovrebbe essere troppo difficile riprodurre un eseguibile funzionante.
Kasperd,

Risposte:


7

Questa non è una risposta, piuttosto una raccolta di collegamenti e pensieri nel caso in cui qualcun altro vorrebbe studiare anche. Perché questa è una cosa abbastanza interessante.

Risposta correlata su Unix e Linux menzionando che è (o era, al momento non è possibile testare con il kernel vanilla) è possibile eseguire il dump della lettura dei soli binari in questo modo.

Grsecurity stava cercando di correggere questa opzione di configurazione e la patch stessa (anche se potrebbe essere cambiata da allora)

Questo commit sembra davvero che gli sviluppatori del kernel si preoccupino davvero solo del dumping dei binari di suid.

Ma in realtà da questa linea immagino che il kernel voglia prevenire il dumping di binari illeggibili riguardo allo stato dei SUID. E questa linea suggerisce che i binari non scaricabili non dovrebbero essere rintracciabili.

Quindi a prima vista sembra che tu abbia trovato un bug nel kernel con implicazioni di sicurezza. Ma non sono uno sviluppatore del kernel, quindi non posso dirlo con certezza. Vorrei chiedere su LKML.

Modifica: un'ulteriore scoperta, per quanto riguarda il debugger, menzionata nei commenti al post originale - dalla ricerca rapida (di nuovo) mi sembra che gdb usi i binari tracciati e /proc/<pid>/mem. Una volta che il binario in esecuzione non è leggibile, cat /proc/<pid>/memritorna EPERM. Se il file binario è leggibile, ritornaEIO . (Testato su Ubuntu 14.10, che esegue diverse patch di sicurezza, quindi potrebbe essere diverso dal kernel vanilla. Ancora una volta non ho kernel vanilla in esecuzione ovunque a portata di mano :()

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.