많은 기관들이 작업을 수행하기 위해 Microsoft 기술에 의존하고 있습니다. 동시에, 위협 사용자들은 Windows와 같은 운영 체제를 악용할 수 있습니다. 다행히도, Windows는 이러한 동작을 추적하기 위해 OS 보안 이벤트를 기록합니다.
Windows가 생성하는 보안 이벤트는 사고 대응 과정에서 중요한 자원으로 작용합니다. Microsoft의 Windows 이벤트 뷰어와 같은 도구를 사용하여 캡처된 이벤트를 검토할 수 있는 액세스 권한을 제공하지만, 혼잡한 로그를 수동으로 스크롤하여 이상을 탐지하는 것은 현실적이지 않습니다.
이 게시물에서는 감사 정책, Windows 이벤트 로그 및 PowerShell을 사용하여 Windows에서 잠재적인 보안 침해를 추적하는 방법에 대해 배우게 될 것입니다.
필수 사항
이 문서는 PowerShell을 사용하여 Windows 보안 이벤트를 분석하는 방법을 가르칠 정보를 전달하기 위한 것입니다. 어떤 데모를 따라하려면 다음이 필요합니다:
- A Windows 10+ PC – This PC will be used to generate and track down potential security events in the event log. This tutorial will be using Windows PowerShell 5.1.
- Windows PC에서 관리자 권한
- A PowerShell code editor such PowerShell ISE or Visual Studio (VS) Code.
Windows가 보안 이벤트를 저장하는 위치
Windows 운영 체제에서 작업을 수행하면 Windows는 해당 작업을 하나 이상의 이벤트 로그에 이벤트로 기록합니다. Windows 이벤트 로그는 기본적으로 파일 시스템에 %SystemRoot%\system32\winevt\logs 디렉터리에 저장됩니다. 이 위치는 해당 이벤트 로그의 EventLog 레지스트리 하위 키를 수정하여 변경할 수 있습니다.
시스템에서 가장 주요한 이벤트 로그 (응용 프로그램, 보안 및 시스템)가 저장된 위치를 확인하려면 아래 코드를 PowerShell 콘솔에 복사하여 붙여넣거나 스크립트로 저장하십시오.
보안 로그 파일의 저장 위치에 액세스하려면 코드를 관리자로 실행해야 합니다.
다음 스크린샷은 코드의 예상 출력을 보여주며 응용 프로그램, 보안 및 시스템 로그 파일의 이름과 저장 위치를 표시합니다.

감사 정책: 기록할 이벤트 정의
기본적으로 Windows는 침입을 감지하거나 조사하는 데 필요한 모든 보안 이벤트를 캡처하지 않습니다. Windows가 기록하고 기록하지 않을 것을 제어하려면 감사 정책을 정의하고 적용해야 합니다. 감사 정책은 Windows에 전달되는 일련의 명령으로, 어떤 이벤트를 기록할지를 알려줍니다.
그룹 정책과 같은 다양한 방법으로 감사 정책을 할당하고 사용할 수 있습니다. 그룹 정책은 여러 대의 컴퓨터에 감사 정책을 적용해야 하는 경우 효과적입니다. 그러나 이 문서에서는 단일 장치에 집중할 것이므로 auditpol 도구를 사용합니다. auditpol 도구는 Windows에 설치되어 있으며 Windows 시스템에서 감사 정책을 찾고 설정할 수 있게 해줍니다.
감사 정책 찾기
예를 들어 Windows 시스템에서 모든 감사 정책의 상태를 찾으려면 아래와 같이 /get
매개변수를 사용하십시오. 와일드카드 뒤에 따라오는 /category
매개변수를 사용하면 auditpol이 특정 범주나 하위 범주와 일치하는 정책 하나가 아니라 모든 감사 정책의 상태를 찾도록 할 수 있습니다.
다음 스크린샷은 코드의 예상 출력의 일부를 보여줍니다. 계정 관리 감사 정책 범주, 하위 범주 및 상태 (설정)을 표시합니다.

