WeSeong Log in
← Back to posts
Disk & File

ZIP 구조체, DISK

ZIP 구조체, DISK

Ⅰ. 개요

ZIP 파일 구조체에 대해 알아본다. Header가 어떻게 구성되어 있고 각 Header에 해당하는 정보들이 어떻게 분류되어 있는지 살펴본다. DISK는 기억 장치로서 주 기억 장치와 보조 기억 장치로 나뉠 수 있다. DISK의 작동 원리와 구조(MBR, VBR)를 간단히 살펴보고, 실제 컴퓨터에서는 어떻게 동작하는지 원리를 이해한다. 그리고 HDD와 SDD의 차이, 속도와 관련된 파일 읽기, 쓰기, 삭제, 복사의 차이 등을 알아본다. 실습으로 MBR, VBR을 HxD를 통해 분석(이 실습은 다음 게시글에..)하기 위해 FTK Imager를 통해 Image dump 작업을 할 예정이다.



Ⅱ. ZIP 구조체

ZIP File Structure Analysis

ZIP파일 구조에 대해 참고한 블로그를 소개한다. 자세히 설명되어 있으니 들어가보길 권장한다.


ZIP 파일 구조는 간단하게 이렇게 되어 있다. 크게 Local File Header, Central Directory File Header가 압축된 개별 파일 마다 존재하고 마지막에 End of Central Directory Record Header로 끝난다. 이제부터 각각의 Header의 구성요소를 살펴본다.


  1. Local File Header


Local File Header는 이렇게 구성되어 있으며, 각각의 자세한 부분은 위 블로그를 참고 바라며, 주황색으로 된 Signature나 Version, Flags 등은 정적으로 바이트가 고정되어 있다. 그러나 초록색으로 된 File Name, Extra Field, Data부분은 가변적으로 그럴 수 밖에 없는 게 간단히 예를 들어, 메모장의 경우 제목을 얼마나 작성할지, 내용을 얼마나 작성할지는 전부 다르기 때문이다.


  1. Central Directory File Header


Central Directory File Header는 이렇게 구성되어 있는데, Local File Header에서 더 확장된 데이터 정보를 표시해준다. 압축 크기, 파일 설명, 버전, 수정일 등 더 자세한 정보가 들어 있다.


  1. End of Central Directory Header


위의 Local File Header나 Central Directory File Header는 압축된 파일의 개수만큼 여러 개일 수 있지만, 이 End of Central Directory Header는 이름에서부터 알 수 있듯, 압축된 ZIP파일 전체적인 정보를 가지고 있기 때문에, 마지막에 하나의 Header만 있다. 그래서 가장 마지막 0xB0, 0xC0 부분을 보면 전체 Central Directory의 개수나 크기, ZIP 파일 설명 등의 정보가 담겨 있다.


※ 실제 실습으로 ZIP 파일을 Python에서 Binary로 불러와 각 Header와 Header의 속성을 추출하는 자동화 코딩을 진행했는데, 대단한 코드라서가 아니라 실제 해보는 게 구조를 익히는 데 좋다고 생각해서 올리지 않는다. 실제로 추출한 16진수 값들을 가지고 수정일을 바꾸거나, 제목을 바꾸거나, 내용을 바꾸는 등의 작업을 할 수 있다. 단, 재미로 할 수 있는 조작이다.


※ 참고로 이 압축 파일 구조체는 거의 웬만한 파일 형식에서 다 사용된다고 봐도 되는데, 한글 파일의 hwpx, 엑셀의 xlsx 확장자를 본 적이 있을 것이다. 이게 압축 파일 형식이다.



Ⅲ. DISK

