Windows 컴퓨터 없이 .evtx 파일 읽기
이벤트 로그는 이동합니다. 압수된 노트북에서, 디스크 이미지 안에서, 이미 서버가 재구축된 고객이 내보낸 것으로. 도착하는 것은 .evtx 파일이고, 그것을 여는 도구인 이벤트 뷰어는 Windows에만 존재하며, 화면에 보이는 것의 절반을 로그를 쓴 컴퓨터의 DLL에서 렌더링합니다. 이 가이드는 .evtx에 실제로 무엇이 들어 있는지, 브라우저 로컬 EVTX 뷰어로 어디서든 분류하는 방법, 그리고 첫 질문 대부분의 답이 되는 네 가지 이벤트 ID를 다룹니다.
마지막 업데이트:
로그는 앉아 있는 컴퓨터에 결코 있지 않다
패턴은 언제나 같습니다. 무슨 일이 일어났습니다 — 의심되는 침해, 잠금 폭증, 03:00에 죽은 서비스 — 그리고 증거는 누군가가 내보내거나, 이미지를 뜨거나, 부팅할 수도, 로그온할 수도, 만질 권한도 없는 컴퓨터에서 복사한 Windows 이벤트 로그입니다. 내 컴퓨터는 Mac이거나 Linux 워크스테이션이거나, Windows VM이라곤 찾아볼 수 없는 잠긴 회사 노트북입니다. 이벤트 뷰어는 도와주러 오지 않습니다.
다행히도 .evtx 파일은 문서화된, 자기 완결적인 바이너리 형식입니다. 이벤트 뷰어가 레코드에 대해 보여주는 것은 모두 — 아래에서 다룰 중요한 예외 하나를 빼고 — 파일 안에 있으며, 제대로 된 파서라면 어디서든 읽을 수 있습니다. 이 사이트의 EVTX 뷰어는 그 파서(Rust evtx 크레이트를 WebAssembly로 컴파일한 것)를 브라우저 탭 안에서 실행합니다. 이벤트 로그에는 사용자와 컴퓨터, IP 주소가 기록되어 있어, 패킷 캡처와 마찬가지로 무작위 변환 사이트에 업로드되어서는 안 되기 때문입니다. 이어지는 내용은 도구의 사용법이 아니라 작업 방법입니다. 무엇을, 어떤 순서로 볼 것인지, 그리고 필드가 알려줄 것과 알려주지 못할 것.
.evtx 파일 안에 실제로 들어 있는 것
.evtx 파일은 4096바이트 헤더 뒤에 64 KB 청크가 이어진 것입니다. 각 청크에는 일련의 이벤트 레코드가 들어 있고, 각 레코드는 바이너리 XML(BinXML)로 저장됩니다. 운영 체제가 채우는 System 블록과, EventData 또는 UserData 형태의 제공자 고유 페이로드입니다. 레코드를 하나 열면 문장이 아니라 필드가 보입니다 — EventID 4625, 타임스탬프, 채널, 그리고 IpAddress, TargetUserName, LogonType 같은 이름 있는 값들. 그 필드들이 증거입니다. 그리고 그것은 다른 컴퓨터의 파서가 정직하게 건넬 수 있는 전부이기도 합니다.
여기에 예외가 하나 있고, 그것이 이 가이드의 나머지 전부를 규정합니다. 이벤트 뷰어가 표시하는 문장 — "계정이 로그온하지 못했습니다" — 은 파일에 없습니다. Windows는 그것을 로그를 쓴 컴퓨터에 있는, 각 제공자에 속한 메시지 DLL에서 볼 때 렌더링합니다. 데이터 값이 가끔 %%14592처럼 보이는 이유가 바로 그것입니다. 그것들은 파일이 싣고 오지 않는 메시지 테이블에 대한 참조입니다. 다른 컴퓨터의 뷰어는 이벤트가 기록한 모든 필드와, 저장된 그대로의 원시 XML을 보여줄 수 있습니다 — 하지만 남의 .evtx에 대해 다듬어진 메시지 텍스트를 제시하는 도구는 자기 DLL 사본에서 재구성하거나 추측하는 것입니다. 필드가 먼저, 문장은 마지막, 그것이 정직한 순서입니다.
수치를 인용하기 전에 알아둘 구조적 사실이 하나 더 있습니다. 파일의 청크들은 서로 독립적입니다. 디스크 이미지에서 카빙된 로그나 죽어가는 드라이브에서 복사한 로그는 종종 더 이상 파싱되지 않는 개별 청크를 포함합니다. 좋은 리더는 손상된 청크를 각각 바이트 오프셋과 함께 보고하고 그 주변의 모든 것을 읽습니다. 이 점에 대한 침묵 — 더 짧아진 로그를 아무 말 없이 돌려주는 도구 — 이야말로 레코드가 조사에서 조용히 사라지는 방식입니다.
System 블록에서 시작하기
모든 레코드의 System 블록은 같은 골격을 지닙니다. Provider(어떤 구성 요소가 썼는지), EventID(그 제공자의 번호 체계에서 무슨 일이 일어났는지), Level(1 심각부터 5 자세한 정보까지, 수준이 없는 이벤트는 0), Channel(Security, System, Application, 그리고 Microsoft-Windows-* 아래의 수백 개 운영 로그), Computer, UTC 타임스탬프, 그리고 EventRecordID. 분류는 로그 전체를 그 골격으로 분류하는 것에서 시작합니다. 레코드가 몇 개인지, 어떤 시간 범위에 걸치는지, 어떤 채널에서 왔는지, 어떤 이벤트 ID가 지배적인지. Security 로그의 80%가 하나의 이벤트 ID라면 대개 그 하나의 이야기입니다 — 결정을 내리는 방화벽, 반복해서 인증하는 서비스 — 그리고 요약은 레코드를 하나 읽기 전에 그것을 알려줍니다.
레코드를 참조할 때는 System 블록의 EventRecordID를 인용하세요. 카빙되거나, 선택되거나, 다시 내보내진 파일은 레코드 헤더가 그것을 만든 도구에 의해 다시 번호가 매겨질 수 있지만, System 블록은 컴퓨터가 원래 할당한 ID를 유지합니다 — "이 발췌의 레코드 7"과 "원본 로그의 EventRecordID 319457858"의 차이는 누군가가 여러분의 발견을 재현하려 할 때 중요해집니다. 타임스탬프도 같은 주의를 기울일 가치가 있습니다. 파일 안에서는 언제나 UTC입니다. 이벤트 뷰어는 그것을 로그를 여는 컴퓨터의 현지 시간으로 변환하기 때문에, 같은 레코드의 스크린샷 두 장이 몇 시간씩 어긋날 수 있습니다. 보고서에서는 UTC를 선택하고 그 사실을 명시하세요.
값을 하는 네 가지 이벤트 ID
1102 — 감사 로그가 지워졌다. Security 로그는 스스로 지워진 일을 새 로그의 첫 이벤트로 기록합니다. 그 필드는 지운 사용자를 밝힙니다. 사고에서 1102는 증거이자 경계입니다. 그 로그에서 그 이전의 모든 것은 여러분이 가진 파일에서 사라졌고, 지워졌다는 사실 자체가 보고서에 한 줄 쓸 가치가 있습니다. 로그의 가장 오래된 레코드가 관심 기간 안의 타임스탬프를 가진 1102라면, 누군가가 그 이전 이벤트의 부재 위에 이론을 세우기 전에 그 사실을 밝히세요.
4624와 4625 — 성공과 실패의 로그온. 이것들은 계정 조사의 주력입니다. 중요한 필드는 TargetUserName, IpAddress, 그리고 무엇보다 LogonType입니다. 3은 네트워크 로그온, 10은 원격 데스크톱, 2는 대화형 콘솔 로그온, 7은 잠금 해제입니다. 무차별 대입 패턴은 한 주소에서 한 계정을 향한 4625의 집중으로 읽히고, 그 뒤에 — 중요한 순간은 바로 그 지점입니다 — 4624가 따릅니다. 4625 하나는 오타입니다. 신호는 시퀀스의 모양이며, 그래서 스크롤하지 않고 필터링하고 셉니다.
4688 — 프로세스가 생성되었다. 감사 정책이 기록할 때, 각 4688은 새 프로세스(NewProcessName), 그것을 실행한 계정, 그리고 종종 부모 프로세스를 밝힙니다 — "이 컴퓨터에서 무엇이, 언제 실행되었는가"의 원료입니다. 정직함을 지키는 주의 사항 두 가지: 4688은 원본 컴퓨터에서 "프로세스 만들기 감사"가 활성화되었을 때만 존재하며(그 부재는 무엇이 실행되었는지에 대해 아무것도 증명하지 않습니다), 명령줄 캡처는 또 별개의 설정입니다. 풍부한 4688 흔적은 당연한 권리가 아니라 선물로 대하세요.
이 네 가지는 시작 집합이지 교육 과정이 아닙니다 — 4624의 특수 로그온 형제인 4672, 명시적 자격 증명 로그온 4648, System 로그의 서비스 설치 7045가 통상적인 다음 목적지입니다. 하지만 첫날 질문의 놀라운 몫 — 로그가 지워졌는가, 누가 들어왔는가, 어디서 들어왔는가, 무엇을 실행했는가 — 은 1102, 4624, 4625, 4688만으로 답이 나옵니다.
필드가 알려줄 수 없는 것
부재에 대한 규율이 로그 작업의 대부분입니다. 파일은 원본 컴퓨터가 기록한 적 없는 이벤트를 보여줄 수 없습니다. 무엇이 존재하는지는 감사 정책이 결정하며, 기본 구성 컴퓨터는 조사자가 바라는 것보다 훨씬 적게 기록합니다. 위에서 다룬 대로 메시지 텍스트도 보여줄 수 없습니다 — %% 참조는 여러분이 갖고 있지 않은 컴퓨터의 문자열을 가리키는 포인터입니다. 그 자체로 변조나 그 부재를 증명할 수도 없습니다. 레코드 ID의 공백은 지워진 로그뿐 아니라 정직하게 카빙된 파일에도 나타나며, 그래서 기대야 할 신호는 공백이 아니라 명시적인 1102 레코드입니다.
그리고 로그는 하나의 증인입니다. 타임스탬프는 원본 컴퓨터의 시계에서 오며, 그 시계는 틀렸을 수 있습니다. 계정은 컴퓨터가 알던 이름으로 나타납니다. 네트워크 로그온의 IP는 NAT와 VPN을 포함해 컴퓨터가 본 주소입니다. 필드는 컴퓨터가 기록한 그대로입니다 — 그 이하도 아니고, 규율이란 그 이상이 아님을 기억하는 것입니다.
5분 분류 절차
첫째 분: EVTX 뷰어에서 파일을 열고 어떤 레코드보다 먼저 요약을 읽습니다 — 전체 개수, 시간 범위, 채널, 상위 이벤트 ID. 뷰어가 읽을 수 없다고 보고하는 청크가 있으면 오프셋과 함께 기록합니다. 그 주의 사항은 나중의 각주가 아니라 처음부터 여러분의 노트에 속합니다.
둘째 분: 1102를 확인합니다. 로그가 지워졌다면 접근 방식 전체가 바뀌고, 지운 시각과 계정이 첫 번째 확실한 사실이 됩니다. 셋째 분: 4625를 필터링하고 모양을 봅니다 — 계정별, 출발지 주소별 개수. 집중 뒤에 같은 계정에 대해 같은 주소에서 온 4624가 있으면 그것이 발견입니다. 정확한 타임스탬프를 기록하세요. 넷째 분: 의심스러운 시간대가 고정되면 그 시간대 안에서 4688을(원격 액세스가 문제라면 4624 유형 10도) 필터링하고 무엇이 실행되었고 누가 로그온했는지 나열합니다. 다섯째 분: 필터링된 레코드를 JSON이나 CSV로 내보내고 수치가 눈앞에 있는 동안 단락을 씁니다 — 레코드 ID, UTC 시각, 계정, 주소. 내보낸 파일이 작업지이고, 읽을 수 없는 청크와 메시지 텍스트의 한계에 대한 주의를 단 단락이 결과물입니다.
이 절차가 조사를 끝내는 것은 아닙니다. 낯선 바이너리 파일을 인용할 수 있는 다섯 가지 사실과 방어 가능한 다음 질문으로 바꾸어, 앞에 있는 컴퓨터가 무엇이든 쓸 수 있게 합니다 — 그리고 그것이 분류라는 것의 대부분입니다.
자주 묻는 질문
이벤트 뷰어에서 로그를 CSV나 XML로 내보냈습니다. 그 대신 그것을 읽을 수 있나요?
그런 내보내기는 다른, 더 못한 것입니다. CSV 내보내기는 각 이벤트를 이벤트 뷰어가 보여주던 열로 납작하게 만들고, 구조화된 EventData의 대부분 — 분류가 실제로 다루는 필드 — 을 버립니다. 원본에 아직 접근할 수 있다면 "다른 이름으로 모든 이벤트 저장…"으로 다시 내보내 .evtx를 선택하세요. 가진 것이 CSV뿐이라면, 그것은 더 이상 구조적인 의미의 이벤트 로그가 아니므로 스프레드시트가 어떤 .evtx 도구보다 더 많은 것을 알려줄 것입니다.
여기의 타임스탬프가 이벤트 뷰어에서 찍은 스크린샷과 다른 이유는 무엇인가요?
이벤트 뷰어가 변환하기 때문입니다. .evtx 파일 안의 타임스탬프는 UTC로 저장됩니다. 이벤트 뷰어는 그것을 로그를 여는 컴퓨터의 현지 시간으로 표시합니다. 같은 레코드가 두 도구에서 정직하게 몇 시간씩 어긋나 보일 수 있습니다. 이 사이트의 뷰어는 UTC를 유지하고 열에 그 표시를 붙이며, 보고서의 작업 규칙도 같습니다. UTC로 인용하고, 시간대를 밝히고, 하나의 타임라인에 둘을 섞지 마세요.
제 파일의 레코드 ID에 공백이 있습니다. 로그가 변조된 건가요?
공백만으로는 증명되지 않습니다. 레코드는 평범한 이유로 누락됩니다 — 고장 나는 디스크에서 손상된 청크, 할당되지 않은 공간에서 카빙된 파일, 부분 집합을 선택한 내보내기 — 그리고 카빙된 파일은 System 블록이 원본 ID를 유지한 채 헤더가 다시 번호 매겨질 수도 있습니다. 의도적인 지우기는 그 자체의 레코드를 남깁니다. 새 Security 로그의 첫 항목으로 쓰이며, 지운 계정을 밝히는 이벤트 1102입니다. 부재에서 결론을 내리기 전에 먼저 그것을 찾으세요.