Śledzenie pliku wykonywalnego bez uprawnień do odczytu

17

Znalazłem zaskakujące zachowanie na Ubuntu 14.04 podczas korzystania stracez pliku wykonywalnego, na którym nie mam uprawnień do odczytu. Zastanawiam się, czy to jest błąd, czy też jakiś standard nakazuje to niejasne zachowanie.

Najpierw zobaczmy, co się stanie, gdy uruchomię zwykły plik wykonywalny w tle i dołączę do niego. Zgodnie z oczekiwaniami to działa:

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

Następnie próbuję z plikiem wykonywalnym, do którego nie mam uprawnień do odczytu:

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

Dołączanie do tego uruchomionego procesu jest niedozwolone:

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

Tego też bym się spodziewał. Udzielenie pozwolenia na wykonanie bez uprawnienia do odczytu nie przyniosłoby wiele dobrego, gdybym mógł po prostu dołączyć do procesu debugera i skutecznie mieć w ten sposób uprawnienia do odczytu pliku wykonywalnego.

Ale jeśli uruchomię plik wykonywalny w ramach już prześledzonego procesu, wolno mi to zrobić:

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

To jest dla mnie nieoczekiwane. Czy to błąd bezpieczeństwa, czy jest to funkcja wymagana przez standard?

kasperd
źródło
3
@ StéphaneChazelas: Chodzi o to, że może go śledzić, wykorzystując go jako argument do strace. Wydaje się, że główną przyczyną jest to, że w przypadku execvepołączeń uprawnienia do odczytu wykonanego pliku nie są sprawdzane ponownie, jeśli proces jest już śledzony. Jego pytanie dotyczy tego , czy jest to błąd bezpieczeństwa, czy też wymagana funkcja (jeśli to drugie, nadal uważałbym to za błąd bezpieczeństwa, po prostu błąd bezpieczeństwa specyfikacji).
celtschk
@celtschk, przepraszam, przeczytałem pytanie zbyt szybko.
Stéphane Chazelas
1
EPERMWydaje się pochodzić z get_dumpable()(stosowane również w celu sprawdzenia, czy rdzeń dumping jest dozwolone, a tym samym „dumpable”) o nazwie z __ptrace_may_access()wywoływana z ptrace_attach()na kernel/ptrace.c.
ninjalj
Czy podczas działania programu debuger będzie miał dostęp do wystarczających informacji, aby wygenerować wykonywalny plik wykonywalny zawierający jego kod, czy też program ładujący program odrzuci takie poprawki, jak poprawki relokacji, które byłyby potrzebne, aby program faktycznie działał?
supercat
@supercat O ile mi wiadomo, debugger ma dostęp do jednego kroku przez cały wykonywany kod trybu użytkownika, w tym kod relokacji. Przy takim poziomie dostępu odtworzenie działającego pliku wykonywalnego nie powinno być zbyt trudne.
kasperd

Odpowiedzi:

7

To nie jest odpowiedź, a raczej zbiór linków i przemyśleń na wypadek, gdyby ktoś chciał się uczyć. Ponieważ jest to dość interesująca rzecz.

Powiązana odpowiedź na Unixa i Linuksa, w której wspomniano, że w ten sposób (lub nie można było teraz testować jądra wanilii) można zrzucić tylko pliki binarne do odczytu.

Grsecurity próbował naprawić tę opcję konfiguracji i samą łatkę (choć od tego czasu mogła się zmienić)

To zatwierdzenie naprawdę sprawia wrażenie, że programiści jądra naprawdę troszczą się tylko o zrzucanie plików binarnych suid.

Ale właściwie z tego wiersza domyślam się, że jądro chce zapobiec zrzucaniu nieczytelnych plików binarnych dotyczących statusu SUID. Ta linia sugeruje, że pliki binarne, których nie można zrzucić, nie powinny być identyfikowalne.

Na pierwszy rzut oka wydaje się, że znalazłeś błąd w jądrze, który ma wpływ na bezpieczeństwo. Ale nie jestem programistą jądra, więc nie mogę powiedzieć na pewno. Chciałbym zapytać o LKML.

Edycja: jeszcze jedno stwierdzenie, dotyczące debuggera, wspomniane w komentarzach do oryginalnego postu - od szybkiego tworzenia (ponownie) wydaje mi się, że gdb używa śledzonych plików binarnych i /proc/<pid>/mem. Gdy działający plik binarny nie jest czytelny, cat /proc/<pid>/memzwraca EPERM. Jeśli plik binarny jest czytelny, zwraca EIO. (Przetestowałem to na Ubuntu 14.10, który uruchamia kilka poprawek bezpieczeństwa, więc może się różnić od jądra wanilii. Znowu nie mam jądra wanilii działającego pod ręką :()

Lis
źródło