Sovversione del flag di esecuzione su sistemi Linux. Perché è possibile?


23

Mentre leggevo questo , ho trovato il seguente exploit:

% cp /usr/bin/id ~
% chmod -x ~/id
% ls -al ~/id
-rw-r--r-- 1 edd edd 22020 2012-08-01 15:06 /home/edd/id
% ~/id
zsh: permission denied: /home/edd/id
% /lib/ld-linux.so.2 ~/id
uid=1001(edd) gid=1001(edd) groups=1001(edd),1002(wheel)

Questo frammento mostra che possiamo facilmente eludere le autorizzazioni di esecuzione del filesystem come un normale utente senza privilegi. L'ho eseguito su un Ubuntu 12.04.

Mentre il caricatore di Linux è un oggetto condiviso secondo il file (1), ha anche un punto di ingresso che consente di eseguirlo direttamente. Se eseguito in questo modo, il caricatore di Linux funge da interprete per i binari ELF.

Sulla mia macchina OpenBSD, tuttavia, questo exploit non è efficace, perché non è possibile eseguire il caricatore come programma. La pagina del manuale di OpenBSD dice: "ld.so è esso stesso un oggetto condiviso inizialmente caricato dal kernel.".

Prova questo su Solaris 9 e otterrai un segfault. Non sono sicuro di cosa succede altrove.

Le mie domande sono quindi:

  • Perché il caricatore di Linux (se eseguito direttamente) non controlla gli attributi del filesystem prima di interpretare un binario ELF?
  • Perché implementare un meccanismo progettato non consente l'esecuzione di file, se è così banalmente evitato? Ho perso qualcosa?

1
Nessun buon motivo, ma se sei mai riuscito a eliminare il tuo sistema libc(l'ho fatto una volta, aggiornando una scatola Arch), sarai grato per questa piccola stranezza.
new123456

1
@ new123456 oh dio, il canale IRC dopo quell'aggiornamento è stato doloroso essere presenti.
Rob

È il caricatore , non il linker.
Smetti di fare del male a Monica l'

Risposte:


33

L'obiettivo executedell'autorizzazione non è impedire l'esecuzione in generale . È (1) dire ai programmi quali file devono essere eseguiti e (2) impedire l'esecuzione come utente privilegiato , quando viene specificato il bit setuid (ecc.).

L'hack del linker è meno di un exploit di quanto sembri. È possibile eseguire qualsiasi file non eseguibile che si dispone delle autorizzazioni per leggere ancora più facilmente:

$ cp unexecutable_file ~/runme
$ chmod +x ~/runme
$ ~/runme

Vedi questa discussione sul forum Arch Linux .

In sintesi:

Contrassegnare i file che dovrebbero essere eseguiti

Quando si scrive uno script di shell, è possibile contrassegnarlo come eseguibile con chmod +x. Questo suggerisce alla tua shell che intendi che sia eseguibile (altrimenti, per quanto la shell lo sappia, è solo un altro file di testo semplice). La shell può quindi mostrarlo nel completamento della scheda durante la digitazione ./Tab.

Allo stesso modo: le something.ddirectory (ad es. init.d) Contengono script di shell di avvio o controllo che vengono in genere eseguiti automaticamente dai demoni. È possibile che si desideri inserire un commento o un file README nella directory come file di testo semplice. Oppure potresti voler disabilitare temporaneamente uno degli script. Puoi farlo cancellando il bit di esecuzione per quel particolare file. Questo dice al demone di ignorarlo.

Prevenire l'esecuzione privilegiata

Il setuidbit indica che quando si esegue il file, questo viene eseguito come utente specificato (ad es. Root).

Il post sul forum lo spiega bene:

Volete che un eseguibile sia setuid per alcuni utenti, ma volete che solo le persone di un gruppo specifico siano in grado di eseguirlo come setuid. Possono ancora eseguirlo copiando, ma il flag setuid si perde, quindi lo eseguiranno come se stessi, piuttosto che l'utente che possiede il file originale.


2
Grazie - ho trascurato il fatto che l'utente può copiare qualsiasi file che può leggere e quindi scegliere autorizzazioni arbitrarie.
Edd Barrett,

che ne dici di file con permesso di esecuzione ma senza permesso di lettura?
Lie Ryan

@LieRyan Che ne dici di loro?
Ripristina Monica il

@BrendanLong: Ovviamente non puoi copiarli, quindi non puoi cambiarne i permessi. (Ma perché non vorrai dirlo, l'unica cosa che potresti comunque fare con la copia è abbandonare il permesso di esecuzione)
MSalters

9

Se hai accesso in lettura a un file, puoi sempre crearne una copia.

Se riesci a fare una copia personale, puoi sempre contrassegnare quella copia eseguibile.

Questo non spiega il comportamento di ld-linux ma indica che potrebbe non essere una scappatoia di sicurezza molto utile.

Se vuoi una maggiore sicurezza, considera SELinux


Questo è molto vero
Edd Barrett,

Era solo una domanda concettuale. Suppongo che potresti impostare nonexec anche su filesystem.
Edd Barrett,

2

Osservando la domanda in modo leggermente diverso: come dice Mechanical Snail, l'autorizzazione di esecuzione su un file non ha lo scopo di impedire l'esecuzione. Tuttavia, l'opzione del file system "noexec" impedisce l'esecuzione e non è così facilmente aggirabile (non supportata da tutti i file system, ma certamente dai più popolari Linux). Se l'amministratore voleva impedire agli utenti di eseguire i propri programmi, potevano specificare l'opzione noexec nelle directory home e tmp e qualsiasi altro in cui gli utenti potessero essere in grado di creare file.

$ mount -o noexec /dev/sdd1 /test
$ cd /test
$ cp /usr/bin/id .
$ ./id
-bash: ./id: Permission denied

Apparentemente era possibile aggirare l'opzione noexec usando il trucco del caricatore menzionato nella domanda, ma che era stato corretto nel kernel alcune versioni precedenti.

A partire dal http://linux.die.net/man/8/mount :

noexec

Non consentire l'esecuzione diretta di alcun file binario sul filesystem montato. (Fino a poco tempo fa era possibile eseguire comunque i binari usando un comando come /lib/ld*.so / mnt / binary. Questo trucco fallisce da Linux 2.4.25 / 2.6.0.)

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.