A Setting that is configured as No Auditing means that all events associated with that audit policy subcategory will not be logged.
감사 정책 설정
auditpol 도구는 감사 정책 설정을 보기 위해 사용할 수 있는 것 이상의 기능을 제공합니다. auditpol /set
명령을 사용하여 이를 수정할 수도 있습니다. 이 튜토리얼의 향후 섹션을 보여주기 위해 관리자 권한으로 PowerShell 콘솔을 열고 아래 명령을 실행합니다. 이 명령은 로그온 하위 범주의 일부인 모든 이벤트 (성공 및 실패)를 기록을 시작합니다.
로그온 하위 범주를 구성하면 시스템이 이벤트를 기록하도록 강제됩니다:
- 4624: 계정이 성공적으로 로그온함
- 4625: 계정이 로그온에 실패함
- 4626: 사용자/장치 클레임 정보
- 4648: 명시적 자격 증명을 사용하여 로그온을 시도했습니다
- 4675: SID가 필터링되었습니다
최상의 감사 정책 구성을 지원하는 다양한 리소스가 있습니다. 이에는 인터넷 보안 센터 (CIS) 벤치마크 및 국방 정보 시스템 에이전시 (DISA) 보안 기술 구현 지침 (STIG) 및 Microsoft에서 발표한 지침이 포함됩니다.
분석을 위한 로그온 실패 로그 생성
이 문서는 자습서이며 여러분이 따라오기를 기대합니다. Windows를 로그온 이벤트를 감사로 구성했다면 이제 보안 이벤트를 생성하여 나중에 분석할 것입니다. 구체적으로 시스템 보안 로그에 기록된 35회 실패한 로그온 시도를 생성하여 무차별 대입 활동을 모방하겠습니다.
1. 좋아하는 코드 편집기를 엽니다.
2. 다음 코드를 복사하여 코드 편집기에 붙여넣습니다. 이 코드 스니펫은 가짜 사용자 이름과 암호를 사용하여 Start-Process
cmdlet을 사용하여 PowerShell.exe 프로세스를 열려고 시도합니다.
3. PowerShell 스크립트를 Invoke-BogusEvents.ps1 또는 원하는 이름으로 저장하고 스크립트를 실행합니다.
실행되면 예상된 오류가 35번 반복되어 나타납니다. 사용자 이름 또는 암호가 올바르지 않습니다.

예상된 출력을 받지 못하는 경우 보조 로그온 서비스가 실행 중인지 확인하십시오.
PowerShell로 Windows 이벤트에 액세스
이제 최소한 35개의 Windows 보안 이벤트를 보유하고 있음을 확인했으므로 PowerShell의 Get-WinEvent
cmdlet을 사용하여 해당 이벤트를 찾는 방법을 살펴보겠습니다.
아마도 PowerShell의
Get-EventLog
cmdlet에 익숙할 것입니다. 이 cmdlet은 이벤트 로그에 프로그래밍 방식으로 액세스하는 데 사용되며 Win32 응용 프로그램 프로그래밍 인터페이스 (API)를 사용합니다. 이 API는 폐기되었으며 이 게시물에서는 논의되지 않습니다.
파워셸 콘솔을 관리자 권한으로 열고 아래와 같이 FilterHashtable
및 MaxEvents
매개변수를 전달하여 Get-WinEvent
cmdlet를 호출하십시오.
아래 명령은 시스템의 보안 로그(LogName='Security'
)에서 이벤트 ID 4625 (ID=4625
)를 조회하고 최신 10개의 인스턴스를 반환합니다(MaxEvents 10
).
성공적으로 실행되면 다음과 유사한 출력이 표시됩니다:

