Uprawnienia administratora w Linuxie dla każdego - siedmioletni bug w różnych dystrybucjach

Uprawnienia administratora w Linuxie dla każdego - siedmioletni bug w różnych dystrybucjach

Jak do tego doszło... w sumie wiadomo. Błąd znaleziono w aplikacji polkit odpowiadającej za autoryzację użytkownika, kiedy zechce mu się wykonać czynność na poziomie administratora.

polkit to nie jest to okienko. Ale hasło wpisywane tutaj do niego trafia.
A to już owszem polkit sam w sobie. Grzecznie pyta o hasło administratora.

W niektórych przypadkach polkit sam zdecyduje, czy użytkownik ma zezwolenie czy nie, a w innych zapyta o hasło w postaci graficznej lub tekstowej (jak wyżej).

No dobrze, ale na czym polega błąd?

Trzeba zabić, ale w odpowiednim czasie!

Słabość w zabezpieczeniach można wykorzystać np. za pomocą dbus-send. Usługa ta odpowiada za komunikację pomiędzy innymi apkami i usługami systemu. Przy jej odpowiednim użyciu można wypracować taki exploit:

dbus-send --system --dest=org.freedesktop.Accounts --type=method_call --print-reply /org/freedesktop/Accounts org.freedesktop.Accounts.CreateUser string:produkcja string:"NaProdukcji XYZ" int32:1 & sleep 0.008s ; kill $!

Jest to dosyć skomplikowana komenda na utworzenie w systemie nowego użytkownika, ale przecież nie robimy tego zwyczajną metodą. Skupić się należy tutaj na samej końcówce - sleep i kill. Jak się okazuje, polkit odpytuje dbus-daemon o ID żądającego procesu w tym połączeniu . Co się jednak stanie, kiedy połączenie nie istnieje? dbus-daemon zachowuje się w tej sytuacji w porządku i zwraca błąd. polkit próbując ten błąd przetworzyć, traktuje go jak żądanie pochodzące od samego systemu (a konkretniej - od procesu o UID 0). Natychmiastowo więc zezwala na wykonanie jakiejkolwiek akcji, gdyż myśli, że chce ją wykonać system, lecz w rzeczywistości jest to użytkownik bądź atakujący.

Ważny jest też czynnik czasu. Okazuje się, że polkit odpytuje dbus-daemon wiele razy o identyfikator procesu, który go wywołał (tutaj - dbus-send). Zazwyczaj robi to dobrze, ale nie zawsze. Jeżeli ubije się polecenie dbus-send za wcześnie, w polkit zadziała dobra partia kodu i żądanie zostanie odrzucone. Komendę z exploitem należy więc powtarzać, dopóki nie wykona się wadliwy kod. Czasem należy dostroić czas oczekiwania, który i tak jest już śmiesznie niski (w przykładzie powyżej to osiem tysięcznych sekundy!).

Pogubiłeś się czytelniku? Spokojnie, ja też. Dlatego przedstawiam rysunek pomocniczy.

Dostanę plusa za wykorzystanie Painta?

Grafika ta jednak może zbyt bardzo upraszczać temat. W zasadzie powinna wyglądać tak:

Oba procesy powyżej kreskowanej linii są nieautoryzowane - działają na prawach zwykłego użytkownika. Poniżej znajdują się procesy systemowe z prawami admina. Pośrodku znajduje się demon, który odpowiada za komunikację między procesami.

No dobrze, skoro utworzyliśmy sobie konto użytkownika o prawach administratora, należy mu ustawić hasło. Z exploitem to już żaden problem, wystarczy tylko jeden prosty trik! No i poznać ID konta, co można zrobić za pomocą polecenia id.

dbus-send --system --dest=org.freedesktop.Accounts --type=method_call --print-reply /org/freedesktop/Accounts/User1002 org.freedesktop.Accounts.User.SetPassword string:'$5$u4ak5dxgVq1b4LSj$O/6G9SK.qW./ynvub5G0JFx76yVEBhAcxtuHtJfhuo0' string:GoldenEye & sleep 0.008s ; kill $!

Przy okazji: kto odgadnie, jakie jest oryginalne hasło? :)

Najtrudniejsze za nami, wystarczy się tylko przelogować. Należy wklepać su - produkcja i podać ustalone przez nas wcześniej hasło. Gotowe!

Ale ja kce wincyj detaluufff!

Błąd został wprowadzony aż siedem lat temu w commicie bfa5036b i wydany w wersji 0.113. W przypadku Debiana i pochodnych numeracja jest inna, ponieważ dlaczego nie, i tam błąd zawiera się w wersji 0.105-26. Co ciekawsze, stabilny Debian nie załapał się na nowsze wydanie polkit, ale wersja testowa owszem (a wraz z nią Ubuntu i pochodne). Dosyć wolna implementacja nowej wersji pakietu spowodowała taki paradoks, że Ubuntu 18.04 nie zawierało wadliwej paczki, a 20.04 już tak, co prezentuje poniższa tabelka.

Nie tylko Debilian, ale także Bubuntu oraz dziwne czapki.

Swoją drogą, tabela ta wydaje się już nieaktualna, gdyż Ubuntu 20.04 już załatano, ale nadal jest przydatna w ukazywaniu śmieszności tej sytuacji. Błąd sprzed siedmiu lat nie występował w wersji z 2018 roku, ale w wersji z 2020 już tak. Fajnie!

Błąd w polkit został wyceniony przez RedHat na 7.8 w skali CVSS. Może wydawać się to zbyt małym wynikiem, ale przypominam - w atakowanym systemie nadal należy mieć dostęp do zwykłego konta użytkownika. Inaczej ani rusz.


Dokładniej o tym błędzie można poczytać na blogu GitHuba we wpisie Kevina Backhouse - link. W tym artykule trochę uprościłem niektóre tematy, aby były bardziej przystępne, lecz odważnych odsyłam do źródła.