debugging the life logo
  • About 
  • Blog 
  • Tags 
Blog
  1. Home
  2. Blogs
  3. HackerWhale - Offensive Docker Image

HackerWhale - Offensive Docker Image

Posted on August 11, 2024  (Last modified on August 14, 2024) • 11 min read • 2,343 words
Hacking
 
Docker
 
Container
 
Kubernetes
 
Hacking
 
Docker
 
Container
 
Kubernetes
 
Share via
debugging the life
Link copied to clipboard

Uma imagem Docker para propostas ofensivas com funções de expansão. Compatível com ambientes Kubernetes.

On this page
  • HackerWhale
  • Motivação
  • Características
    • Lista de Ferramentas
  • Instalação e execução
    • Contrução do container no modo “Baleião” pronto para uso
    • Construção do container utilizando a função de expansão
    • Execução e acesso ao container
  • Casos de uso
    • Proxy externo
    • Conexões Reversas
    • Kubernetes
    • Discovery & Scan
HackerWhale - Offensive Docker Image
  • HackerWhale
  • Motivação
  • Características
    • Lista de Ferramentas
  • Instalação e execução
    • Contrução do container no modo “Baleião” pronto para uso
    • Construção do container utilizando a função de expansão
    • Execução e acesso ao container
  • Casos de uso
    • Proxy externo
      • ZAProxy
      • BurpSuite
    • Conexões Reversas
    • Kubernetes
      • Minikube
      • Kubernetes
    • Discovery & Scan

HackerWhale  

Este projeto é o resultado da necessidade encontrada durante um trabalho onde haviam poucos recursos disponíveis, e uma imagem de container personalizada foi a solução criada.

Assim foi criado o “HackerWhale”, que em poucos minutos te disponibilizará tudo o que é necessário para realizar testes em sua rede, seja em redes corporativas ou ambiente Kubernetes.

Docker

docker pull 0xtiago/hackerwhale:latest

Kubernetes

kubectl apply -f hackerwhale-k8s.yaml

Para casos de uso e detalhes, basta seguir neste humilde artigo. :)

Ferramentas prontas para expansão disponível em https://github.com/0xtiago/HackerWhale.
Ferramentas prontas para expansão disponível em https://github.com/0xtiago/HackerWhale.

Motivação  

Recentemente, me deparei com uma situação onde precisei realizar uma avaliação rápida em um ambiente, mas naquele exato momento eu ainda não possuía direitos administrativos, e muito menos ferramentas de virtualização (VBox/VMWare) no laptop fornecido. No entanto, estava disponível o Docker Desktop. Então, decidi gastar um tempo construindo meu próprio container com minhas ferramentas favoritas.

Haviam outras opções disponíveis, mas elas não eram viáveis naquele momento devido aos seguintes motivos:

  1. Container Docker do Kali Linux: O proxy de rede bloqueou o repositório do Kali (A atualização por apt update && apt -y install kali-linux-headless não era possível);
  2. Hacker Container: É uma opção interessante, mas tudo está centralizado no Dockerfile, algo que, na minha humilde opinião, torna a manutenção deste projeto mais confuso e difícil de manter.

Então, aqui trago duas opções após essa jornada de testes:

  1. Uma versão completa e expandida disponível em Docker Hub.
  2. Possibilidade de criar sua própria imagem personalizada.

Características  

A maior preocupação durante a construção da imagem base era manter a mesma experiência de trabalho em um host Ubuntu Linux que geralmente trabalho, incluido Zsh com Oh-My-Zsh, Oh-My-Tmux, e manutenção do histórico de comandos em $(PWD).

Abaixo um resumo das características deste projeto:

  • Imagem disponível no registry Dockerhub para facilitar o seu uso.
  • Imagem em multiplataforma e script de expansão preparados para construção em amd64 e arm64.
  • Customização de armazenamento de histórico para uso contínuo em /workdir/.zsh_history_docker, podendo ser mapeado e mantido no host, podemos ser reutilizado em outras imagens criadas.
  • Shell com boa experiência para o usuário com ZSH (Ohmyzsh) e TMUX (Ohmytmux).
  • Dockerfile pronto para expansão através de argumentos de uso de scripts em bash local ou a partir de uma URL.
  • Dezenas de ferramentas disponíveis.

