Skype представляет собой одну из самых популярных VoIP-программ, установленную на миллионах компьютеров по всему миру, владельцы которых даже и не подозревают, какая опасность им грозит. А опасность им грозит весьма серьезная: от утечки конфиденциальной информации до проникновения червей и попадания на трафик, не говоря уже о таких мелочах, как нежелание Skype работать при активном SoftICE. Я все это благополучно разгрыз и теперь выставляю продукты своей жизнедеятельности на всеобщее обозрение .
Skype, созданный отцами-основателями скандально известной Kazaa и унаследовавший от своей прародительницы самые худшие ее черты, работает по принципу самоорганизующейся распределенной пиринговой сети (distributed self-organized peer-to-peer network, P2P). Skype – это черный ящик с многоуровневой системой шифрования, напичканного антиотладочными приемами исполняемого файла, считывающий с компьютера конфиденциальную информацию и передающий ее в сеть по закрытому протоколу. Последний обходит брандмауэры и сурово маскирует свой трафик, препятствуя его блокированию. Все это превращает Skype в идеального переносчика вирусов, червей и дронов, создающих свои собственные распределенные сети внутри Skype-сети. К тому же, Skype довольно бесцеремонно обращается с ресурсами твоего узла, используя его для поддержания связи между остальными узлами Skype-сети, напрягая ЦП и генерируя мощный поток трафика. А трафик, как известно, редко бывает бесплатным (особенно в России), так что кажущаяся бесплатность звонков весьма условна: за узлы с «тонкими» каналами расплачиваются «толстые» владельцы.
Skype активно изучается в хакерских лабораториях и security-организациях по всему миру, и большинство исследователей единодушно сходятся во мнении, что Skype - это дьявольски хитрая программа, написанная бесспорно талантливыми людьми в стиле Black Magic Art. Skype не брезгует грязными трюками, создающими огромные проблемы, о которых я и собираюсь рассказать.
Анализ исполняемого файла Skype
Исполняемый файл Skype-клиента представляет собой настоящий шедевр хакерского искусства, вобравший в себя множество интересных и достаточно могучих защитных механизмов. Для противодействия им требуются не только мощные инструментальные средства (отладчики, дизассемблеры, дамперы и т.д.) и знания/навыки, но еще и куча свободного времени.
Двоичный файл полностью зашифрован и динамически расшифровывается по мере загрузки в память. Причем сброс дампа невозможен, точнее, затруднен тем обстоятельством, что стартовый код после выполнения очищается, в результате чего мы получаем exe, который не запускается. Оригинальная таблица импорта не содержит ничего интересного, и API-функции подключаются уже в процессе распаковки. Проверка целостности кода выполняется из разных мест в случайном порядке (преимущественно при входящих звонках), поэтому поиск защитных процедур представляет собой весьма нетривиальную задачу. Тем более что они основаны на криптографических RSA-сигнатурах и снабжены полиморфными генераторами, которые в случайном порядке переставляют инструкции ADD, XOR, SUB и др., перемешивая их с левыми машинными командами.
Статический вызов функций (по жестко прописанному адресу) практически не встречается, и все важные процедуры вызываются по динамически вычисляемому указателю, пропущенному через обфускатор. Следовательно, дизассемблер нам тут уже не поможет, и приходится браться за отладчик.
А вот про отладчик следует сказать отдельно. Skype распознает SoftICE даже при наличии установленного IceExt, наотрез отказываясь запускаться. Это забавно, поскольку для взлома самого Skype отладчик SoftICE не очень-то и нужен, ведь существуют и другие инструменты подобного рода, среди которых в первую очередь хотелось бы отметить The Rasta Ring 0 Debugger, или сокращенно [RR0D], не обнаруживаемый Skype-клиентом и, как и следует из его названия, работающий на уровне ядра. В принципе, можно воспользоваться и отладчиком прикладного уровня (например, стремительно набирающим популярность OllyDbg). Только при этом важно помнить, что Skype легко обнаруживает программные точки останова, представляющие собой однобайтовую машинную инструкцию с опкодом CCh, записывающуюся поверх отлаживаемого кода. А для предотвращения пошаговой трассировки Skype осуществляет замеры времени выполнения определенных участков кода, для прохождения через которые приходится использовать полноценные эмуляторы PC с интегрированным отладчиком, например, знаменитый BOCHS.
Наконец, когда исполняемый файл распакован и все проверки пройдены, защита вычисляет контрольную сумму и преобразует ее в указатель, по которому передается управление, пробуждающее Skype.
Последовательность распаковки исполняемого файла
Антиотладочные приемы, с помощью которых Skype обнаруживает загруженный SoftICE
Проблема в том, что Skype очень следит за своей целостью, поэтому попытка исправления jnz на jmp short работает только до первого входящего звонка, после которого Skype падает и обратно уже не поднимается. Специально для таких хитроумных защит еще во времена MS-DOS была разработана техника онлайн-патча, при которой исправление программы осуществляется непосредственно в оперативной памяти, а после успешного прохождения проверки на наличие SoftICE совершается откат, чтобы не волновать процедуру проверки целости.
Беглая трассировка Skype с помощью OllyDbg быстро выявляет защитный код, выполняющий проверку на присутствие SoftICE
Архитектура распределенной сети
На атомарном уровне структура Skype-сети состоит из обычных узлов (normal/ordinal node/host/nest), обозначаемых аббревиатурой SC (Skype Client), и super-узлов (super node/host/nest), которым соответствует аббревиатура SN. Любой узел, который имеет публичный IP-адрес (тот, который маршрутизируется в интернет) и обладает достаточно широким каналом, автоматически становится super-узлом и гонит через себя трафик обычных узлов, помогая им преодолеть защиты типа брандмауэров или трансляторов сетевых адресов (NAT) и равномерно распределяя нагрузку между хостами. В этом и состоит суть самоорганизующейся распределенной децентрализованной пиринговой сети, единственным централизованным элементом которой является Skype-login-сервер, отвечающий за процедуру авторизации Skype-клиентов и гарантирующий уникальность позывных для всей распределенной сети.
Важно подчеркнуть, что связь между узлами осуществляется не напрямую, а через цепочку super-узлов. Серверов в общепринятом смысле этого слова (таких, например, как в сети eDonkey) в Skype-сети нет. Любой узел с установленным Skype-клиентом является потенциальным сервером, которым он автоматически становится при наличии достаточных системных ресурсов (объема оперативной памяти, быстродействия процессора и пропускной способности сетевого канала).
Каждый узел Skype-сети хранит перечень IP-адресов и портов известных ему super-узлов в динамически обновляемых кэш-таблицах (Host Cache Tables, HC-tables). Начиная с версии Skype 1.0, кэш-таблица представляет собой простой XML-файл, в незашифрованном виде записанный на диске в домашней директории пользователя.
Структура децентрализованной самоорганизующейся пиринговой Skype-сети
Skype-клиенты за отдельную плату могут принимать входящие звонки с обычных телефонов и совершать подобные звонки. Однако в PC2PC-обмене эти серверы никак не участвуют, поэтому мы не будем на них останавливаться.
Помимо звонков внутри Skype-сети, пользователи могут звонить и на обычные телефоны, а также принимать с них звонки.
Как Skype обходит брандмауэры
Протокол обмена между Skype-клиентами совершенно недокументирован, и поэтому вся информация о нем получена методами реинженеринга: дизассемблирования Skype-клиентов, анализа перехваченного сетевого трафика и т.д. Поскольку существует огромное количество значительно различающихся между собой версий Skype-клиентов, то описание протокола может содержать неточности, во всяком случае, open-source-клиента еще никто не написал.
Сразу же после своего запуска Skype-клиент открывает TCP- и UDP-порты. Их номера случайным образом задаются при инсталляции и могут быть в любой момент изменены через диалог конфигурации, что затрудняет блокирование Skype-трафика на брандмауэре. Помимо этого, Skype открывает порты 80 (HTTP) и 443, однако они не являются жизненно важными, и, даже если их заблокировать, Skype ничуть не огорчится.
Структура IP-пакета при работе Skype по протоколу UDP
Ситуация осложняется тем, что Skype шифрует трафик, активно используя продвинутые технологии обфускации, препятствующие выделению постоянных сигнатур в полях заголовков. Алгоритмы шифрования меняются от версии к версии, к тому же выпущено множество специальных версий для разных стран мира, чьи законы налагают определенные ограничения на длину ключа или выбранные криптографические алгоритмы. Но в целом механизм шифрования выглядит так, как показано на рисунке.
Механизм шифрования, используемый Skype
Skype-клиенты крайне деликатно обходятся с брандмауэрами и трансляторами сетевых адресов, просачиваясь сквозь них через хорошо известные протоколы STUN и TURN. Протокол STUN уже вошел в Библию Интернета и подробно описан в RFC-3489. Что же касается TURN'а, то он все еще находится в разработке и в настоящее время доступна лишь черновая версия стандарта: wwwjdrosen.net/midcom_turn.html.
Так что, с юридической точки зрения, действия Skype законны и не попадают под статью. STUN, расшифровывающийся как Simple Traversal of User Datagram Protocol (UDP) Through Network Address Translators (NATs) (простое проникновение датаграмм протокола UDP через транслятор сетевых адресов (NAT)), представляет собой отличное средство, которое страдает, однако, рядом ограничений и не работает в следующих случаях:
1. если путь во внешнюю сеть прегражден злобным брандмауэром, режущим весь UDP;
2. если на пути во внешнюю сеть стоит симметричный транслятор сетевых адресов.
Ну, с брандмауэром все понятно. Если UDP закрыт, то никак его не откроешь. А вот симметричный транслятор сетевых адресов (symmetric NAT) — это что за штука? Не углубляясь в технические детали, скажем, что симметричный NAT представляет собой разновидность обыкновенного транслятора, требующего, чтобы целевой IP-адрес и порт транслируемого пакета совпадали с внешним (external) IP-адресом и портом. Если один и тот же узел посылает пакеты с одинаковыми исходными IP-адресами и портами по разным направлениям, NAT будет вынужден транслировать их на другие порты. Таким образом, чтобы отправить внутреннему узлу UDP-пакет, внешний узел должен первым делом получить запрос от внутреннего узла. Самостоятельно инициировать соединение внешний узел не в состоянии, поскольку NAT просто не знает, на какой внутренний IP и порт следует транслировать неожиданно сваливавшийся UDP-пакет.
Эта проблема решается протоколом TURN (Traversal Using Relay NAT), технические подробности работы которого описаны по вышеупомянутому адресу и большинству читателей совершенно неинтересны. Гораздо важнее другое — протокол TURN значительно увеличивает латентность и теряет большое количество UDP-пакетов (packet loss), что далеко не лучшим образом сказывается на качестве и устойчивости связи, но полное отсутствие связи - еще хуже. Так что пользователям Skype стоит радоваться, а не жаловаться!
Структура Skype-сети, в которой присутствуют Skype-клиенты за NAT и брандмауэрами
Вот только администраторы этой радости почему-то не разделяют, наглухо закрывая UDP-трафик (тем более что большинству нормальных программ он не нужен). Немного поворчав для приличия (замуровали, демоны!), Skype автоматически переключается на чистый TCP, отрубить который администратору никто не позволит. Правда, поколдовав над брандмауэром, тот может закрыть все неиспользуемые порты, но в том-то и подвох, что неиспользуемых портов в природе не встречается! При соединении с удаленным узлом операционная система назначает клиенту любой свободный TCP/UDP-порт, на который будут приходить пакеты. То есть, если мы подключаемся к web-серверу по 80-му порту, наш локальный порт может оказаться 1369-м, 6927-м или еще каким-нибудь другим. Закрыв все порты, мы лишимся возможности устанавливать TCP/UDP-соединения!
Единственный выход — обрубить всем пользователям локальной сети прямой доступ в интернет, заставив их ходить через proxy-сервер. Однако даже такие драконовские меры не решат проблемы, поскольку Skype просто прочитает конфигурацию браузера и воспользуется proxy-сервером как своим родным!
Skype, работающий через proxy-сервер, конфигурация которого прочитана из настроек браузера
Как заблокировать Skype-трафик
Разработчики Skype предостерегают администраторов от попыток выявления и блокирования его трафика (типа: «Все равно у вас ничего не получится!»). И действительно, распознать Skype-трафик очень сложно, а заблокировать его можно только по содержимому, которое зашифровано и не содержит никаких предсказуемых последовательностей. К счастью для администраторов, создатели Skype, при всей своей гениальности, допустили ряд оплошностей, оставив часть трафика незашифрованной. UDP-соединение использует открытый протокол для получения публичных IP-адресов super-узлов, что вполне может быть выявлено анализатором трафика. Это раз. TCP-соединение использует один и тот же RC4-поток дважды, что позволяет нам восстановить 10 первых байт ключа, расшифровав часть постоянных полей заголовков Skype-протокола. Это два! Кстати, весьма полезная вещь для шпионажа за чужими разговорами! Однако мне не известен ни один готовый блокиратор Skype-трафика, а писать свой собственный — лениво, да и времени нет.
Повторное использование RC4-потока позволяет восстановить 10 байт ключа из 12-ти, расшифровывая часть Skype-трафика
Распознать и заблокировать UDP-трафик намного проще. Каждый фрейм начинается с двухбайтового идентификационного номера (ID) и типа пакета (payload). В UDP-пакет вложен 39-байтный NACK-пакет, пропущенный через обфускатор и содержащий следующие данные:
* идентификатор пакета (непостоянен и варьируется от пакета к пакету);
* номер функции (func), пропущенный через обфускатор, но func & 8Fh всегда равно 7h;
* IP отправителя;
* IP получателя.
Таким образом, чтобы заблокировать UDP-трафик, генерируемый Skype, достаточно добавить в брандмауэр следующее правило:
iptables -I FORWARD -p udp -m length --length 39 -m u32
--u32 '27&0 x8f=7' --u32 '31=0 x527c4833 ' -j DROP
Структура NACK-пакета
К сожалению, блокировка UDP-трафика ничего не решает, поскольку Skype автоматом переходит на TCP, но тут есть одна небольшая зацепка. Заголовки входящих IP-пакетов, относящиеся к протоколу обмена SSL-ключами (SSL key-exchange packets), содержат нехарактерный для «нормальных» приложений идентификатор 170301h, возвращаемый в ответ на запрос с идентификатором 160301h (стандартный SSL версии 3.1). Таким образом, блокирование всех входящих пакетов, содержащих в заголовке 170301h, серьезно озадачит Skype, и текущие версии потеряют работоспособность. Вот только надолго ли…
Распознание Skype-трафика по необычному идентификатору во время обращения к Login Server при обмене SSL-ключами
Для детектирования и блокирования Skype-трафика можно использовать и другие программно-аппаратные средства, например, PRX от Ipoque или Cisco Network-Based Application Recognition (NBAR). Однако все они недостаточно эффективны, так как разработчики Skype не сидят сложа руки, и если кому-то удается найти надежный способ блокировки его поганого трафика, в следующих версиях поганец появляется вновь.
Армии дронов, или как зомбировать Skype
Дешевизна голосовых разговоров вызвала бурный рост популярности Skype, сеть которого на 27 апреля 2006 года, по официальным данным, составила свыше 100 миллионов зарегистрированных пользователей. А сегодня совершают, по меньшей мере, один Skype-звонок в день свыше 700 тысяч человек! Несложно спрогнозировать, что в скором времени в Skype войдет львиная доля узлов интернета, что имеет как положительную, так и отрицательную сторону.
Хакеры уже давно догадались использовать Skype для распространения вирусов и организации распределенных атак, которым очень сложно воспрепятствовать - Skype-трафик надежно зашифрован и не может быть проанализирован антивирусами, заблокирован брандмауэрами или распознан системами обнаружения вторжения.
Естественно, чтобы захватить Skype-узел, хакер должен найти способ передать на него зловредный код, что при соблюдении всех мер безопасности он ни за что не сможет сделать. Но, как и всякое другое программное обеспечение, Skype подвержен ошибкам, в том числе и ошибкам переполнения, одна из которых была обнаружена 25 сентября 2005 года. Сейчас она уже давно исправлена и представляет лишь исторический интерес, но с ней все-таки стоит познакомиться поближе (а сделать это можно на Skype.com/security/Skype-sb-2005-03.html или на seclists.org/fulldisclosure/2005/Oct/0533.html).
Возможность передачи управления на shell-код позволяла атакующему овладевать любым Skype-узлом, а также всеми известными ему super-узлами и т.д. Над распределенной сетью нависла глобальная угроза, и просто чудо, что она не закончилась катастрофой. Однако, как показывает практика, там, где есть одна ошибка, рано или поздно появляются и другие. Закрытость исходных текстов и множество антиотладочных приемов (затрудняющих тестирование программы) этому только способствуют!
Другая опасная «вкусность» Skype заключается в открытости его API. Пойдя навстречу сторонним разработчикам, создатели Skype предусмотрели возможность интеграции любой прикладной программы со Skype-клиентом. Правда, при этом на экран выводится грозное предупреждение, что такая-то программа хочет пользоваться Skype API: разрешить или послать ее на фиг? Естественно, большинство пользователей на подобные вопросы отвечают утвердительно. Уже привыкшие к надоедливым предупреждениям, они инстинктивно давят «Yes» и только потом начинают думать, а что же они, собственно, разрешили?
Понятное дело, что, чтобы использовать Skype API, зловредную программу нужно как-то доставить на компьютер. Раньше для этого применялась электронная почта, успешно фильтруемая антивирусами, но количество пользователей, запустивших исполняемый файл, все равно исчислялось миллионами. Теперь же для рассылки вирусов можно использовать сам Skype. Локальный антивирус — единственное средство обороны, потенциально способное отразить атаку. Но, если он и установлен, распознать неизвестный науке вирус он не в состоянии даже при наличии антивирусных баз первой свежести (эвристика пока все-таки работает больше на рекламу, чем на конечный результат).
Важно, что протокол Skype уже частично расшифрован и созданы хакерские инструменты, позволяющие взаимодействовать со Skype-узлами в обход стандартных Skype-клиентов, и даже без сервера регистрации! И хотя в настоящее время дело ограничивается простым сбором адресов super-узлов, существует принципиальная возможность создания своих собственных сетей на базе распределенной Skype-сети, главная ошибка разработчиков которой заключается в том, что Skype-узлы безоговорочно доверяют друг другу и вся «безопасность» зиждется лишь на закрытости протокола.
Географическое распределение super-узлов Skype по планете
Заключение
Заканчивая статью, я хотел бы спросить: что же все-таки скрывают создатели Skype в недрах своего кода? Почему, распространяя программу бесплатно, они зажимают исходные тексты и используют закрытый протокол, вызывая тем самым недоверие специалистов по безопасности? Для чего бесплатной программе столь навороченная защита, снижающая производительность и потребляющая большое количество памяти, ведь ломать ее никто не собирается? Почему вообще Skype-клиент реализован как черный ящик?
Вопросы риторические. Но чует мой хвост, неспроста все это!
WWW
General Skype Analysis - мини-портал с кучей ссылок на статьи и прочие ресурсы, посвященные анализу Skype и методам борьбы с ним: http://www1.cs.columbia.edu/~salman/Skype.
Skype Trojan - тезисная презентация Walter Sprenger, показывающая, как можно использовать Skype-сеть для распространения червей и прочей заразы: http://www.csnc.ch/static/download/misc … _v1.1.pdf.
How to use Skype with Softice? - любопытная статья, рассказывающая, почему Skype-клиент не работает при установленном SoftICE и как это побороть: http://gcasiez.perso.orange.fr/Skypeandsoftice.html.
Skype Reads Your BIOS and Motherboard Serial Number - заметка в блоге, разоблачающая махинации, скрыто проделываемые Skype, читающим BIOS и серийный номер материнской платы: http://www.pagetable.com/?p=27.