В этой короткой статье я хочу поделиться о том как получить RCE на системе с установленной CouchDB на большинстве инсталляций в локальной сети или во внешней сети, не защищенных брандмауэром. Для справки, в Shodan таких нашлось около полутора тысяч.
TL;DR: В конце статьи есть ссылки и способы эксплуатации.
Интро
CouchDB — документо-ориентированная система управления базами данных с открытым исходным кодом, не требующая описания схемы данных, распространяется свободно, написана на языке Erlang (Wiki).
Познакомился я с ней случайно, во время препарирования продукта по безопасности одной Южнокорейской компании (спойлер - нашел много интересного, готовлю статью). Сначала я подумал, что разработчики плохо знают ПО из которого они собрали свой “продукт”, для защиты других компаний от угроз ИБ, но оказалось что это массовая проблема.
Как и любая программа написанная на Erlang, CouchDB имеет встроенную поддержку распределенных вычислений (кластеризацию). Общение узлов кластера происходит по протоколу Erlang/OTP Distribution Protocol, который предусматривает возможность выполнения команд ОС через запрос модуля OS:
Разумеется, для подключения нужно знать секретную фразу - “cookie” в терминологии Erlang/OTP. Хранится эта фраза либо в файле .erlang.cookie либо в vm.args в каталоге с программой. В случае с CouchDB это файл /opt/couchdb/etc/vm.args
Инсталлер CouchDB оставляет значение куки по умолчанию даже при установке в режиме Standalone - “monster”.
Казалось бы ничего страшного, возьми да поменяй этот “пароль” по умолчанию, но проблема в том, что администратор может и не подозревать об этом функционале. Ведь информация о том, что нужно сменить куку есть только в мануале на сайте в разделе с настройкой кластера:
И это не мои домыслы - из полутора тысяч хостов на shodan.io при рандомной проверке я не наткнулся на CouchDB, администратор которой видел это предупреждение. Более того, создатели продукта безопасности, о котором я писал выше, тоже в их числе.
Другими словами, если вы наткнулись на хост с CouchDB в своей сети или сети заказчика, скорее всего он будет уязвим.
Обнаружение
Для того чтобы подключиться к хосту Erlang, нужно знать динамический порт ноды. За его обнаружение отвечает Erlang Port Mapper Daemon. Запросить у него информацию о нодах можно несколькими способами.
Отправив три байта непосредственно на порт демона tcp/4369:
echo -n -e "\x00\x01\x6e" | nc -vn <IP> 4369
Либо при помощи сканера nmap:
nmap -sV -Pn -n -T4 -p 4369 --script epmd-info <IP>
Эксплуатация
Для подключения к ноде, вам необходим доступ к TCP-порту EPMD (tcp/4369) и к порту самой ноды, который обычно выбирается случайно.
Для эксплуатации доступно несколько способов:
модуль Metasploit “erlang_cookie_rce”;
несколько скриптов доступных по запросу в Google “erlang cookie rce” ;
мой скрипт на Python: https://github.com/sadshade/erlang-otp-rce.
Взяв за основу код скрипта 1F98D, я добавил автоматический запрос информации у EPMD:
К слову, использовать стандартный эмулятор Erlang erl
для подключения к CouchDB не получится, так как необходимо задавать имя ноды в формате name@host.fqdn
, а он по умолчанию couchdb@127.0.0.1
. Вероятно разработчики CouchDB посчитали это надежным способом защиты.
Исправление
Исправить эту проблему достаточно просто, необходимо заменить куку по умолчанию на что-то другое в файле /opt/couchdb/etc/vm.args
Вот такой однострочник, запущенный от имени суперпользователя, сделает всю работу:
COOKIE=$(tr -dc 'a-zA-Z0-9' < /dev/urandom | head -c32);\
sed -i "s/-setcookie\ monster/-setcookie\ ${COOKIE}/g"\
/opt/couchdb/etc/vm.args
После чего необходимо перезапустить демон CouchDB.
Итог
Надеюсь эта статья будет полезна и поможет кому-то повысить безопасность своих систем, а кому-то взять очередной флаг.
Команда безопасности CouchDB обещала исправить инсталлер в будущих релизах, не особо заботясь о текущих инсталляциях.
Дополнительные ссылки для информации по теме:
UPD: Команда ChouchDB позаботилась о текущих инсталляциях и выпустила релиз 3.2.2. При обновлении инсталлер потребует смены cookie. Беру свои слова обратно.