CAPTCHA防护

在本节中,我们将学习使用CAPTCHA防御专门伪装成人类的Bot

机器人控制可以在2个层面上运行,被动防护和主动防护。之前是通过被动检查(如请求中的User-Agent标头或源IP)来检测机器人。更复杂的机器人可能会隐藏这些特征,甚至可能来自实际的浏览器,需要采取更积极的方法来应对它们,迫使它们证明自己是人类或至少具有一致的浏览器功能,这是许多脚本无法做到的。

场景介绍

之前以下命令会被403:

curl -v https://<<d1234567890>>.cloudfront.net/

我们的curl请求被Common Bot Control阻止,因为它明显使用了curl User-Agent作为标头。

让我们尝试通过更换User-Agent来愚弄Bot Control

curl -v  https://d33zkcemxgrpo3.cloudfront.net   -H 'Sec-Fetch-Dest: document' \
  -H 'Sec-Fetch-Mode: navigate' \
  -H 'Sec-Fetch-Site: none' \
  -H 'Sec-Fetch-User: ?1' \
  -H 'Upgrade-Insecure-Requests: 1' \
  -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36' \
  -H 'sec-ch-ua: "Not/A)Brand";v="8", "Chromium";v="126", "Google Chrome";v="126"' \
  -H 'sec-ch-ua-mobile: ?0' \
    -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7' \
  -H 'Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,pl;q=0.7,az;q=0.6' \
  -H 'Connection: keep-alive' \
  -H 'sec-ch-ua-platform: "macOS"'

结果能正常访问:

image-20240623214107318

看起来curl可以轻松地冒充一个真正的Chrome浏览器,很可能爬虫也会使用同样的技术。

实施CAPTCHA操作

在我们的AWS WAF Web ACL的Rules选项卡上创建一个新的自定义规则。将其命名为CAPTCHAAllIncomingRequests

匹配语句应该是URI Path,匹配Starts with string要匹配的字符串应该是**/**:

image-20240623214428175

将规则操作设置为CAPTCHA。请注意,immunity time默认设置为300秒。这意味着成功解决CAPTCHA后,5分钟内的请求不会再次被质询。在我们的例子中,让我们将时间改为整整一天(86400秒):

image-20240623214527139

单击添加规则,将规则向上移动到AllowGoodCurlTester规则之后。我们这样做是为了确保我们不会阻挡一些健康检查类的请求:

image-20240623214559555

然后通过浏览器访问我们的应用程序。现在我们被要求解决CAPTCHA:

image-20240623214635807

解决CAPTCHA后,可以正常浏览网站

再次运行curl命令:

curl -v  https://d33zkcemxgrpo3.cloudfront.net   -H 'Sec-Fetch-Dest: document' \
  -H 'Sec-Fetch-Mode: navigate' \
  -H 'Sec-Fetch-Site: none' \
  -H 'Sec-Fetch-User: ?1' \
  -H 'Upgrade-Insecure-Requests: 1' \
  -H 'User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/126.0.0.0 Safari/537.36' \
  -H 'sec-ch-ua: "Not/A)Brand";v="8", "Chromium";v="126", "Google Chrome";v="126"' \
  -H 'sec-ch-ua-mobile: ?0' \
    -H 'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7' \
  -H 'Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,pl;q=0.7,az;q=0.6' \
  -H 'Connection: keep-alive' \
  -H 'sec-ch-ua-platform: "macOS"'

我们可以看到,curl正被要求解决CAPTCHA,这是curl无法做到的:

image-20240623214736572

实现原理

通过CAPTCHA后,浏览器发送请求会携带一个aws-waf-token字段:

image-20240623214839275