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

authkey=rfp.23462382.temp&uname=rfp

Рассматривая систему аутентификации как «черный ящик» без малейшего представления о принципах его работы, была предпринята попытка найти закономерности работы системы при изменении входных данных параметров. Первый шаг состоял в изменении значения параметра authkey: сначала имени пользователя, а затем случайного числа и дополнительной величины «temp». Целью данных манипуляций было проверить возможность аутентификации пользователя с другими случайными недействительными значениями параметра. Не получилось. Затем значение параметра uname было изменено на другое правильное имя пользователя. В результате была получена строка вида

authkey=rfp.23462382.temp&uname=fringe.

После этого удалось зарегистрироваться под именем другого пользователя («fringe»). Исходя из этого, был восстановлен фрагмент программы аутентификации на языке Perl (заметим, что без знания истинного кода форума PacketStorm):

if (-e “authkey_directory/$authkey”) {

print “Welcome $uname!”;

# do stuff as $uname

} else {

print “Error: not authenticated”;

}

Таким образом, authkey – это файл, создаваемый при входе в систему с использованием случайного числа. Приведенный фрагмент программы позволяет любому пользователю, изменившему параметр uname, получить доступ к учетной записи иного пользователя, используя известный и правильный authkey (например, свой собственный).

Основываясь на форматах параметров authkey и uname, естественно было предположить, что значение authkey относится к файловой системе. Прежде всего потому, что значение параметра authkey в формате username.999999. temp не похоже на информацию, которую хранят в базе данных. Вполне возможно, что приложение разделяло параметр authkey на три части, используя для запроса к базе данных имя пользователя и случайное число. При этом отпадала необходимость в передаче через значение параметра uname имени пользователя, а постоянное окончание «.temp» становилось бесполезным и бессмысленным. Следуя интуиции и зная, что формат представления параметра authkey похож на задание имени файла, было высказано предположение, что значение параметра authkey определяет имя файла, как в итоге и оказалось.

Конечно, PacketStorm была поставлена в известность, и ошибка была исправлена. Выбранное ими решение лаконично, но давайте рассмотрим другой вариант исправления ошибки. Пусть программа была бы исправлена следующим образом:

if (-e “ authkey_directory/$authkey” && $authkey=~/^$uname/) {

print “Welcome $uname!”;

# do stuff as $uname

} else {

print “Error: not authenticated”;

}

Хотя это решение и выглядит правильным (в фрагменте кода выполняется проверка того, что значение параметра authkey начинается со строки символов, совпадающих со значением параметра uname), но оно ошибочно. В фрагменте кода проверяется только то, что параметр authkey начинается со значения параметра uname. Это значит, что если значение authkey было бы «rfp.234623.temp», то можно было бы использовать в качестве значения параметра uname символ «r», так как строка «rfp» начинается с символа «r». Ошибка исправляется заменой $authkey=~/^$uname/ íà $authkey=~/^$uname\./. В результате выполняется проверка на совпадении всего значения первой части параметра authkey с uname. PacketStorm решил использовать вариант, похожий на следующий:

@authkey_parts = split(“.”, $authkey);

if ($authkey_parts[0] eq $uname && -e «authkey_directory/

$authkey»){ …,

Приведенный вариант – всего лишь иной способ убедиться в совпадении значения первой части параметра authkey со значением uname. Но все равно в демонстрационном коде присутствуют погрешности. Зачем дублировать и сравнивать имя пользователя параметра authkey со значением uname? Оно всегда должно быть одним и тем же. Храня его в двух местах, всегда существует вероятность ошибок. Корректнее использовать следующий код:

if (-e «authkey_directory/$uname.$authkey.temp»){...

В этом случае следует лишь переслать URL:

authkey=234562&uname=rfp.

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