GraphStrike

Post de lançamento: GraphStrike: Usando a Graph API da Microsoft para Fazer o Tráfego do Beacon Desaparecer
Post do desenvolvedor: GraphStrike: Anatomia do Desenvolvimento de Ferramentas Ofensivas
Introdução
O GraphStrike é um conjunto de ferramentas que permite ao HTTPS Beacon do Cobalt Strike usar a Microsoft Graph API para comunicações C2. Todo o tráfego do Beacon será transmitido através de dois arquivos criados no site do SharePoint do atacante, e todas as comunicações do Beacon serão roteadas para https://graph.microsoft.com:

O GraphStrike inclui um provisionador para criar os ativos do Azure necessários para o Cobalt Strike HTTPS sobre a Graph API:

O GraphStrike não cria ativos pagos no Azure, portanto nenhum custo adicional é incorrido pelo uso do GraphStrike ou do seu provisionador.
Por quê?
Inteligência de ameaças foi divulgada sobre vários APTs diferentes que utilizam a Microsoft Graph API e outros serviços da Microsoft para campanhas ofensivas:
- BLUELIGHT - APT37/InkySquid/ScarCruft
- Graphite - APT28/Fancy Bear
- Graphican - APT15/Nickel/The Flea
- SiestaGraph - DESCONHECIDO
Os atores de ameaças continuam a utilizar serviços legítimos para fins ilegítimos. Utilizar um domínio de alta reputação como graph.microsoft.com para comunicações C2 é extremamente eficaz e desejável, mas muitas vezes complicado e proibitivo em termos de tempo e esforço. A maioria dos frameworks C2 não suporta métodos para buscar ou rotacionar tokens de acesso, o que os impede de usar a Graph API. Isso pode dificultar que equipes vermelhas repliquem essas técnicas e priva os defensores da oportunidade de observar e desenvolver assinaturas para esse tipo de atividade. O GraphStrike busca aliviar esse fardo e fornecer um processo confiável e repetível para utilizar a Microsoft Graph API, mantendo a familiaridade e confiabilidade da experiência do Cobalt Strike.
Isso é um External C2?
Tecnicamente, não. Tendo construído anteriormente um verdadeiro External C2 usando Graph API (que enviava o tráfego do Beacon como mensagens do Microsoft Teams), o fardo de ter que desenvolver, manter e integrar um implant personalizado que atenda às especificações do External C2 e faça o trabalho é muito familiar. O GraphStrike, em vez disso, utiliza um User Defined Reflective Loader(UDRL) de código aberto chamado AceLdr por Kyle Avery (adaptado como 'GraphLdr' neste projeto) para interceptar as chamadas da biblioteca WinINet que o Beacon normalmente faz e manipulá-las conforme necessário para usar a Graph API. Não há implant personalizado ou processo adicional, apenas o processo do Beacon com algumas APIs do Windows interceptadas. No lado do servidor, há um programa Python3 que traduz o tráfego do Cobalt Strike Team Server em tráfego da Graph API e vice-versa.
Funcionalidades
O GraphStrike suporta quase todas as atividades normais do Cobalt Strike, incluindo:
- Uso de Proxychains através de um proxy SOCKS do Cobalt Strike (embora seja muito lento...)
- Upload/Download de arquivos grandes
- BOFs, execute-assembly, etc.
Isso também inclui a integração do GraphStrike com os comandos sleep, exit e remove para sincronizar os tempos de sleep do GraphStrike Server com o Beacon, bem como excluir arquivos no SharePoint quando um Beacon é encerrado ou removido.
O GraphStrike também incorpora todas as funcionalidades do AceLdr original, com algumas APIs adicionais para utilizar também o call stack spoofing.
Requisitos
O GraphStrike requer o seguinte antes de começar:
- Um tenant do Microsoft Azure com uma licença de SharePoint/O365 atribuída + site criado. O site padrão é suficiente.
- Uma conta do Azure com permissões de Administrador Global nesse tenant.
- Python 3.8-3.11Nota #4 (e dependências adicionais que serão instaladas durante o processo de configuração).
Regras de Firewall
- Certifique-se de que cada máquina onde o cliente do Cobalt Strike é executado consiga se conectar à máquina do Cobalt Strike team server nas portas 443 e 5000.
Configuração
Anote o seguinte antes de prosseguir com o processo de configuração:
1. Certos componentes utilizam caminhos relativos para localizar outros ativos. Por favor, mude de diretório conforme instruído abaixo.
2. O perfil do Cobalt Strike só pode ser editado ANTES do passo 5 no processo de configuração abaixoNota #1.
Na máquina que executará o Cobalt Strike team server:
- Clone o repositório.
- A partir do diretório do repositório, execute
sudo setup/install_dependencies.sh para instalar as dependências de sistema necessárias.
- Execute
python3 -m venv virtual e depois source virtual/bin/activate para criar e entrar no ambiente virtual.
- Mude para o diretório setup e execute
pip3 install -r requirements.txt.
- Execute
./provisioner.py new e complete o processo de configuração.
- Inicie o Cobalt Strike team server usando graphstrike.profile como o perfil C2 maleável.
- Inicie uma instância do cliente do Cobalt Strike (você pode fazer isso em uma máquina cliente, ou na máquina do TS e depois matá-la) e crie um listener HTTPS do Cobalt Strike na porta 443 com
graph.microsoft.com nos campos HTTPS Hosts e HTTPS Host(Stager).
- Volte ao diretório principal do repositório e execute o GraphStrike Server com
./GraphStrike.py.
Em TODAS as máquinas que executarão o cliente do Cobalt Strike:
- Copie o diretório GraphStrike/client para a máquina cliente a partir da máquina do TS. Isso deve ser feito APENAS após concluir o provisionamento!
- Importe o GraphStrike.cna para o Cobalt Strike usando o Script Manager.
- Crie payloads do Cobalt Strike, seja shellcode bruto ou artefatos compilados usando o Artifact Kit ou um framework alternativo de geração de payloads. Usuários do Artifact Kit vejam abaixo!
- Aproveite.
Usuários do Artifact Kit
Devido ao tamanho do GraphLdr, os usuários do Artifact Kit precisarão recompilá-lo com opções específicas para que o GraphStrike seja compatível com payloads gerados pelo Artifact Kit. Especificamente, os campos 'Stage Size' e 'RDLL Size' precisam ser especificados para usar o tamanho de 100K RDLL. Dois exemplos de sintaxe funcional são fornecidos abaixo:
./build.sh pipe VirtualAlloc 505029 100 false false none /opt/cobaltstrike/artifacts
./build.sh peek HeapAlloc 492376 100 false true indirect /opt/cobaltstrike/artifacts
Limpeza
Na máquina que está executando o TS + GraphStrike Server:
- Pare o servidor GraphStrike.
- Volte para o diretório setup e execute
./provisioner.py delete para remover os ativos do Azure criados.
Notas
Em nenhuma ordem particular, aqui estão algumas sugestões e observações para ajudar a usar o GraphStrike em todo o seu potencial.
- O perfil incluído com o GraphStrike é muito minimalista; isso é proposital. Alterar qualquer um dos campos EXISTENTES no perfil pode/quebrará o GraphStrike! Você deve conseguir adicionar linguagem/comportamento de perfil adicional a outras seções que já não estejam definidas (por exemplo, personalizar nome do pipe, comportamento de injeção, etc). Quaisquer edições no perfil DEVEM ser feitas antes de executar o provisionador!
- O aplicativo Azure usado para comunicações C2 tanto pelo Beacon quanto pelo GraphStrike Server tem um limite de taxa de 1200 requisições/min. O GraphStrike Server usa 120/min como base para funcionar. Quanto menor o tempo de sleep do Beacon, mais requisições ele fará; além disso, cada Beacon criado usando o GraphStrike estará consumindo parte desse limite de 1200/min. Ficar interativo com um Beacon é possível, mas ficar interativo com mais de um Beacon provavelmente não é. Se você encontrar problemas de limitação de taxa, considere aumentar o tempo de sleep dos seus beacons, diminuir o número de Beacons em execução, ou ambos.
- Embora o tempo de sleep do GraphStrike Server mude por Beacon de acordo com os comandos sleep emitidos, o que isso realmente significa é que o GraphStrike Server dormirá pelo tempo especificado antes de verificar o TS por tarefas. Isso NÃO significa que o Beacon receberá e processará imediatamente a tarefa assim que for recuperada do TS pelo GraphStrike server. O Beacon dormirá o tempo especificado antes de contactar o SharePoint para recuperar as tarefas do TS, mas devido à natureza assíncrona do C2, isso não estará em sincronia com o momento em que o GraphStrike Server as enviar.
- Se um Beacon morrer sem ter sido encerrado corretamente (AV, travamento, etc), o Beacon parecerá ainda estar se comunicando com o TS, e o fato de estar morto só ficará aparente quando você emitir um comando para ele. O que realmente está se conectando ao TS / fazendo parecer que o Beacon ainda está se comunicando é o GraphStrike server, então isso não reflete a saúde de um Beacon. Essa é a natureza do C2 assíncrono.
- O GraphStrike funciona em um modelo 1:1:1; 1 site do SharePoint está associado a 1 GraphStrike server que está associado a 1 TS. Você terá problemas se tentar conectar dois TS/GraphStrike servers a um único site do SharePoint. Você pode, claro, conectar vários clientes do Cobalt Strike a um único TS / GraphStrike server; cada cliente precisa apenas de uma cópia da pasta 'client' produzida pelo processo de provisionamento.
- Existe um problema conhecido sobre compatibilidade do utilitário az usado pelo GraphStrike com Python 3.12.
- Recomendo que você revise a documentação do AceLdr, pois todas as notas desse projeto se aplicam aqui também.
Limitações
As seguintes limitações existem no GraphStrike:
- Apenas Beacons x64 são suportados.
- Beacons em estágios (staged) não são suportados.
- O GraphStrike é compatível apenas com a biblioteca WinINet; a nova opção da biblioteca WinHTTP para Beacons não é suportada.
- Não há suporte para emitir um comando sleep através do menu de contexto do Beacon. Use a opção de linha de comando para dormir beacons.
- O GraphStrike é suportado apenas em instâncias Linux do Cobalt Strike. O suporte para Windows é certamente possível de implementar e é basicamente uma questão de alterar alguns caminhos nos arquivos Python e no script Aggressor.
Créditos
O GraphStrike não seria possível sem as contribuições das seguintes pessoas:
- Kyle Avery por AceLdr
- Didier Stevens por cs-decrypt-metadata.py
- Mike Saunders, Corey Overstreet, Chris Truncer e Justin Palk da equipe Red Siege, que gentilmente testaram o GraphStrike em beta e identificaram vários problemas que foram corrigidos antes do lançamento.