디스크(Disk)의 종류는 주기억 장치보조기억 장치가 있다. 예전에 데이터는 순차적이어서 중간의 데이터를 찾으려면 다시 돌아가는게 정말 어려웠다. 거기다 비영구적인 특징도 있었는데, 현대의 디스크는 'Random Access Method of Accounting Control' 기법을 통해 이를 개선했다. 주기억 장치는 일반적으로 RAM(Random Access Memory)로 불리며, 휘발성 데이터를 저장한다. 이 RAM에 대해서는 지난 게시글에서 조금 더 자세히 설명했다. 단, 플래쉬 메모리(USB와 같은)는 RAM이 휘발성이 아니다. 속도가 빠른 게 장점으로 컴퓨터의 성능에 큰 영향을 미치는 요소 중 하나다. 보조기억 장치는 우리가 항상 컴퓨터를 새롭게 키더라도 설치한 프로그램, 작성한 문서 등이 다 남아있을 수 있게 만들어 주는 반영구적 저장 장치이다. 주기억 장치(RAM)과 다르게 비휘발성 데이터를 저장하지만, 속도가 느리고 일반적으로 Disk라고 부르는 게 보조기억 장치이다.


Disc라는 것도 있는데 이는 Disk와는 다르다. 오디오 CD, CD-ROM(Read Only Memory), DVD-ROM(Read Only Memory), DVD-RAM 등 광학 미디어를 가리킨다. 일부는 읽기 전용으로 컴퓨터와 언제든 분리될 수 있고 콘텐츠(음악, 영상 등)를 저장하거나 여러 번 저장 가능한 Disc도 있다. CD를 생각하면 이해가 용이할 것이다. VMware에서 네트워크를 다룰 때 랜카드에 대한 인터페이스가 필요했듯 디스크에서도 인터페이스가 필요하다. IDE(Integrated Drive Electronics) 또는 ATA(Advanced Technology Attachment)인데, 병렬이라는 의미에서 PATA(Parallel Advanced Technology Attachment)라고 부른다.


PATA 방식


SATA 방식

PATA는 예전에 많이 사용하던 방식으로 요즘엔 기존 IDE 속도를 개선한 SATA(Serial Advanced Technology Attachment)를 사용한다. SATA1의 경우 초당 150mb, SATA2의 경우 초당 300mb의 속도가 나오며 SATA2 이후에는 USB처럼 허브를 이용해 하나의 포트에 여러 하드 디스크를 연결할 수 있게 됐다. USB를 PC를 킨 상태로 이용하듯 끄지 않고 장치를 연결하는 핫플러그 기능도 추가됐다.


SCSI(Small Computer System Interface): 은행권에서 사용하는 디스크 인터페이스도 있다. 초당 320mb로 일반적인 하드 디스크보다 상당히 빠르다. 서버 또는 워크스테이션(Workstation - 미니 컴퓨터의 성능과 비슷한 고성능 컴퓨터 일반 PC보다 고속 연산이 가능하고 처리 속도가 빠름)용으로 사용되고 별도로 확장 카드가 필요하다. 이후 SAS(Serial Attached SCSI - 서버 등의 대형 컴퓨터 용)로 발전되어 대체되어가고 있다.


DISK가 부팅되어 과는 과정을 살펴보면, 일반적으로 이렇다고 볼 수 있다.


컴퓨터에 전원을 넣었을 때 '삐~' 같은 소리를 들은 적이 있을 것이다. 이는 POST(Power on Self Test)가 하드웨어 장치들을 읽어오며 전원 공급이 제대로 되고 있는지 체크하는 과정이다. 전반적인 하드웨어 점검이 끝나면 우리가 많이 본 BIOS 화면을 보게 된다. 포맷을 해보신 분이라면 여기서 설정을 변경해 본 적 있을 텐데, BIOS는 하드웨어 설정을 다룰 수 있고 약간의 저장 공간(ROM)이 있다. 포맷할 때, 부팅 디스크를 선택하거나 오버클럭을 할 수 있다.


다음으로 MBR(Master Boot Record)가 실행되는데 굉장히 중요하다. 훼손되면 부팅이 안되며, BIOS가 부팅 가능한 장치를 읽어 들일 때, MBR의 부트 섹터를 읽어 들이기 때문이다. 총 512Byte로 디스크를 덤프 떠 본다면 가장 먼저 0번 섹터에 자리 잡고 있는 모습을 볼 수 있다. 주 파티션, 보조 파티션으로 총 4개의 파티션 정보를 가질 수 있고 파티션 하나당 446Byte부터 마지막 2Byte를 뺀 510Byte까지 각각 16Byte에 파티션의 정보가 담겨 있다.



