Znalazłem zaskakujące zachowanie na Ubuntu 14.04 podczas korzystania strace
z 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?
źródło
execve
połą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).EPERM
Wydaje się pochodzić zget_dumpable()
(stosowane również w celu sprawdzenia, czy rdzeń dumping jest dozwolone, a tym samym „dumpable”) o nazwie z__ptrace_may_access()
wywoływana zptrace_attach()
nakernel/ptrace.c
.Odpowiedzi:
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>/mem
zwracaEPERM
. Jeśli plik binarny jest czytelny, zwracaEIO
. (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ą :()źródło