Lista de Ferramentas  

Abaixo a lista de ferramentas disponível até o momento da última atualização deste post. O código sempre será mantido e atualizado em https://github.com/0xtiago/HackerWhale.

# Tool
1. Altdns
2. Alterx
3. Amass
4. Anew
5. Antiburl
6. Arjun
7. arp_scan
8. Assetfinder
9. Burl
10. Brutespray
11. ChaosClient
12. Collector
13. DalFox
14. Dirsearch
15. Dnsx
16. DNSValidator
17. ffuf
18. Findomains
19. Gau
20. Gauplus
21. Gf
22. GithubSearch
23. GitDorker
24. GitDumper
25. GoogleChrome
26. GoSpider
27. Gowitness
28. Hakrawler
29. Hakrevdns
30. Haktrails
31. Httprobe
32. Httpx
33. JohnTheRipper
34. JSScanner
35. K9s
36. Kiterunner
37. Kubectl
38. LinkFinder
39. Mapcidr
40. Massdns
41. Masscan
42. MegaPy
43. Metabigor
44. Naabu
45. Netcat
46. Nmap
47. Notify
48. Nrich
49. Nuclei
50. ParamSpider
51. Qsreplace
52. ShufleDNS
53. Sqlmap
54. Sub404
55. Subfinder
56. Subjs
57. sslscan
58. Stress_ng
59. Telegram_Send
60. TurboSearch
61. Unfurl
62. Uro
63. Waybackurls
64. wafw00f
65. WPScan

Instalação e execução  

Contrução do container no modo “Baleião” pronto para uso  

Este modo carinhosamente chamado de Baleião, se trata do container em seu formato completo, com todas as ferramentas. Você pode contruí-lo acessando o repositório no Github ou realizar o pull desta imagem completa diretamente do DockerHub.

Faça o pull da imagem do repositório do Github.

docker pull 0xtiago/hackerwhale:latest

Execute o container.

docker run -d -v ${PWD}:/workdir --name hackerwhale hackerwhale

Acesse o terminal do container.

docker exec -it hackerwhale /bin/zsh 

Construção do container utilizando a função de expansão  

Como citado no inicío, uma da maiores motivações para construir esta imagem era a possibilidade torná-la expansível, entregando uma imagem base para uma boa experiência de uso. Para realizar a construção no formato expansível basta seguir os passos seguintes.

Clone o repositório, acesse-o.

git clone https://github.com/0xtiago/HackerWhale && cd HackerWhale 

Com o uso de argumentos você poderá expandir o container com as aplicações que desejar escrevendo o seu próprio shell script de expansão. Você pode usar este aqui como base, se quiser.

Esta imagem está configurada para receber dois argumentos a partir da opção --build-arg, EXPANSION_SCRIPT_LOCAL e EXPANSION_SCRIPT_URL, onde você pode passar um script local ou um script disponível em uma URL, respectivamente.

Exemplo utilizando script local:

docker build --build-arg \
EXPANSION_SCRIPT_LOCAL=scripts/expansion_script.sh -t hackerwhale .

Exemplo utilizando script remoto:

docker build --build-arg \
EXPANSION_SCRIPT_URL="https://raw.githubusercontent.com/0xtiago/HackerWhale/main/scripts/expansion_script.sh" -t hackerwhale .

Execução e acesso ao container  

Nos exemplos há algumas opções de uso que serão aprofundadas mais adiante. No comando docker run iremos utilizar algumas opções de destaque:

  • -v ${PWD}:/workdir: Mapeamento do diretório local de execução do host com o diretório /workdir do container. Essa é uma opções que particularmente gosto para fins de organização.
  • --net=host: Configuração do container na mesma rede do host, assim seus serviços podem se comunicar entre si. Um exemplo de necessidade desta opção é a comunicação entre o container e a porta de um proxy no host, como ZAProxy ou BurpSuite.
  • -p {Porta do Container}:{Porta do Host}: Opção muito utilizada para expor portas de serviços do container para acesso pelo host. Mais adiante demonstramos seu uso para o recebimento de conexões reversas. Obs.: Não deve ser usada em conjunto com --host.

