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.