Partition Table 상세 구분

※ 여기서 섹터(Sector)는 디스크 구조를 찾아보면 좋다. 디스크는 여러 섹터로 나뉘어 데이터를 보관하고 관리하는데, 마지막 4Byte의 정보는 전체 디스크의 섹터가 아닌 개별 파티션의 총 섹터수를 의미한다. 그리고 여러 섹터의 집합이 클러스터(Cluster)이다. 클러스터는 크면 클수록 속도가 빠르다. 섹터 단위로 한 번에 불러 읽는 것보다 클러스터 단위로 한 번에 불러 읽는 게 당연히 더 빠르기 때문이다. 그러나 클러스터가 크면 클수록 사용하지 않는 빈 공간은 낭비가 심하게 된다.


이렇게 글로만 하면 이해가 어려울 수 있어 위 사진을 보면 이해가 용이할 것이다. MBR은 446Byte까지 Boot Code를 가지고 그 다음 Partition Table이 446Byte부터 510Byte까지 총 4개 있다. 마지막은 2Byte는 Signature이다. MBR에 기록되는 파티션(Partition)은 주 파티션으로 부팅이 가능한 목록인데, 하나의 디스크에는 파티션이 하나일 수도, 여러 개일 수도 있다. 디스크를 처음 장착하게 되면 파티션 작업을 하게 될텐데, 포맷할 때 이 부분도 볼 수 있을 것이다. C드라이브와 D드라이브를 나눠서 D드라이브는 백업용으로 많이 쓰신 적 있을텐데, 그게 파티션을 나눈 것이다. 물론, 두 드라이브 모두 개별의 디스크일 수도 있다.


※ MBR은 부팅 코드가 오염되면 부팅이 되지 않고 백업이 없기 때문에 복원이 굉장히 어렵다.


예전에 HDD(Hard Disk Drive)를 많이 썼지만, 요즘엔 SSD(Solid State Drive)를 쓸 것이다. HDD는 위에 설명한 MBR 방식이 이용되는데 SSD는 GPT(GUID Partition Table) 방식이 사용된다. GPT 방식의 경우 MBR과 가장 큰 차이는 4개의 파티션만 가능했던 거에 비해 개수 제한이 없고 용량 제한이 2TB로 되어 있던 MBR 방식에 비해 제한이 없다. 즉, GPT는 파티션 관리에 있어 더 높은 편의성과 장점을 보인다.


논리 디스크물리 디스크 개념이 있는데, 논리 디스크는 파티션 디스크를 의미하고 물리 디스크는 실제 HDD나 SDD 하드웨어 디스크를 의미한다.


MBR, GPT가 파티션에 관한 작업이 끝나면 파일 시스템에 대한 작업이 이루어지는데, 위 사진처럼 VBR(Volume Boot Record)Master File Table을 통해 파일을 읽고 쓴다. 어떤 파티션에 데이터가 어디에 저장되는지 관리하며 실제 데이터는 위 사진에서 보이는 것처럼 Data Area에 저장되어 있고 Master File Table과 매핑되어 관리된다. 백업이 있기 때문에, 복원도 용이하긴 하지만, 부팅이 안되면 어려울 수 있다. 이 VBR은 윈도우를 쓰다 보면 포맷 방식을 정하라고 할 때 볼 수 있을텐데, FAT, NTFS 등이 바로 이 파일 시스템이다. FAT는 하나의 파일의 최대 용량이 4기가를 넘을 수 없었고 32bit로 길이 제한도 있었지만, NTFS는 이런 FAT의 단점을 보완해서 4기가 제한도 없애고 전반적으로 개선되어 가장 많이 쓰일 것이다.


※ 물론, FAT도 개선된 버전으로 FAT32가 있다. 추가적으로 FAT32에서는 VBR 다음에 예약된 영역(부트 섹터, 파일 시스템 기본 정보 등 저장)이 있고 FAT1과 FAT2(Mirror 관계 - 동일한 구조)에 파일 할당된 걸 기록하고 있다. 그 다음에 MFT(파일 정보 저장되어 있는 테이블)이 나온다.


