Checagem de dependências externas
Recentemente, li esse artigo aqui no Medium, que deixarei como referência, assim como um vídeo que usei como base para a prova de conceito que explicarei aqui adiante.
https://www.youtube.com/watch?v=yVLR1SIw0BM&t=5120s
Então, falaremos sobre um assunto, que muitos desenvolvedores esquecem de realizar: atualizar dependências.
Isso pode ser visto, inclusive agora com a atualização da OWASP TOP 10, 2021. No qual, a vulnerabilidade relacionada as dependências, que antes estava entre as últimas posições, cresceu consideravelmente (como podem observar no retângulo vermelho).
Pode parecer algo bem comum, mas muita das vezes, os desenvolvedores não querem atualizar uma dependência/biblioteca por medo que o código onde está a aplicação quebre e isso pode dar margem a uma exploração. Tendo em vista, que muitas vezes, podemos fazer pesquisa sobre determinada versão do framework utilizando o Wappalyzer (como mostrado no outro artigo sobre Headers) ou mesmo, através da análise de código fonte e uma busca através do exploit-db ou cve-details.
Após ler esse artigo, resolvi procurar mecanismos para eu criar minha própria POC (Prova de Conceito) também. Pois muita das vezes, precisamos entender como o ataque funciona para poder mostrar aos desenvolvedores como é importante atualizar uma biblioteca e analisar se ela pode ser vulnerável ou não.
Vamos ao ataque! :)
Tudo começa com DNS!
O que é DNS?
Domain Name System (DNS), o qual serve para converter endereço IP e hostname (site.com , por exemplo) para que uma pessoa não precise decorar o endereço IP e seja assim legível. Dessa maneira, fazemos uma requisição para podermos acessar o servidor WEB, por exemplo e assim, essa informação vai até o servidor DNS para saber se dentro dele há essa tabela de conversão. Caso esse servidor não conheça, ele vai buscando essa informação em outros servidores até encontrar (através de uma hierarquia).
Conforme podemos ver nessas imagens aqui:
Como pode acontecer o ataque?
Como explicado, tudo depende da configuração do DNS! Portanto, se uma dependência interna tivesse o mesmo nome de uma dependência externa (no NPM Registry), a dependência externa seria chamada e não a interna. Então, se não houvesse o problema de DNS pelo NPM, apenas a dependência interna seria chamada.
Ok, e o nome do ataque? Dependency Confusion.
Isso se deve ao fato de que um atacante conseguiu perceber que uma dependência deveria ser chamada apenas internamente.
Então, após analisar o Github (ou outro site de versionamento de código) de uma determinada empresa e olhar as dependências ali expostas, ela não seria pública e consequentemente, não estaria disponível no npm ou no pip, por exemplo. Dessa maneira, a confusão ocorre por existir uma dependência interna como o mesmo nome publicamente :)
Aqui, podemos perceber dois pontos:
- Sempre utilize a fase de Descobrimento de um Pentest da maneira mais ampla possível. Essa fase é crucial para ter ótimos resultados.
- Nunca disponibilize código da sua empresa de forma pública.
Agora, vamos ao ataque!
Primeiro, eu utilizei a ferramenta BurpSuite para criar minha aplicação. Eu poderia utilizar o BurpCollaborator se eu tivesse a versão paga. No entanto, eu utilizo a versão community, gratuita. Dessa maneira, existe um plugin desenvolvido que funciona muito bem para o nosso teste!
O nome dela é Interactsh.
Você só precisa adicioná-la e copiar a url para o seu código.
Após termos acesso a nossa url, iremos desenvolver nosso plugin malicioso!
Como PoC, utilizaremos o instalador de dependência do nodejs, visto no artigo anterior que o npm instala a extensão automaticamente :)
Primeiramente, iremos criar um pacote e dentro dele, chamaremos nossa dependência.
Aqui, podemos perceber que o nome do meu pacote é "pkg_test_poc_mm" e a minha dependência é "pkg_test_poc_mm_dep".
Conforme visto na imagem anterior, eu criei uma pasta separada para minha dependência e criei o seguinte código:
Na parte dos scripts que são carregados inicialmente (preinstall), eu utilizei o nslookup, apenas para finalidade de receber a informação da minha aplicação do BurpSuite. Na qual, essa url foi gerada pelo plugin falado anteriormente.
Após isso, precisamos criar nossa conta no npm para podermos subir nosso pacote além da dependência.
Para isso, acesse o site. No terminal, digite "npm login". Assim será pedido suas credenciais.
Depois de finalizado, apenas digite: "npm publish ." — tanto para a dependência, quanto para o pacote.
Assim, caso você ou outra pessoa queira instalar o pacote malicioso:
npm i nome_do_pacote
É possível perceber que foi executado o script (no qual poderia ser qualquer outro código)
Assim, como é possível receber no Burp, a informação de quem acessou.
Como forma de prevenção, a Microsoft possui um artigo falando de algumas medidas, como uma tabela bem interessante.
Além disso, temos sempre atualizar as bibliotecas para última versão. Como também, podemos usar plugins para IDEs como por exemplo, para o VSCode.
Recomendo bastante esse plugin do Snyk (que somente serve para npm) — Vuln Cost.
No entanto, como é possível perceber na imagem abaixo, ele não conseguirá alertar sobre um plugin tão específico assim, apenas se alguém ja tiver relatado anteriormente.
Portanto, vale sempre observar se várias pessoas ja baixaram aquele plugin e analisar para ver se ele é realmente seguro.
Dessa forma, podemos manter nossas aplicações em segurança ❤