Чтение онлайн

на главную - закладки

Жанры

19 смертных грехов, угрожающих безопасности программ

Виега Джон

Шрифт:
...

CREATE PROCEDURE dbo.doQuery(@query nchar(128))

AS

exec(@query)

RETURN

А вот следующий код распространен куда шире и не менее опасен:

...

CREATE PROCEDURE dbo.doQuery(@id nchar(128))

AS

DECLARE @query nchar(256)

SELECT @query = \'select ccnum from cust where id = \'\'\' + @id + \'\'\'\'

EXEC @query

RETURN

Здесь опасная конкатенация строк выполняется внутри процедуры. То есть вы по–прежнему совершаете постыдный грех, даже если процедура вызвана из корректного

кода на языке высокого уровня.

Стоит поискать и другие операторы конкатенации, имеющиеся в SQL, а именно «+» и «||», а также функции CONCAT и CONCATENATE.

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

Классическая атака состоит в том, чтобы видоизменить SQL–запрос, добавив лишние части и закомментарив «ненужные». Например, если противник контролирует переменную Id, то может задать в качестве ее значения строку 1 or 2>1 – – , тогда запрос примет такой вид:

...

SELECT ccnum FROM cust WHERE id=1 or 2>1 – –

Условие 2>1 истинно для всех строк таблицы, поэтому запрос возвращает все строки из таблицы cust, другими словами, номера всех кредитных карточек. Можно было бы воспользоваться классической атакой «1 = 1», но сетевые администраторы часто включают поиск такой строки в системы обнаружения вторжений (IDS), поэтому мы применили условие «2>1», которое столь же эффективно, но «проходит под лучом радара».

Оператор комментария – – убирает из поля зрения сервера все последующие символы запроса, которые могла бы добавить программа. В одних базах данных для комментирования применяются символы —, в других – #. Проверьте, что воспринимает в качестве комментария ваша база.

Различных вариантов атак слишком много, чтобы перечислять их здесь, дополнительный материал вы найдете в разделе «Другие ресурсы».

Родственные грехи

Во всех приведенных выше примерах демонстрируются и другие грехи:

□ соединение от имени учетной записи с высоким уровнем доступа;

□ включение пароля в текст программы;

□ сообщение противнику излишне подробной информации в случае ошибки.

Рассмотрим их по порядку. Везде соединение устанавливается от имени административного или высокопривилегированного пользователя, хотя достаточно было бы пользователя, имеющего доступ только к одной базе данных. Это означает, что противник потенциально сможет манипулировать и другой информацией, а то и всем сервером. Короче говоря, соединение с базой данных от имени пользователя с высоким уровнем доступа – скорее всего, ошибка и нарушение принципа наименьших привилегий.

«Зашивание» паролей в код – почти всегда порочная идея. Подробнее см. грех 11 и 12 и предлагаемые там «лекарства».

Наконец, в случае ошибки противник получает слишком много информации. Воспользовавшись ей, он сможет получить представление о структуре запроса и, быть может, даже узнать имена объектов базы. Более подробную информацию и рекомендации см. в грехе 6.

Где искать ошибку

Любое приложение, обладающее перечисленными ниже характеристиками, подвержено риску внедрения SQL:

□ принимает данные от пользователя;

□ не проверяет корректность входных данных;

□ использует введенные пользователем данные для запроса к базе;

□ применяет конкатенацию или замену подстроки для построения SQL–запроса либо пользуется командой SQL exec (или ей подобной).

Выявление ошибки на этапе анализа кода

Во время анализа кода на предмет возможности

внедрения SQL прежде всего ищите места, где выполняются запросы к базе данных. Ясно, что программам, не обращающимся к базе данных, эта напасть не угрожает. Мы обычно ищем следующие конструкции:

Выяснив, что в программе есть обращения к базе данных [1] , нужно определить, где выполняются запросы и насколько можно доверять данным, участвующим в запросе. Самое простое – найти все места, где выполняются предложения SQL, и посмотреть, производится ли конкатенация или подстановка небезопасных данных, взятых, например, из строки Web–запроса, из Web–формы или аргумента SOAP. Вообще, любых поступающих от пользователя данных!

Тестирование

Надо признать, что реальной альтернативы добросовестному анализу кода на предмет внедрения SQL не существует. Но иногда у вас может не быть доступа к коду, или вы просто не имеет опыта чтения чужих программ. Тогда дополните анализ кода тестированием.

Прежде всего определите все точки входа в приложение, где формируются SQL–запросы. Затем создайте тестовую программу–клиент, которая будет посылать в эти точки частично некорректные данные. Например, если тестируется Web–приложение, которое строит запрос на основе одного или нескольких полей формы, попробуйте вставить в них произвольные ключевые слова языка SQL. Следующий пример на Perl показывает, как это можно сделать.

