[Case Study] 포렌식 특명 ‘숨어있는 데이터를 찾아라’
- NTFS를 통한 파일 위치 추적
컴퓨터를 사용하거나 분석하다 보면 가끔 파일들이 실제 어디에 있는지 궁금해진다. 하지만 파일이 존재하는 장소를 친절하게 알려주는 곳은 없었다. 책을 들여다보아도 그 광대한 분량과 많은 정보 속에서 핵심만 확인하고, 파일의 위치를 찾는 것은 매우 어려운 작업이 아닐 수 없다.
대체 내가 저장하는 파일은 어디에 있는 것일까?
특히, 파일 시스템 포렌식을 진행할 때 파일이 어디에 있었는지 증명하는 것은 매우 중요한 일이다. 만약 검증되지 않은 도구를 사용하여 잘못된 결과를 보고하게 되면 증거로 채택되지 않기 때문이다. 이러한 오류를 범하지 않기 위해, 이번호에서는 NTFS를 통해 파일의 위치를 확인하는 법과 그러한 파일을 이미지에서 복구하는 법을 알아보자.
Ⅰ. 파일은 어디 있지?
파일들은 디스크 안에 저장된다. 여러 가지 정보는 코드별로 다양하게 산재돼 있으며, 숫자와 문자가 겹쳐져 있다. 많은 정보가 들어있는 디스크에는 일종의 길이 놓여 있다. 택배 기사들이 배송표를 보고 물건을 배달하듯이, 디스크도 이와 같은 과정을 거쳐 파일을 저장한다.
택배 기사들이 이동하기 위해 확인하는 것은 지도와 주소다. 주소를 보고 어느 거리에 있는지 확인한 후에 지도를 보면서 정확한 위치를 찾는다.
디스크도 마찬가지다. 디스크 주소는 오프셋(offset)이라는 값으로 표현하기도 한다. 일반적으로 16진수를 사용하며, 사용자가 해당 정보를 쉽게 확인하기 위해 10진수로 변경하기도 한다. 헥스에디터(Hex editor)로 디스크를 열어보면, 아래와 같이 헥스 코드(Hex Code)로 가득 찬 내용을 확인할 수 있다. 헥스 코드가 담긴 구간에는 정해진 정보가 삽입되므로 그 구간에 대한 정보를 확인해가면서 파일이 어디에 있는지 확인해 보겠다.
만약 파일 크기 정보가 0x20~0x23이라면, 해당하는 오프셋으로 움직여서 적혀있는 헥스 코드를 확인하면 된다. 그리고 해당 구간에 적혀있는 값은 리틀 엔디언(Little Endian) 속성으로 거꾸로 읽어서 확인해야 한다. 예를 들어 0x20~0x23에 0x00 0x04 0x00 0x00이라고 하면, 값은 0x400이라는 의미이다. 해당 값을 10진수로 변경하면 1024라는 값이 나온다.

[그림 1] 오프셋으로 표현된 디스크 주소
Ⅱ. 이미지 만들기
디스크의 구간별 속성과 파일의 위치를 파악하기 위해서 이미지 파일을 만든다. 해당 섹션은 Write Blocker를 통해서 무결성을 유지한 채 작업이 되었다. 이미지를 만드는 순서는 아래와 같다.
<테스트 이미지 만들기 순서>
1. 가상 머신으로 OS 설치 : 윈도우 7, XP 등 (가상 머신은 VMware나 Virtual Box 등이 있다.)
2. 디렉터리 생성 : 사용자가 알기 편한 디렉터리(예 : C:\dorumugs\)
3. 디렉터리에 파일 생성 : 가능한 700바이트가 넘는 파일을 선택
4. 디스크 이미징 : 파일 포맷은 E01(Encase 이미지 확장자)로 하였다.
dorumugs라는 폴더에 FIRST.jpg라는 파일을 생성하였다. 해당 파일을 확인해보면, 아래 이미지와 같다.
이미지는 Network Write Blocker인 F-response를 사용, 무결성을 보장하였으며, FTK imager를 사용하여 E01 포맷으로 디스크를 이미지화하였다.
[그림 2] F-response

