
Determinar privilégios a partir de credenciais de nuvem através de teste de força bruta.
Eu tenho credenciais, e agora?
CloudPrivs é uma ferramenta que aproveita o poder existente de SDKs como o Boto3 para forçar privilégios de todos os serviços em nuvem, determinando quais privilégios existem para um determinado conjunto de credenciais.
Esta ferramenta é útil para Pentesters, Red Teamers e outros profissionais de segurança. Os serviços em nuvem normalmente não oferecem uma maneira de determinar quais permissões um determinado conjunto de credenciais possui, e o enorme número de serviços e operações torna uma tarefa assustadora confirmar manualmente. Isso pode significar que a escalada de privilégios pode ser possível a partir de um conjunto de credenciais, mas ninguém jamais saberia porque simplesmente não sabem que as credenciais AWS que encontraram podem executar Lambda.
Atualmente não disponível no PyPi, mas estou trabalhando nisso
git clone https://github.com/AbstractClass/CloudPrivs
cd CloudPrivs
python -m pip install -e .
Isso é sem um ambiente virtual e não é recomendado se você executa muitos programas Python
git clone https://github.com/AbstractClass/CloudPrivs
cd CloudPrivs
python -m venv venv/
./venv/bin/activate # activate.ps1 no windows
python -m pip install -e .
Você também pode usar Pyenv+virtualenv se disponível:
git clone https://github.com/AbstractClass/CloudPrivs
cd CloudPrivs
pyenv virtualenv CloudPrivs
pyenv local CloudPrivs
python -m pip install -e .
cloudprivs [PROVEDOR] [ARGUMENTOS]
Atualmente, o único provedor disponível é a AWS, mas estou trabalhando no GCP. Se você quiser ajudar, veja #Customização.
Opções:
-v, --verbose Mostrar testes com falha e erro na saída
-s, --services TEXTO Testar apenas os serviços fornecidos em vez de todos
os serviços disponíveis
-p, --profile TEXTO O nome do perfil AWS a ser escaneado, se não
especificado, as variáveis de ambiente serão usadas
-t, --custom-tests NOME_ARQ localização do arquivo YAML de testes personalizados. Leia a documentação
para mais informações
-r, --regions TEXTO Uma lista de filtros para corresponder às regiões,
ex.: "us", "eu-west", "ap-north-1"
--help Mostrar esta mensagem e sair.
Vários argumentos são suportados para --region e --service, no entanto, eles devem ser fornecidos com a flag cada vez, ex.: cloudprivs aws -r us -r eu -s ec2 -s lambda. Eu também não gosto disso, mas é uma limitação no Click para a qual ainda não encontrei uma solução alternativa.
Observe que a flag
regionsuporta correspondências parciais, os argumentos mais comuns são-r us -r eupara cobrir apenas as regiões comuns
Os resultados são exibidos agrupados por região e cada linha contém um caso de teste e o resultado do teste.
Se a ferramenta encontrar erros inesperados durante o teste, eles serão emitidos para stderr à medida que ocorrem, o que significa que podem interromper o fluxo da saída. Se você não quiser vê-los, pode redirecionar o stderr.
Ao contrário de outras ferramentas, como WeirdAAL, que escrevem manualmente cada caso de teste, o CloudPrivs consulta diretamente o SDK Boto3 para gerar dinamicamente uma lista de todos os serviços disponíveis e todas as regiões disponíveis para cada serviço.
Uma vez gerada a lista completa, cada função é chamada sem argumentos por padrão, embora a opção de adicionar argumentos personalizados por operação seja suportada (mais informações em #Customização)
Nota: algumas funções da AWS podem incorrer em custos quando chamadas. Eu permiti apenas operações que começam com
get_,list_edescribe_para mitigar custos acidentais, o que parece ser seguro nos meus próprios testes, mas use com cautela. Isso parece seguro para outras ferramentas como enumerate-iam — não garanto que você não incorrerá acidentalmente em custos ao chamar todas essas funções (mesmo que seja sem argumentos)
CloudPrivs suporta fácil extensão/customização em duas áreas:
Implementar um novo provedor (ex.: GCP) é simples
CloudPrivs/providers, crie uma nova pasta para seu provedor (ex.: 'gcp')CloudPrivs/providers/__init__.py, adicione seu provedor à variável __all__, ele deve corresponder ao nome da pastacli.py na pasta do seu provedorcli (veja o provedor AWS como referência)cloudprivs <provedor> agora deve mostrar sua CLIO provedor AWS suporta a injeção de argumentos ao chamar funções AWS. Este recurso é fornecido porque muitas vezes uma função AWS requer argumentos para ser chamada e, em alguns casos, esses argumentos podem ser variáveis fixas. Isso significa que, se pudermos fornecer variáveis fictícias, podemos aumentar nossa cobertura de teste. Em outros casos, podemos injetar argumentos como dryrun=true para tornar as chamadas mais rápidas.
Testes personalizados são armazenados em um arquivo YAML em cloudprivs/providers/aws/CustomTests.yaml.
A estrutura do YAML é a seguinte:
---
<nome-do-serviço>:
- <nome-da-função>:
args:
- <arg1>
- <arg2>
kwargs:
arg1: val1
arg2: val2
Nota: O nome da função funciona com correspondências parciais, o que significa que você pode usar um nome de função como 'describe_' e os argumentos especificados serão injetados em todas as funções que contenham 'describe_'. As regras são correspondidas na base de 'primeiro encontrado', então, se você quiser substituir uma regra genérica, coloque sua regra mais específica acima da regra genérica. Ex.:
ec2:
- describe_instances
args:
kwargs:
DryRun: True
NoPaginate: True
- describe_
args:
kwargs:
DryRun: True
Novas regras podem ser adicionadas modificando o arquivo CustomTests.yaml existente ou criando um novo arquivo YAML e especificando-o com a flag --custom-tests. O novo arquivo será mesclado com o arquivo de testes existente e quaisquer valores duplicados serão substituídos, com o arquivo fornecido tendo prioridade.
O provedor AWS é escrito como uma biblioteca para integração com outras ferramentas. Você pode usá-lo da seguinte forma:
import boto3
from cloudprivs.providers.aws import service
from concurrent.futures import ThreadPoolExecutor
session = boto3.Session('default')
with ThreadPoolExecutor(15) as executor:
iam = service.Service('iam', session, executor=executor)
scan_results = iam.scan() # cobrirá todas as regiões listadas no executor (todas as regiões disponíveis por padrão)
formatted_results iam.pretty_print_scan(scan_results)
print(formatted_results)
Tudo está totalmente documentado no código, deve ser bem fácil de interpretar.
Esta ferramenta é funcional, mas está longe de estar completa. Estou trabalhando ativamente em novos recursos e estou aberto a contribuições, então fique à vontade para abrir Issues/Solicitações de Recursos e enviar PRs.
Recursos Planejados