
Coletor de dados do Active Directory baseado em TUI que ingere objetos LDAP, realiza coleta remota via RPC/SMB/HTTP e gera dumps compatíveis com BloodHound CE para análise de caminhos de ataque.
Uma TUI para coleta do Active Directory.
Os principais objetivos deste projeto são:
Flashingestor implementa 3 etapas básicas separadas: Injeção LDAP, Coleta Remota e Conversão, ao contrário de outros coletores que executam os métodos especificados em uma única etapa:
Injetar (Ctrl+l) - Coleta dados de atributos brutos de objetos do LDAP e os armazena em output/ldap em arquivos msgpack intermediários. As consultas podem ser personalizadas no config.yaml.
Remoto (Ctrl+r) - Lê esses arquivos intermediários na memória, calcula a lista de computadores a coletar e realiza uma série de requisições RPC/SMB/HTTP para obter informações remotas relevantes para objetos Computer e EnterpriseCA, que são armazenadas em output/remote.
Converter (Ctrl+s) - Lê os arquivos intermediários na memória, mescla informações das etapas de injeção e coleta remota, e gera um dump compatível com o Bloodhound em output/bloodhound - esta etapa é totalmente offline.
Para mais detalhes técnicos e insights, confira nossa 📖 Wiki.
$ git clone https://github.com/Macmod/flashingestor
$ cd flashingestor
# Para compilar apenas:
$ go build ./cmd/flashingestor
# Para instalar o executável em $GOBIN ou $GOPATH/bin:
$ go install ./cmd/flashingestor
[!NOTE] Você também pode usar binários pré-compilados dos Releases fornecidos.
Primeiro autentique-se com uma das seguintes opções:
# Anônimo
# [Requer dSHeuristics de 0000002 no objeto DirectoryServices
# e pode ter visibilidade limitada devido à falta de ACEs de leitura]
$ ./flashingestor -u '@<DOMINIO>' -p '' [...]
# Usuário + Senha
$ ./flashingestor -u <USUARIO>@<DOMINIO> -p <SENHA> [-k] [...]
# Usuário + NTHash
$ ./flashingestor -u <USUARIO>@<DOMINIO> -H <NTHASH> [-k] [...]
# Usuário + PFX
$ ./flashingestor -u <USUARIO>@<DOMINIO> --pfx <CAMINHO_PFX> [--pfx-password <SENHA_PFX>] [-k] [...]
# Usuário + PEM
$ ./flashingestor -u <USUARIO>@<DOMINIO> --cert <CAMINHO_PEM> --key <CAMINHO_KEY> [-k] [...]
# Usuário + AESKey
$ ./flashingestor -u <USUARIO>@<DOMINIO> --aes-key <CHAVE_AES> -k [...]
# Usuário + Ticket
$ ./flashingestor -u <USUARIO>@<DOMINIO> --ccache /caminho/para/ticket.ccache -k [...]
ou
$ KRB5CCNAME=/caminho/para/ticket.ccache ./flashingestor -u <USUARIO>@<DOMINIO> -k [...]
Em seguida, execute as etapas conforme desejado. Para uma coleta apenas LDAP (DCOnly com exceção de GPOLocalGroup e CertServices), basta executar Ctrl+l, verificar se a injeção foi bem-sucedida e então executar Ctrl+s para gerar o dump final.
Especificar --dc e --dns para executar o flashingestor é recomendado. Se você não especificar --dc, o flashingestor tentará encontrá-lo com consultas SRV / A, o que pode atrasar a etapa inicial de Injeção.
Você deve então especificar --dns se seu servidor DNS padrão não conhece o domínio - quando o DNS integrado ao AD está em uso, basta apontar --dns para o DC que o hospeda. Além disso, independentemente de --dc, se você quiser executar a etapa de Coleta Remota e seu servidor DNS não conhece os computadores no domínio, então você deve especificar --dns para as consultas.
[!TIP] Em ambientes com múltiplos DCs, você também pode usar o utilitário
dcprobepara medir a latência para todos os DCs e encontrar um bom candidato alvo para a injeção:$ go build ./cmd/dcprobe $ ./dcprobe --dns 192.168.88.6 -d creta.local -r 10
Se o arquivo de configuração não estiver presente no diretório atual como config.yaml ou no caminho fornecido via --config, as opções padrão (as mesmas do config.yaml fornecido) serão assumidas - elas estão codificadas em config/fallback.go. Para mais informações, leia Arquivo de Configuração.
Considere usar --log para especificar um arquivo de saída para logs (caso precise revisá-los após fechar a TUI) e -vv para ver mensagens de log de depuração, pois isso pode ajudar a solucionar possíveis problemas. Para uma referência completa dos argumentos de linha de comando, leia Argumentos de Linha de Comando.
[!NOTE] As consultas padrão no
config.yamlfornecido são projetadas com as informações necessárias para a conversão do Bloodhound em mente. Você pode optar por personalizar consultas ou atributos noconfig.yaml, mas é melhor evitar remover atributos necessários e evitar alterar o significado dos filtros de busca.
Se recurse_trusts estiver definido como true, ele irá ingerir quaisquer domínios confiáveis encontrados recursivamente com a credencial inicial fornecida para a injeção.
Se search_forest estiver definido como true, ele irá ingerir domínios que fazem parte da mesma floresta que o domínio inicial a partir da partição Configuration - nenhuma consulta adicional será emitida, pois isso já faz parte do plano de injeção padrão. Ambas as opções podem ser definidas ao mesmo tempo, e o flashingestor irá ingerir qualquer domínio encontrado apenas uma vez (seja por uma confiança ou pela floresta atual).
Se recurse_trusts estiver habilitado e recurse_feasible_only também estiver definido como true, ele só tentará ingerir um domínio confiável se a confiança for:
Isso significa que confianças apenas de saída não serão percorridas e, além do primeiro nível de confianças, os caminhos de injeção param em confianças não transitivas - se B confia em A de forma não transitiva, então A ainda pode autenticar em B; mas se C também confia em B de forma não transitiva, então A não pode autenticar em C.
[!IMPORTANT]
recurse_trusts/search_forestsó autenticarão no LDAP em domínios descobertos com as credenciais especificadas do domínio de origem quando as credenciais fornecidas foremsenha simplesou umNT hash; usar um TGT para emitir um ticket de referência para esse fim é teoricamente possível, mas ainda não implementado na bibliotecaadauth.
Cadeias de middleware do Macmod/ldapx também podem ser usadas diretamente com o flashingestor para ofuscar as consultas LDAP na etapa de injeção usando as opções -f (--ldapx-filter), -a (--ldapx-attrs) e -b (--ldapx-basedn). Com -vv, as consultas brutas antes e depois da ofuscação também serão exibidas no log.
Se você pretende executar a etapa de coleta remota, verifique os methods habilitados - eles correspondem aproximadamente aos métodos oferecidos pelo SharpHound e podem ser usados para ativar/desativar coleções específicas via RPC ou HTTP.
Os argumentos --remote-* podem ser usados para especificar um conjunto separado de credenciais para coleta remota. Se não forem especificados, o flashingestor tentará usar as mesmas credenciais do usuário fornecido nos argumentos padrão de injeção (--user, --password, etc).
Um administrador local também pode ser usado para coleta remota especificando --remote-user Administrator@., por exemplo, mas a eficácia dessa abordagem dependerá se a conta é o administrador interno ou não, e dos valores das chaves de registro FilterAdministratorToken / LocalAccountTokenFilterPolicy. Para mais detalhes sobre esse comportamento, consulte Pass-the-Hash Is Dead: Long Live LocalAccountTokenFilterPolicy
As opções compress_output e cleanup_after_compression podem ajudar a manter o uso de disco reduzido. Após carregar o dump final no Bloodhound, você pode excluir com segurança os arquivos em output/ldap e output/remote manualmente se não precisar deles, mas esses arquivos podem ser mantidos para consultar informações importantes sem ter que reexecutar a coleta completa.
[!TIP] O objetivo principal dos arquivos
msgpacknas pastasoutput/ldapeoutput/remoteé servir como um formato intermediário para segregar responsabilidades de todo o processo, mas esses arquivos também podem ser usados como fonte de informação, convertendo-os para JSON - dessa forma você não precisa consultar atributos brutos de objetos ou resultados de coleta remota:$ go build ./cmd/ingest2json $ ./ingest2json output/ldap/YOURDOMAIN/SelectedFile.msgpack -o output.jsonUma maneira legal de inspecionar esses arquivos seria usar JQ/FX, ou sua linguagem de programação favorita 🙂
Contribuições são bem-vindas através da abertura de uma issue ou do envio de um pull request.
Muitos agradecimentos à SpecterOps pelo BloodHound, SharpHound / SharpHoundCommon e ao dirkjanm pelo BloodHound.py, que foram as principais referências para esta ferramenta.
Agradecimentos ao rtpt-erikgeiser e à RedTeamPentesting pelo adauth e ao p0dalirius pelo winacl, ambas bibliotecas muito úteis.
Agradecimentos ao oiweiwei pelo go-msrpc, pois sua biblioteca tornou possível implementar métodos de coleta remota baseados em RPCs.
Da mesma forma que a restrição de métodos permitidos para autenticação entre domínios na injeção, ao executar a coleta remota com Kerberos (por exemplo, quando o usuário faz parte de Protected Users ou quando a autenticação NTLM está bloqueada por configurações de segurança) ou com certificados (que usa PKINIT internamente), a coleta remota não tentará autenticar em computadores de domínios diferentes do domínio ao qual o usuário pertence. Isso também se aplica ao método GPOLocalGroup, que nesses casos não tentará ler arquivos de GPO de DCs de outros domínios, mesmo que haja múltiplos domínios nos dados ingeridos.
SmbInfo para o tipo Computer ainda é uma implementação básica (apenas verificações de registro).
HttpEnrollmentEndpoints funciona apenas com um nome de usuário/senha fornecidos.
A resolução de AllowedToDelegateTo / ServicePrincipalNames ainda é uma implementação básica.
Quase todas as propriedades implementadas no SharpHound são suportadas, mas existem muitas diferenças arquiteturais entre esta ferramenta e o SharpHound, portanto não espere que a saída corresponda exatamente à implementação oficial (com exceção de eventuais bugs). Diferenças chave podem surgir especialmente para as implementações mais complexas, como coleções remotas via RPC e coleções relacionadas a abuso de CA/certificados.
Os timeouts ainda são em sua maioria estáticos - a implementação do SharpHound usa um timeout adaptativo (bastante inteligente!), mas ainda não tive tempo de estudar isso. Se necessário, personalize os timeouts com as opções --timeout, --computer-timeout e --method-timeout (config/config.go especifica outros timeouts específicos de operações).
Testes atualmente não estão implementados e eu testei apenas um pequeno subconjunto de funcionalidades manualmente.
A Licença MIT (MIT)
Copyright (c) 2023 Artur Henrique Marzano Gonzaga
A permissão é concedida, gratuitamente, a qualquer pessoa que obtenha uma cópia deste software e dos arquivos de documentação associados (o "Software"), para lidar com o Software sem restrição, incluindo, sem limitação, os direitos de usar, copiar, modificar, mesclar, publicar, distribuir, sublicenciar e/ou vender cópias do Software, e para permitir que as pessoas às quais o Software é fornecido o façam, sujeitas às seguintes condições:
O aviso de copyright acima e este aviso de permissão devem ser incluídos em todas as cópias ou partes substanciais do Software.
O SOFTWARE É FORNECIDO "NO ESTADO EM QUE SE ENCONTRA", SEM GARANTIA DE QUALQUER TIPO, EXPRESSA OU IMPLÍCITA, INCLUINDO, MAS NÃO SE LIMITANDO ÀS GARANTIAS DE COMERCIALIZAÇÃO, ADEQUAÇÃO A UM DETERMINADO FIM E NÃO VIOLAÇÃO. EM NENHUM CASO OS AUTORES OU TITULARES DOS DIREITOS AUTORAIS SERÃO RESPONSÁVEIS POR QUALQUER REIVINDICAÇÃO, DANOS OU OUTRA RESPONSABILIDADE, SEJA EM UMA AÇÃO DE CONTRATO, ATO ILÍCITO OU DE OUTRA FORMA, DECORRENTE DE, FORA DE OU EM CONEXÃO COM O SOFTWARE OU O USO OU OUTRAS NEGOCIAÇÕES NO SOFTWARE.