No exemplo abaixo, configuramos para que sua pasta local seja mapeada no em /workdir no container para facilitar a organização durante os trabalhos. No comando também foi adicionada a opção --net=host para extender a possibilidade de interagir com algum proxy do host, como ZAProxy, Burp Suite, Caido, etc.

Execução do container sem configurações de redes ou portas. Opcionalmente, mantendo o seu nome como hackerwhale.

docker run -d -v ${PWD}:/workdir --name hackerwhale hackerwhale

Execução do container na mesma rede do host.

docker run -d --net=host -v ${PWD}:/workdir --name hackerwhale hackerwhale

Execução do container expondo portas de serviço (Ex.: netcat).

docker run -d -v ${PWD}:/workdir -p 4444:4444 --name hackerwhale hackerwhale

Uma vez executado o container em qualquer das opções, acesso o container pelo entrypoint /bin/zsh para acessar a shell e iniciar o seu uso.

docker exec -it hackerwhale /bin/zsh 

Casos de uso  

Proxy externo  

Para utilizar proxies externos e poder interceptar comunicação HTTPS, é necessário instalar seus certificados. As configurações de certificado dos proxies são todas realizadas a partir da shell do container.

docker exec -it hackerwhale /bin/zsh 

ZAProxy  

Após executar o ZAProxy, baixe o certificado acessando o endereço padrão http://localhost:8080.

Ou baixe o certificado pela próprio GUI:

Após o download, pela shell do container, é necessário converter o certificado em DER ou PEM para Base64.

openssl x509 -inform PEM -in ZAPCACert.cer -out ZAPCACert.crt

Depois é só importar o certificado convertido. Para facilitar este passo, foi criado shell script. Os mesmos passos serão necessários para os outros proxies.

sh -c "$(curl -fsSL https://raw.githubusercontent.com/0xtiago/HackerWhale/main/scripts/check_and_copy_cert.sh)" - ZAPCACert.crt

Após a importação basta configurar as variavéis de ambiente http_proxy e https_proxy do container para acessar a portar do proxy do host. No exemplo abaixo a porta é a 8080.

# Caso queira usar o Burp, basta exportar internamente as portas de proxy

export http_proxy="http://host.docker.internal:8080" ;\
export https_proxy="http://host.docker.internal:8080"

Para desfazer a configuração do proxy, basta remover as variáveis de ambiente.

#Para desconfigurar
unset http_proxy && unset https_proxy

BurpSuite  

Após executar o BurpSuite, baixe o certificado acessando o endereço padrão http://localhost:8080.

Ou baixe pelo pela interface da ferramenta seguinte os seguintes passos:

Pela shell do container, converta o certificado do formato DER para Base64.

openssl x509 -inform DER -in burp_cert.der -out burp_cert.crt

Realize a importação do certificado:

sh -c "$(curl -fsSL https://raw.githubusercontent.com/0xtiago/HackerWhale/main/scripts/check_and_copy_cert.sh)" - burp_cert.crt

Configure as variáveis de ambiente para direcionar o tráfego para o Burp:

export http_proxy="http://host.docker.internal:8080" ;\
export https_proxy="http://host.docker.internal:8080"

E agora é só testar.

Para desfazer a configuração do proxy, basta remover as variáveis de ambiente.

#Para desconfigurar
unset http_proxy && unset https_proxy

Conexões Reversas  

Se quiser abrir uma porta para receber conexões reversas, no exemplo é demonstrado o mapeamento da porta 4444 no host e direcionando para mesma porta no container:

docker run -d -v ${PWD}:/workdir -p 4444:4444 --name hackerwhale hackerwhale

Acesse o container e execute o netcat para receber as conexões:

docker exec -it hackerwhale /bin/zsh 
nc -nlvp 4444
Recebendo conexão reversa na porta 4444.
Recebendo conexão reversa na porta 4444.

Recebendo conexão de um outro pod em ambiente Kubernetes.

