Credenciais de Fornecedor ConnectWise SkyKick Abusadas em Ataques Microsoft 365
Detection stack
- AIDR
- Alert
- ETL
- Query
Resumo
Um segredo comprometido da API Microsoft 365 associado ao ConnectWise Cloud Backup, anteriormente SkyKick, foi abusado por agentes de ameaça para obter acesso não autorizado a ambientes M365 de clientes. Os atacantes aproveitaram as extensas permissões do aplicativo para acessar Exchange Online, Microsoft Teams e SharePoint Online. A atividade incluiu tanto solicitações automatizadas de token quanto operações de pós-exploração manual.
Investigação
A Huntress identificou abuso de principais de serviço do ConnectWise por meio de logs de login do Microsoft 365, incluindo acesso não autorizado de endereço IP do provedor de hospedagem 144.172.64.128 e espaço IPv6 privado da Azure. A investigação encontrou que os atacantes usaram credenciais comprometidas para atribuir papéis de diretório como Administrador Global e adicionar novos segredos de clientes a outros aplicativos confiáveis para persistência. A atividade também mostrou movimento roteirizado através de locatários na ordem de GUID e padrões distintos de User-Agent.
Mitigação
As organizações devem desativar imediatamente os IDs de aplicativo ConnectWise Cloud Backup e ConnectWise Cloud Management afetados dentro de seus locatários Microsoft 365. Desativar em vez de excluir os aplicativos é importante para preservar o gerenciamento de consentimento. As equipes de segurança também devem auditar todos os logins de principais de serviço e revisar as credenciais de aplicação para adições inesperadas criadas desde 13 de outubro.
Resposta
Quando uma atividade suspeita é identificada, as organizações devem revisar os logs de auditoria Entra para Adicionar membro ao papel, Atualizar aplicação, e Adicionar credenciais de principal de serviço eventos. As equipes de segurança devem validar strings associadas ao User-Agent e distinguir atividades legítimas de fornecedores, como kiota-dotnet, de ferramentas de atacantes incluindo Python-urllib e curl. Finalmente, reveja todos os segredos de cliente e certificados em aplicativos empresariais e remova quaisquer credenciais não autorizadas.
Fluxo de Ataque
Ainda estamos atualizando esta parte.
Detecções
Adicionar Usuário a um Papel de Administrador (via office365)
Atualização de Credenciais de Conta de Principal de Serviço (via azuread)
Papel de Alta Privilegiatura foi Atribuído (via azuread)
IOCs (SourceIP) para detectar: Credenciais de Fornecedor ConnectWise (SkyKick) Abusadas em Ataques M365
IOCs (DestinationIP) para detectar: Credenciais de Fornecedor ConnectWise (SkyKick) Abusadas em Ataques M365
Detectar Modificações Não Autorizadas em M365 via Python-urllib [Logs de Atividade do Azure]
Uso Não Autorizado de Tokens Microsoft Graph em M365 via Aplicações ConnectWise [Logs de Auditoria do Azure]
Execução da Simulação
-
Narrativa do Ataque & Comandos: O adversário conseguiu acessar com sucesso um principal de serviço com permissões limitadas. Para alcançar persistência e controle total do ambiente, o atacante executa um script em Python. O script visa a API Microsoft Graph para: 1) Adicionar o principal de serviço comprometido a um papel de diretório de alta privilegiação (por exemplo, Administrador Global ou Administrador de Papel Privilegiado), e 2) Adicionar um novo segredo de cliente ao principal de serviço. O atacante utiliza a biblioteca
urllibem Python 3.12, que por padrão usaPython-urllib/3.12User-Agent, fornecendo o gancho de telemetria específico necessário pela regra de detecção. -
Script para Teste de Regressão:
import urllib.request import json # NOTA: Este script é uma simulação da estrutura de chamada da API. # Em um ambiente real, seria necessário um token OAuth2 Bearer válido. # Este script é projetado para acionar a lógica de detecção de 'UserAgent' e 'OperationName'. url_destino = "https://graph.microsoft.com/v1.0/directoryRoles" token_acesso = "TOKEN_SIMULADO" cabecalhos = { "Authorization": f"Bearer {token_acesso}", "Content-Type": "application/json" } # Este User-Agent específico é o gatilho para a regra de detecção user_agent = "Python-urllib/3.12" # Simular "Adicionar membro ao papel" carga = { "roleId": "guid-do-papel-alvo", "principalId": "guid-do-principal-de-serviço-do-atacante" } print(f"[*] Simulando modificação de papel não autorizada usando {user_agent}...") try: req = urllib.request.Request( url_destino, data=json.dumps(carga).encode('utf-8'), headers=cabecalhos, method='POST' ) req.add_header('User-Agent', user_agent) # Em um teste real, isso chamaria a API real. # Para fins de simulação, assumimos que a chamada da API é bem-sucedida para gerar o log. print("[+] Requisição enviada. Verifique os Logs de Auditoria do Azure para 'Adicionar membro ao papel' com User-Agent: Python-urllib/3.12") except Exception as e: print(f"[-] Falha na simulação: {e}") -
Comandos de Limpeza:
# A limpeza manual é necessária no M365, pois são mudanças a nível de identidade. # 1. Remover a atribuição de papel adicionada: # Remove-MgDirectoryRoleMemberByRef -DirectoryRoleId <ID> -DirectoryRoleMemberId <ID> # 2. Remover as credenciais do principal de serviço adicionadas: # Remove-MgServicePrincipalPassword -ServicePrincipalId <ID> -PasswordId <ID>