Самый лучший квест: Руководство по прохождению HackQuest 2010В данной публикации описано прохождение большинства предложенных этапов хак-квеста, который проходил в конце августа на фестивале Chaos Constructions 2010, а затем в урезанном формате был доступен online на портале SecurityLab. HackQuest 2010 — это открытые соревнования по защите информации, сутью которых является выполнение ряда разнообразных заданий, связанных с информационной безопасностью: webhacking, social engineering, reverse engineering и тому подобное. Участникам хак-квеста предоставлялась полная свобода выбора по прохождению заданий — их можно было выполнять в любой последовательности. Для захвата одного ключа (флага) необходимо было воспользоваться чередой реальных уязвимостей в самых настоящих (продуктивных) системах, так что участники конкурса могли почувствовать себя реальными взломщиками :). Правда, результаты соревнований продемонстрировали, что для большинства участников задания HackQuest 2010 оказались довольно сложными. Эта статья представляет собой руководство по прохождению некоторых из них. Задание №1: КлассикаПосле предварительного сканирования сети обнаруживался вебсайт некого турагентства под названием «Хаос». Немного побродив по этому сайту, в разделе поиска можно было по выдаваемому базой данных MySQL сообщению об ошибке отыскать уязвимость типа «Внедрение операторов SQL» (insert-based). Стоит отметить, что сайт был защищен mod_security с правилами по умолчанию. Уязвимый SQL-запрос имеет вид:
Таким образом, запрос для проведения атаки может выглядеть так:
Приведенный выше запрос отобразит идентификатор пользователя, от имени которого веб-приложение взаимодействует с базой данных. Как это работает? 1. Используется конструкция /*!...sql-код...*/, которая позволяет выполнять SQL-код в обход правилам по умолчанию всех версий mod_security, включая последние версии (см. devteev.blogspot.com/2009/10/sql-injection-waf.html). 2. Используется символ «+» (%2b) для работы со строками (подробнее см. https://rdot.org/forum/showthread.php?t=60). 3. Используется универсальный способ проброса полезной нагрузки в сообщении об ошибке (см. qwazar.ru/?p=7):
4. SQL–запрос приводится к синтаксически корректному виду путем добавления конструкции «,0)», а все лишнее обрезается с использованием двух символов тире. Чтобы обрезать конец добавляемого запроса на веб-сервере, используется пробельный символ «+» (в HTTP GET-запросе является эквивалентом пробелу). Развивая вектор атаки, требовалось стянуть полезные данные из базы данных. Для MySQL 5.x это довольно просто, так как в этой версии присутствует база information_schema, которая содержит всю необходимую информацию о структуре СУБД. Таким образом, атака с использованием уязвимости SQL Injection сводилась к типовому набору запросов:
На выходе — таблица admins.
А на десерт — имена колонок login и password в таблице admins.
В результате получаем данные из таблицы admins (имя пользователя и MD5-хеш от пароля). После получения MD5-хеша его требовалось восстановить. Самый простой способ — воспользоваться бесплатными сервисами восстановления MD5-хешей по «радужным таблицам» (например, xmd5.org). Став обладателем имени пользователя и пароля, самое время вбить их в какой-нибудь интерфейс :). Обнаружить таковой можно в файле robots.txt, расположенном в корневом каталоге веб-сервера. После доступа в админку выдается сообщение об ошибке, по которой легко определяется уязвимость класса Remote File Including (RFI). Эксплуатация подобных уязвимостей является довольно тривиальной задачей и сводится к указа нию атакуемому веб-приложению запросить файл с сервера атакующего. Атакующий же подготавливает файл, содержащий код на языке PHP. Пример самого простого кода, позволяющего выполнять команды операционной системы:
После получения возможности выполнения команд ОС требовалось скопировать приватный RSA-ключ одного из пользователей системы, а затем, используя полученный RSA-ключ, реализовать доступ к системе по протоколу SSH и получить доступ к долгожданному флагу. Именно за последовательность SQLi->RFI->RSA задание и получило кодовое имя «Классика». Задание №2: Не классикаНа этапе исследования сети можно было, аналогично предыдущему заданию, наткнуться на некое веб-приложение, связанное с SMS-сервисами. Беглый анализ позволял обнаружить уязвимость типа «Внедрение операторов SQL» (selection-based) в базе данных PostgreSQL:
Приведенный выше запрос выведет версию используемой базы данных в сообщении об ошибке. Это работает, так как, во-первых, приложение возвращает сообщение об ошибке СУБД пользователю, а во-вторых, используется приведение строкового типа к числовому. Используя базу information_schema эквивалентно MySQL 5.x, можно легко и быстро восстановить структуру СУБД:
Следуя подсказке, что в системе зарегистрирован миллионный пользователь, которого ждет специальное вознаграждение, требовалось получить доступ именно к его учетной записи (интересно, что участники старательно не замечали эту подсказку и сливали всю таблицу пользователей или пытались создать этого «козырного» миллионного пользователя). Получив доступ в интерфейс счастливчика, можно заметить новый интерфейс, в котором содержится уязвимость типа File Including (вернее даже Local File Including/LFI). Сложность эксплуатации уязвимости заключается в том, что происходит проверка длины поступающего запроса, и, если он не равен шестнадцати символам, то поступающий запрос не попадает в функцию include(). Решением этой проблемы является использование самого короткого PHP веб-шелла (см. raz0r.name/releases/mega-reliz-samyj-korotkij-shell):
Как это работает?
Получив таким образом возможность выполнения команд на сервере, требовалось получить список пользователей системы (/etc/passwd). После чего, используя любой инструментарий подбора пароля к сервису telnet (например, THC-Hydra, Medusa, ncrack), следовало осуществить подбор используемых паролей пользователями системы. Перебор должен был позволить выявить пользователя, у которого установлен пароль, совпадающий с его идентификатором. Доступ по протоколу telnet с привилегиями этого пользователя давал возможность получить содержимое очередного флага. Задание №3: Самописный веб-серверДовольно простую уязвимость можно было отыскать на веб-сервере, который светил своей мордочкой задание с крякмисом. Это одно из самых простых заданий хак-квеста, в котором требовалось найти уязвимость типа «Выход за корневой каталог веб-сервера» (path traversal). Указанную уязвимость легко можно было обнаружить автоматизированным путем с использованием соответствующих инструментов (поэтому очень настораживают конечные результаты online-соревнований securitylab.ru/hq2010/list.php). Эксплуатация уязвимости требовала лишь отправить веб-серверу запрос следующего вида: «GET /../../../root/.history HTTP/1.1». Получив содержимое истории вводимых администратором команд, с помощью консольной магии можно было легко получить очередной флаг. Задание №4: Доска объявленийВ игровой сети располагалось веб-приложение, которое эмулировало работу электронной доски объявлений. Получив доступ к исходному коду приложения (для этого требовалось обратиться к index.bak) можно было восстановить всю логику работы приложения, которая заключалась в следующем: если пользователь пытался добавить более одного сообщения в течение одной минуты, то его IP-адрес добавлялся в черный список (файл blacklist.php). Уязвимость заключалась в том, что приложение проверяло переменную окружения веб-сервера HTTP_X_FORWARDED_FOR, и, если указанная переменная была установлена, то вместо IP-адреса в черный список попадало содержимое заголовка браузера X-Forwarded-For без какойлибо проверки (на самом деле идея баги была позаимствована у приложения CuteNews). Эксплуатация уязвимости сводилась к установке в качестве заголовка X-Forwarded-For чего-то вроде этого:
После получения возможности выполнения команд на сервере и прочтения истории команд, вводимых администратором, можно было понять, где спрятан заветный ключ. Задание №5: Cross-Site ScriptingКогда речь заходит про атаки вида XSS (предполагается, что ты понимаешь, что эти три буквы значат :)), то все сразу вспоминают про обычные отраженные и хранимые XSS, и лишь иногда — еще и про так называемые DOM-based XSS (см. owasp.org/index.php/DOM_Based_XSS). А ведь последние известны как минимум с 2005 года, когда были описаны в известной статье Амита Клейна (см. webappsec.org/projects/articles/071105.shtml). Если коротко, то данный тип XSS базируется на том, что входные данные веб-приложения принимаются и используются для модификации DOM на стороне веб-браузера в контексте JavaScript-языка. Сам HTTP-ответ сервера таким образом никак не изменяется! Классический пример данной уязвимости:
Эксплуатация представляет собой передачу JavaScript-нагрузки в параметре default следующим образом:
Всё было бы замечательно, но современные веб-браузеры решили обезопасить пользователей и параметры адреса передаются в JavaScript-контекст в url-закодированном виде, добавляя проблем атакующему и делая эксплуатацию не такой тривиальной. К сожалению, такая защита не является достаточным средством, поскольку вариантов использования параметров адреса довольно много, и они вовсе не ограничиваются приведенным выше примером. А с развитием веб-приложений (переносом всё большей части логики работы на сторону веббраузера) этот вид Cross-Site Scripting ждет перерождение. Но вернемся к нашему заданию. Оно было воплощено в виде очередного клона популярного сервиса микроблоггинга. Открываем и изучаем HTML-код главной страницы. В самом конце замечаем уязвимый участок кода счётчика посещений:
Дальнейшие действия очевидны — воруем сессию администратора сервиса, который, судя по всему, достаточно активно им пользуется. Для этого:
Задание №6: ХостингПроводя исследование игровой сети, можно наткнуться на сервер, который светил страницей по умолчанию веб-сервера Apache на 80-м порту, а также использовался в качестве SMTP- и DNS-сервера. Чтобы понять, какие сайты обслуживает веб-сервер, требовалось осуществить перенос DNS-зоны. Но какой зоны? Ответ на этот вопрос мог быть получен из обратной DNS-зоны, которая также обслуживалась на этом сервере. Узнаем про DNS-суффикс, используемый веб-сервером: dig Осуществляем перенос DNS-зоны:
Далее требовалось настроиться на использование этого DNSсервера (или прописать соответствующие имена в файлик hosts). После беглого осмотра доступных сайтов можно было обнаружить уязвимость типа Local File Including на сайте Василия Пупкина. Для ее эксплуатации и дальнейшего развития атаки единственным способом являлось использование SMTP-демона в качестве транспорта для проброса полезной нагрузки (см. xakep.ru/post/49508/default.asp). Например, следующим образом:
Проделав ряд шаманских манипуляций с SMTP-демоном, становилось возможным получить доступ к выполнению команд операционной системы:
Но даже с таким доступом к серверу чтобы получить игровой ключ, нужно очень постараться. Причина этому — модуль SuEXEC, который разграничивал доступ к соседним сайтам. Для обхода указанных ограничений требовалось использовать символические ссылки (см. kernelpanik.org/docs/kernelpanik/suexec.en.pdf). Это было возможным только по причине того, что в конфигурации веб-сервера использовалась директива AllowOverride All. Дальнейшая атака сводилась к выполнению следующих запросов: 1. Включение возможности использования символических ссылок путем переопределения настроек на каталог сайта vasya.cc10.site:
2. Осуществление доступа к каталогу сайта, содержащему игровой «флаг»:
3. Осуществление доступа к файлу, содержащему данные для аутентификации на сайте r00t.cc10.site:
4. Расшифровка полученного MD5-хеша (например, с использование PasswordsPro или John the Ripper) 5. Доступ к содержимому сайта r00t.cc10.site и получение игрового ключа Задание №7: Позитивный PDFВ одном из заданий хак-квеста предлагалось изучить (позитивный) pdf-файл, который обращался к веб-приложению с использованием встроенных алгоритмов шифрования. По специальным маркерам можно было сделать вывод, что в pdf-файл внедрен еще и flash-объект. Далее, также по специальному маркеру, необходимо было определить, что swf внутри pdf-файла внедрен с использованием сжатия zlib. Таким образом получить «чистый» swf-файл возможно, например, при помощи библиотеки zlib языка Python. Следующим этапом являлось восстановление алгоритма формирования запроса к веб-приложению по выдернутому swf-файлу. Для этого можно было воспользоваться утилитой swfdump из пакета swftools. Особое внимание следовало обратить на функцию Obfuscate — она и выполняет функцию генерации запроса к серверу. Сам ключ, по которому выполняется шифрование, нужно было восстановить из следующего фрагмента кода:
Зная ключ и алгоритм шифрования, возможно генерировать произвольные запросы к веб-приложению. Чтобы получить игровой флаг, требовалось сформировать запрос к вебприложению с использованием простейшей техники эксплуатации уязвимости «Внедрение операторов SQL». Задание №8: СтеганографияСтеганография — это наука о скрытой передаче информации путем сохранения в тайне самого факта передачи. В отличие от криптографии, которая скрывает содержимое секретного сообщения, стеганография скрывает само его существование. В цифровом мире в качестве контейнера для скрываемой информации обычно используют мультимедиа-объекты (изображения, видео, аудио, текстуры 3D-объектов) и внесение искажений, которые находятся ниже порога чувствительности среднестатистического человека и не приводят к заметным изменениям этих объектов. Но, как несложно догадаться, контейнером может выступить не только мультимедиа-файл. В нашем случае в роли контейнера выступил HTML-код! Дело в том, что веб-браузер при отображении страницы игнорирует идущие подряд пробельные символы, если они не заданы как HTML-мнемоники. Таким образом два и более пробела показываются как один. То же самое относится к символам табуляции и переноса строк. Это был краткий экскурс в теорию. А само задание представляло собой HTML-страницу с Манифестом хакера (стыд и позор тебе, %username%, если ты не читал это послание Ментора), которое можно было отыскать на просторах игровой сети. Предполагая всю трудность раскрытия специфики задания, в HTML-коде была заботливо оставлена подсказка, указывающая на то, что пробелы в коде могут выполнять не только роль разделения слов в предложениях. Внимательный участник мог обнаружить, что слова в тексте разделены не везде одинаково. Если говорить более конкретно, то один пробел представлял собой не что иное, как «0», а двойной пробел, соответственно, «1». Иными словами, речь идет про один бит информации. Восемь бит есть один байт и одновременно код символа в ASCII-таблице. Ограничителем сообщения выступала последовательность «пробел + символ табуляции». Задание было осложнено именно пониманием того, что текст - не просто очередная попытка пропаганды хакинга, а эта обычная статичная HTML-страница и есть задание, из которого и надо добыть заветный ключ. Задание №9: CiscoПомимо ханипотов, эмулирующих сетевые устройства и различные операционные системы, в игровой сети можно было отыскать самый что ни на есть «живой» роутер на базе Cisco IOS. Сканирование TCP-портов должно было показать, что доступен сервис FINGER. Обратившись к этому сервису, можно было получить имя зарегистрированного пользователя на устройстве. Дальше достаточно было проверить на порту TELNET имя этого пользователя с паролем «cisco» (стандартный пароль для оборудования Cisco). Следующий шаг заключался в поднятии привилегий на устройстве. Само собой, речь не шла о пятнадцатом уровне доступа :). Но на третий уровень доступа с паролем «cisco» можно было подняться. Уже на этом этапе у пользователя хватало привилегий, чтобы просмотреть запущенную конфигурацию. Используя команду «Router#show running-config view full» можно было получить конфигурацию устройства, а вместе с ней и игровой флаг. Задание №10: TFTPОдно из самых простых заданий, которое можно было отыскать в игровой сети — это задание, связанное с TFTP-сервисом. Как раз подбор и вызвал наибольшие сложности у участников соревнования. Имя файла, которое необходимо было подобрать — это «router-config», стандартное имя файла по умолчанию при копировании конфигурации с консоли оборудования на базе Cisco IOS. Примечательно, что в словарях систем поиска уязвимостей и даже специализированных инструментах (таких, как tftptheft) отсутствует заветное имя «router-config». Если же файл был все-таки получен, то проблем с выдергиванием из него игрового ключа не возникало. Ключ хранился в формате паролей «secret 7» и мог быть восстановлен различными инструментами (например, с использованием Cain&Abel). ЗаключениеК сожалению, формат журнала не позволяет рассказать про все задания (их было более двадцати), предложенные на HQ2010. Поэтому расширенная версия данной публикации доступна в электронном виде по адресу xakepru.habrahabr.ru/. Спасибо всем, кто принимал участие в соревновании HQ2010! Спасибо разработчикам HQ2010, сделавшим его таким насыщенным и интересным. Отдельное спасибо Тимуру Юнусову, Сергею Павлову, Александру Матросову, Владимиру Воронцову aka D0znp, Валере Марчуку. Также хочется поблагодарить всех организаторов и спонсоров (в частности, ESET и SecurityLab), которые предоставили возможность провести подобное мероприятие. До скорых встреч на будущих хак-квестах! |