2015-02-08 4 views
14

От WikipediaМожет ли случайный сон предотвратить временные атаки?

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

На самом деле, чтобы предотвратить атаки синхронизации, я использую следующую функцию, взятую из this answer:

function timingSafeCompare($safe, $user) { 
    // Prevent issues if string length is 0 
    $safe .= chr(0); 
    $user .= chr(0); 

    $safeLen = strlen($safe); 
    $userLen = strlen($user); 

    // Set the result to the difference between the lengths 
    $result = $safeLen - $userLen; 

    // Note that we ALWAYS iterate over the user-supplied length 
    // This is to prevent leaking length information 
    for ($i = 0; $i < $userLen; $i++) { 
     // Using % here is a trick to prevent notices 
     // It's safe, since if the lengths are different 
     // $result is already non-0 
     $result |= (ord($safe[$i % $safeLen])^ord($user[$i])); 
    } 

    // They are only identical strings if $result is exactly 0... 
    return $result === 0; 
} 

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

function timingSafeCompare($a,$b) { 
    sleep(rand(0,100)); 
    if ($a === $b) { 
     return true; 
    } else { 
     return false; 
    } 
} 

Или, может быть, увеличивая хаотичность сна

sleep(rand(1,10)+rand(1,10)+rand(1,10)+rand(1,10)); 

Этот подход может полностью предотвратить временные атаки? Или просто сделать работу сложнее?

+2

Просто используйте 'hash_equals()' и назовите это днем. –

ответ

14

Этот подход может полностью предотвратить временные атаки? Или просто сделать работу сложнее?

Ни то, ни другое.Он не предотвращает временные атаки и не делает их более трудными.

Чтобы понять, почему, посмотрите на docs for sleep. В частности, значение первого параметра:

Остановить время в секундах.

Так что ваше приложение занимает 0,3 секунды, чтобы ответить без сна. С сном он принимает либо 0,3, 1,3, 2,3 и т.д. ...

Так на самом деле, чтобы получить часть мы заботимся о (разности времени), нам просто нужно отрубить целую часть:

$real_time = $time - floor($time); 

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

Ну, измерения проводятся в шкале 15-50 nano. Так что сон все еще около 100 раз меньше гранулированнее измерений. Таким образом, мы можем усреднить до одной микросекунды:

$microseconds = $time * 1000000; 
$real_microseconds = $microseconds - floor($microseconds); 

И все еще иметь содержательные данные.

Вы можете пойти дальше и использовать time_nanosleep, который может спать с точностью до наносекундной шкалы.

Тогда вы можете начать путаться с цифрами.

Но данные все еще существуют. Красота случайности заключается в том, что вы можете просто усреднить ее:

$x = 15 + rand(1, 10000); 

Запустите это достаточно времени, и вы получите красивый симпатичный график. Вы скажете, что существует около 10000 различных чисел, поэтому вы можете в среднем вычесть случайность и вывести «частный». 15.

Поскольку добросовестная случайность объективна, ее довольно легко обнаружить статистически на достаточно большом уровне образец.

Так вопрос, который я бы спросить:

Зачем беспокоиться сна, как взломов, когда вы можете решить эту проблему правильно?

+2

Мне нравится, как я являюсь автором сообщения, цитируемого в обоих других ответах, и они выше, чем я: -P ... (Просто играю, на самом деле это большая честь) – ircmaxell

+0

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

+0

Вы уверены, что они «не делают их более трудными вообще»? Вообще? Если одно время ответа равно 1 мс, и вы добавляете около 1 секунды случайного сна, по крайней мере теперь злоумышленник должен ждать в тысячу раз больше (или использовать больше потоков), делая атаки не сложнее, но дольше, по крайней мере. Если мой webapp имеет безумный трафик в течение 1 недели, это легче обнаружить, чем короткий всплеск трафика в 3 утра. –

8

Это нормально для по одному запросу, если единственным наблюдаемым атакующим боковым каналом является время отклика.

Однако, если злоумышленник делает достаточно запросов эта случайная задержка может усреднить, как указано в @Scott's answer со ссылкой ircmaxell's blog post:

Так что, если нам нужно запустить 49,000 тесты, чтобы получить точность 15ns [без случайной задержки ], тогда нам понадобится, возможно, 100 000 или 1 000 000 тестов с одинаковой точностью со случайной задержкой. Или, может быть, 100 000 000. Но данные все еще существуют.