Get-WinEvent로 이벤트 속성에 액세스하기
위 섹션에서는 Get-WinEvent
를 사용하여 Windows 보안 이벤트를 높은 수준에서 볼 수 있었지만, Windows 이벤트에는 더 많은 정보가 포함되어 있습니다. 각 Windows 이벤트에는 보다 심층적인 분석에 사용할 수 있는 가치 있는 속성이 있습니다.
Windows 이벤트를 XML로
Windows가 이벤트를 기록할 때 XML 형식으로 저장됩니다. 그렇다면 왜 Get-WinEvent
명령이 일반적인 PowerShell 객체를 반환했을까요? Get-WinEvent
cmdlet는 네이티브 Windows API를 읽고 이벤트를 PowerShell 객체로 변환하여 기능을 향상시킵니다.
각 Windows 이벤트에는 특정 XML 스키마 또는 구조를 따르는 여러 속성이 있습니다.
아래에서 각 이벤트가 세 가지 속성을 가진 특정 구조를 따르는 것을 볼 수 있습니다:
name
– 속성의 이름inType
– 입력 유형 정의 또는 이벤트가 값을 수용하는 방법outputType
– 출력 유형 정의 또는 이벤트가 기록되는 방법
PowerShell을 사용하여 이벤트 XML 템플릿 찾기
위에서 언급한 대로 모든 Windows 보안 이벤트는 XML에 저장되어 특정 스키마를 가지고 있지만, 그 스키마는 어떻게 보이나요? 알아봅시다.
이전 섹션 중 하나에서 보안 이벤트 로그에서 ID 4625를 가진 몇 가지 이벤트를 생성했습니다. 이 유형의 이벤트에는 해당하는 특정 속성이 있습니다. 이러한 속성 및 템플릿이 어떻게 보이는지 찾으려면:
1. 이미 관리자로 PowerShell 콘솔을 열지 않았다면 PowerShell 콘솔을 엽니다.
2. ListProvider
매개변수를 사용하여 Windows가 보안 이벤트 로그에 이벤트를 기록하는 데 사용하는 제공자를 지정하고 Events
속성만 반환하여 다시 Get-WinEvent
를 실행합니다.
Events
속성에는 목록 제공자가 기록한 모든 이벤트가 포함되어 있으며 각 이벤트의 XML 템플릿을 노출합니다.

3. 이제 모든 이벤트 유형의 템플릿을 찾는 코드가 있으므로 ID 4625에 연결된 이벤트만 반환하도록 제한합니다.
4. 이제 이벤트 ID 4625의 로그온 이벤트 유형만 반환되도록 제한한 후 아래와 같이 Template
속성만 표시합니다.
다음 스크린샷은 코드 출력의 일부를 보여주며, 이벤트 속성 이름, 입력 유형 및 출력 유형을 식별합니다. 이벤트 ID 4625에는 다양한 입력 및 출력 정의가 있는 이벤트 속성이 있음을 확인할 수 있습니다.
아래 스크린샷은 이벤트 ID 4625의 SubjectUserSid
속성을 강조합니다. 이 특정 이벤트는 입력 유형 (inType
)으로 win:SID
를 수용하고 출력 (outType
)을 string
으로 렌더링합니다. 이는 보안 로그 내에서 저장되는 방식입니다.

PowerShell이 XML을 객체로 변환하는 방법
이제 Windows가 XML로 이벤트를 저장하는 방법과 PowerShell에서 해당 템플릿을 볼 수 있는 방법을 보았으니, PowerShell이 그 XML을 객체로 변환하는 방법을 살펴봅시다.
1. 다시 Get-WinEvent
명령을 실행하여 이벤트 ID 4625를 반환합니다. 지금까지는 새로운 내용이 없습니다. PowerShell은 TimeCreated
, Id
, LevelDisplayName
, Message
네 가지 속성만 표시한다는 점에 유의하십시오.

Get-WinEvent
cmdlet은 이벤트의 XML 데이터 소스에서 모든 속성을 PowerShell 객체로 반환하지 않습니다.
2. 이전 명령의 출력을 Select-Object
cmdlet으로 파이핑하고 Property
매개변수를 지정하여 값을 전달하여 모든 속성을 표시합니다.
아래에서 PowerShell이 여러 가지 다른 속성을 숨겼음을 알 수 있습니다. 구체적으로 Properties
라는 속성입니다. Properties
속성에는 XML 템플릿에서 이전에 본 각 이벤트 속성의 값이 포함됩니다.

