繁体   English   中英

使用 PHP 进行定时攻击

[英]Timing attack with PHP

我正在尝试在 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);

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

  • 仅 az
  • 最多 10 个字符

该脚本可以毫无问题地找到单词的长度,但是单词的值永远不会通过计时攻击按预期返回。

有什么我做错了吗?

脚本通过长度循环,正确识别长度。 然后循环遍历每个字母 (az) 并检查这些字母的速度。 理论上,'haaaa' 应该比 'aaaaa' 稍慢,因为第一个字母是 h。 然后继续处理五个字母中的每一个。

跑步给出了类似 'brhas' 的东西,这显然是错误的(每次都不同,但总是错误的)。

有什么我做错了吗?

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

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

总之,如果memcmp()受到计时攻击,这在很大程度上取决于具体情况。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM