Niewielu początkujących programistów i administratorów wie o tej zmiennej, a warto przyjrzeć się bliżej jej możliwościom, które wprowadzają tyle samo dobrego, co i złego.
Co to jest?
Zmienna środowiskowa LD_PRELOAD, oraz jej plikowy odpowiednik /etc/ld.so.preload pozwalają na załadowanie przez glibc DOWOLNEJ dynamicznej biblioteki zewnętrznej w ciało wykonywanego programu przed jego wykonaniem. Odpowiednie użycie tego mechanizmu może pozwolić administratorowi serwera na zabezpieczenie dziurawego programu bez modyfikacji jego kodu (co niekiedy jest jedyną opcją). Jednak ta zaleta może być także jedną z większych pułapek! Pozwala ona przykryć praktycznie każdą funkcję obsługującą wywołania systemowe, czy te z innych bibliotek!
Możliwości
- Możliwość łatania zamkniętego oprogramowania;
- Stworzenie warstwy pośredniej pomiędzy systemem, a samą aplikacją — jej możliwości wykorzystuje fakeroot, torsocks, proxytunnel, a także mój projekt “MIU";
- Możliwość cichej ingerencji w dowolny program;
- Zakrycie funkcji innych bibliotek własnymi.
Dobrodzejstwo, czy przekleństwo?
Pomimo ułatwień dla administratorów, jak zwykle rozwiązanie tego typu na drugie dno. Programista aplikacji raczej nie przewidział, że ktoś w ten sposób będzie majstrował przy funkcjach które wywołuje — złośliwa, lub po prostu źle napisana biblioteka może spowodować nieprzewidywalne działanie takiego programu, nadużycia jego przywilejów, a w konsekwencji kompromitację systemu zabezpieczeń.
Metody ochrony
Zabezpieczenie plików konfiguracyjnych
Jeśli wspomniany plik /etc/ld.so.preload istnieje, należy sprawdzić jego zawartość, usunąć podejrzane wpisy, a sam plik zabezpieczyć ograniczając prawa dostępu i wykonując chattr +i /etc/ld.so.preload zablokować możliwość jego modyfikacji.
Ochrona zmiennej środowiska
Jeśli używamy programów typu sudo lub rozszerzenia PAM o nazwie pam_env, wymuśmy czyszczenie wspomnianej zmiennej.
Podsumowanie
Przykłady użycia tej techniki “nakładania” swojego kodu można zobaczyć w projekcie MIU. Pomimo kuszących możliwości należy się wystrzegać przed pisaniem ogromnych bibliotek ładowanych w ten sposób do każdego możliwego procesu jako systemu zabezpieczeń — każdy program będzie z osobna wykonywał wszystkie funkcje naszej biblioteki co ma zgubny wpływ na wydajność.