Читаем Защита от хакеров корпоративных сетей полностью

В новом варианте программы имя файла «rfp.234562.temp» собирается из двух половинок. Тем самым гарантируется, что в приложении будет использовано одно и то же имя пользователя, совпадающее со значением параметра uname, и что атакующий может ссылаться только на файлы с расширением имени «.temp», поскольку так определено в программе. Тем не менее возможны и другие трюки злоумышленника. Например, передача символа NULL в конце значения параметра authkey вынудит систему проигнорировать добавление строки «.temp». Этого можно избежать, убрав все NULL из переданной строки. Но злоумышленник может использовать для аутентификации любой известный. temp-файл с помощью символов «../» в совокупности с другими хитростями. Поэтому лучше убедиться, что параметр $uname содержит только допустимые символы (предпочтительно лишь буквы), а $authkey – только числа. В общем случае для аутентификации лучше использовать запросы SQL к базе данных пользователей и паролей. Например, следующий запрос:

SELECT * FROM Users WHERE Username=’$name’ AND Password=’$pass’,

где $name и $pass – параметры имя пользователя и его пароль. В результате выполнения запроса будут найдены все записи в базе данных, у которых имя пользователя и пароль совпадают со значениями параметров, введенными пользователем. Полученный результат может быть обработан следующим образом:

if ( number_of_return_records > 0) {

# username and password were found; do stuff

} else {

# not found, return error

}

Приведенный фрагмент программы обрабатывает результат запроса. Если в результате запроса были найдены записи, то введенная пользователем комбинация из имени пользователя и его пароля действительна. Тем не менее это образец небрежного программирования, основанного на ошибочном предположении. Представьте, что злоумышленник передаст в качестве параметра $pass следующее значение:

boguspassword OR TRUE

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

Ошибка заключается в логическом условии (при number_of_return_records > 0). Это условие предполагает наличие ситуации, при которой одной комбинации имени пользователя и его пароля соответствуют многочисленные записи в базе данных. В правильно разработанном приложении подобная логическая ошибка должна быть исправлена. Исправленное логическое условие должно быть таким: (number_of_return_records == 1). Потому, что если число записей равно нулю, то в результате запроса не было найдено ни одной записи с заданной комбинацией имени пользователя и пароля, что свидетельствует о неуспешном завершении процедуры аутентификации. Одна найденная запись говорит об успешном завершении процедуры аутентификации, а более одной – о наличии проблемы из-за ошибки работы с базой данных или атаки злоумышленника.

Конечно, из-за взятого в кавычки параметра
$pass описанная только что ситуация может не произойти. Результат непосредственной подстановки значения параметра в запрос будет выглядеть так:

… AND Password=’boguspassword OR TRUE’

В итоге часть запроса OR TRUE не будет интерпретироваться как команда. Можно расставить собственные кавычки (boguspassword\' OR TRUE) и преодолеть это ограничение. При этом запрос примет вид:

… AND Password=’boguspassword’ OR TRUE’

Обычно это приводит к выдаче диагностического сообщения о том, что кавычка непарная. Для того чтобы избавиться от сообщения, можно использовать символ комментария за ключевым словом TRUE или использовать в запросе замыкающую кавычку. При присвоении параметру $pass значения

boguspassword’ OR NOT Password=’otherboguspassword

запрос станет следующим:

… AND Password=’boguspassword’ OR NOT Password=’otherboguspassword’

Перейти на страницу:
Нет соединения с сервером, попробуйте зайти чуть позже