2013-04-12 10 views
5

Czy istnieje (kompatybilne) sposobem fałszywej (jako root) w gniazda Unix (gniazd File System)poświadczeń rówieśnicze, który można otrzymać przez getsockopt() opcja SO_PEERCRED?Gniazda UNIX: czy można sfałszować getsockopt() SO_PEERCRED?

Tło:
muszę podłączyć do serwera aplikacji (których nie można modyfikować), który sprawdza UID procesu, który łączy się z nim za pośrednictwem SO_PEERCRED. Chciałbym sfałszować informacje, aby móc podłączyć do aplikacji jako root, również.

UPDATE

wyjaśnić kwestię:
Szukam nieinwazyjny sposób, że serwer widzi konkretnej sieci peer UID/GID. Rozwiązania są zniechęcony które trzeba zmienić jądra (lub wziąć użycie modułów jądra) lub które zmienia proces serwera lub jego załadunku/proces łączenie w jakikolwiek sposób (LD_PRELOAD, przechwyceniu wywołania systemowego itd.).

Zasadniczo rozwiązanie powinno działać, gdy działa na dowolnym serwerze Linux (lub unixie w ogóle) bez żadnych specjalnych wymagań. Proces serwera może już być uruchomiony.

+1

Jeśli jesteś "root", dlaczego nie po prostu "setuid"? Możesz to zrobić z całkowicie kontrolowanego procesu potomnego, aby uniknąć utraty przywileju. – nneonneo

+0

Nie jestem pewien, ale pod Linuksem jest ustawiona liczba ósemkowa z flagami w '/ proc//fdinfo/'. – alk

+1

Czy można kontrolować uruchamianie procesu serwera, tj. Czy można użyć LD_PRELOAD do zmodyfikowania funkcji biblioteki/sashcunk thunk w celu zmiany poświadczonych poświadczeń? –

Odpowiedz

-1

Nie. Powodem jest to, że mechanizm udostępniający identyfikator UID i identyfikator GID rówieśnika to wewnętrzny dla jądra i nie można podszyć jądra! Jądro używa PID peera do dedukcji efektywnych poświadczeń peera. Dzieje się tak, gdy jedna strona ma connect na gnieździe. Zobacz wywołanie copy_peercred() od unix_stream_connect() w net/unix/af_unix.c. Nie ma żadnego sposobu, aby peer mógł zmienić wysyłane dane lub gniazdo, które przekona jądro, że PID peera nie jest tym, czym jest. Różni się to od gniazd AF_INET, w których jądro nie ma wewnętrznej wiedzy o procesie peera i widzi tylko dane w nagłówkach pakietów IP wysyłanych przez partnera.

Jedyną rzeczą, którą możesz zrobić, aby uzyskać ten efekt, jest ustawienie efektywnego UID procesu peera na root lub jakikolwiek inny UID/GID, a do tego potrzebujesz albo hasła root albo sudo uprawnień.

+1

Ale ty * możesz * podszyć jądro - jako root możesz modyfikować zachowanie uruchomionego jądra, ładując moduł. –

+0

@ChrisStratton: Żaden moduł, który napiszesz, nie może zmienić zachowania gniazd domenowych systemu Unix. –

+0

Jesteś ** poważnie ** mylnie w to uwierzyć. Najłatwiejszym rozwiązaniem byłoby stworzenie modułu, który przekieruje wywołanie systemowe w punkcie wysyłania zaraz po wejściu do jądra, ale ostateczną opcją jest także modyfikacja wewnętrznych elementów gniazda domeny unix. Pamiętaj, że coś, co nie jest eksportowane, nie jest * chronione *, jest tylko * trudniejsze do zlokalizowania * - i nie wszystko, co jest trudne, gdy źródło jest otwarte, a ustawienia kompilacji prawdopodobnie znane. –

3

Jesteś na właściwej linii. Proces root'a ma uprawnienia do podszywania się pod takie rzeczy, problem polega tylko na tym, że SO_PEERCRED nie udostępnia żadnego mechanizmu ani interfejsu API dla procesu określania, jaka tożsamość powinna być przedstawiona uczestnikowi.

Dwie rzeczy, które możesz zrobić:

  1. Tymczasowo upuść root (setreuid(desired,-1)) po dokonaniu połączenia connect. Połączenie w domenie unixowej jest stemplowane poświadczeniami peera w czasie procesu o nazwie connect (i listen dzieje się w drugą stronę). SO_PEERCRED nie podaje poświadczeń peera w danym momencie. Następnie możesz wznowić root.

  2. Lepiej, użyj innego interfejsu API. Interfejs API przekazujący komunikaty pozwala procesowi wybrać to, co identyfikuje, aby przedstawić go jednemu z uczestników. Zadzwoń pod numer sendmsg z numerem struct cmsg, który zawiera poświadczenia, które chcesz wysłać. Jądro zignoruje poświadczenia określone przez nieuprawnionego użytkownika i zawsze upewni się, że druga strona widzi rzeczywistą tożsamość, ale proces uprzywilejowany może udawać, że jest kimkolwiek innym. Jest to lepsze dopasowanie do twoich potrzeb, ponieważ upuszczenie i odzyskanie root'a jest ryzykownym działaniem, a w tym przypadku niepotrzebnym. Google dla "SCM_CREDENTIALS" (lub "man -K" dla niego w twoim systemie), aby pobrać próbki kodu.

+1

Jeśli serwer nie ustawi opcji gniazda SO_PASSCRED i nie odczyta poświadczeń, wówczas rozwiązanie 2 nie będzie działać. Jeśli używa tylko SO_PEERCRED, utkniesz przy prostym, jednorazowym uwierzytelnianiu PID. W przypadku przykładu SO_PEERCRED patrz http://man7.org/tlpi/code/online/dist/sockets/scm_cred_recv.c.html. W każdym razie, aby root użył SCM_CREDENTIALS do obniżenia uprawnień, trudno jest "podszyć się". –

+1

OK, nazwij to "podszywanie się", a potem ... Wydaje mi się, że jeśli wysyłasz jakieś referencje, nie powinieneś ustawiać SO_PASSCRED na drugim końcu; powinni po prostu przybyć do ciebie na wyjściu 'recvmsg'. Być może to zależy od systemu operacyjnego? Nie używam Linuksa. SO_PASSCRED jest zwykle używany do odczytywania poświadczeń, ale druga strona ich nie pisze; mówi kernelowi, aby przekazał ci referencje każdego z komunikatów (szczególnie miłe dla gniazd DGRAM). –

+1

Przeczytaj przykład "Musimy ustawić opcję gniazda SO_PASSCRED, aby otrzymywać poświadczenia". To samo dotyczy BSD/FreeBSD, gdzie opcja nazywa się SCM_CREDS. –

Powiązane problemy