[그림 3] FTK Imager
그 외의 방법으로는 nc.exe를 사용하여, 디스크 이미징하는 것을 추천한다. 사용 방법은 아래와 같다.
분석가 PC : nc.exe -lvp 8080 > A_FIRST.RAW
대상 PC : dc3dd if=\\.\Physicaldrive0 | nc.exe 172.16.97.180(분석관_IP) 8080(분석가가_Open한_Port) -w 3
Ⅲ. 이미지 분석
1. E01 포맷 변환
E01 포맷은 일반 포맷과 다르게 데이터를 압축하므로, 분석할 때 RAW 데이터로 변환해야 한다(dc3dd로 이미징한 경우, E01 포맷을 변환할 필요는 없다).
변환 방법은 아래와 같다.
root@SIFT-Workstation:/cases/dorumugs/RAW_divided# mount_ewf.py A_FIRST.E01 /cases/dorumugs/RAW/
위 방법을 사용하여, E01 확장자를 RAW로 변경하면, /cases/dorumugs/RAW/ 폴더에 A_FIRST라는 파일이 생성된다. 해당 파일은 분할된 E01을 RAW 데이터로 만들어주며, 통합까지 해줘서 분석하는데 어려움이 없게 샘플을 제공한다.

[그림 4] RAW 데이터 현황
2. NTFS 파일 시스템
원래 디스크를 이미징할 경우, MBR이 나오고 reserved area가 나온 후에 VBR이 나오지만, 네트워크로 마운트하고 이미징 작업을 수행하였으므로, 파티션만 이미징하였다.
1) VBR
헥스에디터로 실제 이미지를 열면 VBR을 볼 수 있다. VBR에는 MFT로 접근할 수 있는 정보는 아래와 같다.
0xB~0xC까지는 섹터의 크기를 정한다. 현재 0x0200이므로 512바이트를 뜻한다.
0xD는 클러스터(Cluster)를 이루는 단위를 말한다. 현재 0x08이므로 512x8 = 4096이다.
0x30~0x37은 MFT의 실제 위치를 클러스터로 말해준다. 현재 0x0C0000이므로 십진수로 786432이며, 오프셋으로는 786432x4096 = 3221225472(0xC0000000)이다.
2) MFT
MFT 데이터 속성을 확인해보면, 3가지 크기 정보가 나온다. 3가지 크기 정보 중 속성 내용의 실제 크기의 값을 확인하면 MFT의 실제 크기를 알 수 있다.
실제 크기를 클러스터 단위인 4096바이트만큼 나눈 결과 6692라는 값을 확인하였다. 이 값은 dd명령어에서 count로 쓰인다.
명령어 : root@SIFT-Workstation:/cases/dorumugs/RAW# dd if=A_FIRST of=/cases/dorumugs/MFT_6692 bs=4096 skip=786432 count=6692

3) 저장된 데이터 찾기
MFT에서 찾고자 하는 파일의 이름을 검색한다. 이미지에서 생성한 파일은 FIRST.jpg였으므로, FIRST.jpg를 검색하여 아래 MFT Entry를 확인한다. Entry에서 $DATA 속성을 확인하여 클러스터 오프셋 정보와 몇 개의 클러스터가 사용되었는지 알 수 있다.

해당 파일이 정확한지, 덤프해보면 아래와 같다.
명령어 : root@SIFT-Workstation:/cases/dorumugs/RAW# dd if=A_FIRST of=../FIRST.jpg skip=144805 count=4 bs=4096
3. Sleuth Kit
RAW 데이터를 조사하기 위해 Ubuntu OS와 Sleuth kit을 사용하였다. Sleuth kit은 윈도우 버전도 있다. 다운로드 경로는 아래와 같다. 모두 실행 가능한 파일들이므로, Batch 파일을 만들거나, shell Script를 만들어서 사용하면 손쉽게 자동화할 수 있다.
다운로드 : http://www.sleuthkit.org/sleuthkit/download.php
RAW 데이터로 변환한 뒤, Sleuth kit에 들어 있는 도구를 사용하여 분석했다. 분석가가 Sleuth kit을 사용하여 분석할 수 있는 이미지 타입은 아래와 같다.

