* 본 게시판은 DMA 팀원이 기존에 풀었던 CTF 문제나, 개인이 작성해 낸 문제를 정리한 내용입니다. 문제에 대한 공유 및 관련 내용은 댓글에 문의 하시거나 필자의 E-Mail로 문의 주시면 내부 회의 후 답변 드리도록 하겠습니다. 추가적으로 포스팅의 제목과 실제 CTF 문제와는 관련이 없으며 풀이 과정을 토대로 어떤 내용인지에 대한 간략한 설명을 제목에 작성하였습니다.

- 필자 E-Mail : wotmd9408@naver.com

- 가상머신 : 미사용(본래 분석간에는 가상머신 활용 권고)

- OS : Windows 10 EnterPrise 64bit

- RAM : 32GB

- 필요 Tool : HxD 또는 WinHex

DMA 스터디가 쉰지도.. 대략 1년? 그정도가 된 듯 싶다. 개인의 사정에 의해, 그리고 여러가지 핑계로 인해 쉰지 약 1년쯤.. 그리고 지금으로 부터 한 두달전쯤일까.. 아래 두 Quest를 준 팀원이 어김없이 문제를 하나 던졌다. 그에게서 주어진 문제는 hi.docx 파일 뿐. 본인도 기억나진 않지만 CTF에서 나왔던 문제라고 했고, Flag를 가져오라는 미션이 주어졌다.

 

[그림 1. 실행화면]

 

저기요??? 시작부터 난관에 부딧치기 시작했다. 물론 지금처럼 이렇게 함부로 파일을 열어서는 안된다. 가상머신을 켜지 않은 지금은 더더욱 이래서는 안됐다. 문서를 받을 때 이미 수없이 질문하고 검증을 했으니 이번만은 넘어가도록 한다. 아무튼 정상적으로 켜지지 않았지만, 강제로 확인을 계속 눌러봤다.

 

[그림 2. 힌트로 보이는 문구]

 

" 이 문서는 오픈 포멧으로 저장되었습니다" 라는 문구가 보인다. 
오픈 포멧은 다음과 같이 정의되어있다. "오픈 포맷(open format)은 디지털 자료 저장을 위한 규격으로 보통 사유가 아닌 표준 조직이 관리하며 사용에 법적 제한이 없다."[1] 과연 오픈 포멧이라는 문구가 힌트가 될지, 아니면 함정이 될지는 문제를 풀어가면서 봐야 할 듯 하다.

한가지 중요한건, 이 문서가 100% 정상적인 Word 파일은 아닌것 같다는 점이다. 정상적인 워드 파일이라면 [그림 1]과 같은 오류코드는 나타나지 않고 [그림 2]의 문구가 열려야 정상이기 때문이다. 물론 완전히 손상된 파일은 또 아닌 것 같은데, 이는 어쨋든 복구로는 열리긴 열린다는 점이다.
일단, 문서 내에 흔히 랜섬웨어에 사용되는 매크로 같은 것들은 포함되지 않은 것으로 보여진다. 본 분석에 사용된 PC는 필자가 집에서 개인적으로 사용하는 PC인데, 기본적으로 워드파일의 매크로 설정을 사용하지 않고, 필요 시 알림 처리 하도록 되어 있기 때문이다.

[그림 3. 매크로 옵션]

 

문서 내에서 확인할 수 없다면 문서 밖에서 살펴보도록 하자. 우리가 늘 그래왔던 것처럼.. 일단 HxD를 켜서 해당 문서를 열어보도록 하자. 이미 어느정도 공부를 했던 분들이라면 이 문서의 일부분을 본순간 "아! 저 답은 어디에 있겠구나!"라는 것을 알 수 있겠지만, 이 블로그의 기본 목적은 그래도 나름 쉽게 풀어보는 것이기 때문에 조금 지루하더라도 같이 보는 친구에게 스포를 하지 말도록 하자.

 

[그림 4. hi.docx의 HxD 화면]

 

아마 과거에 모든 파일에는 File Signature라는 것이 존재한다는 것을 이야기 한 적이 있다. 시그니처라는 것은 일종의 그 존재만이 가지고 있는 유일한 것을 의미한다. 실제로 개인이 카드 결제 후 하는 서명도 Signature라고 하는데, 우리가 흔히 싸인 이라고 말하는 signature라는 것은 결국 자신만이 하는 서명이기 때문이다. 
필자가 분명히 바로 위에서 signature는 유일 한 것이라고 했다. 이 부분에서 고개를 갸우뚱 하는 독자분들도 분명히 존재할 것이다. 몇몇 게시글에서도 이야기 했지만 [그림 4]의 가장 앞 두개(0x4B50, PK)는 우리가 잘 알고 있듯이 ZIP의 시그니처이기 때문이다.

 

[그림 5. ZIP File Signature] 

 

위 사진은 자주 애용하는 File Signature 정리 사이트[2]에서 캡쳐한 부분으로, 일반적으로 파일의 값이 PK로 시작할 경우 ZIP 파일인 경우가 대부분이다. 그런데 왜 워드파일인 docx의 확장자에서 zip파일의 파일 시그니처가 확인 되는 것일까?

마이크로소프트에서 제공하는 Office 확장자들(docx, pptx, xlsx 등)은 OOXML(Office Open XML)을 기반으로 한 파일 포멧을 가지고 있는데, 기본적으로 XML 파일을 기반으로 하고 있다. 2000년 Excel 을 위해 만들어진 초기 버전이 발표되었으며, 2002년 워드를 위한 파일포멧이 추가되었고, 2003년 오피스에 통합되었다. 그리고 이 OOXML은 '압축된' XML 기반의 파일형식을 가지고 있기 때문에 HxD에서 확인될 때 ZIP파일과 같은 PK로 시작하는 signature를 가지고 있는 것이다. 자, 이제 그러면 본격적으로 분석을 위해 분석용 백업 파일을 생성하고 확장자를 zip으로 변경하도록 하자.

[그림 6. docx 파일을 zip 파일로 바꾼 후 압축 해제 직전 모습]


파일 시그니처가 zip파일과 동일하기 때문에 zip 파일로 확장자를 변경한다 하더라도 동작을 안한다거나 하는 문제가 발생하지는 않는다.(zip 파일 이외에 7zip같은 확장자로 변경을 시도하지는 말자. 두 확장자는 파일 시그니처가 다르다.)
[그림 6]에서 보이는 모습이 실제 word 파일의 구조라고 보면 된다. 위에서 설명했듯이 OOXML 파일포멧을 가지고 있는 word 파일은 압축된 XML의 형태를 가지고 있고 폴더를 들어가보면 xml 파일들이 다수 들어가 있는 것을 알 수 있다.

각각의 폴더의 내용들에 대해서는 이곳에서 다루지는 않을 것이다. 주 목적이 아닐뿐더러, 글이 너무 길어지면 보기 짜증나는 수도 있으니까 말이다. 아무튼 위에서 워드파일은 압축된 xml 파일들이라고 말했다. 이제부터 각 폴더를 들어가 특이한 내용이 있는지 한번 확인해보도록 하자.

 

[그림 7. word 폴더 내 존재하는 파일들]

 

필자의 경우는 무식하게 하나하나 열어보긴 했었지만, 이 글에서는 그 부분은 생략하도록 한다. word라는 폴더를 보면 secret.xml이라는 뭔가 우리를 부르는 듯한 파일이 하나 존재한다. 해당 파일을 열어보면 아래와 같은 내용이 존재한다.

 

[그림 8. secret.xml]

 

secret.xml을 열면 우리가 알 수 없는 문자열로 표기되어 있는 xml 파일을 볼 수 있다. 그런데 뭔지 모르겠으면서도 뭔가 어디선가 본거 같은 형태이다. =(equal) 표시가 있다면 가장 확실하겠지만 그렇게 난이도가 쉬운 문제를 CTF에서 내 줬을것 같지는 않다. 일단 가장 머리속에 가장 의심되는 base64를 먼저 이용해보자. 구글에 base64 decoding을 검색하면 가장 먼저 뜨는 사이트가 있다. 필자는 그곳을 제일 많이 이용하는 편이다.[3]

 

[그림 9. secret.xml 내용의 base64 디코딩 결과]

 