Kubernetes  

Uma vez que temos um container com estas capacidades, podemos utilizá-lo dentro de um cluster de Kubernetes como um pod. Estão disponíveis dois YAMLs para este laboratório, um para Minikube e outro para Kubernetes, além de outros YAMLs prontos para outros serviços que utilizaremos no laboratório. As imagens que utilizaremos serão as seguintes:

  • 0xtiago/hackerwhale
  • postgres:latest
  • nginx:latest
  • rabbitmq:latest

Todos os arquivos necessários para os laboratórios abaixo estão dentro da pasta k8s no repositório deste projeto.

Minikube  

Para um laboratório mais simples como o nosso, como prova de conceito, podemos utilizar o Minikube para simular um cluster de Kubernetes. Neste laboratório precisaremos customizar algumas coisas para evitar conflitos com caminhos absolutos dentro do pod do HackerWhale. Mas tenha fé que tudo vai dar certo! :-)

Instale o Minikube e o inicie.

minikube start

Utilizando o nosso repositório base de scripts, aplique os yamls prontos para os nossos tres serviços alvos.

kubectl apply -f postgresql.yaml
kubectl apply -f nginx.yaml
kubectl apply -f rabbitmq.yaml

Verifique se os pods estão em execução.

kubectl get deployments
kubectl get services
kubectl get pods

Agora será necessário realizar algumas customizações no kubeconfig. Obtenha o endereço do Minikube para que possamos gerar um arquivo kubeconfig especifico para o Pod no minikube para evitar conflitos dos endereçamentos.

minikube ip
192.168.49.2

Edite o arquivo minikube-kubeconfig com o endereço obtido em seu ambiente. No ambiente testado ficou assim:

apiVersion: v1
kind: Config
clusters:
  - cluster:
      certificate-authority: /etc/kubernetes/certs/ca.crt
      server: https://192.168.49.2:8443 # IP do Minikube ($ minikube ip)
    name: minikube
contexts:
  - context:
      cluster: minikube
      user: minikube
    name: minikube
current-context: minikube
users:
  - name: minikube
    user:
      client-certificate: /etc/kubernetes/certs/client.crt
      client-key: /etc/kubernetes/certs/client.key

Agora, vamos criar o Secret para o nosso kubeconfig personalizado e para os certificados :

$ kubectl create secret generic minikube-kubeconfig-secret --from-file=config=./minikube-kubeconfig

$ kubectl create secret generic minikube-certificates \
  --from-file=client.crt=$HOME/.minikube/profiles/minikube/client.crt \
  --from-file=client.key=$HOME/.minikube/profiles/minikube/client.key \
  --from-file=ca.crt=$HOME/.minikube/ca.crt

Agora podemos aplicar nosso hackerwhale-minikube.yaml para gerar o nosso pod.

kubectl apply -f hackerwhale-minikube.yaml 

Liste novamente os pods para verificiar se todos estão disponíveis:

kubectl get pods

Comos todos disponíveis em nosso Minikube, podemos acessar o pod e verificar se podemos utilizar o kubectl internamente. Isso nos permitirá mais facilmente enumerar o ambiente interno e poder realizar qualquer assessment necessário.

Agora já podemos acessar o nosso pod com os secrets importados durante sua criação.

kubectl exec -it hackerwhale -- /bin/zsh

E a partir do pod, podemos listar os demais. \o/

kubectl get pods

Kubernetes  

Para este laboratório, foi criado um cluster de Kubernetes no Vultr.

Baixe as configurações do seu cluster e adicione à variável de ambiente $KUBECONFIG . O nome do meu arquivo exportado foi vke-58626b70-6270-4106-b1a1-a1e7754f6131.yaml.

export KUBECONFIG=$KUBECONFIG:~/.kube/config:~/.kube/vke-58626b70-6270-4106-b1a1-a1e7754f6131.yaml

Uma vez com as configurações importadas, podemos visualizar todos os contextos disponíveis:

kubectl config get-contexts

Saia do contexto do Minikube e inicie os trabalhos em nosso novo cluster criado.

