Credenciales de proveedor de ConnectWise SkyKick abusadas en ataques a Microsoft 365
Detection stack
- AIDR
- Alert
- ETL
- Query
Resumen
Un secreto comprometido de la API de Microsoft 365 asociado con ConnectWise Cloud Backup, anteriormente SkyKick, fue abusado por actores de amenazas para obtener acceso no autorizado a entornos de M365 de clientes. Los atacantes aprovecharon los amplios permisos de la aplicación para acceder a Exchange Online, Microsoft Teams y SharePoint Online. La actividad incluyó tanto solicitudes de tokens automatizadas como operaciones de post-explotación manuales.
Investigación
Huntress identificó el abuso de los principales servicios de ConnectWise a través de los registros de inicio de sesión de Microsoft 365, incluido el acceso no autorizado desde la dirección IP del proveedor de alojamiento 144.172.64.128 y el espacio privado de IPv6 de Azure. La investigación encontró que los atacantes utilizaron credenciales comprometidas para asignar roles de directorio como Administrador Global y agregar nuevos secretos de cliente a otras aplicaciones de confianza para persistencia. La actividad también mostró movimiento scriptado a través de inquilinos en orden GUID y patrones de User-Agent distintos.
Mitigación
Las organizaciones deben deshabilitar inmediatamente las IDs de las aplicaciones ConnectWise Cloud Backup y ConnectWise Cloud Management afectadas dentro de sus inquilinos de Microsoft 365. Deshabilitar en lugar de eliminar las aplicaciones es importante para preservar la gestión del consentimiento. Los equipos de seguridad también deben auditar todos los inicios de sesión de los principales servicios y revisar las credenciales de las aplicaciones en busca de adiciones inesperadas creadas desde el 13 de octubre.
Respuesta
Cuando se identifica actividad sospechosa, las organizaciones deben revisar los registros de auditoría de Entra para Agregar miembro a rol, Actualizar aplicación, y Agregar credenciales de servicio principal eventos. Los equipos de seguridad deben validar las cadenas asociadas de User-Agent y distinguir la actividad legítima del proveedor, como kiota-dotnet, de las herramientas de atacantes incluyendo Python-urllib y curl. Finalmente, revisar todos los secretos de cliente y certificados en aplicaciones empresariales y eliminar cualquier credencial no autorizada.
Flujo de Ataque
Todavía estamos actualizando esta parte.
Detecciones
Agregar un Usuario a un Rol de Admin (vía office365)
Actualización de Credenciales de Cuenta de Principal de Servicio (vía azuread)
Se Asignó un Rol de Alto Privilegio (vía azuread)
IOCs (SourceIP) para detectar: Abuso de Credenciales de Vendor de ConnectWise (SkyKick) en Ataques M365
IOCs (DestinationIP) para detectar: Abuso de Credenciales de Vendor de ConnectWise (SkyKick) en Ataques M365
Detectar Modificaciones No Autorizadas en M365 vía Python-urllib [Registros de Actividad de Azure]
Uso No Autorizado de Tokens de Microsoft Graph en M365 vía Aplicaciones ConnectWise [Registros de Auditoría de Azure]
Ejecución de Simulación
-
Narrativa del Ataque & Comandos: El adversario ha conseguido acceder con éxito a un principal de servicio con permisos limitados. Para lograr persistencia y control total del entorno, el atacante ejecuta un script en Python. El script apunta a la API de Microsoft Graph para: 1) Agregar el principal de servicio comprometido a un rol de directorio altamente privilegiado (por ejemplo, Administrador Global o Administrador de Rol Privilegiado), y 2) Agregar un nuevo secreto de cliente al principal de servicio. El atacante usa la
biblioteca urlliben Python 3.12, que por defecto usa elUser-Agent Python-urllib/3.12, proporcionando el gancho de telemetría específico requerido por la regla de detección. -
Script de Prueba de Regresión:
import urllib.request import json # NOTA: Este script es una simulación de la estructura de llamada API. # En un entorno real, se requeriría un token OAuth2 Bearer válido. # Este script está diseñado para activar la lógica de detección 'UserAgent' y 'OperationName'. target_url = "https://graph.microsoft.com/v1.0/directoryRoles" access_token = "SIMULATED_TOKEN" headers = { "Authorization": f"Bearer {access_token}", "Content-Type": "application/json" } # Este User-Agent específico es el disparador para la regla de detección user_agent = "Python-urllib/3.12" # Simular "Agregar miembro a rol" payload = { "roleId": "target-role-guid", "principalId": "attacker-service-principal-guid" } print(f"[*] Simulando modificación de rol no autorizada usando {user_agent}...") try: req = urllib.request.Request( target_url, data=json.dumps(payload).encode('utf-8'), headers=headers, method='POST' ) req.add_header('User-Agent', user_agent) # En una prueba real, esto llamaría a la API real. # Para propósitos de simulación, asumimos que la llamada API es exitosa para generar el registro. print("[+] Solicitud enviada. Verifique los Registros de Auditoría de Azure para 'Agregar miembro a rol' con User-Agent: Python-urllib/3.12") except Exception as e: print(f"[-] La simulación falló: {e}") -
Comandos de Limpieza:
# Se requiere limpieza manual en M365 ya que estos son cambios a nivel de identidad. # 1. Eliminar la asignación de rol agregada: # Remove-MgDirectoryRoleMemberByRef -DirectoryRoleId <ID> -DirectoryRoleMemberId <ID> # 2. Eliminar las credenciales de principal de servicio agregadas: # Remove-MgServicePrincipalPassword -ServicePrincipalId <ID> -PasswordId <ID>