使用PHP进行定时攻击

exu*_*sum 11 php timing-attack

我试图在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);
Run Code Online (Sandbox Code Playgroud)

这是在搜索具有以下约束的单词

az最多只有10个字符

脚本找到单词的长度没有问题但是单词的值永远不会像定时攻击那样回归.

有什么我做错了吗?

脚本循环遍历长度,正确识别长度.它然后循环每个字母(az)并检查这些字母的速度,理论上'haaaa'应该比'aaaaa'略慢,因为第一个字母是啊,然后继续为5个字母中的每个字母.

跑步会产生类似"brhas"的东西,这显然是错误的(每次都不同,但总是错的)

rla*_*vin 3

我做错了什么吗?

我不这么认为。我尝试了你的代码,我也像你和其他在评论中尝试过的人一样,得到了第二个循环的完全随机的结果。第一个(长度)大部分是可靠的,尽管不是 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));
Run Code Online (Sandbox Code Playgroud)

现在很容易明白为什么第一次对长度的计时攻击效果很好。如果长度不同,则memcmp永远不会被调用,因此返回速度要快得多。即使没有太多迭代,差异也很容易注意到。

一旦确定了长度,在第二个循环中,您基本上就是在尝试攻击底层memcmp. 问题是时间上的差异很大程度上取决于:

  1. 实施memcmp
  2. 当前负载和干扰进程
  3. 机器的架构。

我推荐这篇题为“针对定时攻击的 memcmp 基准测试”的文章,以获取更详细的解释。他们做了更精确的基准测试,但仍然无法在时间上获得明显的差异。我简单引用一下这篇文章的结论:

memcmp()总之,a 是否受到定时攻击很大程度上取决于具体情况。