NTFS(Next Technology File System)FAT(File Allocation Table)은 Master File Table이 파일을 읽고 쓰고 저장하고 삭제하는 역할을 담당한다. 보통 파일을 생성할 때, MBR에 접근해서 파티션에 대한 정보를 얻고 VBR(NTFS, FAT)에 접근한다. VBR에서 MFT(Master File Table)을 토대로 계산하여 Data Area에 새로운 파일을 저장할 빈 공간을 찾고 MFT에 Data Area 빈 공간에 대한 정보를 저장한 후 파일을 실제 저장한다. 파일을 복사하거나 이동할 때 속도에서 차이가 보이는데,


복사

이동

같은 파티션

느림

빠름

다른 파티션

느림

느림

※ NTFS의 경우 용량이 작은 파일이면 Data Area에 파일 내용을 저장하지 않고 MFT에 다 기록한다.


이 차이가 나타나는 이유는,



위 이미지를 보면 이해가 용이할 것이다. 같은 파티션 내의 복사의 경우 Data Area에 새롭게 파일을 복사하고 MFT에 정보(파일 이름, 날짜, 크기, 저장 위치 등)를 갱신해야 한다. 하지만 이동의 경우 MFT에 정보만 수정하면 되기 때문에 속도에 있어서 더 빠르다. 다른 파티션의 복사의 경우 같은 파티션 내 복사와 마찬가지로 MFT도 수정하고 Data Area에 파일 정보도 새로 써줘야하기 때문에 느리다. 이동도 마찬가지일 수 밖에 없다. 그러나 일반적인 삭제


이렇게 MTF의 Data Area 링크 정보만 삭제하면 되기 때문에, 굉장히 빠르다. 덮어쓰기를 하면 어떻게 될까?

덮어 쓰기는 일반적인 방법으로 복원이 안된다. 오염되기 때문인데, 기존 파일의 Data Area의 영역을 수정하면 MFT의 Header 정보들이 깨져버린다. 즉, MFT의 정보들이 덮어 쓴 데이터의 정보들로 바뀌어 버린다. 그러니 예전 파일의 정보는 남아있지 않게 되는 것이다. 여기서 HDD와 SSD의 차이가 있는데, HDD는 덮어쓰기가 가능했지만 SSD는 일반적으로 안된다. Trim 기법 때문인데, 예전엔 덮어 쓰기로 복원이 안되는 점을 이용해서 HDD의 감추고 싶은 데이터를 의도적으로 덮어씌워 복원이 어렵게 만들었다. 그러나 랜덤으로 동작하는 Trim 기법은 주기적으로 사용하지 않는 파일 데이터를 관리한다. 실제로 덮어쓰기할 때 0과 1로만 수정하면 됐지만, 그렇게 되면 기존의 데이터는 삭제된 것으로 간주한다. Trim은 삭제하게 된 순간(MFT와 데이터 상의 링크가 끊어진 순간) 링크를 찾아가서 상태 없음을 만들기 때문에, 그리고 속도도 굉장히 빠르기 때문에, 덮어 쓰는 건 어렵다.


※ 이전에 XP때는 가비지 컬렉션(Garbage Collection)이 있었지만, 윈도우 7에서는 Trim이 도입됐다.


※ 파일을 복사해올 때 생성 시간이 수정 시간 보다 느릴 때가 있다. 그건 인터넷이나 USB를 통해 가져오게 된 것인데, 즉, 파티션 간의 이동이 아닌 별도의 디스크 간의 이동이다. 인터넷에서 받은 경우에는 'Zone.Identifier'(CMD에서 dir로 조회했을 시)라고 나온다. 추가 정보로 USB는 플래그 앤 플레이로 연결된 순간 바로 인식되며 드라이버가 설치된다.


속도와 관련된 또 다른 부분은 단편화(Fragmetation)개념이다.


