kw.
7

Słów kilka o system() z stdlib.h

Po stosunkowo długiej przerwie czas wrócić do bloga. Dziś pod lupę wpadnie pewien mankament, z którym spotkałem się już kilkakrotnie: używanie system() z stdlib.h przez programistów.


Konsolowe aplikacje mają to do siebie, że wypluwają na czarne okienko terminala wiele informacji. Z kolei programiści maja to do siebie, ze bardzo często informacje te chcąc zaraz po wyświetleniu wyczyścić. Zerknijmy na kawałek kodu, pisanego pod Linuksa:

#include <stdlib.h>
int main()
{
(...)
system("clear");
return 0;
}

Zastanówmy się, skąd program wie, gdzie znajduje się wywoływany clear? Nie podaliśmy mu przecież pełnej ścieżki (/usr/bin/clear). Ale przecież wywołując clear bezpośrednio z terminala (bash -c clear) również nie podajemy pełnej ścieżki do programu clear.
Okazuje się, że system() zna pełną ścieżkę do wywoływanego programu w bardzo prosty sposób – korzysta ze zmiennej środowiskowej $PATH

Skoro mamy pełną kontrolę nad zmienną środowiskową $PATH, to możemy zmusić nasz program, aby wykonywał fałszywy program clear. Utwórzmy w lokalizacji /home/X program, otwierający powłokę i nazwijmy go clear (nie zapomnijmy o chmod +x). Teraz dodajmy na początek naszej zmiennej środowiskowej lokalizację naszego fake-programu:

PATH = "/home/X;$PATH"

Teraz, kiedy system() będzie próbował uruchomić clear znajdzie go najpierw w /home/X. Dzięki temu wykona się nasz podstawiony clear, uruchomi on powłokę, a powłoka ta odziedziczy takie uprawnienia, jakie miał skompilowany program z system().

Jak temu zapobiegać? Na pierwszy rzut oka wystarczy podawać pełne ścieżki do uruchamianych przez system() programów. Okazuje się jednak, że bawiąc się chroot’em również możemy system() oszukać. Najlepszym rozwiązaniem jest więc niekorzystanie z tej funkcji.

  

Dodaj komentarz

*

Audio-CAPTCHA