Издательский дом ООО "Гейм Лэнд"СПЕЦВЫПУСК ЖУРНАЛА ХАКЕР #52, МАРТ 2005 г.

Атака на БД

Клейстер

Спецвыпуск: Хакер, номер #052, стр. 052-084-3


3. UNION не может идти после операторов LIMIT и ORDER.

Так как же UNION может стать пособником злоумышленника? В нашем скрипте присутствует запрос "SELECT article_id, article_title FROM articles where category_id=$cid". Что мешает хакеру, используя SQL injection, вставить еще один SELECT-запрос и выбрать нужные ему данные? Правильно: ничего!

Допустим, цель хакера - получить логины и пароли всех авторов, которые могут добавлять статьи. Есть скрипт чтения списка статей http://serv.com/read.php?cid=1, подверженный SQL injection. Первым делом хакер узнает версию MySQL, с которой работает скрипт. Для этого он сделает следующий запрос: http://serv.com/read.php?cid=1+/*!40000+AND+0*/. Если скрипт вернет пустую страницу, значит, версия MySQL >= 4. Почему именно так? Число 40000 - версия MySQL, записанная без точек. Если версия, которая стоит на сервере, больше или равна этому числу, то заключенный в /**/ код выполнится как часть запроса. В результате ни одна запись не подойдет под запрос и скрипт не вернет ничего. Зная версию MySQL, хакер сделает вывод о том, сработает фишка с UNION или нет. В случае если MySQL третьей версии, фишка работать не будет. В нашем случае MySQL >= 4 и злоумышленник все-таки воспользуется UNION.

Для начала взломщик составит верный UNION-запрос, то есть подберет действительное количество указываемых столбцов, которое бы совпало с количеством указываемых столбцов левого запроса (вспоминай правила работы с UNION). Хакер не имеет в распоряжении исходников скрипта (если, конечно, скрипт не публичный) и поэтому не знает, какой именно запрос шлет скрипт к MySQL. Придется подбирать вручную - модифицировать запрос вот таким образом: http://serv.com/read.php?cid=1+UNION+SELECT+1. И тут о своем присутствии объявит ошибка, так как количество запрашиваемых столбцов не совпадает. Хакер увеличивает количество столбцов еще на единицу: http://serv.com/read.php?cid=1+UNION+SELECT+1,2 - получает список статей из категории 1, а также в самом конце две цифры: 1 и 2. Следовательно, он верно подобрал запрос.

Посмотрим на модифицированный запрос от PHP к MySQL: SELECT article_id, article_title FROM articles where category_id=1 UNION SELECT 1,2. В ответ MySQL возвращает результат первого SELECT (список статей) и результат второго SELECT - число "1" в первом столбце и "2" во втором столбце (SELECT+1,2). Другими словами, теперь, подставляя вместо '1' и '2' реальные имена столбцов из любой таблицы, можно будет заполучить их значения.

Составив верный SELECT+UNION запрос, хакер постарается подобрать название таблицы с нужными ему данными. Например, таблица с данными пользователей будет, скорее всего, называться users, Users, accounts, members, admins, а таблица с данными о кредитных картах - cc, orders, customers, orderlog и т.д. Для этого злоумышленник сделает следующий запрос: http://serv.com/read.php?cid=1+UNION+SELECT+1,2+FROM+users. И если таблица users существует, то PHP-скрипт выполнится без ошибок и выведет список статей плюс '1 2', иначе - выдаст ошибку. Так можно подбирать имена таблиц до тех пор, пока не будет найдена нужная.

Назад на стр. 052-084-2  Содержание  Вперед на стр. 052-084-4