1) fsstat
fsstat은 RAW 데이터에서 확인할 수 있는 디스크 정보를 제공한다. 파일 시스템 정보, 시리얼 넘버, OS, MFT, 섹터 크기, 클러스터 크기 등에 대한 정보를 확인할 수 있다.
A_FIRST 이미지를 확인해 본 결과는 아래와 같다.
명령어 : root@SIFT-Workstation:/cases/dorumugs/RAW_divided# fsstat -f ntfs A_FIRST


2) blkcat
blkcat 명령어는 블록 단위로 디스크 정보를 확인할 수 있다. 아래 명령어를 사용할 경우 VBR을 확인할 수 있다. 명령어는 아래와 같다.
명령어 : root@SIFT-Workstation:/cases/dorumugs/RAW_divided# blkcat A_FIRST 0 1 –h

3) VBR 떼어내기
VBR만 떼어서 보고 싶다면, dd로 섹터 단위를 512로 설정한 후 count를 1로 주면 된다(count는 sector x count만큼 덤프한다는 의미이다. 즉 여기서는 bs가 512이고 count가 1이므로 512 x 1 = 512가 된다).
명령어 : root@SIFT-Workstation:/cases/dorumugs/RAW_divided# dd if=/cases/dorumugs/RAW/A_FIRST of=/cases/dorumugs/RAW_divided/A_FIRST_VBR bs=512 count=1
![]()
4) blkcat으로 MFT 떼어내기
First Cluster of MFT는 786432이며, Range는 0~26768이다. Range 값은 0부터 시작하므로 실제 계산될 때 26768 + 1 = 26769가 된다. Range 값은 1046(MFT entry) 값을 기준으로 하였으므로 나누기 4를 한다. 그럼 6692라는 값이 나오는데, 이것은 count의 값이 된다. 이제 blkcat으로 MFT를 떼어낸다. 명령어는 아래와 같다.
명령어 : root@SIFT-Workstation:/cases/dorumugs/RAW# blkcat A_FIRST 786432 6692 > /cases/dorumugs/VBR

5) fls
fls는 이미지에서 디렉터리 경로를 확인할 수 있도록 도와준다. 이미지를 생성할 때, 만들어 놓은 dorumugs 폴더의 메타데이터(metadata)는 12306-113-1이라는 메타데이터를 갖고 있으며, FIRST.jpg 파일은 12308-123-3이라는 메타데이터를 가진다. 명령어는 아래와 같다.
명령어 : root@SIFT-Workstation:/cases/dorumugs/RAW_divided# fls A_FIRST
명령어 : root@SIFT-Workstation:/cases/dorumugs/RAW_divided# fls A_FIRST 12306-114-1(metadata)

여기서 ffind로 해당 메타데이터를 확인하면, 실제 경로를 확인할 수 있다.
![]()
6) icat
icat의 I는 Inode라는 의미이지만, 윈도우에서는 메타데이터에 해당한다. 이미지에서 복원하고자 하는 파일의 메타데이터를 fls로 알아냈으며, 해당 정보를 바탕으로 파일을 복구한다.
명령어 : root@SIFT-Workstation:/cases/dorumugs/RAW# icat A_FIRST 12308-123-3 > /cases/dorumugs/RAW_divided/FIRST.jpg
7) istat
istat으로 FIRST.jpg의 메타데이터를 기입하면, 4클러스터가 사용중인 것으로 확인된다.
명령어 : root@SIFT-Workstation:/cases/dorumugs/RAW# istat A_FIRST 12308-123-3

4개의 클러스터 중 첫째 클러스터가 144805이므로 blkcat으로 파일을 덤프할 경우, 아래와 같다.
root@SIFT-Workstation:/cases/dorumugs/RAW# blkcat A_FIRST 144805 4 > /cases/dorumugs/RAW_divided/FIRST_blkcat.jpg

지금까지 NTFS를 통해 파일의 위치를 추적하고, 이 파일을 이미지에서 복구하는 방법을 알아보았다. 이것은 파일 시스템 포렌식에서 매우 유용하게 활용될 것이다.@
- 안철수연구소