Зловживання обліковими даними постачальника ConnectWise SkyKick у атаках на Microsoft 365
Detection stack
- AIDR
- Alert
- ETL
- Query
Резюме
Зламаний секрет Microsoft 365 API, пов’язаний з ConnectWise Cloud Backup, раніше відомим як SkyKick, був зловмисно використаний зловмисниками для отримання несанкціонованого доступу до середовищ M365 клієнтів. Нападники використовували широкі дозволи застосування для доступу до Exchange Online, Microsoft Teams і SharePoint Online. Активність включала як автоматизовані запити до токенів, так і ручні операції після експлуатації.
Розслідування
Huntress виявила зловживання службовими обліковими згідно з ConnectWise через журнали входів Microsoft 365, включаючи несанкціонований доступ з IP-адреси хостинг-провайдера 144.172.64.128 і приватного IPv6-простору Azure. У ході розслідування було виявлено, що атакуючі використовували скомпрометовані облікові дані для призначення ролей у каталозі, таких як Глобальний адміністратор, і додавання нових секретів клієнтів до інших довірених застосунків для стійкості. Активність також показала сценарійний рух через орендарів у порядку GUID і відмінні шаблони User-Agent.
Пом’якшення
Організації повинні негайно вимкнути уражені ConnectWise Cloud Backup і ConnectWise Cloud Management ідентифікатори застосунків у своїх орендарях Microsoft 365. Вимкнення, а не видалення застосунків є важливим для збереження управління згодою. Командам з безпеки слід також провести аудит усіх входів службових облікових записів і перевірити облікові дані застосунків на предмет неочікуваних додатків, створених після 13 жовтня.
Відповідь
Коли виявлено підозрілу активність, організаціям слід перевірити журнали аудиту Entra для Додати учасника до ролі, Оновити застосунок, і Додати облікові дані службового облікового запису події. Командам з безпеки слід перевірити асоційовані рядки User-Agent і відрізняти легітимну активність постачальника, таку як kiota-dotnet, від зловмисних інструментів атакуючих, включаючи Python-urllib і curl. Нарешті, перевірте всі секрети клієнтів і сертифікати по підприємницьких застосунках і видаліть будь-які несанкціоновані облікові дані.
Потік атаки
Ми ще обновлюємо цю частину.
Виявлення
Додати користувача до адміністраторської ролі (через office365)
Оновлення облікових даних службового облікового запису (через azuread)
Високопривілейована роль була призначена (через azuread)
IOC-адреси (SourceIP) для виявлення: Зловживання обліковими даними постачальника ConnectWise (SkyKick) у M365 атаках
IOC-адреси (DestinationIP) для виявлення: Зловживання обліковими даними постачальника ConnectWise (SkyKick) у M365 атаках
Виявлення несанкціонованих змін у M365 через Python-urllib [Azure Activity Logs]
Несанкціоноване використання токенів Microsoft Graph у M365 через ConnectWise Applications [Azure Auditlogs]
Експериментальна симуляція
-
Опис атаки та команди: Противник успішно отримав доступ до службового облікового запису з обмеженими дозволами. Щоб досягти стійкості та повного контролю середовища, атакуючий виконує сценарій на Python. Сценарій спрямований на Microsoft Graph API для: 1) Додавання скомпрометованого службового облікового запису до високо привілейованої директорної ролі (наприклад, Global Administrator або Privileged Role Administrator), та 2) Додавання нових секретів клієнтів до службового облікового запису. Атакуючий використовує
бібліотеку urllibв Python 3.12, що за замовчуванням використовуєUser-Agent Python-urllib/3.12, надаючи спеціальний гачок телеметрії, необхідний для правила виявлення. -
Сценарій регресійного тестування:
import urllib.request import json # УВАГА: Це сценарій моделювання структури виклику API. # У реальному середовищі потрібен дійсний OAuth2 Bearer токен. # Цей сценарій призначений для активації логіки виявлення 'UserAgent' та 'OperationName'. target_url = "https://graph.microsoft.com/v1.0/directoryRoles" access_token = "SIMULATED_TOKEN" headers = { "Authorization": f"Bearer {access_token}", "Content-Type": "application/json" } # Цей конкретний User-Agent є тригером для правила виявлення user_agent = "Python-urllib/3.12" # Імітація "Додати учасника до ролі" payload = { "roleId": "target-role-guid", "principalId": "attacker-service-principal-guid" } print(f"[*] Імітація несанкціонованої модифікації ролі з використанням {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) # У реальному тесті це викликало б реальний API. # Для моделювання припустимо, що виклик API успішний для генерації журналу. print("[+] Запит відправлено. Перевірте журнали аудиту Azure на 'Додати учасника до ролі' з User-Agent: Python-urllib/3.12") except Exception as e: print(f"[-] Імітація провалилась: {e}") -
Команди очищення:
# У M365 потрібне ручне очищення, оскільки це зміни на рівні ідентифікації. # 1. Видалити додане призначення ролі: # Remove-MgDirectoryRoleMemberByRef -DirectoryRoleId <ID> -DirectoryRoleMemberId <ID> # 2. Видалити додані облікові дані службового облікового запису: # Remove-MgServicePrincipalPassword -ServicePrincipalId <ID> -PasswordId <ID>