kubectl config use-context vke-58626b70-6270-4106-b1a1-a1e7754f6131

Confirme a mudança e listando o contexto e os seus nodes.

$ kubectl config current-context
$ kubectl get nodes

Agora podemos subir os mesmos pods gerados em nosso lab no Minikube.

kubectl apply -f postgresql.yaml; \
kubectl apply -f nginx.yaml; \
kubectl apply -f rabbitmq.yaml

Verifique se os pods estão disponíveis.

kubectl get pods

Com o ambiente preparado para atender o YAML disponível para ambientes em K8s, podemos gerar o secret para ser importado para o nosso pod e poder interagir com o cluster de dentro do pod.

kubectl create secret generic k8s-kubeconfig-secret --from-file=config=/Users/tiago/.kube/vke-58626b70-6270-4106-b1a1-a1e7754f6131.yaml

Agora é só subir o pod.

kubectl apply -f hackerwhale-k8s.yaml

Para acompanhar o pull da imagem e sua configuração durante ou após sua aplicação, pode executar o seguinte comando.

kubectl describe pod hackerwhale-k8s

Uma vez com status de RUNNING, podemos entrar no terminal do nosso container.

kubectl exec -it hackerwhale-k8s -- /bin/zsh

Agora é só testar e verificar se os certificados foram importados para interagir com o cluster.

$ kubectl get pods
$ kubectl get pods -o wide -n default

O mesmo pode ser feito com o K9s, disponível na imagem.

Uma vez com estes casos de uso demonstrados, podemos seguir com os labs de Discovery & Scan.

Discovery & Scan  

Utlizando como base o ambiente em Kubernetes, podemos combinar o uso de kubectl e k9s com as ferramentas tradicionais de testes para um assessment interno.

O jeito mais fácil dentro do K8s é obter o endereçamento dos pods, para isso vamos verificar em qual namespace estamos. Se retornar vazio, significa que estamos no “default”.

kubectl config view --minify --output 'jsonpath={..namespace}'

Para confirmar, podemos listar todos os namespaces.

$ kubectl get namespaces

NAME              STATUS   AGE
default           Active   37m
kube-node-lease   Active   37m
kube-public       Active   37m
kube-system       Active   37m

Agora é só obter os IPs dos pods, assim também saberá em qual range eles estão.

$ kubectl get pods -o wide -n default

# ou 

$ kubectl get pods -o wide

O K9s também está disponível na imagem, podendo obter as mesmas informações de forma mais “amigável”.

Se você é roots, pode utilizar métodos mais tradicionais para a enumeração de ips em redel local, consultando a tabela arp ou fazendo “ping sweep”.

arp-scan --interface=eth0 --localnet

Com isso, pode iniciar os testes, como exemplo, realizando um nmap nos pods do Nginx, Postgres e RabbitMQ.

nmap -p- -Pn 10.244.0.4-6

Para facilitar um pouco mais, sabendo que estamos no namespace “default”, copie e cole o código abaixo para guardar todos os IPs dos pods com exceção de nosso container em um arquivo, e reutilizá-lo para outras tarefas.

CURRENT_POD_NAME=$(hostname); \
kubectl get pods -o wide -n default| grep -v $CURRENT_POD_NAME | awk '{print $6}' > pod_ips.txt

Passando o arquivo para o nmap.

nmap -iL pod_ips.txt

Ou fazendo um rápido teste com nuclei para encontrar misconfigurations:

cat pod_ips.txt |  nuclei --silent

👾

 Github Commiters Spy - Dimensionando licenças de SAST, SCA e IaC.
Open Source SAST com Horusec 
On this page:
  • HackerWhale
  • Motivação
  • Características
    • Lista de Ferramentas
  • Instalação e execução
    • Contrução do container no modo “Baleião” pronto para uso
    • Construção do container utilizando a função de expansão
    • Execução e acesso ao container
  • Casos de uso
    • Proxy externo
    • Conexões Reversas
    • Kubernetes
    • Discovery & Scan
comments powered by Disqus
👾

Eternal student.

     
Copyright © 2024 Tiago Tavares.
debugging the life
Code copied to clipboard