...

#!/usr/bin/perl

use strict;

use HTTP::Request::Common qw(POST GET);

use HTTP::Headers;

use LWP::UserAgent;

srand time;

# Приостановить исполнение, если найдена ошибка

my $pause = 1;

# Тестируемый URL

my $url = \'http://mywebserver.xyzzy123.com/cgi-bin/post.cgi\

# Максимально допустимый размер HTTP-ответа

my $max_response = 1000;

# Допустимые города

my @cities = qw(Auckland Seattle London Portland Manchester Redmond

Brisbane Ndola);

while (1) {

my $city = randomSQL($cities[rand @cities]);

my $zip = randomSQL(10000 + int(rand 89999));

print «Пробую [$city] и [zip]\n»;

my $ua = LWP::UserAgent->new;

my $req = POST $url,

[ City => $city,

ZipCode => $zip,

];

# Послать запрос, получить ответ и поискать в нем признаки ошибки

my $res = $ua->request($req);

$_ = $res->as_string;

die "Хост недостижим\n" if /bad hostname/ig;

if ($res->status_line != 200

|| /error/ig

|| length($_) > $max_response) {

print "\nПотенциальная возможность внедрения SQL\n";

print;

getc if $pause;

}

}

# Выбрать случайное ключевое слово SQL, в 50% случаев перевести

# его в верхний регистр

sub randomSQL {

$_ = shift;

return $_ if ($rand > .75);

my @sqlchars = qw(1=1 2>1 «fred=»fre" + "d" or and select union drop update insert into dbo < > = \' .. – #);

my $sql = $sqlchars[rand @sqlchars]; $sql = uc($sql) id rand > .5;

return $_ . \' \' . $sql if rand > .9;

return $sql . \' \' . $_ if rand > .9;

return $sql;

}

Этот код обнаружит возможность внедрения SQL только в случае, когда приложение возвращает сообщение об ошибке. Как мы уже сказали, нет ничего лучше тщательного анализа кода. Другой способ тестирования заключается в том, чтобы воспользоваться приведенной выше Perl–программой, заранее выяснить, как выглядит нормальный ответ, а затем анализировать, на какие запросы получен ответ, отличающийся от правильного, или вообще нет никакого ответа.

Имеются также инструменты третьих фирм, например AppScan компании Sanctum (теперь Watchfire) (www.watchfire.com), Weblnspect компании SPI Dynamics (www.spidynamics.com) и ScanDo компании Kavado (www.kavado.com).

Поделиться:
Популярные книги

Зубных дел мастер

Дроздов Анатолий Федорович
1. Зубных дел мастер
Фантастика:
научная фантастика
попаданцы
альтернативная история
5.00
рейтинг книги
Зубных дел мастер

Бывшие. Война в академии магии

Берг Александра
2. Измены
Любовные романы:
любовно-фантастические романы
7.00
рейтинг книги
Бывшие. Война в академии магии

Идеальный мир для Лекаря 7

Сапфир Олег
7. Лекарь
Фантастика:
юмористическая фантастика
попаданцы
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 7

Возвышение Меркурия. Книга 3

Кронос Александр
3. Меркурий
Фантастика:
попаданцы
аниме
5.00
рейтинг книги
Возвышение Меркурия. Книга 3

Кодекс Охотника. Книга X

Винокуров Юрий
10. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
6.25
рейтинг книги
Кодекс Охотника. Книга X

Хозяин Теней

Петров Максим Николаевич
1. Безбожник
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Хозяин Теней

Опасная любовь командора

Муратова Ульяна
1. Проклятые луной
Фантастика:
фэнтези
5.00
рейтинг книги
Опасная любовь командора

Друд, или Человек в черном

Симмонс Дэн
Фантастика:
социально-философская фантастика
6.80
рейтинг книги
Друд, или Человек в черном

Волхв

Земляной Андрей Борисович
3. Волшебник
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Волхв

Мастер Разума VII

Кронос Александр
7. Мастер Разума
Фантастика:
боевая фантастика
попаданцы
аниме
5.00
рейтинг книги
Мастер Разума VII

Всемирная энциклопедия афоризмов. Собрание мудрости всех народов и времен

Агеева Елена А.
Документальная литература:
публицистика
5.40
рейтинг книги
Всемирная энциклопедия афоризмов. Собрание мудрости всех народов и времен

Сумеречный Стрелок 5

Карелин Сергей Витальевич
5. Сумеречный стрелок
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Сумеречный Стрелок 5

Морской волк. 1-я Трилогия

Савин Владислав
1. Морской волк
Фантастика:
альтернативная история
8.71
рейтинг книги
Морской волк. 1-я Трилогия

Прогрессор поневоле

Распопов Дмитрий Викторович
2. Фараон
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Прогрессор поневоле