概述
我想大家之前都有过下面这样的想法。当你看到一个简单的图片验证码时,你会想,或许我可以攻破这个验证码。这个验证码可能是个带有简单的倾斜文字的图片,并且在图片上会有几条横线或者图片上的文字会左右晃动。你没时间使用OCR来突破验证码,但你有一种强烈的感觉,那就是通过现代的一些高级技术可以轻易的绕过这种验证码。
文本将阐述如何使用最少的预处理技术和标准的预先训练的OCR模型来轻松的突破下面这种图片验证码。
CAPTCHA(全自动区分计算机和人类的图灵测试)是一个挑战-响应问题。如果正确实现验证码程序,那么这个问题将只能由人类解决。CAPTCHA自2003年被开发出来后,其使用量一直在稳步增长。它们主要用在需要或显示敏感信息的场景中,例如身份验证或注册过程。CAPTCHA的主要目标是防止垃圾邮件,用户名枚举和密码暴力等自动攻击。如果只有人类可以解决这个挑战问题,那么攻击者就不可能通过创建一个自动化脚本来暴力攻击验证码验证机制或从页面中枚举敏感信息。
CAPTCHA有很多种形式,其范围包括很多第三方的解决方案以及自定义实现。特别是Google 的 reCAPTCHA 。这篇文章的重点是评估基于文本的CAPTCHA,它要求用户输入给定图片中的文本。由于现有的CAPTCHA解决方案通常需要很大的成本,因此企业内部开发的基于文本的CAPTCHA很常见。与大多数安全控制一样,重新发明轮子必然会带来一系列问题。
你可以拥有最强大,最复杂的CAPTCHA程序,但如果你没有正确的实现它,这就没有任何意义。我们在现实的场景中经常看到的一些错误包括开发人员设置的硬编码的绕过、在服务器响应中泄露了CAPTCHA程序的验证码答案,甚至完全无法验证CAPTCHA的情况(即CAPTCHA 失效)。
但是,如果你能够在实现CAPTCHA时避免这些错误,并使用足够复杂的基于文本的图片作为验证码,那么你可能会相信它可以阻止常见的自动化攻击技术。
然而,随着机器学习技术和计算能力的提高,即使是实现良好的基于文本的CAPTCHA也应该被认为是脆弱的。强大的字符识别技术不再局限于学术界和谷歌。下面,我们将演示如何使用免费提供的开源软件破解六个定制实现的基于测试的CAPTCHA。
如何破解CAPTCHA?
尝试破解CAPTCHA可以看作是常见的Web应用程序安全测试方法的一部分。传统的方法是使用图像预处理技术对CAPTCHA图片进行“过滤”,然后尝试使用现有的OCR模型来识别字符。但这可能需要大量的手动调整工作,并且由于验证码验证过程通常具有严格的时间限制,以及应用程序通常具有比CAPTCHA更多的关键功能,因此开发有效的CAPTCHA破解器通常是不切实际的。
我们尝试采用传统的方法来对抗一些看似相当简单的CAPTCHA。这个CAPTCHA中的图像具有相当小的噪声,并且字符个数非常少。虽然字符是三维的,但是这种3D效果可以被滤除掉,因为显示的3D效果与基本字符的轮廓具有不同的颜色。对于攻破这种CAPTCHA,我们感到非常自信,我们决定使用500个CAPTCHA样本测试我们的理论方法。
我们尝试了各种预处理技术对原始的图片进行“过滤”处理,然后使用Tesseract-OCR模型识别字符。令我们沮丧的是,每次执行都会失败。如果我们幸运的话,OCR会正确地识别出五个字符中的两个。无论我们尝试使用何种过滤技术,都没能让我们得到一个可能构成实际威胁的模型准确度。
在花了几个小时后,我们决定从错误的角度看待这个问题。为什么我们要尝试对CAPTCHA图片进行“过滤”让图片更适合已经训练过的OCR模型处理?为什么我们不能为这个特定的CAPTCHA训练特定的模型呢?
在通过谷歌搜索后,我们找到了理想的Tensorflow模型,可以针对OCR进行训练:基于注意力的OCR(AOCR)。训练模型需要训练和验证数据。我们花了两个小时,手动标记了所有500个CAPTCHA样本。其中450个 CAPTCHA样本用于训练模型,剩余50个样本用于验证模型。使用笔记本电脑的CPU训练模型大约需要一个小时。但结果仍然不是很乐观,在经过给数据打标的繁琐过程和一整天的反复试验之后,我们决定停止训练并运行验证数据看看结果。
我们不得不执行三次训练过程 —— 我们真的不相信上图中的结果。100%的准确率?这说明我们没有犯过任何错误。
在训练模型时,它会对解决方案的准确度和置信度进行评估。有趣的是,对该指标的分析表明我们在初始数据集中出现了数据打标的错误。在四个样本实例中,我们将“M”标记为了“N”,并且这个错误是由训练的模型检测到的。
我们开始怀疑这个结果的统计意义,很显然,我们需要更大的样本量。因此,我们将模型的CAPTCHA样本提升至1500个:1000个用于训练,500个用于验证。同样,我们得到了100%的准确率。
训练过程
有关创建自己的CAPTCHA破解器的过程和脚本的详细操作指南,请参阅此Github仓库。
为了训练学习模型,你必须准备一组重要的CAPTCHA样本。收集数据集的过程可以自动化完成,并且可以在相对短的时间内检索大量样本集,例如通过有目的地提交不正确的用户名并保存新生成的CAPTCHA。
对于一些更简单的CAPTCHA,我们发现使用500个标记的样本数据足以得到很好的结果,而更复杂的CAPTCHA则要求样本数据需要超过1000个。在我们努力进行手动分类过程的情况下,需要更多的样本来提供准确的结果。
第二步是需要手动对数据集进行打标。根据CAPTCHA的复杂程度,此步骤的简易性可能会有所不同。这一步的单调操作并非如此。
可以使用脚本尽可能简化打标过程。CAPTCHA一次只显示一个字符来用于标记,可以使用OpenCV,之后以标签作为文件名并保存图片。为了满足所需的人力,每打标1000个CAPTCHA平均需要一个小时。
基于注意力的OCR(AOCR)模型可以用于分类。由Qi Guo和 Yuntian Deng开发的这种Tensorflow OCR模型使用了堆叠有长短期记忆(LSTM)单元的滑动卷积神经网络(CNN)进行分类。这些都是大而复杂的AI术语,我们不会在这里讨论。我们想要展示的是,通过谷歌搜索和遵循Github README页面的说明,几乎每个具有基本开发技能的人都可以开始动手破解CAPTCHA。
为了进一步证明我们的想法,初始的训练是在配有Core i7的工作站笔记本电脑上完成的,Tensorflow在CPU上运行。使用这种方式,每个训练步骤平均耗时2.5秒。对于大多数示例,大约需要1000到2000个步骤。即使是最复杂的模型也可以在两小时内训练完成。
作为一项实验,我们在Nvidia GTX 960上测试了支持GPU的Tensorflow构建。平均训练步骤时间降至0.2秒。如前面所述,为更复杂的CAPTCHA训练模型需要更多的训练步骤和更长的训练时间。如果步骤的复杂性和数量大幅增加,切换到GPU上的训练可以显着提升效率。
训练结果
每个CAPTCHA及其各种复杂因素的描述包含在下表中:
每个CAPTCHA模型的准确度结果如下表所示:
虽然乍一看所有CAPTCHA的结果看起来不太令人满意,但下一张表证明并非如此。如上所述,模型将输出CAPTCHA预测以及预测正确的确定性评估。正确的猜测通常比不正确的猜测具有更高的确定性。因此可以指定一个最小确定性值或阈值。如果从服务器接收到的CAPTCHA预测的确定性值没有超过该阈值,则将请求新的CAPTCHA。这种方法将限制提交可能不正确的CAPTCHA值,但代价是需要丢弃一些CAPTCHA。阈值越高,丢弃的CAPTCHA越多。
确定性阈值与丢弃的CAPTCHA之间的权衡如下表所示。如果我们想要达到指定的接受率,每个CAPTCHA的值表示平均丢弃多少CAPTCHA然后提交一个CAPTCHA。
考虑C-2:如果我们想要向服务器提交CAPTCHA,并且我们知道接近100%的所有提交都会是正确的,所以我们的过滤器只允许提交每250个CAPTCHA中的1个。如果我们调低了我们的接受率,接受大约10%的提交都是不正确的,那么过滤器将允许提交每八个CAPTCHA中就会有一个。相反,对于C-1,由于在预测中没有出现错误,因此不必丢弃CAPTCHA以实现任何接受率。
复杂性与用户体验
如上面的结果所示,要防止CAPTCHA被破解,很明显的一个解决方案就是使基于文本的CAPTCHA更复杂,例如添加更多噪声,群集文本,增加长度和可用字符集。下面的例子可以被视为一种基于文本的CAPTCHA验证码的更安全的实现:
当然,解决方案需要在可用性和人性友好之间进行权衡。如果经过训练的模型在CAPTCHA上达到了50%的准确度,但人类也可以达到相同的结果,那么这种情况下,模型真的有缺陷吗?成功实现自动化解决方案的目标不一定是实现100%的成功率,而是达到类似人类的准确度。如果模型可以达到人类级别的准确性,则由不正确的CAPTCHA提交产生的噪声将被屏蔽为正常的人为错误。
如前所述,AOCR训练模型不仅提供了CAPTCHA的分类,还提供了预测准确的概率。这个概率值可用于在比较困难的情况下通过丢弃低于特定预测概率的分类结果,然后请求不同的CAPTCHA来确保高水平的预测准确性。
CAPTCHA破解的下一步是什么?
这不是一个新问题。在2014年,已经有人证明可以通过自动化手段破解基于文本的CAPTCHA。我们只是展示了在这四年中如何大大减少突破这些系统所需的工作量。
虽然这篇文章旨在强调基于文本的CAPTCHA的不安全性,但存在不同类型的第三方CAPTCHA解决方案,这些第三方解决方案对于计算机来说可能更复杂,但仍可供人类使用。最受欢迎的CAPTCHA实现是Google的reCAPTCHA。reCAPTCHA是一个基于图像的CAPTCHA,要求用户单击与提供的描述所匹配的所有图像。虽然图像验证挑战本身被认为更加安全,但也有一些攻击案例已经证明,可以通过请求和自动解决音频挑战来绕过挑战。此外,与基于文本的解决方案非常相似,计算能力也使这种攻击方法变得微不足道只是时间问题。
另一个不错的解决方案是根据用户的行为构建威胁模型。例如,人类将在非线性路径中移动鼠标,具有不一致的点击率并且将滚动鼠标滚轮读取内容。一个这样的例子是谷歌的reCAPTCHA v3。目前,这仍然需要集成第三方组件,但它似乎确实是目前最好的解决方案。
使用第三方解决方案确实存在限制,因为企业可能并不总是愿意将第三方软件引入到敏感的应用程序中。就目前而言,不愿加入Google革命组织的开发人员只能在等待更好的解决方案出现前尝试使自己的CAPTCHA足够复杂。
CAPTCHA的目标是通过要求人类用户进行交互来阻止垃圾邮件和自动化。随着人工智能在能力和复杂程度上的增长,这将变得更加困难。这强调了深度防御的重要性。如果CAPTCHA在登录功能中提供的防线被攻破,则可以通过帐户锁定策略,强密码策略和双因素身份验证等功能进一步保护帐户免受自动登录暴力尝试的攻击。随着攻击CAPTCHA解决方案的门槛的降低,自动枚举和其他暴力攻击将变得更加可行,这些应该被纳入安全防御的缓解策略中。