3. Get-WinEvent
명령의 출력을 제한하여 Properties
속성을 노출합니다. 이 속성은 모든 이벤트 속성을 배열에 저장합니다. 이 속성은 PowerShell 객체 속성이 아니라 입니다.
아래 스크린샷의 왼쪽에는 위 명령의 출력이 표시됩니다. 배열은 스크린샷의 오른쪽에 있는 XML 템플릿의 각 XML 속성에 대한 값을 포함합니다.
스크린샷에 표시된 코드의 출력은 사용자 AtaBlogUser
(TargetUserName
)가 시스템 Desktop-XXXXX
(WorkstationName
)에서 ::1
(IpAddress
)를 사용하여 인증 실패가 발생했음을 나타냅니다.

아마도 TargetUserName
이벤트 속성의 값만 반환하려고 할 것입니다. 이미 모든 이벤트 속성을 $eventProperties
변수에 저장했으므로 TargetUserName
에 대한 값이 들어 있는 다섯 번째 인덱스를 참조하십시오.
개별 이벤트 속성 개체의 value
속성을 참조하여 값 (AtaBlogUser
)만 반환해야 합니다. $eventProperties[5].value

이 섹션에서 설명된 실습은 이후에 본 포스트에서 시뮬레이트한 브루트 포스 시도를 추적하는 데 사용될 것입니다.
브루트 포스 공격 감지
지금 PowerShell 기술을 사용하여 이전에 복제한 브루트 포스 공격을 추적할 준비가 되었습니다! 특정 시간대를 기반으로 브루트 포스 공격을 추적하는 것이 어떻게 보일지 시뮬레이션해보는 것으로 여러분의 기술을 시험해 봅시다.
조직에서 어제부터 중요한 Windows Server에 로그인하려는 사람이 관리자 계정을 사용하려고 시도하는 것을 의심한다는 사고를 감지했다고 가정해 봅시다. 이 활동은 어제 시작되었습니다. 지난 24시간 동안 발생한 이벤트 ID 4625: 계정 로그온 실패의 수를 발견하고 각 이벤트의 로그온 유형을 결정해야 합니다.
1. 지난 24시간 동안 Windows 보안 로그(LogName="Security"
)에서 ID 4625의 모든 이벤트(ID=4625
)를 찾습니다 (StartTime=((Get-Date).AddDays(-1).Date
), 현재 시간을 기준으로 종료합니다 (Get-Date
).
2. 이제 변수에 저장된 모든 이벤트를 계산하여 예상보다 더 많은 로그온 실패 이벤트가 있는지 확인합니다.
이제 지난 24시간 동안 보안 이벤트 로그에서 이벤트 ID 4625가 발견된 횟수를 나타내는 숫자 값을 볼 수 있어야 합니다.
3. 브루트 포스 공격이 발생했다고 판단했으므로 이제 이 Windows 보안 이벤트에 대한 자세한 정보를 추적하세요. 그러려면 관심 있는 각 이벤트의 속성만 반환하십시오.
이전에 언급한 대로, 특정 이벤트에 대한 각 값은 특정 인덱스와 함께 배열에 저장됩니다. 이 데모에서 흥미로운 이벤트 속성은 아래와 같습니다.
- TargetUserName 인덱스:
[5]
- LogonType 인덱스:
[10]
- WorkstationName 인덱스:
[13]
- IpAddress 인덱스:
[19]
다음 코드 샘플은 $events 변수에서 각 객체를 읽고, 흥미로운 속성만 모아서 하나의 줄로 연결합니다.
다음 스크린샷은 코드의 예상 출력의 일부를 요약하여 보여줍니다. 쉼표로 구분된 TargetUserName, LogonType, WorkstationName 및 IpAddress 목록입니다.

XML 템플릿에서 보았듯이 이벤트 ID 4625의 템플릿에는 LogonType
속성이 있습니다. 이 속성은 계정이 인증을 시도한 방법을 나타냅니다. 추가 조사를 통해 때로는 LogonType
이 다른 것을 알게 되었습니다.

LogonType
attributeLogonType
값은 2에서 11까지의 숫자 값입니다. 그러나 이것이 무엇을 의미하는지 궁금하신 것 같아 조사를 진행하였습니다.
2 – 대화형 – 사용자가 이 컴퓨터에 로그인했습니다.
3 – 네트워크 – 사용자 또는 컴퓨터가 네트워크를 통해 이 컴퓨터에 로그인했습니다.
4 – 일괄 – 일괄 로그인 유형은 일괄 서버에서 사용되며 사용자의 직접적인 개입 없이 프로세스가 실행될 수 있습니다.
5 – 서비스 – 서비스가 서비스 제어 관리자에 의해 시작되었습니다.
7 – 잠금 해제 – 이 워크스테이션이 잠금 해제되었습니다.
8 – 네트워크 평문 – 사용자가 네트워크를 통해 이 컴퓨터에 로그인했습니다. 사용자의 암호는 해시되지 않은 형식으로 인증 패키지에 전달되었습니다. 내장 인증 패키지는 모두 자격 증명을 네트워크를 통해 평문(또는 클리어텍스트라고도 함)으로 보내기 전에 자격 증명을 해시합니다.
9 – 새 자격 증명 – 호출자가 현재 토큰을 복제하고 외부 연결에 대한 새 자격 증명을 지정했습니다. 새 로그온 세션은 동일한 로컬 식별자를 사용하지만 다른 네트워크 연결에 대한 다른 자격 증명을 사용합니다.
10 – 원격 대화형 – 호출자가 현재 토큰을 복제하고 외부 연결에 대한 새 자격 증명을 지정했습니다. 새 로그온 세션은 동일한 로컬 식별자를 사용하지만 다른 네트워크 연결에 대한 다른 자격 증명을 사용합니다.
11 – 캐시 대화형 – 사용자가 이 컴퓨터에 네트워크 자격 증명으로 로그인했습니다. 도메인 컨트롤러는 자격 증명을 확인하기 위해 연락되지 않았습니다.
이제 각 LogonType
에 대한 좋은 이해가 있으므로 출력에서 숫자 값 대신 설명적인 문자열을 보고 싶습니다. PowerShell에서 “맵”을 만들려면 해시 테이블을 사용하십시오.
5. 원하는 속성만 반환하는 스크립트를 만들려면 Get-WinEvent
및 LogonType
해시 테이블을 ForEach-Object
와 결합하십시오. 아래와 같이 사용자 친화적인 LogonType
값과 함께. Format-Table
cmdlet은 PowerShell의 응답을 테이블 형식으로 서식 지정하여 사용자 친화적인 출력을 추가합니다.
이 시점에서 PSCustomObject 유형 객체를 반환하는 스크립트가 있으므로 여러 가지 다른 유형의 분석을 수행할 수 있습니다! 이 튜토리얼의 분석을 완료하려면 TargetUserName
을 기준으로 인증 실패 시도를 우선합니다. 위의 코드를 Group-Object
cmdlet와 결합하여 TargetUserName
속성을 기준으로 실패를 우선 순위로 지정하십시오. Sort-Object
및 해당 Descending
스위치를 사용하여 가장 위반된 사용자를 식별하십시오.
잘 하셨습니다! 이 게시물에서 이전에 시뮬레이션한 브루트 포스 시도를 탐지하기 위해 PowerShell을 사용했습니다. 출력에 따르면, AtaBlogUser이(가) 지난 24시간 동안 30번 인증에 실패했습니다!

다음 단계
이 튜토리얼에서는 Windows가 이벤트를 기록하는 방법, 특정 이벤트 유형에 대한 이벤트 기록을 활성화하는 방법, 그리고 이러한 이벤트를 쿼리하기 위한 PowerShell 도구를 작성하는 방법을 배웠습니다.
이제 갖고 있는 PowerShell 스크립트로 어떻게 더 좋게 만들 수 있을까요? 오늘 배운 코드를 어떻게 활용하여 더 나은 도구를 만들 것인가요?
Source:
https://adamtheautomator.com/windows-security-events/