В качестве примера давайте оценим количество запросов, которые должны иметь временную атаку, чтобы получить действительный 160-битный идентификатор сеанса, такой как PHP at 6 bits per character which gives a length of 27 characters. Предположим, что, как и linked answer, атака может выполняться только на одного пользователя одновременно (поскольку они хранят пользователя для поиска в файле cookie).

Принимая наилучший случай из сообщения в блоге, 100 000, количество перестановок будет 100,000 * 2^6 * 27.

В среднем, злоумышленник найдет значение на полпути через количество перестановок.

Это дает количество запросов, необходимых для обнаружения идентификатора сеанса от временной атаки до 86 400 000. Это сравнивается с 42 336 000 запросов без вашей предлагаемой защиты времени (при условии, что точность в 15 нс, как и в блоге).

В блоге, взяв самую длинную тестированную длину, 14, в среднем составляло 0,01171 секунды, что означает, что 86 400 000 займет 1,011,744 секунды, что соответствует 11 дням 17 часов 2 минуты 24 секунды.

Может ли случайный сон предотвратить временные атаки?

Это зависит от контекста, в котором используется ваш случайный сон, и силы бита строки, которую она защищает.Если функция «сохранить меня вошла в систему», которая является контекстом в связанном вопросе, может стоить злоумышленнику потратить 11 дней на использование тактовой атаки для грубой силы. Тем не менее, это предполагает идеальные условия (т. Е. Довольно последовательное время отклика из вашего приложения для каждой проверенной позиции строки и без сброса или опрокидывания идентификаторов). Кроме того, этот вид активности от злоумышленника создаст много шума, и, скорее всего, они будут обнаружены через IDS и IPS.

Он не может полностью предотвратить их, но это может сделать их более трудными для исполнения злоумышленником. Было бы намного проще и лучше использовать что-то вроде hash-equals, которое предотвратило бы временные атаки, полностью предполагая, что длины строк равны.

Ваш предложенный код

function timingSafeCompare($a,$b) { 
    sleep(rand(0,100)); 
    if ($a === $b) { 
     return true; 
    } else { 
     return false; 
    } 
} 

Обратите внимание, что rand функция PHP не криптографически безопасный:

Внимание Эта функция не создает криптографически безопасных значений, и не должны использоваться для криптографические цели. Если вам требуется криптографически безопасное значение, попробуйте вместо этого использовать openssl_random_pseudo_bytes().

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

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

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

Кроме того, согласно комментарию ircmaxell, sleep не является достаточно узким, поскольку он принимает только целое число, представляющее количество секунд. Если вы попытаетесь использовать этот подход, посмотрите на time_nanosleep со случайным числом наносекунд.

Эти указатели должны помочь защитить вашу реализацию от такого типа атаки времени.

+1

Также: 'sleep()' принимает ** секунды ** в качестве параметра. У меня слишком низкая степень детализации, чтобы скрыть что-либо ... – ircmaxell

9

Anthony Ferrara ответил на этот вопрос в своем блоге, It's All About Time. Я настоятельно рекомендую эту статью.

Многие люди, когда они слышат о временных атаках, думают: «Ну, я просто добавлю случайную задержку! Это сработает!». И it doesn't.

+0

Множество красивых графиков, и я уверен, что в этой лекции объясняется это, но я лично не вижу, как добавить истинный случайный сон недостаточно для смягчения временной атаки , – Phil

+2

@ Phil_1984_ 1) гранулярность. Большинство «случайных» сна находятся на миллисекундном уровне, где разница, которую мы измеряем, находится на уровне 10-ти наносекундного уровня. 2) Местность. Агент на оборудовании может наблюдать загрузку ЦП и говорить сон от активности (в виртуальных машинах и т. Д.). 3) Статистически эти случайные сна могут быть усреднены. 4) Это бандайда. Это не смягчает, это не забивает лежащую в основе рану, а просто делает это так, что вы не можете ее увидеть. Это безвестность. – ircmaxell

+0

А я читаю только 2-ю ссылку. 1-я ссылка объясняет все это и очень интересна, спасибо. Вам просто нужно сделать много запросов, чтобы усреднить случайность. Существует также случайность в нагрузке (как вы сказали) и на каждом сетевом переходе, который теоретически может быть усреднен таким же образом.Для проблемы сравнения строк OPs, есть ли что-то неправильно с простое хеширование, а затем сравнение результатов? – Phil

Смежные вопросы