Grant Residue

Forensic medium

В архиве `grant_residue_case.zip` находится выгрузка SOC. В материалах инцидента описаны отправка кода финансовому отделу под предлогом передачи встречи и последующий экспорт Microsoft Graph. Пароль не менялся, MFA прошла штатно. По журналам определяем, какой поток авторизации использовался для доступа. ## Решение Начинаем с рабочей станции, затем идём по облачным журналам: | Файл | Что ищем | |---|---| | `endpoint/powershell_transcript.txt` | Код, который видела жертва | | `endpoint/defender_device_events.jsonl` | Подтверждение того же кода | | `entra/signin_logs.jsonl` | Успешный вход и `correlationId` | | `entra/audit_logs.jsonl` | Выданный OAuth-грант | | `m365/unified_audit_log.jsonl` | Экспорт с этим грантом | В транскрипте PowerShell находим `FJQ9-L2RM` — строку формата `[A-Z0-9]{4}-[A-Z0-9]{4}`. Тот же код есть в телеметрии Defender, в `AdditionalFields.UserCodeObserved`. Теперь фильтруем входы Entra: `authenticationProtocol == "DeviceCode"`, `userCodeEvidence == "FJQ9-L2RM"`, `status.errorCode == 0`. Получаем успешную авторизацию через device code flow и её `correlationId`. Пароль не менялся, поскольку жертва прошла штатный вход, но подтвердила код чужого запроса. Теперь выясняем, какие права получила эта авторизация. В `entra/audit_logs.jsonl` находим `Consent to application` с тем же `correlationId` и `result == "success"`. Среди `targetResources[].modifiedProperties[]` читаем `newValue` свойства `OAuth2PermissionGrant.Id`. Сохраняем полный идентификатор для сопоставления событий, а его хвост после последнего дефиса, `grant72`, используем в ответе. Проверяем последствия в M365. Нужна запись `GraphExportJobCreated`, где одновременно совпадают `CorrelationId` и `OAuth2PermissionGrantId`, а `ResultStatus == "Succeeded"`. Из `ExportId` берём хвост `export18`. Формат ответа собирается так: ```python parts = ["dc", "FJQ9-L2RM".replace("-", "").lower(), "grant72", "export18"] flag = "caplag{" + "_".join(parts) + "}" ``` `dc` обозначает найденный поток. Остальные части связывают наблюдение кода на рабочей станции с успешным входом, выдачей согласия и последующим экспортом. Совпадение идентификаторов на каждом переходе подтверждает эту связь. [Солвер](solve/solve.py). ## Флаг `caplag{dc_fjq9l2rm_grant72_export18}`