우리가 원하는 값이 저곳에 포함되어 있는 것으로 보인다. CTF란 말 Capture The Flag, 즉 Flag를 찾으면 되는 내용이고 친절하게 secret flag= 라는 내용이 있는 것으로 봐서 bcactf{0OxMl_1s_4m4z1Ng가  Flang 값인 것을 알 수 있다.
마지막으로 끝내기 전에, secret.xml이 기본적으로 워드파일내에 존재하는지 확인해 보도록 하자.
동일한 내용의 워드파일을 test.docx라는 파일로 만들고 zip 파일로 변경하였다.

[그림 10. 원본파일 확인을 위한 테스트 파일 생성]

 

이후 백업파일을 생성 후 위 과정과 동일한 과정을 거쳐 secret.xml이 존재하는지 확인해 보았다

[그림 11. 변경되지 않은 docx 파일의 word 폴더]

변조되지 않은 워드 파일에는 secret.xml이 없다!
문제를 푸는데는 여러가지 방법이 있을 수 있다. 이 방법 외에 다른 방법이 더 있을지는 모르겠으나, 공부에는 왕도가 없고 풀이에도 크게 왕도는 없다!! 문제 출제자가 원하는 답변은 있겠지만...

 

※ 출처

[1] https://ko.wikipedia.org/wiki/%EC%98%A4%ED%94%88_%ED%8F%AC%EB%A7%B7
[2] https://www.garykessler.net/library/file_sigs.html

[3] https://www.base64decode.org/

Posted by Latte_
,

* 본 게시판은 DMA 팀원이 기존에 풀었던 CTF 문제나, 개인이 작성해 낸 문제를 정리한 내용입니다. 문제에 대한 공유 및 관련 내용은 댓글에 문의해 주시거나 필자의 E-Mail로 문의 주시면 내부 회의 후 답변 드리도록 하겠습니다. 추가적으로 포스팅의 제목과 실제 CTF 문제와의 관련은 없으며 풀이 과정을 토대로 어떤 내용인지에 대한 간략한 설명을 제목에 작성하였습니다.

 - 필자 E-Mail : wotmd9408@naver.com

 - 가상머신 : 미사용(본래 분석간에는 가상머신 활용 권고)

 - OS : Windows 10 EnterPrise 64bit

 - RAM : 32GB

 - 필요 Tool : HxD 또는 WinHex


이 문제를 처음 받았을 때의 정확한 날짜는 기억이 나질 않는다. 단순히 밥을 먹던 저녁 시간때 인 것만 기억날 뿐.. 대략 19시 정도..? 지난 Quest_1에 해당하는 문제를 줬던 팀원이 다시한번 문제를 발송했다. 주어진 시간은 2시간 정도? 그리 길게 시간이 주어지지 않은 것으로 보아 문제 난이도가 그리 높지는 않아보였다. 


[그림 1. 출제 문제]

우리에게 주어진 것은 png 확장자로 된 파일 하나, 그리고 그 파일에는 [그림 1]과 같이 hackover18이라고 쓰여있었다. 사실 처음에는 저게 문제가 아니라 저 사이트를 찾아 들어가는 줄 알았는데 그게 아니라 저 파일 자체가 문제였다.(기존 문제처럼 첨부가 아니라 단순 사진으로 올라와서 햇갈렸기 때문이다.

이 글을 보는 독자라면 Quest_1도 보고 왔으리라 생각하지만, 그래도 혹시모르니까 다시 한번 이야기를 하도록 하자. 아마 이번이 마지막으로 설명하는 내용이 아닐까 싶다. 

파일은 각자를 표현하는 고유한 값이 존재한다. 이 값을 File Signature 라고 하며 그것을 볼 수 있는 사이트[1]를 공유하니 참고하기 바란다. 물론 모든 File Signature가 다 다른건 아니다. 보통 앞의 4개가 Signature로 구분되기는 하나, 파일이 너무 많고 비슷한 구조가 있어 뒤에 4자리 까지 더해 8자리로 구분하거나 중간에 값을 통해 구분하기도 하니 무조건 맹목적으로 앞의 4자리만 보는 일은 없도록 하자.(Ex MS Office)


[그림 2. PNG 확장자 File Signature]

[그림 3. hackover18.png 파일의 File Signature와 Trailer]

[그림 2]에서 보는바와 같이 png 파일의 File Singature는 89 50 4E 47 0D 0A 1A 0A 이며 Trailer 값은 49 45 4E 44 AE 42 60 82 이다.(물론 이렇게 외우는 것 보다 %PNG / IEND 로 외우는게 더 편하다) 이를 토대로 볼때, 이 파일은 확장자 변조가 되지 않은 정상적인 PNG 파일임을 알 수 있다. 

그럼 여기서 문제가 하나 생긴다. 하나의 통으로 정상적으로 된 PNG 파일이란 소린데, 그림에는 아무 힌트도 없다. 그렇다면 설마 [그림 3]에 보이는 저 알 수 없는 값들을 해석해야 한단 소리인가? 아무리 분석이 노가다라지만 저 노가다는 사실 하고 싶지는 않다. 어떤 분들은 이 포스팅의 제목에서 눈치를 챘을 수도 있을 것이고, 아니면 PNG 파일을 열어 봤을 때 눈치를 챘을 수도 잇을 것이다. 필자는 문제를 받아 PNG 파일음을 봤을 때 어느정도 감이 오기는 했다.


[그림 3]의 Trailer는 분명 정상적인 PNG 파일의 끝을 나타내 주는 문구가 맞다. 다만 그것은 어디까지나 이 파일이 하나의 PNG Structure를 가지고 있을 때의 이야기다. 이제 어느정도 감이 오는가? 결론부터 말해주자면 이 파일은 하나의 PNG 파일이 아니다.

우선 [그림 3]을 보기 위해 열었던 HxD로 돌아가 보도록 하자. 그리고 커서를 가장 앞쪽에 위치하도록 해주자. 그리고 [Ctrl + F] 눌러 찾기로 들어가서 아까 알려준 File Signature 사이트로 접근하여 PNG 파일에 해당하는 Trailer의 hex 값을 복사하도록 하자.(띄어쓰기도 동일하게 적용해야 한다.) 그리고 확인을 눌러 [그림 3]에서 봤던 가장 마지막 부분으로 가는지 확인하자.

[그림 4. Trailer값 복사하기]

[그림 5. Trailer 결과 확인]


이상하다. [그림 5]에서 보면 중간에 PNG 파일의 끝부분이 나온 뒤 다시 PNG 파일의 Signature가 시작된다. 분명 내가 보는 것은 하나의 파일인데 두개의 파일이 들어있는 것 처럼 보인다. [그림 5] 부분에서 다시 검색을 하면 그제서야 이제 마지막 부분의 Trailer가 보이게 된다. 이제 새 File Signature부터 마지막까지 선택한 뒤 복사하여 새 PNG 파일로 저장해 보도록 하자.

[그림 6. 새 PNG 파일의 결과]

Quest_1에서 봤던 것처럼 이번에도 그림에 우리가 찼던 Flag 값이 보이는 것을 알 수 있다. 해당 문제는 실제 외국에서 있었던 CTF 문제로 지난번 Quest_1에 비해서는 어찌보면 조금 더 직관적으로 쉽게 풀수 있는 문제가 아니었나 싶다. 해당 문제는 찾기가 그리 어렵지 않을 듯 하기에 한번쯤은 풀어볼 것을 추천한다.


 * 참 조

 [1] https://www.garykessler.net/library/file_sigs.html

Posted by Latte_
,

* 본 게시판은 DMA 팀원이 기존에 풀었던 CTF 문제나, 개인이 작성해 낸 문제를 정리한 내용입니다. 문제에 대한 공유 및 관련 내용은 댓글에 문의해 주시거나, 필자의 E-Mail로 문의 주시면 내부 회의 후 답변 드리도록 하겠습니다. 추가적으로 포스팅의 제목과 실제 CTF문제와의 관련은 없으며 풀이 과정을 토대로 어떤 내용인지에 대한 간략한 설명을 제목에 작성하였습니다.

 - 필자 E-Mail : wotmd9408@naver.com

 - 가상머신 : 미사용(본래 분석간에는 가상머신 활용 권고)

 - OS : WIndows 10 EnterPrise 64bit

 - RAM : 32GB

 - 필요 Tool : WireShark 혹은 기타 패킷 분석 프로그램(본 풀이는 와이어샤크로 진행 예정)


특별히 다를게 없었던 토요일이었던 것으로 기억된다. 그날도 특이사항 없이 스터디는 진행되었고, 그렇게 또 하루가 지나가는 것 처럼 보였다. 다만 평소와 달랐던 점은, 팀원 중 하나가 숙제를 내 주었다는 점..?

주기적으로 올라오지는 않을 것으로 보이는 이 게시판은 DMA 내에서 CTF 문제풀이 숙제(?)에 대한 풀이로 구성 된다. 문제 공유 등에 관련해서는 가장 상단에 기재한대로 문의를 주시면 답변 드리도록 하겠다.


이번에 풀어볼 문제는 패킷파일을 분석해 Flag 값을 찾아내는 문제이다. Flag를 찾는 문제는 CTF(Capture The Flag)에서 흔히 나오는 내용으로 취약점이나 분석을 통해 특정 Flag를 찾는 형태로 되어있다.


[그림 1. 문제 파일의 속성 정보]


해당 파일은 pcapng 확장자로 되어있는데 해당 확장자는 PCAP Next Generation의 약자로 기존의 pcap 확장자를 발전시킨 파일 형식이다. 기존 pcap 파일에 비해 인터페이스 정보, 주석, 이름 확인 정보 등 더 다양한 정보가 들어가있다.[1]


파일을 열어보면 아래와 같이 여러 통신 패킷이 나오는데 눈에 띄는 몇가지를 한번 보도록 하자.

[그림 2. 문제 파일의 패킷 정보]

해당 패킷들을 보면 여러가지 종류의 Protocol을 볼 수 있는데 눈에 확 들어오는 Protocol은 TCP, FTP, FTP-data, TLSv1.2이다. 패킷자체를 처음부터 끝까지 보더라도 Flag에 대한 단서는 보이지 않기에 다른 정보를 찾아야 할 것으로 보인다.

TCP 통신은 현재 패킷에서 크게 특이점이 없어보이고 TLSv1.2는 내용을 알 수 없게 쓰여있기 때문에 FTP 관련된 내용을 먼저 보도록 하자. 와이어샤크의 필터 기능을 이용해 ftp만을 따로 필터링을 하면 [그림 3]과 같이 FTP 관련된 패킷만 확인 할 수 있으며 패킷에 대해 마우스 우클릭 -> Follow -> TCP Stream을 클릭하면 [그림 4]처럼 패킷에 대한 문구만 따로 볼 수 있다.

[그림 3. FTP Packet Filter 결과 값]

[그림 4. FTP Filter 한 패킷에 대한 TCP Stream 값]

[그림 3]도 나쁘지 않게 정리가 되어 있지만, 아무래도 [그림 4]가 우리눈에는 조금 더 보기 편하니 [그림 4]를 보고 해당 FTP 통신이 어떤 행위를 하는지 확인해 보도록 하자. 우선 확인하고 넘어가야할 부분이 있다. 위 패킷에서 볼 수 있듯이 FTP는 암호화 통신을 하지 않는다. 따라서 FTP 통신을 하는 서버나 그 사이에서 도청(할 수 있다면)을 하는 경우 FTP 계정 정보 및 어떤 행위를 하는지 탈취가 가능하다. 그래서 많이 사용하는 것이 SFTP(Secure FTP)로 SSH 위에서 동작하기 때문에 암호화도 되어있고 보안적으로 안정되니 해당 기능을 사용하도록 하자.

명령어들을 간략히 살펴보면, 우선 해당 FTP의 USER 계정은 user / 비밀번호는 password 임을 알 수 있다.

또한 파일을 전송하는 방식을 Ascii 모드(TYPE A)로 전송하려 함을 알 수 있고 Passive 모드로 하기위한 명령어(PASV)도 확인 할 수 있다.

LIST 명령어를 통해 디렉터리를 확인하고 files 디렉터리로 이동해(CWD fiels) key.zip 파일을 클라이언트로 보내는 명령(RETR key.zip)을 내리는 것을 확인 할 수 있다.

실제로 파일을 전달하는 명령어를 확인했고, Transfer Complete 명령어를 확인했다면 정상적으로 key.zip 파일이 전달 되었음을 알 수 있다. 그럼 이제 할 일은 해당 전달된 파일의 패킷을 찾아서 실제로 파일을 획득하는 일이다.


[그림 5] 처럼 필터를 ftp에서 ftp-data로 변경해 보자. ftp-data는 FTP 사용 간 실제 데이터를 보낼 때 사용되는 Port 이다.

[그림 5. ftp-data 필터 결과]

ftp-data로 패킷을 필터링하면 [그림 5]와 같이 데이터가 전송된 것을 볼 수 있는데 우리가 봐야할 패킷은 RETR key.zip이 있는 세번째 패킷이다. 세번째 패킷에 대고 아까와 동일하게 마우스 우클릭 -> Follow -> TCP Stream 을 누르면 [그림 6]과 같은 알 수 없는 문자 배열이 나타나는 것을 볼 수 있다.

[그림 6. RETR key.zip 관련 패킷에 대한 TCP Stream]


대충 보면 아실 분도 있으시겠지만, 해당 파일은 server key.pem 파일을 가지고 있는 무언가로 보인다. 알 수 없는 문자열이 다수 존재하지만, 내부 내용을 보면 우리가 알만한 경로의 주소경로도 보이기 때문이다. 저 내부 내용을 해석하기 전에 우선 File Signature에 대하여 알아보도록 하자.

File Signature는 해석 그대로 파일의 서명을 의미한다. 서명이란 무엇인가? 일상 생황에서 서명은 주로 5만뭔 이상의 금액을 결제할 때 많이 사용한다. 아니면 계약서를 작성할 때 사용하던가? 즉 서명은 자신을 증명하는 무언가다. Sign이 될 수도 있고, 도장이 될 수도 있다. 즉, File Signature는 파일이 가지고 있는 '고유한 값'을 나타낸다. 

자 여기서 문제는 우리가 사용하는 파일의 개수가 많아도 너무 많다는 것이다.  exe, ppt, xml, sh, py 등등.. 물론 외우고 다니시는 분들도 있으실 것이다. 자주 보다보면 외우게 되는 signature도 분명히 존재하니까 말이다. 다만 필자는 게으름을 이겨내지 못했는지 아직 외우지 못한것이 많아 특정 사이트를 이용하고 있다. [2]

해당 사이트를 들어가면 (구글에 File Signature 라고 검색하면 최 상단에 위치한다) 여러가지 글귀가 보이고 아래로 내리면 우리가 뭔하는 File Signature 정보를 확인할 수 있다. Hex 값으로 된 Signature를 확인 할 수도 있으며, 이미 알고있는 확장자 혹은 ASCII 값으로도 확인이 가능하다. 위에서 ASCII 값으로 보이는 PK를 기준으로 찾아보면 가장 위쪽에 zip 파일이 있고 그 아래에도 여러가지 PK로 시작하는 File Signature 들이 존재한다.

그럼 저 위에 내용을 기준으로 어떻게 파일 확장자를 구문할까? 내부에서 알아볼 수 있는 문구들로 알 수 있는 분들도 계실것이다. 하지만 그것만으로 구분이 힘든 분들은 [그림 6] 중앙 하단에 보면 Show and save data as 부분이 있는데 저 ASCII를 Hex Dump로 변경하면 ASCII 값과 함께 각 값에 해당하는 Hex 값을 얻을 수 있다.

[그림 7. Hex Dump 결과]


File Signature Site를 보면 알 수 있겠지만, 같은 PK 값을 Signature로 가졌다고 해서 동일한 Hex 값을 가지지 않습니다. 물론 PK 부분은 동일한 값을 가지지만 파일간의 구분을 위해 뒤에 내용을 약간 다르게 해서 구분합니다. 이를 기준으로 볼 때, 해당 파일은 압축파일에 해당하는 ZIP 파일임을 알 수 있습니다.

패킷들을 토대로 보면, 우리는 서버에서 클라이언트로 key.zip 파일이 전송되었고, 해당 파일에 대한 데이터 패킷이 [그림 6] 과 [그림 7]에 포함되어 있는 것을 알 수 있다. [그림 2]에는 전체가 보이지 않지만, 전체 패킷을 보면 Flag로 추정되는 패킷은 보이지 않고 TLSv1.2가 보이는 것으로 보아 뒤쪽에서는 SSL 통신을 하는 것을 알 수 있는데, 우리가 찾은 key.zip이 해당 key 파일 이기를 빌면서 파일을 받아 보도록 하자.

일반적으로 파일을 HxD에 옮겨보면, 그 파일에 대한 hex값이 나오개 된다. 당연히 [그림 7]의 값을 복사하거나, [그림 6]의 값을 복사해서 넣으면 간단하다 라고 보는 사람도 있겠지만, 그것이 반드시 그렇지만은 않다. [그림 6]의 ASCII 값을 복사할 경우, HxD에 넣을 때 16진수의 값이 아니기 때문에 맞게 넣을 수 없다고 나오며, [그림 7]을 넣기 위해서는 노가다가 상당히 필요하다. 그러나 'Show and save data as'에서는 Raw 기능도 지원하는데 이는 말 그대로 Raw한 16진수 값으로만 파일을 주게 된다. 해당 값을 그대로 전부 복사하여 HxD에 붙여 넣으면 [ㄱ림 8]과 같이 저장되고, 그것을 zip파일로 풀어내면 우리는 [그림 9]와 같은 파일을 볼 수 있다.

[그림 8. Raw로 보기와 HxD에 복사한 화면]

[그림 9. key.zip 파일 안에서 나온 pem 파일]


zip 파일을 풀면 server_key.pem 이란 파일을 확인 할 수 있는데 내부 내용을 notepad 등으로 열어보면 기존의 pem파일과는 약간 다른 것을 알 수 있다. pem 파일은 인증서와 key 파일로 구성되어 있기 마련인데, 이 파일은 Key 파일만으로 구성된 것으로 보아 실제 파일 확장자는 .key 임을 추측 할 수 있다.(그러나 pem 파일로 그냥 둬도 문제를 푸는데는 하등의 지장이 없다.) 그럼 우리는 이 key 파일을 어디에 사용할 수 있을까?

고민의 답은 그렇게 오래 걸리지 않을 것으로 보인다. 전체 패킷을 처음부터 자세히 훝어보면 SSL 통신을 하는 패킷이 보인다. 패킷은 전체적으로 내용이 암호화 되어있어 보이지 않으며, 현재 우리가 찾은 정보는 Flag 값이 아니기 때문에 우리가 찾는 최종 정보가 .key 파일도 아닌것으로 보인다.(실제로 문제를 보내준 팀원에게 저 값을 답으로 보냈다가 좀 더 노력하라는 답변을 들었다.)

그러면 이제 우리는 SSL 통신의 암호화를 풀어야 한다. 집에 도어락을 열기 위해서는 암호가 필요하듯이, 현재 우리가 보는 패킷에도 키 파일이 필요하다. 상당히 우연스럽게도(?) 우리가 구한 key.zip에는 key 파일이 들어있었다. 이 파일을 이용해서 SSL 통신을 복호화 해 보자.


[그림 10. 현재 패킷에 Key 파일 등록하기]

WireShark에서 SSL Decrypt를 위해 Key 파일을 넣는 방법을 알아보자. 우선 Menu의 [Edit] 탭에 들어가서 [Preference]를 누르면 [그림 10]의 큰 화면이 나오게 된다. 해당 탭에서 왼쪽 메뉴란의 Protocol을 눌러 SSL을 찾아 내려가면 Secure Socket Layer가 나오는데 RSA keys list를 눌러 작은 그림과 같이 파일을 넣어주면 SSL 등록이 완료 된다.

SSL Key 파일 등록을 완료했다면 아까는 암호화되어 제대로 보이지 않던 SSL 통신들이 HTTP로 복호화 되어 우리 눈에 알 수 있게 보이게 된다. 패킷을 아래로 내리다보면 우리가 찾고있던 Flag로 의심되는 파일에 대한 패킷을 볼 수 있다.

[그림 11. 복호화 된 SSL Packet에서의 Flag 값]


보통 CTF의 목표는 Flag 값을 찾아서 입력하여 OK Sign을 받는 경우가 대부분이기에 현재 저 Flag.jpg 파일을 받았다고 해서 이 분석이 마무리 된 것은 아니다. 아까 zip파일을 보던 것과 같이 Follow Stream을 통해 전송 데이터를 확인해야 한다. 단, 아까는 TCP Strem으로 봤더면, 이번엔 SSL Stream으로 봐야 정상적인 데이터 값이 보이게 된다.(해당 통신은 SSL 통신을 복호화 한 것이기 때문이다.)


[그림 12. Flag.jpg 파일의 SSL stream 값]


그 다음 과정은 key.zip 파일을 얻기 위해 진행했던 과정과 동일하다. Show and save data as ASCII 를 Raw로 변환한 뒤 복사하여 HxD에 붙여넣고 jpg File Signature(FF D8 FF E0)을 찾아 해당 파일부터 마지막까지 값을 jpg 확장자로 저장한다. 그러면 [그림 13]과 같은 최종 값을 알 수 있다.

[그림 13. Flag.jpg 파일 복원]

[그림 13]에서 알 수 있듯이 해당 CTF는 TJ CTF라는 외국 CTF 문제 중 하나이다. 패킷을 분석해 Flag 값을 찾는 CTF 문제로 CTF에서는 꽤 출제되는 유형이다. 향후 [무작위_문제풀이]에 올라오는 문제들의 경우 팀에서 공유된 문제에 대한 간단한 Write Up 형식으로 올라올 가능성이 높다. 다만 필자는 실제 CTF에 참여해 본 경험이 없기에 보고서 형식의 Write Up이 아닌 이런 문제 풀이 방식의 Write Up을 올릴 것으로 보인다. 되도록이면 앞으로 자주 블로그를 할 수 있도록 노력하겠다.



* 참조

 [1] https://chp747.tistory.com/55

 [2] https://www.garykessler.net/library/file_sigs.html

Posted by Latte_
,

마지막으로 FAT32 FileSystem을 다룬것이 작년 10월 경이니, 어느새 1년 가까운 시간이 지나버렸습니다. 지난 1년간 블로그를 그냥 두려고 했던 것은 아니나, 본의아니게(?) 실컷 놀아버린 꼴이 되어버렸습니다.

정신을 차리고보니 이도 저도 아닌 제 모습이 보여서.. 뭐라도 해야 할 것 같았습니다. 그래서 매번 공부해야지 해야지 하고 못했던.. 리버스 엔지니어링을 시작해보고자 합니다. 

Reverse Engineering, 주로 리버싱이라고 불리는 이 역공학 방식은 소프트웨어 공학의 한 분야로 '이미 만들어진 시스템을 역으로 추적하여 처음의 문서나 설계자료를 얻어내는 일'을 말합니다.[1] 역공학이라고 불리우는 이유는, 보통 소프트웨어 생명주기의 마지막 단계에서 초기의 자료등을 얻어내기 때문에 기존 소프트웨어 공학의 역방향으로 흐르기에 역공학이라고 지칭되고 있습니다.

리버싱은 단순히 소프트웨어 공학에만 쓰이는 것이 아니라, 보안쪽에서도 많이 사용되고 있습니다. 주로 백신사나 침해사고 대응 업무에서 많이 사용되고 있는데 침해 PC나 Web 상에서 수집 된 악성코드를 역공학을 이용해 분석 후 탐지될 수 있는 Singnature를 추출하거나 특정 Software를 분석하여 취약점을 찾는데 사용되고 있습니다.


리버스 엔지니어링을 할 줄 안다는 것은 그만큼 여러 분야에 도움이 될 수 있다는 장점이 될 수 있지만 반면 수요가 그리 많지 않다는 단점도 존재합니다. Anti-Virus 생산 업체나 일부 특수한 조건을 제외하고는 해당 분야에 필요한 인재를 뽑지 않거나, 뽑더라도 적은 수를 뽑기 때문입니다. 

필자도 악성코드 분석가가 되고 픈 마음은 굴뚝같지만, 리버싱을 잘 하지 못하기 때문에 지원하지 못하고 있습니다.(이 블로그는 제가 잘 알아서 쓰는게 아니라, 제가 공부한 것을 정리하는 개념으로 작성하는 부분입니다)

따라서 여러분께 이 블로그를 통해 악성코드 분석의 비법을 전달해 드린다기 보다는 '필자는 이렇게 공부했다' 라는 내용을 보여드리는 쪽으로 진행 될 것 같습니다. File System 때와 마찬가지로 부족한 부분이 많겠지만 보시고 많은 질책과 격려 부탁드립니다.

시간이 지나면 여러 악성코드도 분석하고 할 기회가 있겠지만, 이 [Reverse Engineering] 의 시작은 Lena's Tutorial로 시작 할 예정입니다.

그럼 많은 관심 부탁드립니다. 아! 그리고 본격적인 설명 및 분석에는 File System 때와 마찬가지의 어법이 쓰일 예정입니다. 지금처럼 완전 존대가 되지 않으니 참고 하시기 바랍니다.


[참고]

[1] https://terms.naver.com/entry.nhn?docId=1180896&cid=40942&categoryId=32837

Posted by Latte_
,

2018년 새해가 되자마자 보안업계 뿐 아니라 일반 업체에도 한바탕 크게 태풍이 몰아쳤다. 과거에도 이런 큰 태풍이 있었을까? 경력이 그렇게 길진 않아서 과거에 얼마나 큰 이슈가 있었는지 까지는 알지 못한다. 

그나마 작년에 크게 터진 이슈라면 전 세계적으로 확산 된 WannaCry 정도 일 것이다. 근데 그런 WannaCry도 Microsoft에서 긴급 패치를 발표하고 일단락이 됐다.


그런데 이녀석은 그렇지 않다. 다른건 둘째치고 규모가 어마어마하다. 과거 WananCry의 경우 Windows OS를 사용하는 PC로 제한됐다. SMB를 사용하기 때문에 Linux는 Target이 아니었기 때문이다.

지금 소개할 두 녀석은 WannaCry를 뛰어넘는다. 이녀석은 OS를 구분하지 않는다. Windows, Linux, Mac OS 할 것 없이 취약하다. 이게 무엇을 의미하는지 아는가?

이 두 녀석은 Software적인 취약점이 아닌 Hardware 취약점이다. 즉 특정 Hardware가 들어간 PC 혹은 서버는 이 취약점을 가지고 있다는 소리이다. 문제는 이 Hardware의 점유율이 80%에 육박한다는 점이다. 


제목에도 나와있지만 지금부터 소개할 두 녀석은 Meltdown과 Spectre이다. 2017년 6월 Google Project Zero Team에 의해 발견된 이 취약점은 2018년 새해가 되자마자 전 세계에 태풍을 몰고 왔다. 그간 일반 유저의 PC 뿐 아니라 기업의 Server에 독보적인 점유율을 자랑하던 Intel CPU에 잠들어 있던 취약점이 공개되자 보안 업계는 술렁했고, 기업들 역시 패치에 고심하고 있는 추세이다.

이 두녀석이 태풍을 몰고 온 이유는 바로 저 점유율이 큰 역할을 했다. CPU는 Intel과 AMD가 대립하고 있다고는 하지만, AMD로서는 Intel의 점유율을 따라갈 수가 없었다. Ryzen을 공개하며 돌풍을 몰고가나 헀던 AMD의 점유율은 Intel과의 큰 차이를 극복하지 못했고, 현재도 60%가까운 차이를 보이고 있다.

문제는 이 Intel의 점유율이 단순히 수치만으로 보이지 않는다는 점이다. 이 두 취약점은 Intel CPU의 구조적인 취약점을 이용한다. 문제는 이 취약점이 최근 프로세서에 생긴 문제가 아니라, 과거 20년이상 이어온 취약점이라는 점이다.

취약점 자체가 20년동안 발견되지 않은 것도 놀랍지만, 20년산(?) 취약점이 생각보다 큰 파급력을 가져온다는 것이 문제였다. Meltdown은 보안 전반에, 그리고 Spectre는 특히 가상화를 사용하는 기업에 큰 피해를 유발 할 가능성이 있다. 무엇보다! 대부분 기업에서 사용하는 서버에는 Intel CPU가 들어가있다는 점이다!!!


일반 사용자분들은 크게 와닿지 못할 Meltdown과 Spectre! 한번 필자와 쉽게 이해 할 수 있도록 해보자. 

'보안 > Issue_알아보기' 카테고리의 다른 글

#1. 들어가며  (0) 2018.03.05
Posted by Latte_
,

마지막으로 블로그에 글을 언제 연재했나 봤더니 2017년 10월이다.

그간 공부를 얼마나 안했는지 알 수 있는 지표이며, 또한 필자가 얼마나 끈기가 없는 지 보여주는 지표가 아닐까 싶다.

사실 리버싱도 일을 벌려놓고 작성도 못한 포스트들이 넘쳐나는데, 이 포스팅도 제대로 진행할 수 있을지는 필자 스스로에 대한 의문이 든다.

부디 올 한해는 열심히 포스팅을 하겠다는 마음가짐으로.. 최선을 다해보도록 노력 하겠다.


2018년이 시작되고 3달이 지났고, 그 사이에 우리가 알게 모르게 보안 취약점들이 많이 나왔으며 그 중에는 Meltdown / Spectre와 같은 큰 충격으로 다가온 취약점들도 있었다.

사실 Meltdown과 Spectre가 나오고 나서도 필자는 그렇게 크게 탐구하거나 하지는 않았다. 내가 근무하고 있는 업체는 Endpoint를 방어하는게 아니라 상단 Network 구간을 담당하고 있었으니까.

그러다 최근 회사에서 해당 이슈를 알아야 할 필요성이 생겨 간단히 찾아보게 되었고, 그를 토대로 이렇게 포스팅을 할 기회가 생긴것 같다.

물론 '이미 공개된지 2달이 지난 시점이고 많은 분석가 분들이 분석을 해 주셨기에 따로 포스팅을 할 필요가 없다'라는 말씀을 하시는 분들도 있을 것이다.

사실 그 생각은 필자도 어느정도 동의하고 있는 바이다. 이미 인터넷에는 수많은 Meltdown과 Spectre에 대한 설명들이 나와있으니까. 과연 지금 작성하는게 무슨 의미가 있을까?


그래서 이 포스트는 과거 발생한 크고 작은 보안 Issue에 대해 일반인들도 알기 쉽게 설명해 보는데 목표를 두고자 한다.

어느정도 기술적인 부분이 들어가는건 어쩔 수 없을 것이지만, 그래도 비유등을 통해서 쉽게 접근해 보도록 하겠다. 

기술적인 부분은 각종 보안 분석가들이 자세히 설명해 놓으셨거나, github에 올라와 있는 것들이 많을테니, 그부분들을 참조해주시면 되겠다.


그럼, 이번엔 부디 꾸준히 포스팅을 하기를 기원하며..

'보안 > Issue_알아보기' 카테고리의 다른 글

[Meltdown&Spectre] #1. 이슈 소개  (0) 2018.03.05
Posted by Latte_
,

* 들어가기에 앞서 본 스터디에 사용 된 OS 종류 및 VMware 종류에 대해 기술하고 시작하고자 한다. 다른 버전이어도 상관은 없으나, 사용 상 불편한 부분까지 본 블로그에서 일일히 다루어 주지는 않는다. 물론, 질문을 남겨줄 경우, 따로 확인해서 답변을 드리긴 하겠다.

  - 필자 E-Mail : wotmd9408@naver.com

  - 가상머신 : VMWare WorkStation 12

  - OS : Window7 Enterprise K 64bit

  - RAM : 1GB

  - 나머지 사항은 기본적인 세팅으로 설정하였다.

  - 추가 필요 Tool : Hxd(https://mh-nexus.de/en/downloads.php?product=HxD)


여기까지 따라온 독자들에게 깊은 감사의 인사를 드린다. 되도록이면 하나의 포스팅을 짧게 끝내려고 생각은 하고 있으나, 쓰다보니 그게 마음대로 되지 않아 전반적으로 내용이 길어져 읽는데 힘들었을 독자들을 생각하면 조금 죄송스러운 마음이 드는건 사실이다. 이 이야기를 여기에 쓰는 이유는 앞으로 만들어질 실습을 제외하면(물론 정확히 언제 완성될지는 모르겠지만..) 마지막 포스팅이 될 예정이기 때문이다. 


[그림 1. FAT32 구조]

위 그림을 기억하겠는가? 포스팅을 잘 따라온 독자라면 "이제는 그만좀 올려도 되지 않을까?"하는 생각을 할만한 그림일 것이다. 우리는 MBR을 시작으로 [그림 1]의 순서대로 공부를 진행해 왔다. 이제 대망의 마지막인 Data Area(데이터 영역)을 보려고 한다.

사실 Data Area는 앞서 포스팅했던 Root Directory Entry를 포함한다. [그림 1]에서는 조금 더 보기 쉽도록 표시되어 있지만, 예약영역(Reserved Area)의 가장 앞 섹터에 존재하는것과 마찬가지로 FAT32에서 Root Directory Entry는 데이터 영역의 가장 앞 섹터에 위치한다. 즉, Root Directory Entry부터 해당 파티션이 갖는 마지막 섹터까지가 데이터 영역이 된다. 


먼저 데이터 영역에 존재하는 내용이 무엇인지 살펴보자. 가장 먼저 앞서 확인한 Directory Entry가 있다. 이때 데이터 영역의 가장 앞에 존재하는 디렉터리 엔트리가 Root Directory Entry이고, 나머지가 그냥 Directory Entry이다. 이 Root Directory Entry에 포함하는 파일/디렉터리는 우리가 파티션에 해당하는 드라이브에 접근했을 경우 보이는 가장 상단 경로의 디렉터리 혹은 파일을 의미한다. 그리고 그 Root Directory Entry에서 우리는 해당 디렉터리 엔트리에 존재하는 파일과 디렉터리의 각종 정보를 확인 할 수 있다.

디렉터리 엔트리에서 특정 파일에 대한 정보를 수집했다면 이제 그 파일에 대한 데이터가 있는 부분으로 이동할 수 있다.(이 부분에 대해서는 이후에 자세히 설명하도록 한다.) 물론, Root Directory Entry에서 확인한 정보가 '파일'에 대한 정보라면 해당 파일의 데이터 정보에 접근할 수 있다. 그러나 파일이 아닌 디렉터리에 대한 정보라면 해당 디렉터리가 가지고있는 디렉터리 엔트리 부분으로 향하게 된다. 이번 포스팅에서는 파일을 분석해 파일의 데이터를 확인하고, 실제로 정보들을 역 이용해 데이터를 생성하는 과정을 진행해 볼 것이다.


[그림 2. Directory Entry내 파일 정보]

파일의 데이터 영역에 접근하기 위해서는 디렉터리 엔트리 내에 있는 파일의 정보를 읽어 낼 수 있어야 한다. 사실 데이터 영역에 접근하기 위해서 [그림 2]에 있는 모든 정보를 구할 필요는 없다. 결론부터 이야기하면 3가지(First Cluster High, First Cluster Low, File Size)만 알면 데이터 정보를 찾아오는데는 아무런 문제가 없다. 그러나 복습을 위해서, 하나하나 분석 해 보도록 하자.

  - File Name / Extender : KOALA.JPG

  - Attribute : 0x20 => 일반적인 File을 지칭

  - Create Time : 0x1B38 => ‭0001 1011 0011 1000‬

    Time값이니 5/6/5로 나누면 ‭00011 011001 11000 가 되고, 이를 다시 10진수로 변환하면 ‬3시 25분 48(시간값은 계산값에 *2)초 가 된다.

  - Create Date : 0x4B3B => ‭0100 1011 0011 1011‬

    Date값이니 7/4/5로 나누면 ‭0100101 1001 11011‬ 가 되고, 이를 다시 10진수로 변환하면 2017(년도 값은 기본 1980년에 계산값을 더한다)년 9월 27일이 된다.

  - Last Access Date : 0x4B3B => 위의 Create Date와 값이 같으니 계산은 생략한다.

  - First Cluster High : 0x0000

  - Write Time : 0x7410 => ‭0111 0100 0001 0000‬

    Time 값이니 5/6/5로 나누면 ‭‭01110 100000 10000‬‬ 가 되고, 이를 다시 10진수로 변환하면 14시 32분 32(시간값은 계산값에 *2)초가 된다.‬

  - Write Date : 0x3AEE => ‭0011 1010 1110 1110‬

    Date값이니 7/4/5로 나누면 ‭0011101 0111 01110 가 되고, 이를 다시 10진수로 변환하면 ‬2009(년도 값은 기본 1980년에 계산값을 더한다)년 7월 14일이 된다.

  - First Cluster Low : 0x03

  - File Size : 0x000BEA1F => ‭780,831‬

    여러분이 FAT32 또는 NTFS에서 "유일"하게 이 부분만이 추가적인 계산 없이 바로 용량을 표기하게 된다.(다른 부분에서는 사용하는 Sector 수 로 확인되는 경우가 많다)

    또한 디렉터리의 경우 용량이여기 존재하지 않기 때문에 File Size 값이 0으로 되어있다.

 * 지난 포스팅에서 소개한 NT Resource 및 Create Time Tenth의 경우 중요하지 않아 따로 표기하지 않았다. 추가적으로 필자가 적은 결과와 독자가 계산한 결과는 다를 수 있다. 과정을 동일하게 진행했더라도 생성 시간 등은 같을 수 없기 때문에 반드시 본인이 작성한 환경에서 계산을 진행해야 한다.

 * 당시 포스팅에서 제대로 소개하지 않았지만, FAT32 구조에서는 Access Time을 표기하지 않는다. 해당 내용을 표기하지 않는 이유는 32byte 안에 해당 내용을 다 기입 할 수 없기 때문이다.


이 Koala.jpg 파일을 기준으로 파일의 데이터가 위치한 곳으로 접근해 보도록 하자. 우선 파일의 데이터 영역으로 가기 위해서 중요한 부분은 First Cluster High, First Cluster Low 그리고 File Size이다. 사실 First Cluster High의 경우 항상 0을 가지니 결국엔 First Cluster Low와 File Size만 중요하다고 보면 된다. 방금 설명한 세가지에 대한 계산은 [그림 2]를 분석하며 확인했으니 다시 기입하지는 않겠다.

데이터로 가기 위해서는 First Cluster High와 First Cluster Low를 순서대로 결합한 뒤 2을 빼 주면 된다. 이는 FAT32에서 0번과 1번 클러스터는 이미 시스템에서 예약 후 사용하고 있기 때문이다. 이를 토대로 계산을 해보도록 하자.

  - First Cluster High + First Cluster Low = 0x00000003 = 3

  - FAT32에서 0번과 1번 클러스터는 이미 사용중이니 빼면 3-2 = 1

여기서 우리가 한가지 알아야 할 내용이 있는데, 1개의 클러스터는 8개의 섹터를 가진다는 점이다. 이를 토대로 Root Directory Entry인 16512 섹터에서 8 섹터를 이동한 16520으로 가면 우리가 찾던 Koala.jpg 파일의 데이터를 확인 할 수 있다.


[그림 3. Koala.jpg 파일의 Data 부분]

여러분이 필자와 동일하게 구성을 했거나, 아니면 각자의 세팅에 맞게 찾아 갔다면 위와 같이 정상적인 koala.jpg 파일의 데이터를 확인 할 수 있다. 여기서 문제는 여러분이 찾아간 16520 섹터에 있는 내용이 정말로 koala.jpg 파일의 데이터가 맞냐는 점이다. 물론 File Size를 이용해 데이터를 복사해서 따로 저장한 뒤 확인 하는 방법도 있을것이다. (그리고 그게 가장 정석적인 방법이기는 하다.) 그 방법은 잠시 후에 확인 해 볼 예정이며 지금은 File Signature를 이용해 확인하는 방법을 알아보자.

File Signature란 문자 그대로 해석하면 '파일의 서명'이 되는데 보다 자세히 풀이하면 '파일이 가지고 있는 고유한 문자열'이라고 봐도 무방하다. 파일은 일부 확장자를 제외하면 대부분의 확장자가 각기 다른 시작 문자열을 가지고 있다.(여기서 말하는 시작 문자열은 확장자 명이 아닌 해당 파일을 Hex Editor로 열었을 때 보이는 Hex 값 및 String 값을 의미한다.)

  * DLL 과 EXE 확장자처럼 서로 다른 확장자를 가지고 있으나 동일한 시그니처를 가지고 있는 경우도 존재한다. 

시그니처는 보통 파일의 시작 문자열부터 일정 부분까지를 의미하는데 평균 4Byte 정도에서 많게는 16Byte까지 되는 경우가 있다. 우리가 확인한 JPG 확장자의 File Signature는 FF D8 값을 시그니처로 가지고 있으며 데이터의 가장 끝은 항상 FF D9로 끝나게 되어있다. 그러나 보통 JPG/JPEG 파일을 확인 할 경우에는 FF D8 FF E0 와 JFIF 부분을 확인한 뒤 JPG 파일임을 확인하는 경우가 대부분이다.

  * 파일 별 시그니처 정보를 확인하고 싶은 경우 이 URL에 접속해 검색하면 확인 해 볼 수 있다.(http://www.garykessler.net/library/file_sigs.html)


이제 시그니처를 통한 확인이 아니라 데이터 영역을 복사해 파일을 생성함으로써 실제 koala 파일이 맞는지 확인 해 보도록 하자. 만약 koala.jpg 파일의 데이터 섹터에서 벗어났다면 다시 계산을 통해 해당 섹터로 이동하도록 하자. 이후 데이터의 가장 앞부분에 커서를 놓고 마우스를 우클릭한 뒤 [블록 선택]을 누르도록 하자. 

[그림 4. koala.jpg 파일 크기 입력]

이후 [그림 2]를 통해 계산한 File Size 값을 길이에 입력한 뒤(10진수로 변환한 뒤 780,831‬를 입력해도 상관없다.) 수락을 누르면 가장 해당 데이터의 마지막으로 이동되며 그 이전까지가 블록 선택이 된다. 그 내용을 복사해 새로 파일을 만들어 test.jpg로 저장하면 koala.jpg와 동일한 그림이 나타나는 것을 볼 수 있다.


폴더의 경우도 계산하는 방법은 파일과 동일하다. 다만 파일과 달리 폴더는 용량을 가지고 있지 않다. 따라서 동일하게 계산한 섹터로 이동하면 폴더의 데이터 영역이 있는게 아니라 해당 폴더에 저장된 파일들의 디렉터리 엔트리로 이동하게 된다. 그리고 해당 디렉터리 엔트리 내에 있는 파일의 내용을 기준으로 다시 들어가면 파일의 실제 데이터 영역으로 이동하게 되는 것이다. 한번 실습을 통해 확인 해 보도록 하자.

[그림 5. Forensics 폴더의 Directory Entry 정보]

우리가 실습해 볼 폴더는 [그림 5]에 입력 된 forensics라는 폴더이다. 폴더명이 8자를 넘어 LFNs(Long File Names) 방식으로 입력되어 있는 것을 확인할 수 있으며 폴더는 File Size가 0이므로 First Cluster High 와 First Cluster Low만 확인 후 계산하면 된다.

  - First Cluster High + First Cluster Low = 0x000000C2 = 0xC2

  - FAT32에서 0번과 1번 클러스터는 이미 사용중이니 빼면 0xC2 - 2 = 0xC = 192

위에서 파일의 데이터 영역 주소를 찾을 때도 설명했듯이 하나의 클러스터는 8개의 섹터를 가지고 있다. 즉 16,512 섹터로부터 1,563 섹터 뒤로 이동하면 이 폴더의 디렉터리 엔트리로 이동 할 수 있다. 계산 값인 18,048로 이동해 결과를 확인해 보도록 하자.

[그림 6. Forensics 폴더 계산 후 결과 비교]

Foreniscs 폴더의 디렉터리 엔트리 정보를 통해 계산한 결과. Forensics 폴더 안에는 Jellyfish.jpg라는 파일이 있는것을 확인 할 수 있었으며 실제 Windows 탐색기를 통해 확인한 결과 실제로 Jellyfish.jpg 파일을 확인 할 수 있었다.

지금까지 배워온 내용들을 잘 이용하면 Hex Editor를 이용해 실제로 파일을 생성해 내는게 가능하다. 단순히 생성하는 것 뿐만 아니라 MAC Time을 조작한 데이터를 생성할 수 있고 원하는 데이터를 밀어 넣을 수도 있다. 관련된 실습은 추가적인 실습 포스팅을 통해 진행할 예정이다.


이 포스팅을 마지막으로 FAT32에 대한 설명을 마무리 하려고 한다. 필자도 실무에서 포렌식 업무를 수행하지 않고 있어 실제 어떻게 업무가 진행되는지는 정확히 알려줄 수는 없으나 여태까지 진행해온 이론이 실제 업무에 도움이 될 수 있을 것으로 생각한다. 파일 시스템에 대해 공부하다보면 Web Hacking이나 모의해킹과는 다르게 조금 지루함을 느끼기가 쉽다. 아무래도 모의해킹이나 다른 여러가지 분야에 비해서는 실제로 보여지는 퍼포먼스나 결과가 그렇게 화려하거나 크지 않기 때문이다.

그러나 여러분이 실제로 Encase나 FTK(Forensics ToolKit)를 이용해 보면 모의해킹이나 기타 다른 보안 공부를 할때와 같은 기분을 느낄 수 있을 것이다. 지금까지 진행 된 포스팅은 그 밑바탕이 되기 위한 이론을 다지는데 그 목적을 두었다.


길고 긴 FAT32에 대한 포스팅을 따라온 독자분들께 감사의 인사를 남긴다. 다음 포스팅부터는 NTFS를 진행하게 될텐데, 아마 FAT32보다는 조금 어렵고 복잡한 부분이 있기때문에 조금은 더 각오를 하고 들어오는 것을 추천한다. 그동안 고생많았고, 부디 진행된 포스팅들이 여러분의 앞날에 도움이 되었기를 바란다.


* 참고 : 임베디드 개발자를 위한 파일시스템의 원리와 실습(정준석, 정용원 공저), 한빛미디어

* 참고 : http://www.garykessler.net/library/file_sigs.html

Posted by Latte_
,

* 들어가기에 앞서 본 스터디에 사용 된 OS 종류 및 VMware 종류에 대해 기술하고 시작하고자 한다. 다른 버전이어도 상관은 없으나, 사용 상 불편한 부분까지 본 블로그에서 일일히 다루어 주지는 않는다. 물론, 질문을 남겨줄 경우, 따로 확인해서 답변을 드리긴 하겠다.

  - 필자 E-Mail : wotmd9408@naver.com

  - 가상머신 : VMWare WorkStation 12

  - OS : Window7 Enterprise K 64bit

  - RAM : 1GB

  - 나머지 사항은 기본적인 세팅으로 설정하였다.

  - 추가 필요 Tool : Hxd(https://mh-nexus.de/en/downloads.php?product=HxD)


이제 FAT32 파일시스템도 어느정도 마무리 단계에 접어 들었다. 물론 이번 포스팅이 끝이 아니고 몇가지가 더 남아있긴 하지만(간단하게 풀어볼 수 있는 문제도 제작 해 보려고 하고있다.) 그래도 칠부능선을 넘은건 사실이다. 이론만 따지면 두번이나 세번 정도의 포스팅이면 간략하게나마 마무리 될 것으로 보인다.


지난 포스팅을 통해 Root Directory Entry의 구조와 각각의 디렉터리 엔트리가 어떤식으로 구성되어있는지 세부적인 내용들을 알아보았다. 그러나 해당 포스팅에서 다루지 않은 내용이 남아있다. 그것이 이번 포스팅에서 다룰 Short File Name과 Long File Names 이다.

파일 및 디렉터리는 생성할 때 각각의 고유한 이름을 가진다. 물론 이 고유한 이름이 절대적으로 Unique 하지는 않다. 동일한 확장자에 대해서만 고유한 이름을 갖고 있으니 오해 없기를 바란다. 그리고 각각의 파일명은 몇가지 규칙을 가지고 있으며, 해당 규칙을 위반할 경우 파일이 정상적으로 생성되지 않는다. 이 규칙은 SFN(Short FIle Name) 과 LFN(Long File Name)이 조금씩 다른 부분이 있기 때문에 따로 나누어 설명 하도록 하겠다.


먼저 알아볼 내용은 SFN(Short File Name)이다. 의미 그대로 짧은 파일명을 의미하고, FAT32기준에서는 8Byte (영문 8자, 한글 4자)이하, 3Byte이하의 확장자 파일 혹은 디렉터리일 경우 Short File Name으로 표기된다. 그림을 통해 예시를 들어보도록 하자.

[그림 1. Short File Name의 예시]

[그림 1]은 지난번 Root Directory Entry에서도 봤던 코알라 사진이다. 위에서 말한 Short File Name의 조건과 일치하는지 한번 확인해 보도록 하자. 먼저 파일명이 8Byte인지 확인하면 K,O,A,L,A로 총 5개의 알파벳으로 파일명이 구성되어 5Byte 값을 가진다. 그리고 확장자 역시 JPG로 3Byte 값만 가지기 때문에 Short File Name의 조건이 된다고 볼 수 있다.

그러면 Short File Name에 만족한다는 가정하에 어떤 규칙을 지켜야 파일이 생성되는지 확인해 보도록 하자.

  - 영어 대문자 A ~ Z (소문자는 대문자로 바꾸어 저장)

  - 해당 운영체제가 지원하는 언어의 문자( ex : 한글 MS-DOS라면 한글 파일명 가능)

  - 아라비아 숫자 0 ~ 9

  - 특수문자 중 $, %, ', -. _, @, ~, !, (), {}, ^, #,&


위에서 가장 첫번째 조건의 경우, 실제 파일을 만들때는 소문자로 만들어도 문제가 없지만, Root Directory Entry에 저장될 때는 대문자로 저장하기에 저렇게 기입하였다. 또한 따로 적혀있지 않지만, Short File Name 작성 규칙에서 파일 명 사이에 스페이스(0x20)을 입력하는 것은 가능하다. ( ex : MY NAME.HWP) 그러나 일부 프로그램의 경우 파일명 중간에 Space가 포함될 경우 파일을 제대로 인식 못할 수 있기 때문에 Under Bar( _ )를 지향하는 것이 좋다. 또한 영어가 아닌 외래어의 경우 한 글자당 2Byte로 인식하기 때문에 그 또한 알아두면 좋다. 그리고 마지막으로, 전 포스팅에서 이야기 했듯이 파일명 가장 앞에 스페이스(0x20)이 들어갈 수 없다.


SFN(Short File Name)은 이정도로만 설명해 두도록 하자. 이후 추가적으로 필요한 부분이 있으면 필자가 더 채워 두도록 하겠다. 이제부터는 이 포스팅에서 본격적으로 다뤄 볼 LFNs(Long File Names)에 대해 알아보도록 한다.


Window 95가 나오기 이전, 그러니까 MS-DOS와 Window 3.x버전이 PC의 기본 OS였던 시절에는 FAT 파일시스템이 나올 때부터 쓰이던 8.3 Naming, 즉 우리가 위에서 SFN(Short File Name)으로 알고있는 방식만이 사용되었다. 그러한 이유로 많은 유저들은 매킨토시(MAC OS)나 Unix, Linux 계열처럼 긴 파일명을 사용 할 수 있기를 원했다. 그래서 나온 기능이 Window 95와 함께 나온 LFNs(Long File Names)이다.

LFNs의 자세한 구조를 알기전에, LFNs의 특징들에 대해 먼저 짚고 넘어가도록 하자.

  - 유니코드(UTF-16)방식으로 인코딩되어 있기 때문에 다국어 지원이 가능

  - 최대 255자까지 저장 가능

  - 3자리 이상의 확장자도 저장 가능

  - 기존의 SFN(Short File Name)과 호환 됨

  - SFN보다 사용할 수 있는 특수문자 폭이 넓어짐

MircroSoft는 LFNs를 설계하면서 하위 호환의 개념을 버리지 않으려고 노력했다. 앞으로 우리가 보게 될 Long File Name Entry는 전 포스팅에서 보았던 Directory Entry를 변형해서 구성하여 하위 호환성을 유지했다. 물론, 억지로 비틀어(?)만든 방식이니 만큼 구조가 어색하고 상당히 불편하다. 

LFNs의 가장 큰 특징중 하나는 바로 유니코드를 지원한다는 점이다. 이는 Microsoft의 큰 밑그림(빅픽처??)으로 인해 지원하는 부분인데 Windows가 여러 나라에 사용될 것을 대비해 추가 된 기능이다. 물론 이 기능으로 인해 저장 공간이 2배이상 늘어나 버린 단점은 분명히 존재하지만, 현재의 상황으로 따지고 보면 미래를 정확히 내다 본 좋은 선택이었음에는 틀림없다.


[그림 2. Long File Names 표기의 예시]

[그림 2]는 필자가 예시로 만든 Forensics라는 디렉터리를 Root Directory Entry에서 확인한 것이다. [Forensics] 이라는 단어는 총 9자로 Short File Name 방식인 8/3(8자리 파일명, 3자리 확장자명)법칙으로는 만들어 낼 수 없다. 따라서 [그림 2]처럼 LFNs(Long File Names)로 표기된다. [그림 2]를 보면 동일한 Forensics가 2가지 방식으로 표현된 것을 볼 수 있는데, 붉은색 네모칸과 초록색 네모칸이 바로 그것이다. LFNs의 특징 중 하나는 표기 할 수 있는 부분까지 표기해준 뒤 모자란 부분에 대해서 ~1로 표현하여 LFNs로 표현됐음을 알려주는 것이다. 앞으로 여러분이 보게 될 디렉터리 엔트리 중 ~1이 있으면 LFNs로 표기되었다고 보아도 좋다.

위 그림에 대해 자세히 알아보도록 하자. 먼저 초록색 네모를 보면 SFN(Short File Name)처럼 기록되어있다. 최대 6자까지 파일명을 표기하고 남은 부분을 ~1로 표기하여 LFNs(Long File Names)로 표현되었음을 지칭한 뒤. 파일의 나머지 정보(생성시간, 파일 용량 등)을 표기한다. 여기까지는 [그림 1]에서 본 SFN(Short File Name)과 비슷하다. 그런데 LFNs(Long FIle Names)는 어찌됐든 File명을 전체를 표시해 줘야 하기 때문에, 해당 디렉터리 엔트리 상단 32Byte를 추가로 할당하여 파일명을 마저 표기한다. 이 부분이 붉은색 네모에 해당하는 부분이며 Short Directory Entry와 구분되게 Long Directory Entry라 지칭한다.


아래 정리를 통해 [그림 2] 중 붉은색 영역(Long Directory Entry)에 해당하는 부분에 대하여 자세히 알아보도록 하자.

이름

 Order

offset

 0

Size

1 Byte 

 Value

가변적

설명 

Long File Name Entry가 정렬 된 순번을 기록하는 항목으로 만약 이 항목의 6번째 비트(0x40)가 1이라면 해당 파일명을 구성하는 마지막 Entry를 의미

이름

 Name1

offset

 1~10

Size

10 Byte 

 Value

가변적

설명 

해당 엔트리에 저장할 문자열 중 1~5번째 문자열을 여기에 저장

이름

 Attribute

offset

 11

Size

1 Byte 

 Value

0x0F

설명 

이 항목은 언제나 ATTR_LONG_FILE_NAME을 뜻하는 '0x0F'가 들어가야 한다. 그렇지 않으면 MS-DOS와 같이 LFN Entry를 인식하지 못하는 기존 운영체제에서 문제를 일으키게 된다.

이름

 Type

offset

 12

Size

1 Byte 

 Value

일반적으로 0

설명 

이 항목의 값이 0이라면 일반적으로 LFNs의 항목 중 하나라는 의미이다. 다른 값들은 미래를 위해 예약되어 있다.

이름

 Check Sum

offset

 13

Size

1 Byte 

 Value

가변적

설명 

이 항목은 Short Directory Entry 항목에 들어가는 11자의 문자열에 대한 Check Sum을 저장한다.

이름

 Name2

offset

14~25 

Size

12 Byte 

 Value

가변적

설명 

해당 Entry에 저장할 문자열 중 6~11번째 문자열을 이곳에 저장한다.

이름

 First Cluster Low

offset

 26~27

Size

2 Byte 

 Value

반드시 0

설명 

Long Directory Entry는 파일명을 저장하는 기능밖에 없기 때문에 이 부분은 의미 없는 값이기는 하나, 기존의 FAT 코드와의 호환성을 위해 반드시 0으로 기입한다.

이름

 Name3

offset

 28~31

Size

4 Byte 

 Value

가변적임

설명 

해당 Entry에 저장할 문자열 중 12~13번째 문자열을 이곳에 저장한다.

위 표들을 자세히 살펴보면 한가지 특이한 점을 알 수 있다. Long File Name Entry 하나 당 13개의 문자열을 저장할 수 있으며, 문자열을 저장할 때 2Byte 당 1개의 문자열을 저장한다는 점이다. 이는 LFNs가 문자열 지정 방식을 유니코드(UTF-16)으로 하고 있기 때문인데, 이 부분에 대해서는 차후에 기회가 되면 따로 정리해보도록 하겠다. 

여기서 의문점 하나. 만약 파일명, 혹은 디렉터리 명이 13자를 넘어갈 경우에는 어떻게 되겠는가? 간단하다. 필요한 숫자만큼 Long Directory Entry를 생성하게 되며 최대 255자 까지 생성이 가능하기 때문에 255/13을 해보면 최대 20개의 Long Directory Entry가 생성되게 된다.


그러면 Short Directory Entry 와 Long Directory Entry가 저장되는 형태에는 어떠한 규칙이 존재하는지 아래표를 통해 알아보자.

 Directory Entry 순서

 Order 항목 값 

 N번째 Long File Name Entry(마지막 Entry) 

 LAST_LONG_ENTRY(0x40) | N


 두 번째 Long File Name Entry

 0x02

 첫 번째 Long File Name Entry

 0x01

 위와 대응하는 Short Directory Entry

 (해당 없음)

위 표대로 Short Directory Entry가 가장 하단에 위치하고 그 위로 Long Directory Entry가 순서대로 시작되어서 맨 위쪽에 마지막 문자열의 Long File Name Entry가 위치한다. 마지막 Long File Name Entry에는 해당 Entry가 마지막임을 알려주기 위해 Order 항목에 마지막 Entry 번호와 0x40번 비트를 OR시키게 된다. 만약 7번째가 Long File Name Entry라면 Order 값은 0x47이 되는 것이다. 아래 예시를 통해 Short Directory Entry 및 Long Directory Entry를 정리 해 보도록 하자.


[그림 3. Short/Long Directory Entry 예시]

실습을 위해 제목이 긴 파일 하나를 만들었다(필자가 매우 좋아하는 영국 드라마 "Doctor Who"에서 주인공이 타고다니는 우주선 이름이다). [그림 3]을 통해 하나하나 확인 하도록 하자. 먼저 가장 하단의 Short Directory Entry부터 확인해 보도록 하겠다. 기준은 전 포스팅에서 설명했던 디렉터리 엔트리 설명과 이번 포스팅에서 설명한 Long File Name Entry 설명을 기준으로 작성하도록 하겠다.

 - Name  : TIMEAN~1 

   -> 해당 파일명으로만 봤을 때는 TIMEAN~1로 보일 수 있으나 위의 내용들을 함께 봤을 때 이 파일은 LFNs로 표현되어 있음을 알 수 있다.

 - Extender : TXT

 - Attribute : 0x20

   -> 0x10은 디렉터리, 0x20은 파일을 의미한다. 따라서 이 디렉터리 엔트리는 파일임을 알 수 있다.

 - Create Time : 0xB61A => 1011 0110 0001 1010

    5/6/5로 변환하면 10110 110000 11010 가 되는데 이를 다시 10진수로 변환하면 22시 48분 26초가 되는데 마지막 Seconds 부분은 최대 31까지밖에 표기하지 못하므로 2를 곱해야 해서 22시 48분 52초가 된다.

[그림 4. Create Time 확인]

 - Create Date : 0x4B47 => 0100 1011 0100 0111

    7/4/5로 변환하면 0100101 1010 00111 가 되는데 이를 다시 10진수로 변환하면 37년 10월 7일이 된다. 전 포스팅에서 연도를 계산할 때는 기본 1980에 앞에서 구한값을 더하라고 했으므로 최종 값은 2017년 10월 7일이 된다. [그림 4]를 통해 맞는 결과인지 확인하도록 하자.

 - Last Access Date : 0x4B47 => 마지막 접속 날짜는 날짜 변경 이후에 따로 접속한 이력이 없기 때문에 생성 날짜와 동일한 값을 가진다.

 - First Cluster High : 0x00

 - Write Time : 0xB623 => 1011 0110 0010 0011

    5/6/5로 변환하면 10110 110001 00011 이 되는데 이를 다시 10진수로 변환하면 22시 49분 3초가 된다. 위의 Create Time과 마찬가지로 마지막 seconds 값은 2를 곱해줘야 하므로 최종 결과는 22시 49분 6초가 된다. [그림 4]에서 수정한 날짜의 시간을 확인해 보도록 하자.

 - Write Date : 0x4B47 => Create Date와 같은 값이 표기되어 있다.

 - First Cluster Low : 0x00C4 => 다음 포스팅에서 실제로 사용 할 수 있을 것이다.

 - File Size : 0x00000E => 10진수로 변환하면 14Byte가 나온다. [그림 4]에서 크기를 확인해 보도록 하자.


위에서는 Short Directory Entry에 대해서 알아보았다. 전 포스팅의 복습이 되었길 바라며 이제 이번 포스팅에서 다루었던 Long Directory Entry 내용을 확인 해 보도록 하자.

먼저 32Byte 씩 잘라서 총 몇개의 Long File Name Entry가 있는지 확인해보자.

[그림 5. 예제 파일의 Long File Name Entry 종류]

조금 그림자체가 복잡하게 되어있지만 [그림 5]는 에제 파일의 Long Directory Entry 내에 Long File Name Entry를 하나하나 나눈 것이다. Long File Name Entry의 수를 세는것은 생각보다 간단하다. Short Directory Entry에서 LFNs 타입을 확인 한 후 해당 디렉터리 엔트리 위로 32Byte씩 잘라가면서 가장 앞 바이트 값을 확인하면 된다.(마지막 엔트리가 0x01, 0x02 등이 아닌 0x41~ 0x60 사이의 값이 오면 마지막 엔트리가 된다.)

앞서 위의 표에서 봤던 내용을 토대로 Long File Name Entry 값을 확인해 보도록 하자.(내용이 길어지는 관계로 본 포스팅에서는 1번 Long Directory Entry만 함께하도록 하겠다. 이후 내용은 스스로 실습 해 보도록 하자)

 - Order : 0x01 => 첫번째 Long Directory Entry

 - Name1 : T.i.m.e. . => Time 과 스페이스(0x20)이 해당 Name1에 포함된 이름 값으로 되어있다.

 - Attribute : 0x0F => 이 값은 반드시 고정되어야 한다.

 - Type : 0x00 => LFNs의 항목중 하나

 - Check Sum : 0xA3 => 계산법은 추후에 따로 설명하도록 한다.

 - Name2 : A.n.d. .R.e. => And와 스페이스(0x20), 그리고 Re가 Name2에 포함되어 있다.

 - First Cluster Low : 0x00

 - Name3 : l.a. => la가 name3에 포함되어 있다.

위 내용으로 봤을 때 첫번째 Long Directory Entry에 포함된 파일의 이름은 Time And Rela가 된다. 이후 나머지 Long Directory Entry값은 독자분들이 실습을 통해 확인해 보기 바란다. 파일명은 [그림 4]에 나와있으니 최종 결과는 그곳에서 확인하면 되겠다.

생각보다 짧게 끝날것으로 예상했던 포스트였는데 실습이 포함되면서 생각보다 길어진 감이 있다. 이해가 잘 안될수도 있고, 이론만으로 진행하다보니 학습에 지루함이 있을 수 있다. 실제 업무에 들어가서는 이렇게 Hex Editor를 사용하는 일보다는 Encase나 FTK Editor를 이용하는 일이 더 많을 것이다.(필자로 실제로 실무를 하지 않아서 확신할 수는 없지만..) 그러나 이렇게 이론을 알아가는 것이 실제 업무를 하는데 상당한 도움이 될 것이니 소홀히 하지 말기 바란다.

다음 포스팅에서는 FAT32 의 마지막 단계인 Data Area에 대해 기술하도록 하겠다.


* 참고 : 임베디드 개발자를 위한 파일시스템의 원리와 실습(정준석, 정용원 공저), 한빛미디어

Posted by Latte_
,

* 들어가기에 앞서 본 스터디에 사용 된 OS 종류 및 VMware 종류에 대해 기술하고 시작하고자 한다. 다른 버전이어도 상관은 없으나, 사용 상 불편한 부분까지 본 블로그에서 일일히 다루어 주지는 않는다. 물론, 질문을 남겨줄 경우, 따로 확인해서 답변을 드리긴 하겠다.

  - 필자 E-Mail : wotmd9408@naver.com

  - 가상머신 : VMWare WorkStation 12

  - OS : Window7 Enterprise K 64bit

  - RAM : 1GB

  - 나머지 사항은 기본적인 세팅으로 설정하였다.

  - 추가 필요 Tool : Hxd(https://mh-nexus.de/en/downloads.php?product=HxD)


우리는 MBR을 시작으로 FAT32 구조의 순서대로 정리를 진행하고 있다. 앞에서도 지겹게 설명한 내용이지만 이 블로그의 내용일 본 포스팅부터 접한 독자도 있을테고 혹은 기억하지 못한 독자도 있을테니 한번 더 확인하고 넘어가도록 하자.


[그림 1. FAT32 구조]

우리는 지난 포스팅을 통해 FAT 영역에 대해 알아보았다. 이제 오늘 포스팅을 통해 알아 볼 영역은 Root Directory Entry이다. 먼저 Root Directory Entry의 모습을 그림을 통해 보도록 하자.


[그림 2. Root Directory Entry 구조]

[그림 2]는 Root Directory Entry의 구조를 보여주고 있다. 앞에서 보던 FAT 또는 BR 구조와는 다르게 이 Root Directory Entry에서는 우리가 확실히 구분할 수 있는 것들이 보인다. 바로 KOALA JPG와 같은 파일을 의미하는 것 같은 내용들이다. 이를 통해 우리는 Root Directory Entry가 어떤 역할을 하는지 유추 할 수 있을 것 같다.

Rood Directory Entry는 위에서 보는것과 같이 볼륨에 존재하는 파일과 디렉터리의 정보를 가지고 있는 영역이다. 데이터 영역의 가장 앞 섹터에 존재하는 영역으로 데이터 영역과 함께 설명해도 전혀 상관없는 영역이지만, 포스팅의 글이 너무 길어 질 경우 가독성이 떨어져 제대로 보지 않게 되어 나누어 설명하고자 한다.(현재까지는 정상적인 실습을 진행하지 않고 이론적으로 설명만 했는데, 데이터 영역부터는 어느정도 실습이 포함되며, File System 에 대한 전반적인 설명이 끝난후에는 여러분이 실습을 해 볼 수 있도록 어느정도 실습 문제 또는 파일도 제공하려고 하니 참고하기 바란다.)


본격적으로 Root Directory Entry에 들어가기 전에 독자 여러분들이 제대로 해당 영역까지 찾아 갈 수 있는지 확인해 보도록 하자. [그림 2]에 Root Directory Entry의 섹터 위치가 나와있긴 하지만, 이 포스팅을 보는 독자들은 양심적으로 안 보고 계산 할 수 있을 거라 본다. 계산이 되었는가? 혹시 기억이 나지 않는다면, 과거 포스팅들을 보는 방법도 있을 것이지만, 시간을 단축하기 위해서 계산에 참고 할 수 있는 내용을 아래에 적어 드릴테니 기억을 더듬어 보도록 한다.

  - BR 영역의 위치

  - 예약된 영역(Reserved Area)의 크기

  - FAT32 의 수

  - FAT32 영역이 가지고 있는 크기


위의 내용으로 계산이 되었는가? 정확히 Root Directory Entry에 도달했다면 정상적으로 계산을 잘 한것이다. 만약 제대로 도달하지 못했다면 기본 세팅에서 잘못 세팅했거나, 어딘가에서 잘못 계산했을 가능성이 있으니 다시 한번 신중하게 계산 해 보기 바란다.


[그림 3. Root Directory Entry 출력 화면]

앞서 여러분이 봤던 [그림 2]와는 거의 비슷한 내용의 출력화면이다. 달라진게 있다면 확장자가 없는 무언가가 추가 된 것이다. Root Directroy Entry는 Directory Entry라 불리는 구조치들의 집합이며 그들의 가장 상위에 있는 엔트리이다. 데이터 영역에는 두가지 형태의 구조체가 저장되는데 그것이 우리가 알고있는 디렉터리와 파일이다.  파일은 말 그대로 해당 파일의 정보를 가지고 있으며, 디렉터리의 경우 자신의 정보와 하위 디렉터리 및 파일의 정보를 가지고 있다.


[그림 3]의 경우 Root Directory Entry에 들어있는 출력 형태 중 많이 볼 수 있는 내용을 약 3가지로 구분해서 표시한 내용이다. 각각의 파일 혹은 디렉터리는 디렉터리 엔트리에서 32Byte 단위로 표기되며, 이로 인해 한 섹터당 16개의 디렉터리 엔트리를 담을 수 있다. 

가장 먼저 빨강색 테두리 부분을 보도록 하자. 굉장히 눈에 익숙한 모습이다. 여러분이 예상 하듯이 저 빨강색 테두리는 파일 형태의 디렉터리 엔트리이다. 앞쪽에 파일명과 확장자 명이 보이며, 나머지 모양은 아직 해석하기 어려운 내용들로 구성되어 있다. 그다음으로 아래쪽의 파란색 테두리를 먼저 보도록 하자. 저 파랑색 테두리는 빨강색 테두리와는 다르게 확장자가 표시되지 않았다. 즉, 저런 형태로 되어있다면 디렉터리라는 표시이다.(물론 32Byte 중 디렉터리와 파일을 구분할 수 있도록 따로 입력되어있다)마지막으로 가운데 갈색 테두리 역시 디렉터리이다. 다만 파란색 테두리와는 다르게 ~1로 표기되어 있는데, 이는 뒤에서 설명할 Long File Names로 표기 할 수 있는 이름보다 길게 파일 혹은 폴더명이 생성 될 경우 저런식으로 표기된다.


이제 각각의 디렉터리 엔트리를 표기하는 32Byte의 상세 내역을 확인 해 보도록 하자.

이름

 Name

offset

 0~7

Size

8 Byte 

 Value

파일 명

설명 

파일 또는 디렉터리의 이름이 기록되는 항목. 최대 8자리까지 작성 할 수 있으며 반드시 대문자로 기록된다. 만일 8자리 이하의 이름이 들어갈 경우 빈자리는 반드시 0x20으로 채워야 한다. 우리는 일반적으로 채우는 null(0x00)으로 채울 경우 에러가 발생한다.

  * Name의 경우 첫번째 바이트에 오는 내용에 따라 특별한 의미를 가지고 있는 경우가 있는데 이는 아래를 참고하도록 하자.

Name[0]의 값

설명

0xE5 

이 문자열이 파일명의 맨 앞에 위치 할 경우, 해당 디렉터리 엔트리의 파일은 삭제 된 파일이라는 의미이다. FAT 파일 시스템에서는 파일 혹은 디렉터리를 삭제 할 경우 엔트리를 완전히 초기화 하는 것이 아니라 파일명의 맨 앞 바이트를 0xE5로 바꾸어 저장한다. 이로 인해 삭제 하더라도 파일의 복구가 가능하다.

 0x00

해당 디렉터리 엔트리는 비어있으며 이전까지 탐색한 디렉터리 엔트리가 가장 마지막 리스트임을 의미한다. 실제로 해당 내용이 나올 경우 뒤에 나오는 모든 값이 0x00으로 표기되어 있음을 확인할 수 있다. 분석 간 이 문구를 만난다면, 더이상 아래를 분석 할 필요가 없다.

0x05

이 바이트에 대한 실제 파일 이름 문자는 0xE5이다. 일본어로 파일을 만들경우 문제가 하나 발생하는데, 일본 문자(간지)의 집합 선두 바이트도 0xE5로 표기된다. 이로 인해 일본어로 파일명을 만들면 전부 삭제된 데이터로 인식되어 버리게 되어, 이에 대한 편법으로 0x05로 적고 있다. 

 * 여기서 주의할 점이 하나 있다면 파일명의 첫번째 바이트에는 0x20(스페이스)이 올 수 없다. 또한 0x05를 제외하고는 0x20보다 작은 값이 올 수 없다.

이름

 Extender

offset

 8~10

Size

3 Byte 

 Value

확장자

설명 

파일의 확장자를 넣는 항목이다. 최대 3자리까지 입력 가능하며 반드시 대문자로 입력해야 한다. 만약 3자리 이하의 확장자(ex : sh 등등)라면 남는 공간은 반드시 0x20으로 채워야 한다. 파일이 아닌 디렉터리의 경우 확장자가 없기 때문에 반드시 0x20으로 채워 넣어야 한다.


이름

 Attribute

offset

 11

Size

1 Byte 

 Value

아래 참조

설명 

해당 Directory Entry의 용도를 결정하는 값이다. 해당 Directory Entry가 파일인지 폴더인지 결정되는 부분이 바로 이 부분이다. 각각의 항목들에 대해서는 아래 표를 참고하도록 하자.



속성 값

 속성 Name

설명

0x01

Read Only

읽기 전용 파일. 이 속성이 걸려있는 파일은 쓰기를 막도록 코드를 작성해야 함.

0x02

Hidden

숨김 파일. 보통의 사용자에게 해당파일을 보여주지 않음. 

0x04 

System

운영체제(System)이 사용하는 파일

0x08

Value Label

이 파일의 이름이 곧 볼륨의 이름이 된다. 이 속성은 반드시 Root에 있어야 하며 1개만 존재한다. 이 속성의 파일은 ClusterHigh와 ClusterLow가 0x00으로 만들어진다. (클러스터를 할당 할 필요가 없음) 

0x10

Directory

서브 디렉터리를 의미(우리가 일반적으로 말하는 디렉터리를 의미한다) 

0x20

Archive

일반으로 말하는 파일을 의미한다. 

0x0F

Long FIle 

name Entry

파일명, 또는 확장자의 이름이 제한보다 길어 Long File Name Entry로 사용한다.


이름

 NT Resource

offset

 12

Size

1 Byte 

 Value

0x00

설명 

NT 계열의 Windows 운영체제가 사용하기 위해 예약해 놓은 공간. 항상 0으로 해야 한다.


이름

 Create Time Tenth

offset

 13

Size

1 Byte 

 Value

0 ~ 199

설명 

파일이 생성 된 시각을 1/10초 단위로 기록한 항목으로 Create Time과 관련 이 있다.


이름

 Create Time

offset

 14~15

Size

2 Byte 

 Value

가변적

설명 

파일 생성 시간을 표현하는 영역으로, 자세한 내용은 아래 설명을 참고하도록 하자.

 * Create Time은 뒤에서 나오는 다른 시간 관련 설정과 마찬가지로 2Byte 안에 정보를 담아야 한다. 그래서 Create Time 이나 Access Time 등 시간 정보를 정할 때는 해당 Hex 값을 이진수로 바꾸어 계산해야 한다. [그림 3]에 있는 KOALA.JPG 파일을 기준으로 설명해보도록 하겠다. 

[그림 4. koala.jpg 파일의 Create Time 값]

[그림 4]에서 드래그 한 부분은 koala.jpg 파일을 표기하는 32Byte를 보이는 부분이며 붉은색 네모 [38 1B] 가 바로 우리가 지금 확인 할 Create Time 부분이다. 앞서 우리가 사용하는 Intel 기반에서는 리틀엔디언 표기법을 사용한다고 설명했다. 즉 [38 1B]를 우리가 표기할 때는 0x1B38로 확인 후 계산해야 한다. 이 값을 이진수로 변환할 때 바이트 단위로 변환하는게 아닌 값 하나 하나를 변환 해야한다. 다시 말해 1B, 38를 이진수로 변화하는게 아닌 1, b, 3, 8를 각각 이진수로 변환해야 한다는 의미이다. 

각각을 이진수로 변환하면 0001 1011 0011 1000이 된다. 이를 순서그대로 다시 합친 뒤 5bit, 6 bit, 5bit 크기로 자른다. 이 설명대로 실행 하면 00011 011001 11000 가 된다. 각각의 bit 의미는 아래 표를 참고하도록 하자. 

[그림 5. Create Time 항목 구조]

[그림 5]처럼 항목별로 구분했다면, 이제는 각각의 파트를 우리가 알아볼 수 있는 10진수로 다시 변환하면 된다. 이번 koala.jpg의 경우 03시 25분 24초가 된다. 그런데 여기서 한가지 문제가 있는데 5bit의 이진수 표기는 최대 31까지(실제로는 29)만 표기된다는 문제가 있다. 현실세계에서 Seconds(초)는 60초로 표기되기 때문에 Seconds를 계산한 값에 2를 곱해줘야 한다. 즉, 3시 25분 48초가 된다. 지금은 필자의 파일로 테스트를 했지만, 독자분들도 한번 테스트 해보면서 맞는지 확인해보도록 한다. 실제로 필자가 확인 한 파일 생성 시각은 아래 그림과 같았다.

[그림 6. koala.jpg 파일의 생성 시각 확인]

여러분도 과정을 정확히 따라왔다면 정확하게 계산됨을 알 수 있다. 또한 초를 계산할 떄 2가 곱해지기 때문에 짝수로만 표기되게 된다. 해당 계산은 모든 시각에 동일하게 사용되기 때문에 잘 기억하기 바란다. 따라서 시각에 대한 유효 범위는 00:00:00 ~ 23:59:58이 된다.

이름

 Create Date

offset

 16~17

Size

2 Byte 

 Value

가변적

설명 

파일의 생성 날짜를 표시한다.

  * Create Date 역시 Create Time과 비슷하게 2바이트 파일에 날짜 정보를 모두 표기해야한다. 따라서 이 부분도 실제 날짜를 10진수로 확인하기 위해서는 Hex 값을 이진수로 바꾼 뒤 다시 10진수로 변환해야 한다. 이번에도 동일하게 Koala.jpg 파일을 예시로 들어보도록 하겠다.


[그림 7. koala.jpg 파일의 Create Date]

방식은 Create Time을 계산할 때와 비슷하다. [3B 4B] 값을 리틀엔디언으로 표기하면 0x4B3B가 되며, 이를 이진수로 변환하면 0100 1011 0011 1011이 된다. 이를 순서대로 나열한 뒤 이번에는 7bit, 4bit, 5bit로 나누도록 한다. 이대로 실행하면 0100101 1001 11011 가 된다. 각각의 의미는 아래 표를 참고하도록 하자.


[그림 8. Create Date 항목 구조]

[그림 8]을 기준으로 각각의 항목을 10진수로 변환하면 37년 9월 27이 된다. 무언가 이상하지 않은가? 현재 우리가 살고있는 년도는 서기 2017년이다. 앞의 두자리는 빼더라도 뒤의 두자리도 맞지 않는다. 왜 그럴까? 위에서 우리가 Create Time를 계산 할 때 초 단위를 계산하던 것을 생각하면 비슷하다. [그림 8]에서 알 수 있듯이 년도는 총 7bit의 이진수로 구성 되는데, 이 범위는 0 ~ 127까지의 범위만을 표기 할 수 있다. 따라서 FAT32 파일시스템에서는 기준년도 1980년을 기준으로 오프셋을 계산하여 나타낸다. 즉, 이를 기준으로 다시 계산하면 2017(1980 + 37)년 9월 27이 된다. 맞는지 확인해 보도록 하자. 

[그림 6]으로 돌아가서 확인하면 우리가 계산한 값이 맞게 나오는 것을 알 수 있다. 위 계산은 시간 계산할 때와 마찬가지로 모든 날짜(Last Access Date, Write Date)를 표기할 때도 동일하게 적용된다.


이름

 Last Access Date

offset

 18~19

Size

2 Byte 

 Value

가변적

설명 

이 항목은 파일의 읽기/쓰기 작업을 했던 마지막 날짜를 기록한다. 파일 생성과는 다르게 Time은 없이 Date만 표기함을 기억하라. 만약 마지막 작업이 쓰기였다면 이 항목의 값과 Write Date의 값이 동일해야 한다. 10진수로 표현하기 위해서는 Create Date와 동일하게 계산하면 된다.


이름

 First Cluster High

offset

 20~21

Size

2 Byte 

 Value

가변적

설명 

이 항목은 파일의 첫번째 클러스터 번호의 상위 2Byte를 담고 있다. FAT16의 경우 클러스터 번호가 2Byte로 이루어져 있어 이 항목이 필요없다. 지금 공부하는 FAT32 에서는 보통 0x0000으로 기록된다. (value를 가변적이라고 적었지만 아직까지 0 이외의 값을 본적은 없다.)


이름

 Write Time

offset

 22~23

Size

2 Byte 

 Value

가변적

설명 

가장 최근에 이 파일을 수정한 시간을 표시한다. 만일 이 파일이 생성되고 단 한번도 수정되지 않았다면 최초 생성시간으로 기입하기도 한다. 10진수로 표현하기 위해서는 Create Time과 동일하게 계산하면 된다.


이름

 Write Date

offset

 24~25

Size

2 Byte 

 Value

가변적

설명 

가장 최근에 이 파일을 수정한 날짜를 표시한다. 만일 파일이 생성되고 단 한번도 수정되지 않았다면 최초 생성날짜로 기입하기도 한다. 10진수로 표현하기 위해서는 Create Date와 동일하게 계산하면 된다.


이름

 First Cluster Low

offset

 26~27

Size

2 Byte 

 Value

가변적

설명 

이 항목은 파일의  첫번째 클러스터 번호의 하위 2Byte를 담고 있다. FAT16의 경우 클러스터 번호가 2Byte로 이루어져 있기 때문에 이 항목만으로도 확인이 가능하다. 지금 공부하는 FAT32의 경우 파일이 가지는 클러스터의 가장 앞 번호를 표기하도록 되어있다.


이름

 File Size

offset

 28~31

Size

4 Byte 

 Value

가변적

설명 

이 항목은 파일의 크기를 나타낸다. FAT32를 공부하는 동안 유일하게 실제 용량을 나타내는 부분이다. MBR이나 BR영역에서 용량을 계산하려면 사용하는 Sector 양을 확인한 뒤 512를 곱해 계산해야 하지만 이 부분은 따로 추가적인 계산없이 Hex 값을 10진수로 바꾸면 바로 파일의 용량이 나온다. 만약 해당 영역이 디렉터리라면 반드시 0으로 표기되어야 한다.


지금까지 Root Directory Entry에서 표기되는 항목들에 대해 알아보았다. 이후 실습과정에서 실제로 Hex Editor를 통해 파일을 직접 생성해 볼 예정이다. 부디 실습간 유용하게 쓰이기를 빈다. 

그러나 이 포스팅에서 Root Directory Entry에 나오는 모든 항목을 설명하지 않았다. 바로 Long File Names에 대한 내용이다. 이번 포스팅이 좀 내용이 길어져 다음 포스팅에 파일명 등을 정리해 보도록 하겠다.


* 참고 1 : 임베디드 개발자를 위한 파일시스템의 원리와 실습(정준석, 정원용 공저), 한빛미디어

* 참고 2 : http://hyd3.tistory.com/125


Posted by Latte_
,

* 들어가기에 앞서 본 스터디에 사용 된 OS 종류 및 VMware 종류에 대해 기술하고 시작하고자 한다. 다른 버전이어도 상관은 없으나, 사용 상 불편한 부분까지 본 블로그에서 일일히 다루어 주지는 않는다. 물론, 질문을 남겨줄 경우, 따로 확인해서 답변을 드리긴 하겠다.

  - 필자 E-Mail : wotmd9408@naver.com

  - 가상머신 : VMWare WorkStation 12

  - OS : Window7 Enterprise K 64bit

  - RAM : 1GB

  - 나머지 사항은 기본적인 세팅으로 설정하였다.

  - 추가 필요 Tool : Hxd(https://mh-nexus.de/en/downloads.php?product=HxD)


지난 포스팅에 이어 이번에는 FAT 영역에 대해 정리해 보도록 하겠다. 먼저 앞서 설명했던 FAT32의 구조에 대해서 기억하는지 살펴보자.


[그림 1. FAT32 구조]

[그림 1]은 FAT32#1 포스팅에서 보았을 것이다. FAT32 볼륨 가장 앞에는 Boot Record가 오며, 그 뒤를 이어 예약영역, FAT 영역, 데이터 영역 등으로 이루어져 있다. Boot Record는 앞선 포스팅에서 설명을 했고, 이번에 설명할 영역은 FAT #1과 #2로 이루어진 FAT 영역에 대해서 설명하고자 한다.


위 구조대로라면 우리가 원하는 FAT 영역으로 가기위해서는 Boot Record와 예약영역을 지나야 갈 수 있다. 앞에 내용을 복습하기 위해, MBR부터 FAT#1까지 가기위한 계산을 수행해 보도록 하자.

[그림 2. MBR 영역 구조]

가장 먼저 볼륨의 Boot Record의 위치부터 확인해야 한다. BR 영역의 시작을 가르키는 Start LBA Address는 파티션 테이블 영역의 시작에서 8번째 offset ~ 11번쨰 offset에 위치하고 있으며, [그림 2]에서는 0x80 (Dec = 128)을 기록하고 있다. 이를 따라 128번 Sector로 가면 우리가 찾던 BR 영역이 존재함을 확인 할 수 있다. 


[그림 3. Boot Record 영역]

[그림 3]은 바로 지난 포스팅에 설명했던 Boot Record 영역이다. BR영역의 전체적인 구성이나 세부적인 내용은 바로 전 포스팅을 참조하도록 하자. 우리가 이번 포스팅을 통해 공부해야 할 내용은 BR영역이 아니라 FAT 영역이니까 말이다. 

위 FAT 영역의 위치를 잘 모르겠다면 화면을 위로 올려 [그림 1]을 다시 보고 오기 바란다. FAT 영역으로 가기 위해서는 BR영역까지의 섹터와 예약 영역의 섹터 수를 더하면 FAT 영역의 시작 섹터가 나오게 된다. Boot Record에는 예약 영역이 갖는 전체 섹터 수(Reserved Sector Count)를 표기하고 있는데 offset 주소로 000E ~ 000F가 Reserved Sector Count가 된다. 값은 0x2A10으로 기록되어있으나, *리틀엔디언 표기법에 따라 0x102A로 계산하면 4,138이 나온다.

 * 앞서 설명했어야 하나, 미처 설명하지 못해 본 포스팅에서 '리틀 엔디언'에 대해 설명하고자 한다. 엔디언은 쉽게말하면 바이트를 배열하는 순서인데, 큰 단위가 앞에오는 빅 엔디언, 작은 단위가 앞에오는 리틀 엔디언으로 나뉜다. 예를 들어 0x1234를 입력할 경우, 빅 엔디언 기반의 구조에서는 12 34로 입력되고 리틀 엔디언 기반에서는 34 12로 기록되는 것이다. 우리가 사용하는 Intel 기반에서는 리틀 엔디언 기반으로 사용하고 있으니 섹터 수를 계산할 때 특히 햇갈리지 않도록 한다. 특별한 경우가 없다면 앞으로는 리틀 엔디언 기반으로 설명할 예정이며 빅 엔디언 기반으로 설명해야 할 경우에는 따로 언급 하도록 한다.

혹시라도 4,138 섹터로 간 독자가 있는가? 혹시 가봤다면 어떤 결과가 나오는가? 필자랑 동일하게 앞의 과정부터 수행했다면, 나오지 않아야 정상이다. Reserved Area는 말 그대로 시스템에서 나중에 사용하기 위해 '예약한' 영역이기 때문이다. 


[그림 4. FAT Area]

[그림 4]는 [그림 1]에서 FAT#1에 해당하는 영역이다. 우리가 예전에 봐왔던 MBR이나 BR과는 사뭇 다르게 굉장히 심플하게 구성되어있다. 하지만 저 심플하게 구성된 부분이 파일 시스템에서는 굉장히 중요한 역할을 한다. FAT는 이름 그대로 File Allocation Table로 파일 할당 테이블을 의미한다. 윈도우 기반의 파일시스템(현재 주로 사용하는 FAT32, NTFS)은 파일의 용량을 할당할 때 클러스터 단위로 할당 한다. 

따라서 FAT 영역에는 별다른 구조체가 존재하지 않고 클러스터의 상태값만을 보여주는 모습이다. 아래 구조를 보고 FAT 영역의 내용에 대해 조금 더 자세히 알아보도록 하자.


[그림 5. FAT Area Structure]

[그림 5]는 [그림 4]에서 보인 FAT 영역을 구조화 한 표이다. 위에서 볼 수 있는 것과 같이 하나의 클러스터는 4byte를 가지고 있다. 자세히 보면 클러스터의 시작이 0번이 아닌 2번부터 시작하는 것을 볼 수 있다. 이는 파일시스템이 FAT 영역의 0번과 1번 클러스터를 Media Type 과 Partition Status의 용도로 사용해버렸기 때문이다. 이는 다음 포스팅에서 다룰 Root Directory에서의 파일 생성 / 복구 등에서 꽤나 중요하게 작용하니 반드시 기억하기 바란다. 


별다를게 없어 보이는 이 FAT 영역을 굳이 포스팅을 통해 정리하는 이유는 이 영역이 파일의 생성, 삭제 등에 있어서 매우 중요하기 때문이다. FAT32 파일시스템은 생성 된 파일의 용량을 정할 때 Cluster 단위로 저장한다. 예를 들어, 5kbyte의 파일을 생성한다고 가정하자. 파일은 생성 될 때 아무리 작은 용량의 파일이라도 1개 이상의 클러스터를 할당 받는다. 기억할지 모르겠지만, 여러분은 BR영역에서 클러스터 당 섹터 수에 대해 정의한 내용을 보았다.


[그림 6. Boor Record Structure]

앞의 포스팅으로 돌아가서 관련 내용을 확인하고 와도 좋지만, 시간을 낭비하기 싫은 독자들을 위해 [그림 6]을 통해 BR의 구조를 확인하도록 하자. 0x0D를 보면 'Sector Per Cluster' 라는 영역을 볼 수 있는데 이 부분이 우리가 이 포스팅에서 중요하게 봐야 할 부분이다. 실제 여러분의 환경에서 'Sector per Cluster'의 값을 보면 '0x08'로 표기되어있는 것을 볼 수 있는데, 아마 여러분이 앞으로 보게 될 거의 모든 FAT32 환경에서는 동일하게 표기되어 있을 것이다. 

FAT32영역에서 'Sector Per Cluster'는 사용자가 임의로 조정하지 않는 한 Defualt 값으로 0x08을 갖는다. 하나의 Sector는 512byte의 값을 갖는데 이를 볼 때 하나의 클러스터는 4Kbyte ( 512Byte * 8 = 4096Byte)의 크기를 갖는 것을 알 수 있다. 다시 위로 올라가서, 5kbyte의 파일을 예를 들면, 1개의 클러스터로는 용량이 부족하기 때문에 2개의 클러스터를 필요로 한다. 아래에서 파일이 있을 떄의 FAT Area의 상태에 대해 자세히 알아 보도록 하자.


[그림 7. 파일이 존재하는 FAT 영역]

[그림 8. VHD 내 존재하는 파일 List]

[그림 7]은 필자의 FAT 영역 내용 중 일부이다.  또한 [그림 8]은 현재 필자의 가상 환경 내 VHD에 존재하는 파일의 List 이다. 각각의 파일은 jpg 파일이 826kbye, txt 파일은 각각의 6자리의 영문을 담고 있는 파일이다. 지금부터 [그림 8]의 파일 List를 기준으로 [그림 7]에 존재하는 내용들을 정리하는 시간을 갖고자 한다.


먼저 [그림 4]로 다시 한번 올라가보자. [그림 4]는 [그림 8]에서 'Desert.jpg'만 존재하지 않는 상태이다. 앞서 [그림 5]에서 우리는 각각의 클러스터의 구조가 어떤식으로 구성되어있는지 확인했다. FAT 영역에서 각각의 클러스터는 파일이나 디렉터리가 저장 된 위치를 Linked List 방식으로 표현하고 있다. 즉, 각각의 FAT Entry는 자신의 다음 Cluster 값을 담고 있다는 의미이다. 즉, 파일이 1개 이상의 클러스터를 가지고 있을 경우 클러스터에는 다음 클러스터의 위치를 갖게 된다는 의미이다.

[그림 7]을 보면 자세히 알 수 있다. 다만 여기서 주의할 게 하나 있다. [그림 7] 의 1번 클러스터를 보면 앞 뒤로 있는 0, 2번 클러스터와는 조금 다른 것을 알 수 있다. 0번은 [F8 FF FF F0], 1번은 [FF FF FF F7] 그리고 2번은 [FF FF FF F0]으로 되어있다. 여기서 0번 클러스터는 [그림 5]에서 설명한것과 같이 시스템이 Media Type으로 사용하고 있다. 

그러면 [그림 7]의 1번 클러스터가 [그림 5]의 Partition status가 되어야 한다. 근데 그렇게 되면 [그림 4]의 내용이 맞지 않게된다. 결론부터 이야기하자면 1번 클러스터는 Bad Cluster로 인식되어 있다. 즉 잘못된 클러스터로 인식되어 사용하지 못해 시스템이 1번 대신 2번 클러스터를 Partition Status으로 설정 한 것으로 보인다. (정황 사정상 그래보이며, 필자도 추가적인 확인을 하게 될 경우 수정하도록 하겠다.) 추가적으로 Bad Cluster의 경우 [FF FF FF F7]로 표기 된다.


이제 실제 데이터 파일이 포함된 3번 Cluster부터 이야기를 해 보도록 하자. 앞서 말했듯이 윈도우 시스템에서는 파일에 용량을 부여할 때 클러스터 단위로 부여하며, 최소 1개 이상의 클러스터를 가진다. 하나의 클러스터는 8개의 섹터를 가진다.(자세한 설명은 필자의 다른 포스팅인 Boot Record 부분을 참고하라. / http://jh8992.tistory.com/entry/FileSystem-Forensics-4-FAT322)


[그림 7]처럼 파일이 하나의 클러스터만 가질 경우 [FF FF FF 0F] 로 표기된다. 이는 해당 클러스터가 파일이 갖는 마지막 클러스터이며 더이상 Link 되는 클러스터가 없음을 의미한다. 그리고 클러스터가 하나 이상의 클러스터를 가질 경우 앞 클러스터의 가장 앞부분에 다음 클러스터의 위치를 담게 된다. [그림 7]을 보면 5번째 클러스터에서 새로운 파일이 시작됨을 알 수 있다. 그리고 그 클러스터 부터 다음 클러스터들을 쭈욱 보면 하나의 공통점을 알 수 있는데 그것은 바로 클러스터의 가장 앞에 다음 클러스터의 번호가 쓰여있으며 나머지는 0으로 채워져 있다는 점이다. 

이는 클러스터가 항상 연결된 Link를 갖지 않기 때문이다. 완전히 포멧된 깨끗한 파일 시스템의 경우 FAT 영역이 꺠끗하기 때문에 순서대로 채워지겠지만 파일이 생성되고 지워짐을 반복함에 따라 모든 클러스터가 순서를 유지할 수 없게 된다. 이러한 경우를 대비해서 모든 클러스터는 자신의 위에 다른 클러스터가 연결 될 경우 다음 클러스터를 명시하도록 되어있다. 물론 파일의 용량이 작아 단일 클러스터만 가지고 있거나 더이상 연결될 클러스터가 없는 마지막 클러스터일 경우 [FF FF FF 0F] 값을 가지게 된다.


어떻게 보면 앞에서 설명한 Boot Record 부분보다는 단순한 구조를 가지고 있는 영역임에도 상당히 길게 서술된 느낌이 있다. 그림이 많이 포함됐거나 하는 여러 이유등이 있을 수 있지만 가장 큰 이유는 이후 포스팅 할 파일 수동 생성 부분에서 이 FAT 영역이 상당히 중요하기 때문이다. Root Directory 영역에 대해 공부하거나, Data 영역에 파일을 수동으로 생성 할 때 다른 곳을 모두 정상적으로 적용했다고 하더라도 FAT 영역의 클러스터가 맞지 않으면 정상적으로 파일이 열리지 않기 때문이다.

그렇기 때문에 상당히 단순한 구조임에도 확실하게 알고 갈 필요가 있다. 여러분이 공부하는데 이 포스팅이 쉽게 이해되길 빌어본다.


* 참고 : 임베디드 개발자를 위한 파일시스템의 원리와 실습(정준석, 정원용 공저), 한빛미디어

Posted by Latte_
,