Время атаки с переполнением стека

Я пытаюсь произвести синхронизацию атаки в php
Использование php 7.1 со следующим скриптом

<?php
$find = "hello";
$length = array_combine(range(1, 10), array_fill(1, 10, 0));
for ($i = 0; $i < 1000000; $i++) {
for ($j = 1; $j <= 10; $j++) {
$testValue = str_repeat('a', $j);
$start = microtime(true);
if ($find === $testValue) {
//do Nothing
}
$end = microtime(true);
$length[$j] += $end - $start;
}
}

arsort($length);
$length = key($length);
var_dump($length . " found");

$found = '';
$alphabet = array_combine(range('a', 'z'), array_fill(1, 26, 0));
for ($len = 0; $len < $length; $len++) {
$currentIteration = $alphabet;
$filler = str_repeat('a', $length - $len - 1);
for ($i = 0; $i < 1000000; $i++) {
foreach ($currentIteration as $letter => $time) {
$testValue = $found . $letter . $filler;
$start = microtime(true);
if ($find === $testValue) {
//do Nothing
}
$end = microtime(true);
$currentIteration[$letter] += $end - $start;
}
}
arsort($currentIteration);
$found .= key($currentIteration);
}
var_dump($found);

Это поиск слова со следующими ограничениями

только a-z
до 10 символов

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

Есть ли что-то, что я делаю не так?

Скрипт зацикливается на длину, правильно определяет длину. Затем он проходит по каждой букве (a-z) и проверяет их скорость. Теоретически «haaaa» должен быть немного медленнее, чем «aaaaa» из-за того, что первая буква является h, затем он продолжается для каждой из 5 букв.

Бег дает что-то вроде «brhas», что явно неправильно (каждый раз по-разному, но всегда неправильно)

11

Решение

Есть ли что-то, что я делаю не так?

Я так не думаю. Я попробовал ваш код, и я, как и вы, и другие люди, которые пробовали в комментариях, получают совершенно случайные результаты для второго цикла. Первый (длина) в основном надежен, хотя и не в 100% случаев. Кстати, $argv[1] предложенный трюк на самом деле не улучшил согласованность результатов, и, честно говоря, я не очень понимаю, почему это так.

Поскольку мне было любопытно, я взглянул на исходный код PHP 7.1. Функция идентификации строки (zend_is_identical) выглядит так:

    case IS_STRING:
return (Z_STR_P(op1) == Z_STR_P(op2) ||
(Z_STRLEN_P(op1) == Z_STRLEN_P(op2) &&
memcmp(Z_STRVAL_P(op1), Z_STRVAL_P(op2), Z_STRLEN_P(op1)) == 0));

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

Как только вы определили длину, во втором цикле вы пытаетесь атаковать memcmp, Проблема в том, что разница во времени сильно зависит от:

  1. реализация memcmp
  2. текущая нагрузка и мешающие процессы
  3. архитектура машины.

Я рекомендую эту статью под названием «Бенчмаркинг memcmp для синхронизации атак» для более подробных объяснений. Они сделали гораздо более точный тест и до сих пор не смогли получить четкую заметную разницу во времени. Я просто собираюсь процитировать заключение статьи:

В заключение, это сильно зависит от обстоятельств, если memcmp() подвержен временной атаке.

3

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]