about_Logging_Windows — Windows에서 PowerShell 로깅 설정하기
about_Logging_Windows — Windows에서 PowerShell 로깅 설정하기
PowerShell은 엔진·프로바이더·cmdlet의 내부 작업을 Windows 이벤트 로그에 남겨요. 이 문서는 그 로깅을 어떻게 켜고, 어떤 이벤트가 기록되고, 민감한 내용까지 안전하게 남기려면 어떻게 해야 하는지를 하나씩 설명해 드릴게요.
본문
짧은 설명 (Short description)
PowerShell은 엔진, 프로바이더, cmdlet에서 일어나는 내부 작업을 Windows 이벤트 로그에 기록해요.
자세한 설명 (Long description)
PowerShell은 엔진과 프로바이더를 시작하고 멈추는 일, PowerShell 명령을 실행하는 일 같은 세부 내용을 로그로 남겨요. PowerShell이 어떻게 동작했는지를 나중에 돌아볼 수 있게 해 주는 거죠.
Windows PowerShell 5.1에서의 로깅에 대한 내용은 about_Logging을 참고해 주세요.
PowerShell은 로깅을 두 가지 범주로 나눠서 설정할 수 있어요.
모듈 로깅 (Module logging) — 지정한 모듈에 속한 멤버들의 파이프라인 실행 이벤트를 기록해요. 모듈 로깅은 세션과 특정 모듈 둘 다에서 활성화되어 있어야 해요. 설정 방법은 about_PowerShell_Config를 보시면 돼요.
설정을 통해 모듈 로깅이 켜져 있으면, 세션 안에서 특정 모듈의 로깅을 켜고 끌 수도 있어요. 그때는 해당 모듈의 LogPipelineExecutionDetails 속성값을 바꾸면 돼요. 예를 들어 PSReadLine 모듈의 모듈 로깅을 켜려면 이렇게 해요.
$psrl = Get-Module PSReadLine
$psrl.LogPipelineExecutionDetails = $true
Get-Module PSReadLine | Select-Object Name, LogPipelineExecutionDetails
실행 결과를 보면 LogPipelineExecutionDetails가 True로 바뀐 걸 확인할 수 있어요.
Name LogPipelineExecutionDetails
---- ---------------------------
PSReadLine True
스크립트 블록 로깅 (Script block logging) — 명령, 스크립트블록, 함수, 스크립트의 처리를 기록해요. 대화형으로 실행하든 자동화로 실행하든 모두 포함돼요.
Script Block Logging을 켜면 PowerShell이 처리하는 모든 스크립트블록의 내용을 기록해요. 한 번 켜면 그다음부터 새로 시작되는 PowerShell 세션에서 이 정보를 로그로 남겨요. 자세한 내용은 아래의 스크립트블록 로깅 활성화를 참고하세요.
Windows에서 PowerShell 이벤트 프로바이더 등록
Linux나 macOS와 달리 Windows는 이벤트 프로바이더를 등록해야 이벤트를 이벤트 로그에 쓸 수 있어요. PowerShell 이벤트 프로바이더를 활성화하려면 관리자 권한 PowerShell 프롬프트에서 아래 명령을 실행하세요.
$PSHOME\RegisterManifest.ps1
Windows에서 PowerShell 이벤트 로그 항목 보기
PowerShell 로그는 Windows 이벤트 뷰어(Event Viewer)로 확인할 수 있어요. 이벤트 로그는 Application and Services Logs 그룹에 있고 이름은 PowerShellCore예요. 연결된 ETW 프로바이더 GUID는 {f90714a8-5509-434a-bf6d-b1624c8a19a2}예요.
Script Block Logging이 켜져 있으면 PowerShell이 다음 이벤트를 PowerShellCore/Operational 로그에 기록해요.
| 필드 | 값 |
|---|---|
| EventId | 4104 / 0x1008 |
| Channel | Operational |
| Level | Verbose |
| Opcode | Create |
| Task | CommandStart |
| Keyword | Runspace |
Windows에서 PowerShell 이벤트 프로바이더 등록 해제
이벤트 프로바이더를 등록하면 이벤트를 디코딩하는 데 쓰는 바이너리 라이브러리에 잠금(lock)이 걸려요. 이 라이브러리를 업데이트하려면 잠금을 풀기 위해 프로바이더를 먼저 등록 해제해야 해요.
PowerShell 프로바이더를 등록 해제하려면 관리자 권한 PowerShell 프롬프트에서 아래 명령을 실행하세요.
$PSHOME\RegisterManifest.ps1 -Unregister
PowerShell을 업데이트한 뒤에는 $PSHOME\RegisterManifest.ps1을 실행해서 업데이트된 이벤트 프로바이더를 다시 등록해 주세요.
스크립트블록 로깅 활성화 (Enabling scriptblock logging)
Script Block Logging을 켜면 PowerShell이 처리하는 모든 스크립트블록의 내용을 기록해요. 한 번 켜면 새로 시작되는 PowerShell 세션에서 이 정보를 로그로 남겨요.
참고 — Script Block Logging을 진단 목적이 아닌 용도로 쓸 때는 아래에 설명하는 Protected Event Logging을 함께 켜 두는 걸 권장해요.
Script Block Logging은 그룹 정책(Group Policy)이나 레지스트리 설정으로 켤 수 있어요.
그룹 정책 사용하기 — 자동 기록(transcription)을 켜려면 그룹 정책의 Administrative Templates -> PowerShell Core에서 Turn on PowerShell Script Block Logging 기능을 활성화하세요.
레지스트리 사용하기 — 아래 함수를 실행하면 돼요.
function Enable-PSScriptBlockLogging {
$basePath = @(
'HKLM:\Software\Policies\Microsoft'
'PowerShellCore\ScriptBlockLogging'
) -join '\'
if (-not (Test-Path $basePath)) {
$null = New-Item $basePath -Force
}
Set-ItemProperty $basePath -Name EnableScriptBlockLogging -Value "1"
}
PowerShell 구성 파일 사용하기 — PowerShell 동작을 제어하는 powershell.config.json 파일에서 ScriptBlockLogging 옵션을 설정할 수도 있어요. 자세한 내용은 about_PowerShell_Config를 참고하세요.
보호된 이벤트 로깅 (Protected event logging)
시스템의 로깅 수준을 높이면 로그에 민감한 데이터가 들어갈 가능성도 함께 높아져요. 예를 들어 스크립트 로깅을 켜면 스크립트가 사용하는 자격 증명이나 그 밖의 민감한 데이터가 이벤트 로그에 쓰일 수 있어요. 민감한 데이터를 로그로 남긴 머신이 공격을 받으면, 공격자가 그 로그를 통해 영향 범위를 넓히는 데 필요한 정보를 얻을 수 있죠.
이 정보를 보호하기 위해 Windows 10은 Protected Event Logging을 도입했어요. Protected Event Logging은 참여하는 애플리케이션이 이벤트 로그에 쓰는 민감한 데이터를 암호화할 수 있게 해 줘요. 나중에 더 안전하고 중앙 집중된 로그 수집기에서 이 로그를 복호화하고 처리할 수 있어요.
이벤트 로그 내용은 IETF 암호화 메시지 구문(CMS, Cryptographic Message Syntax) 표준으로 보호돼요. CMS는 공개 키 암호화(public key cryptography)를 사용해요. 내용을 암호화할 때 쓰는 키와 복호화할 때 쓰는 키를 분리해 두는 거죠.
공개 키는 널리 공유해도 되고 민감한 데이터가 아니에요. 이 공개 키로 암호화한 내용은 오직 개인 키로만 복호화할 수 있어요. 공개 키 암호화에 대해 더 자세히 알고 싶다면 Wikipedia - Public Key Cryptography를 참고하세요.
Protected Event Logging 정책을 켜려면 보호할 이벤트 로그 데이터가 있는 모든 머신에 공개 키를 배포해요. 대응하는 개인 키는 더 안전한 곳(예: 중앙 이벤트 로그 수집기나 SIEM 집계기)에서 로그를 사후 처리할 때 사용해요. Azure에서 SIEM을 구축할 수도 있고요. 자세한 내용은 Generic SIEM integration을 참고하세요.
그룹 정책으로 Protected Event Logging 활성화
Protected Event Logging을 켜려면 그룹 정책의 Administrative Templates -> Windows Components -> Event Logging에서 Enable Protected Event Logging 기능을 활성화하세요. 이 설정은 암호화 인증서를 요구하는데, 인증서는 여러 형태 중 하나로 제공할 수 있어요.
- base-64로 인코딩된 X.509 인증서의 내용 (예: Certificate Manager의
Export옵션이 제공하는 형태) - 로컬 머신 인증서 저장소에서 찾을 수 있는 인증서의 지문(thumbprint) — PKI 인프라로 배포할 수 있어요
- 인증서의 전체 경로 — 로컬이거나 원격 공유일 수 있어요
- 인증서 하나 또는 여러 개가 들어 있는 디렉터리의 경로 — 로컬이거나 원격 공유일 수 있어요
- 로컬 머신 인증서 저장소에서 찾을 수 있는 인증서의 주체 이름(subject name) — PKI 인프라로 배포할 수 있어요
결과 인증서는 향상된 키 사용(EKU, 1.3.6.1.4.1.311.80.1)으로 Document Encryption을 가져야 하고, 키 사용은 Data Encipherment나 Key Encipherment 중 하나가 활성화되어 있어야 해요.
경고 — 이벤트를 기록하는 머신에는 개인 키를 배포하면 안 돼요. 개인 키는 메시지를 복호화하는 안전한 위치에 보관해야 해요.
Protected Event Logging 메시지 복호화
아래 스크립트는 개인 키를 갖고 있다는 가정 아래 이벤트를 가져와서 복호화해요.
Get-WinEvent Microsoft-Windows-PowerShell/Operational |
Where-Object Id -EQ 4104 | Unprotect-CmsMessage
더 알아보기
- about_Logging_Non-Windows — Windows가 아닌 운영체제에서의 로깅
- PowerShell the Blue Team — PowerShell을 수비(블루팀) 관점에서 다루는 블로그
- Generic SIEM integration — SIEM 연동