위 이미지처럼 예전 HDD는 파일 데이터를 분할해서 저장했다. 그래서 파일을 불러오려면 링크(프로그래밍 언어를 배웠다면 Linked List 를 떠올리면 이해가 쉽다.)를 타고 타고 파일의 데이터를 하나씩 불러 읽어들여야 했다. 하나의 파일이 분산되어 있는 것보다 한 번에 읽는 것이 당연히 속도가 빠르기 때문에, 예전에 디스크 조각 모음을 많이 해줬을 것이다. 하지만 요즘엔 그럴 필요가 없는 게 단편화되어 저장되는 것이 아닌 파일 하나를 연속적으로 저장하기 때문에 속도면에서 빠르다. 또 하나의 속도 관련 개념으로 DISK는 Nand 형태와 NOR 형태가 있다. Nand는 반도체의 셀이 직렬로 되어 있어 순차적으로 데이터를 읽기 때문에, NOR에 비해 느리다. 하지만 별도로 셀의 주소를 기억할 필요 없이 용량을 늘리기 쉽고 쓰기가 빠르다. 이 Nand 형태로 된 디스크가 USB나 SSD가 있다. NOR은 셀이 병렬로 되어 있어 랜덤 엑세스를 통해 읽기가 빠르지만, 하나의 셀씩 기록하기 때문에 쓰기는 느리다. 읽기가 빨라 고가이고 휴대폰같은 모바일 장치에 더 많이 사용된다. 모바일 장치의 경우 대용량 데이터를 쓰는 것보다 읽는 경우가 더 많기 때문이다.


※ 자동차의 엔진 RPM 개념처럼 디스크도 RPM(물리적 회전 수)이 빠를 수록 속도가 빠른데, 일반적인 하드 디스크는 7,200RPM이고 모바일 용이나 노트북 용은 조금 더 느려진다.



Ⅳ. DISK 관련 실습

먼저 할 실습은 디스크를 덤프 뜨는 작업이다. 덤프는 간단히 말해 위에서 얘기한 디스크 구조를 모두 Image 형태로 만들어서 Imager 프로그램을 통해 읽을 수 있게 만드는 것이다. 법적으로 원본이 훼손되면 증거로 채택될 수 없지만, 실제로 포렌식을 진행하게 되면 원본을 사용할 수 없다. 그래서 포렌식 학회에서 배포하는 FTK Imager 프로그램만이 허용되고 있기 때문에, 이 프로그램을 이용해 디스크 덤프를 뜰 예정이다.

프로그램과 관련된 부분은

FTK® Imager - Exterro

이 웹페이지를 참고 바란다.


FTK Imager를 실행하면,


이런 화면이 나올 것이다. 여기서 USB가 연결되었다고 가정하고 USB를 덤프 뜰 예정이다.


Create Disk Image를 눌러주면


이렇게 어떤 드라이브를 사용할 것인지 물어보는데 Logical Drive는 파티션을 의미하고 Image File은 기존의 디스크 덤프 이미지를 의미하기 때문에 생략하고 Physical Drive를 선택해서 USB를 골라주겠다.


이렇게 실제 덤프 뜰 디스크 장치를 선택하고 Finish를 누르면


여기서 Add를 통해 이미지 타입을 정해준다. 가장 많이 사용하는 방식이 Encase인 E01방식이다. 이 부분은 조금 더 찾아봐야 된다.


하고 계속 넘겨주면


저장할 위치와 파일명을 작성하게 된다. 여기서 Image Fragment Size는 이미지 파일을 분할하여 저장할 경우 어느 정도 크기로 분할할지를 나타내며 Compression은 압축 정도이다. 9에 가까워지면 압축을 더 많이 해 용량이 작아지겠지만 이미지 파일 만드는 속도가 느릴 수 있다.


그리고 Start를 누르면 이제 이미지 파일 생성이 시작될 것이다.



후기

DISK를 배울 때 정말 벽에 부딪친 느낌이었습니다.. 그래도 이렇게 여러 번의 실습과 복습을 위해 게시글을 작성하다 보니 점점 머리 속에 구조가 들어오는 느낌입니다. 다음 게시글에 DISK 관련 실습을 조금 더 복습해보면서 써볼 예정입니다!!