Web App 评估可能是当今最流行的渗透测试之一。它们非常受欢迎,以至于 Hacker One 和 Bug Crowd 等公共漏洞赏金网站为希望修复 XSS、SQL 注入、CSRF 等漏洞的公司提供了数百个程序。许多公司还拥有自己的赏金计划,用于向以下人员报告 Web 漏洞一个安全团队。在我们关于网络安全的 4 部分迷你系列博客文章中关注我们:
- 登录门户安全101
- 验证码做得对
- 默默无闻的不安全感
- 用户名发现
验证 码(完全 自动化 的公共图灵测试 告诉计算机和 人类的一部分 )是一种反自动化控制,在保护表单免受自动提交方面变得越来越重要。但是,仅仅因为您的表单上有验证码并不意味着您“做对了”。让我们回顾一下有关实施验证码的一些重要部分:
检查#1:可以重复使用吗?
这是我们最近遇到的一个例子:
一切看起来都不错吧?该应用程序将不允许用户在不解决验证码的情况下登录,并且验证码对于计算机来说很难猜测,但对于人类来说相对容易解决。这是在 Burp 的代理中捕获的示例登录 POST 正文:
您可以看到用户的用户名和密码与 CAPTCHA 的“哈希”和 CAPTCHA 的解决方案一起发送。如果 CAPTCHA 的“哈希”作为一次性使用条目存储在后端数据库中,在用户提交此登录请求时会被删除,那么一切都应该没问题。为了测试这一点,我们需要做的就是重复这个请求给服务器,如果服务器接受了重放的验证码提交,那么我们知道我们可以重用这个验证码提交来暴力猜测用户的登录凭据.
(Burp Intruder 用于在更改提交的密码时重放登录 POST 请求。即使我们在每个请求上重放相同的 CAPTCHA,但在第 86 次尝试时成功猜到了用户的密码。)
最后,这个特殊的登录门户并没有保护他们的用户免受任何比更简化的登录过程的影响。每个用户都因需要解决验证码而感到不便,但攻击者可以通过解决验证码一次然后多次重放来绕过验证码。除了为 CAPTCHA 提供一次性使用的数据库条目外,应用程序还可以将 CAPTCHA 的 id 与用户的当前会话 cookie 值联系起来,并确保需要解决 CAPTCHA 的每个请求都对用户的会话进行查找以确定哪个用户应该解决的验证码。如果在没有会话 cookie 的情况下提交请求,或者重放相同的 CAPTCHA id,则请求应该自动失败。
检查#2:我需要解决它吗?
这是帐户注册页面上验证码实施失败的另一个示例:
我们可以从这个例子中注意到什么?新帐户注册页面已经实施了验证码,但是一旦攻击者将新帐户的电子邮件地址输入到表单中,该表单就会对新帐户的电子邮件地址进行检查……无需解决验证码。攻击者可以使用这种不受保护的功能来暴力发现已经在网站上注册的电子邮件地址。这个特定的应用程序在他们的登录请求中使用电子邮件地址作为用户名(并且还使用了弱密码策略),因此我们能够通过在我们发现的电子邮件地址上尝试一个通用密码来登录到十几个单独的帐户。
检查#3:计算机很难解决吗?
以下是从最近的评估中获取的一些示例验证码:
这些验证码有什么特别之处?他们似乎使用某种预定义的模板来放置字母(字母总是在同一个位置),总是包含 8 个字符,并且只使用英文字母表中的字母(26 种可能性)。OCR 程序在这些 CAPTCHA 的字符分析方面做得不是很好,但是通过一些简单的转换,我们能够获得以下结果:
OCR 在这些转换后的 CAPTCHA 上仍然表现不佳(使用 google 的 TESSARACT 库的匹配率低于 2%),但是对于坚定的攻击者还有另一种可能性:解决每个位置的字母并将它们存储在数据库中以用于解决未来的验证码。一个简单的程序可以向攻击者显示特定位置的字母,然后将单个字母/位置组合存储在数据库中,以便为所有后续验证码进行匹配。这将需要攻击者手动输入 26 x 8 = 208 个单独的字母/位置组合,但随后计算机可以使用攻击者存储的信息来解决此特定应用程序上可能存在的大多数验证码。
解决 208 个不同的字符位置只需要几分钟(尽管编写代码需要几个小时),因此只有当 CAPTCHA 的请求具有很高的价值时,攻击者的回报才值得。
总体而言,该脚本能够以 70% 的准确率解决这些验证码。以下是一些示例结果:
大多数攻击者不会花费所需的时间来解决这种类型的 CAPTCHA,除非他们正在保护一些非常敏感的东西,所以在我们展示的三个坏例子中,这是最好的,因为应用程序 DID 需要解决 CAPTCHA在每次提交时,并且不接受重播的验证码请求。这种类型的 CAPTCHA 通过增加额外的复杂层来提供“足够好”的保护,防止机器人自动提交。
另一个转换示例
尽管我们第一个示例中的 CAPTCHA 存在缺陷,因此无需通过 OCR 解决它们,但这里有一个示例,说明如何转换 CAPTCHA 以使其更容易在自动攻击中识别:
原始图像
转换后的图像
这是用于转换第二组验证码的相关 python 代码:
def change_to_white(data, r, g, b):target_color = (red == r) & (blue == b) & (green == g)data[..., :-1][target_color.T] = (255, 255, 255)return data
im = Image.open(startimagepath)
im = im.convert('RGBA')data = np.array(im) # "data" is a height x width x 4 numpy array
red, green, blue, alpha = data.T # Temporarily unpack the bands for readability
colors = []
for x in range(0, len(red[0])): # Cycle through the numpy array and store individual color combinationsfor i in range(0, len(red)):color = (red[i][x], green[i][x], blue[i][x])colors.append(color)
unique_colors = set(colors) # Grab out the unique colors from the image# Cycle through the unique colors in the image and replace all "light" colors with white
for u in unique_colors: if sum(u) > 220: # Consider a color "light" if the sum of its red, green, and blue values are greater than 220data = change_to_white(data, u[0], u[1], u[2])# save the new image
im2 = Image.fromarray(data)
im2.save(imagepath)
谷歌解决了他们自己的 reCAPTCHA
虽然 Google 已经改进了他们的 reCAPTCHA,但有一个概念证明 github 项目将使用 Google 的语音识别服务来解决他们的 reCAPTCHA 的音频部分。项目信息可以在这里找到: https ://github.com/ecthros/uncaptcha
包起来
Web 应用程序漏洞仍然是组织面临的重大风险。Silent Break Security 了解安全的进攻性和防御性思维方式,可以帮助您的组织通过更复杂的测试和协作补救更好地预防、检测和防御攻击者。