2012-01-26 7 views
6

Kombinacja set-uid i względnej ścieżki w sekcji INTERP pliku binarnego ELF jest bardzo niebezpieczna.Problem bezpieczeństwa z zestawem-uid i względną ścieżką dla INTERP (dynamiczny linker) w ELF

Nie jestem pewien, w jaki sposób i gdzie ten problem powinien być zgłaszane, ale wydaje mi się, jakby ogólnej kwestii bezpieczeństwa dotyczące jak dynamiczne łączenie w pracach linux/glibc, więc pozwól mi wyjaśnić, co to jest:

Rozważ zbudowanie dynamicznie połączonego pliku binarnego i określenie względnej ścieżki w sekcji ELF INTERP (za pomocą opcji --dynamic-linker gcc), aby można było redystrybuować niestandardową wersję glibc do dynamicznie połączonej aplikacji komercyjnej (gdzie nie wolno ci łączyć statycznie przeciwko glibc LGPL, ale nadal musisz sprawić, by twoja praca binarna działała na różnych dystrybucjach Linuksa mających różne wersje glibc).

Jeśli wymienisz plik binarny na root i umieścisz flagę set-uid na twoim pliku binarnym, to faktycznie stanie się rootkitem. Wykonując go z innego katalogu, pozwala zastąpić plik wykonywalny dynamicznego linkera, który zostanie wykonany z uprawnieniami administratora.

Aby to wykazać, spójrz na następujący kod C (issue.c):

#include <stdio.h> 

// 
// build with: 
// gcc -DNAME=\"vulnarable\" -o issue -Wl,--dynamic-linker,.lib64/ld-linux-x86-64.so.2 issue.c 
// sudo chown root issue 
// sudo chmod u+s issue 
// now build some code to be executed with root permissions (we use the same issue.c): 
// mkdir -p .lib64/ 
// gcc -DNAME=\"rootkit\" -o .lib64/ld-linux-x86-64.so.2 --static issue.c 
// 

int main(int argc, char* argv[]) 
{ 
    printf("(%s) euid:%d\n", NAME, geteuid()); 
} 

Jeśli teraz wykonać binarny set-UID jak ten

./issue 

lub nawet tylko robi to

ldd issue 

zamiast się co można się spodziewać, np:

(vulnarable) euid:0 

otrzymasz:

(rootkit) euid:0 

Teraz chodzi o to można zastąpić ld-linux-x86-64.so.6 binarnych z cokolwiek chcesz.

Wydaje się, że podobne problemy zostały rozwiązane, nie rozwiązując $ ORIGIN w RPATH lub ignorując LD_LIBRARY_PATH, jeśli ustawiono flagę set-uid.

Więc zastanawiam się, czy INTERP w ELF musi zostać zignorowane, gdy ustawiona jest flaga set-uid (tj. Za pomocą domyślnego dynamicznego linkera - /lib32/ld-linux.so.2 lub/lib64/ld- linux-x86-64.so.2)?

Co sądzisz, gdzie należy to naprawić lub zgłosić - w glibc lub jądrze?

+0

Sugerujesz sposób na uzyskanie dostępu do roota, co wymaga użycia 'sudo'. Co oznacza, że ​​potrzebujesz do tego dostępu z uprawnieniami administratora. – ugoren

+0

Na jakim kernelu i dystrybucji testowałeś to? Mam problem z odtworzeniem problemu w systemie Ubuntu 10.04 z jądrem 2.6.32-38-generic: wszystko, co otrzymuję, to '(./issue) euid: 0', które jest zgodne z oczekiwaniami programu setuid. –

+0

@ugoren: Niezupełnie. Zakładając, że luka jest rzeczywista, wszystkie osoby atakujące będą musiały znaleźć zagrożony program setuid. Polecenia 'sudo' w instrukcjach są właśnie po to, aby je utworzyć, aby można było wykazać problem. –

Odpowiedz

5

Tak, nie jest bezpiecznie mieć binarny setuid określający interpreter w niezabezpieczonej lokalizacji (wspominasz względną ścieżkę, ale ustalona na świecie stała ścieżka ma ten sam problem). Ale jest to logiczna konkluzja projektu ELF, a dodanie specjalnej sprawy do obsługi INTERP dla plików binarnych z setuidem nie jest drogą do zrobienia. Jest to przypadek "Doktorze, boli, kiedy to robię. - Nie rób tego. " Tak, ta kombinacja jest niebezpieczna, więc po prostu jej nie używaj! Więzienie z tłumaczem ELF jest czymś dość zaawansowanym, więc nie powinieneś tego robić, jeśli nie rozumiesz, co robisz, w takim przypadku możesz logicznie stwierdzić, co jest bezpieczne, a czego nie.

Zaawansowane funkcje ELF/POSIX/Unix/cokolwiek innego dają potężne możliwości strzelania sobie w stopę, ponieważ są potężne.Jeśli chcesz pozbyć się każdej możliwej złej sytuacji, będziesz miał system znacznie mniej elastyczny i trudniejszy do zaprogramowania, a jednocześnie posiadający kilka dziur w nim.

+0

Uzgodnione. To tak, jakby wywołać 'system()' w programie setuid za pomocą polecenia, które nie jest ścieżką bezwzględną. Powinienem dodać, że jeśli chce się używać niestandardowej wersji libc w programie, nie należy tego robić za pomocą względnego INTERP; po prostu połącz je statycznie. LGPL na ogół to umożliwia. – Dolda2000

+0

@ F'x: dobra odpowiedź, zgadzam się na bycie ostrożnym w miejscu, w którym umieścisz flagę set-uid, jednak twój argument będzie miał również zastosowanie do RPATH/RUNPATH w ELF lub LD_LIBRARY_PATH env var - w tym przypadku (flaga set-uid), RPATH/RUNPATH i LD_LIBRARY_PATH są ignorowane razem. Dlaczego więc nie ignorować INTERP? – siddhadev

+2

Nie dotyczy LD_LIBRARY_PATH, ponieważ może być ustawiony przez użytkownika, a nie jako twórca pliku wykonywalnego. Jeśli cokolwiek, myślę, że to dziwne, że RUNPATH rzeczywiście jest obsługiwany, a nie na odwrót. – Dolda2000

Powiązane problemy