About Volume Serial Number
본 포스팅에서는 윈도우 운영체제 파일시스템에서 볼 수 있는 Volume Serial Number의 중요성과 활용 방안에 대해 살펴봅니다. 글 내용 중 틀린 부분이 있거나 첨언, 문의사항이 있으면 언제든 연락 또는 댓글 바랍니다.
볼륨 시리얼 번호가 뭐야?
Volume Serial Number(이하 VSN)는 윈도우 운영체제에서 저장장치를 포맷할 때 생성되는 고유한 16진수 값이다. 볼륨은 하나의 파일시스템을 가지고, 파일시스템은 모두 고유한 VSN 값을 가지게 된다. 대부분의 파일시스템은 VBR(Volume Boot Record, 이하 VBR) 영역(512 bytes)을 가지고 있다. VSN 값은 VBR 특정 위치에 기록되는데, VSN 값이 기록되는 위치는 파일시스템 별 VBR마다 조금씩 다르다. VSN 값은 Microsoft社와 IBM社가 함께 OS/2 운영체제를 개발하던 1987년도부터 파일시스템 포맷 프로세스에 추가되었다. 그 후로 VSN 값은 볼륨을 구분하는 고유한 값으로 지금까지 사용되어 왔다. [Figure 1]은 각 파일시스템 별 VBR에 VSN 값이 기록되는 위치를 정리한 표이다.
[Figure 1]에서 FAT12/16/32, exFAT 파일시스템은 VSN 필드 크기가 모두 4 bytes 이다. 하지만, 특이하게도 NTFS만 유일하게 VSN 필드 크기가 8 bytes 인데, NTFS VBR에 기록되어 있는 VSN 필드의 값 중 실제로 사용되는 값은 4 bytes이다. 이는 먼 미래에 VSN 값을 계산 했을 때, 결과 값이 4 bytes를 초과할 것을 예상 해 VSN 필드 크기를 8 bytes로 설정해둔 것으로 예상된다.
VSN는 고유 값이지만 검증되는 값이 아니므로 사용자에 의해 수정 가능하다. 대표적으로 VSN 값을 수정할 수 있는 도구는 ‘Volume Serial Number Changer‘가 있다.
볼륨 시리얼 번호가 생성되는 원리
VSN 값은 고유 값이어야 하므로 파일시스템이 생성되는 ‘현재 날짜와 시간 값’을 이용해서 생성하는 것으로 알려져 있다. 2003년도에 VSN 값이 생성되는 알고리즘을 설명하는 문서(Written by DIGITAL DETECTIVE 社)가 공개된 적이 있지만, 문서에서 언급한 알고리즘은 현재 윈도우 운영체제에서 사용되지 않는다. 그래서 현재 윈도우 운영체제에서 정확히 어떤 알고리즘을 사용해 VSN 값을 생성하는지 알려진 바는 없다.
앞서 잠깐 언급했듯이 VSN 값은 고유하지만 검증되는 값은 아니다. 그러므로 VBR의 VSN 필드 크기에 맞도록 4 bytes 크기의 고유한 값을 생성하면 된다. 그래서 윈도우 운영체제 파일시스템 포맷 기능 외 별도의 도구들이 지원하는 파일시스템 포맷 기능은 나름대로 VSN 값을 생성하는 알고리즘을 사용한다. ‘현재 날짜와 시간 값’을 입력 값으로 사용하는 것은 대부분의 도구가 비슷하지만, 입력 값을 연산하는 과정이 조금씩 다르다. 다음은 대표적인 파일시스템 포맷 도구 ‘Rufus’의 VSN 생성 코드이다.
/*
* 28.2 CALCULATING THE VOLUME SERIAL NUMBER
*
* For example, say a disk was formatted on 26 Dec 95 at 9:55 PM and 41.94
* seconds. DOS takes the date and time just before it writes it to the
* disk.
*
* Low order word is calculated: Volume Serial Number is:
* Month & Day 12/26 0c1ah
* Sec & Hundredths 41:94 295eh 3578:1d02
* -----
* 3578h
*
* High order word is calculated:
* Hours & Minutes 21:55 1537h
* Year 1995 07cbh
* -----
* 1d02h
*/
static DWORD GetVolumeID(void)
{
SYSTEMTIME s;
DWORD d;
WORD lo,hi,tmp;
GetLocalTime(&s);
lo = s.wDay + (s.wMonth << 8);
tmp = (s.wMilliseconds/10) + (s.wSecond << 8);
lo += tmp;
hi = s.wMinute + (s.wHour << 8);
hi += s.wYear;
d = lo + (hi << 16);
return d;
}
볼륨 시리얼 번호는 어디에 저장되어 있을까?
레지스트리 (Registry)
레지스트리(Registry)는 윈도우 운영체제에서 빠져선 안될 구성요소 중 하나이다. 윈도우 운영체제와 운영체제 내에서 동작하는 프로그램이 필요로 하는 정보를 저장할 때 가장 많이 사용되는 곳이 레지스트리이다. 정보가 방대하게 저장되어 있는 만큼 분석가가 필요로 하는 정보도 많이 저장되어 있다. 알려져 있는 것처럼 레지스트리에는 저장장치 연결 기록이 저장되어 있다. 저장장치 연결 기록과 관련된 레지스트리 키(Key)는 여러가지가 있는데, 이 중 VSN 값을 가지고 있는 키는 ‘EMDMgmt’ 키이다. [Figure 2]는 EMDMgmt 키에 VSN 값이 저장되어 있는 모습이다.
– Registry Path: HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\EMDMgmt\{SUB KEY}
[Figure 2]에서 빨간색 박스로 표시 되어 있는 부분이 해당 저장장치 볼륨의 VSN 값(10진수)이다. 다만, EMDMgmt 키의 하위키는 모든 조건과 환경에서 생성되는 것은 아니다.
바로가기 & 점프목록
바로가기(Lnk) 파일과 점프목록(Jumplist) 파일은 파일 혹은 폴더를 실행했을 때 생성되는 파일이다. 바로가기 파일은 운영체제 혹은 사용자가 생성할 수 있으며, 점프목록 파일은 사용자 행위에 의해 생성된다. 바로가기 파일은 개별 파일 혹은 폴더와 매칭되지만 점프목록 파일은 응용프로그램 별로 점프목록 파일이 생성되어 응용프로그램이 열었던 파일 혹은 폴더를 기록한다. [Figure 3]은 바로가기 파일과 점프목록 파일의 대표적인 생성 경로를 표로 정리한 것이다.
점프목록 파일의 구조는 OLE(Object Linking and Embedding) Compound File 구조로, OLE 파일의 구조는 크게 스토리지(Storage)와 스트림(Stream)으로 이뤄져 있다. 이 중 스트림 부분에 실제 데이터가 저장되어 있는데, 점프목록 파일에서 스트림 데이터의 구조는 바로가기 파일 구조와 동일하다. 즉, 점프목록 파일은 응용프로그램별 바로가기 파일 모음이라고 할 수 있다.
바로가기 파일과 점프목록 파일의 구조는 동적구조이다. 바로가기 파일과 점프목록 파일의 구조는 헤더 영역을 제외하고 모든 영역이 Optional 영역이다. 여러 Optional 영역 중 VSN 값을 저장하고 있는 영역은 ‘VolumeID’ 영역이다. ‘VolumeID’ 영역은 Optional 영역인 ‘LinkInfo’ 영역에 포함되어 있다. ‘VolumeID’ 영역을 포함하고 있는 ‘LinkInfo’ 영역은 Optional 영역이지만 실제로는 임의로 생성한 바로가기 파일이나 점프목록 파일이 아닌 이상 운영체제가 생성한 바로가기 파일과 점프목록 파일은 ‘LinkInfo’ 영역을 저장하고 있다. [Figure 4]는 ‘VolumeID’ 영역의 구조를 표로 정리한 것이다.
이벤트 로그
이벤트 로그(Event Log)는 윈도우 운영체제가 동작하며 운영체제 운영과 트러블 슈팅에 필요한 데이터이다. 윈도우 운영체제마다 이벤트 로그 종류는 다양하다. 윈도우 XP 운영체제는 3가지(시스템, 보안, 어플리케이션) 유형의 이벤트 로그 밖에 없었지만, 윈도우 7 운영체제부터 100개가 넘는 이벤트 로그가 추가 됐다. 현재 윈도우 10 운영체제에서는 이벤트 로그 종류가 250여개이다. 물론 윈도우 운영체제에서 생성하는 이벤트 로그가 매번 저장되는 것은 아니다. 일부 이벤트 로그는 비활성화 되어 있고, 이를 사용자는 임의로 활성화하여 윈도우 운영체제 운영에 도움을 받을 수 있다. 또, 이벤트 로그는 사용자가 임의로 생성할 수 있다. 프로그램 또한 마찬가지이다. 프로그램 혹은 사용자가 임의로 이벤트 로그 파일과 이벤트 ID를 지정해 이벤트 로그를 생성할 수 있다. 이벤트 로그는 이벤트 유형 별 혹은 서비스 등의 기준으로 분류되어 파일(.evt, .evtx)로 저장된다. 이벤트 로그 파일은 다음 경로에 저장된다.
– %SystemRoot%\System32\winevt\Logs\*.evt(x)
VSN 값은 윈도우 운영체제가 지원하는 이벤트 로그 중 ‘Partition’ 이벤트 로그에 저장되어 있다. ‘Partition’ 이벤트 로그는 윈도우 7 운영체제부터 기본으로 제공되는 이벤트 로그이다. ‘Partition’ 이벤트 로그의 실제 파일명은 “Microsoft-Windows-Partition%4Diagnostic.evtx” 이며, 기본적으로 최대로 저장할 수 있는 이벤트 로그 크기가 16384 KB로 설정되어 있다. 필요에 따라 해당 이벤트 로그의 저장 크기를 늘려줄 필요가 있다.
‘Partition’ 이벤트 로그에는 1006(이벤트 ID) 이벤트 로그만 기록된다. 1006 이벤트 로그는 볼륨에 대한 정보가 저장되는데, 저장되는 정보 중 ‘Vbr(x)’ 항목에 VSN 값이 저장되어 있는 VBR raw 데이터가 저장된다.
VBR 데이터에는 VSN 값이 저장되어 있기 때문에 VBR 데이터를 파싱(Parsing)하면 해당 볼륨의 VSN 값을 파악할 수 있다. [Figure 5] 에는 보이지 않지만 1006 이벤트 로그의 다른 정보 중에는 저장장치 ID도 저장되어 있어, 해당 볼륨의 저장장치의 정보도 파악할 수 있다.
프리패치
프리패치(Prefetch)는 윈도우 운영체제의 메모리 관리 기능 중 하나이다. 프리패치 기능은 하드디스크에 저장되어 있는 프로그램 파일을 실행할 때 데이터 로드 시간이 오래 걸리는 것(컴퓨터 관점에서)을 보완하기 위해 개발된 기술이다. 다음은 프리패치 기능의 동작 순서이다.
- 운영체제는 새롭게 실행되는 프로그램에 대해 모니터링(최대 120초)을 진행한다.
- 모니터링 중 프로그램이 사용한 자원(데이터)은 “%SystemRoot%\Prefetch” 경로에 별도의 파일(.pf)로 저장한다.
- 다음 번 컴퓨터(운영체제) 부팅 시 하드디스크에 저장 되어 있는 프리패치 파일을 메모리에 적재(Load)한다.
- 사용자가 메모리에 로드된 프리패치 파일과 매칭되는 프로그램을 실행하면 하드디스크가 아닌, 메모리에 있는 데이터를 이용해 프로그램을 실행한다.
프리패치는 응용프로그램 프리패치와 부트 프리패치로 나뉜다. 프리패칭 중 생성되는 프리패치 파일은 윈도우 운영체제마다 조금씩 다르다. 하지만, 모든 프리패치 파일 구조는 볼륨 정보를 가지고 있고, 볼륨 정보 중에는 VSN 값도 포함되어 있다. 볼륨 정보는 ‘Volume Information’ 영역에 저장되어 있는데 자세한 구조는 다음 주소를 참고하기 바란다.
볼륨 시리얼 번호를 사용한 사례를 알아보자! (사례 분석)
정보유출사고 분석 중 [Figure 6]과 같이 VSN 값이 다른 2개의 Lnk(혹은 Jumplist) 분석 결과가 있다고 가정하자. 그리고 [Figure 6] ‘경로’ 필드에 파일이 어떤 외장저장장치에 저장되어 있는지 분석하는 것이 최종 목적이라고 하자. [Figure 6]은 외장저장장치에 존재한(했던) 파일의 열람 기록이다.
일반적으로 분석가들은 [Figure 6]과 같은 경우, VSN 값, 열람시각, 폴더 구조 등을 근거로 [Figure 6]의 파일 목록을 서로 다른 외장저장장치 파일 목록으로 결론을 내린다. 그리고 각 레코드에 맞는 외장저장장치를 다른 흔적에서 찾으려 노력한다. 그러나 결론부터 말하자면 [Figure 6] 분석 결과는 모두 동일 외장저장장치의 파일 열람 기록이다. 이와 같은 사실은 VSN 값이 존재하는 다른 흔적을 분석해 확인할 수 있다.
첫 번째로, 이벤트 로그의 ‘Partition’ 이벤트 로그를 분석하면 된다. 앞서 설명한 것처럼 ‘Partition’ 이벤트 로그의 1006 이벤트 로그를 분석하면 볼륨의 VBR과 VSN 값을 확인할 수 있다. 열람 시각을 기준으로 분석해도 되고, 1006 이벤트 로그가 많지 않다면 모든 1006 이벤트 로그를 분석한 후, [Figure 6]에서 볼 수 있는 볼륨 시리얼 넘버를 찾으면 된다.
두 번째로, 1006 이벤트 로그에 존재하는 저장장치 정보를 추가로 획득해 레지스트리에 존재하는 저장장치 정보와 비교/분석하면 저장장치의 추가 정보를 획득할 수 있다.
다음은 [Figure 6]의 각 볼륨 시리얼 넘버 별로 분석한 결과이다.
#1630-9FDD
#DA13-D1CA
결론
VSN 값은 앞서 살펴 본 것처럼 쉽게 여러 흔적에서 찾아볼 수 있고, 포렌식 관점에서 중요하게 사용되는 정보이다. 중요하기 때문에 포렌식 분석가는 VSN 값을 이용해 특정 사실을 판단하려 할 때, 조금 더 조심스럽게 판단해야 한다. VSN 값은 절대적이지 않고 고유하지만 검증되지 않기 때문이다. VSN 값은 누구나 조작할 수 있고 조작된 VSN 값은 시스템 운영에 영향을 미치지 않는다. 그러므로 포렌식 분석가는 VSN 값을 활용하기 전에 값에 대한 검증을 진행해야 한다. VSN 값을 검증하는 방법은 추후 정리해서 별도의 포스팅으로 소개할 예정이다.