OLE File Format Structure

OLE File Format?

OLE File Format은 MS 오피스인 워드, 엑셀, 파워포인트의 문서 포맷으로 사용되어 왔다. OLE File Format은 내부가 하나의 작은 하드 디스크와 같은 파일 시스템 구조를 가진다. 따라서 OLE File 내부에는 폴더 및 파일과 비슷한 개념으로 Storage와 Stream이 있다.

 

OLE File Format Structure

OLE File Structure

OLE File은 크게 Header Block 과 Data Block 2개의 블록으로 나뉜다. Header Block은 512Byte의 크기를 가지고 그 이후에 Data Block은 512Byte 이상의 크기를 가지게 된다.

image

Header Block은 OLE 파일 전체의 주요 정보들을 가지고 있으며, Data Block은 크게 아래의 정보들을 가지고 있다.

  • FAT : Sector Index Chain Information
  • Mini FAT : MiniSector Chain Information in MiniStream
  • Double Indirect FAT(DIFAT) : FAT Sector Location
  • Directory Sector : Include Directory Data
  • Stream Sector : Include File Data

이 중에서 Data Block의 대부분은 Stream Sector가 차지하고 있다.

OLE Block Structure

OLE Header Block은 OLE File을 512Byte 씩 나누어 번호를 지정한다. 이 때 맨 처음 Block의 번호는 0이 아닌 -1임을 기억해야 한다.

image

-1 Block이 Header Block이며, 0, 1, 2, ..., n Block이 Data Block이다.

OLE File Format

image

OLE 구조를 가진 파일을 HxD로 열었다.

 

512byte는 Header Block 인데 OLE 파일을 구조적으로 나누어 번호를 매긴다고 앞에서 설명한적이 있다. 하지만 번호를 매길 이유가 없을 때(데이터가 없을 때?)는 FF라는 값으로 채워지는 것 같다.

image

각각의 데이터의 의미는 아래의 표와 같다.

  offset Length(byte) Description
File Header Signature 0x00 8 OLE File Signature D0 CF 11 E0 A1 B1 1A E1
Header CISID 0x08 8 Reserved Class, set 0x00
Minor Version 0x18 2 Version Number for Summary Change
In case major value 0x0003, 0x0004, minor value is 0x003E
Major Version 0x1A 2 Version Number for Changes
each case 0x0003(ver.3) or 0x0004(ver.4)
Byte Order Identifier 0x1C 2 Byte ordering
Little-Endian = LE FE FF
Big-Endian = BE FF FE
Sector Shift 0x1E 2 Size of Sector
each case Major ver.3, Sector Shift value is 9
or Major ver.4, Sector Shift value is C
ex.) Sector Size 2^9=512 / 2^13 = 4096
Mini Sector Shift 0x20 2 Mini Sector Size
Default set 6
Default Sector Size = 2^64
Reserved Area 022 6 set 00
Number of Directory Sector 0x28 4 Number of Directory Sector
In case Major = 3, value is 0
Number of FAT Sector 0x2C 4 Number of FAT Sector
SEC ID 0x30 4 Number of First Directory
Transaction Signature Number 0x34 4 Increases Number when File saved specific API
If not File is transaction, value = 0
Mini Stream Cutoff Size 0x38 4 set 0xD0001000
Mini FAT Location 0x3C 4 Mini FAT Location
Number of Mini FAT 0x40 4 Number of Mini FAT
First DIFAT Sector Location 0x44 4 First DIFAT Sector Location
Means current location here
Number of DIFAT Sector 0x48 4 Number of DIFAT Sector
FAT #n Location 0x4C ~ 0x1F0 4 ~ 1A4 FAT #n Location
Each FAT allocate 4byte
If FAT end, set FF (In case Major ver.4 set 00)

위의 표와 비교해 주요 정보를 확인해 보면 아래와 같다.

  • 섹터의 크기 = 09 00 = 2^9 = 512byte
  • Mini Sector 크기 = 06 00 = 2^6 = 64byte
  • Mini FAT 개수 = 01 00 00 00 = 1개
  • FAT 위치 값 = 03 00 00 00, FAT 위치 = 3 + 1 = 4sector
  • Root Directory 위치 값= 03 00 00 00, Root Directory 위치 = 3 + 1 = 4sector
  • 첫번째 Mini FAT 위치 값= 06 00 00 00 = 6sector, 첫번째 Mini FAT 위치 = 6 + 1 = 7sector

Mini FAT의 위치를 찾아가 봅시다. 위치는 512*7=3584=E00 입니다.

image

실제로 FAT 구조를 가지고 있는 것을 확인할 수 있습니다.

그 다음은 Root Directory를 살펴볼까요.

Root Directory의 위치는 512*3 = 1536 = 0x600입니다.

image

해당 구조를 자세히 보면

image

이런 구조를 가지고 있습니다. 해당 구조에 대한 설명은 아래 표를 참조하시면 될 것 같습니다.

  Offset Length(byte) Description
Directory Entry Name 0x00 64 Null 문자로 끝이 나야 한다.
/ \ : ! 의 문자는 사용할 수 없다.
Directory Entry Name Length 0x40 2 DIrectory Entry Name 문자열의 길이와 일치해야하한다.
null도 길이에 포함해서 계산을 해야하고 64를 초과하면 안된다.
Object Type 0x42 1 파일의 유형에 따라서 값이 달라진다.
Unknown or Unallocated = 0x00
Storage Object = 0x01
Stream Object = 0x02
Root Storage Object = 0x05
Color Flag 0x43 1 0x00 과 0x01 밖에 올 수 없다. 또한 Root의 경우에는 0x01이다.
Red = 0x00, Black = 0x01
Left Sibling ID 0x44 4 왼쪽 스트림 아이디를 포함한다.
값이 없으면 0xFFFFFFFF
Right Sibling ID 0x48 4 오른쪽 스트림 아이디를 포함한다.
값이 없으면 0xFFFFFFFF
Child ID 0x4C 4 하위 스트림 아이디를 포함
값이 없으면 0xFFFFFFFF
CLSID 0x50 16 저장소, 루트 저장소의 경우 개체 클래스 GUID가 포함된다. 스트림에서는 모두 0이다.
State Bits 0x60 4 사용자 정의 플래그
Creation Time 0x64 8 생성시간, Root에는 0이라는 값이 저장된다.
Modified Time 0x6C 8 수정시간, UTC 시간으로 저장
Starting Sector Location 0x74 4 Root Storage : 미니스트림의 첫 번재 섹터
Mini FAT : 데이터가 존재하는 곳의 첫 번째 섹터
Stream Size 0x78 8 값이 4096보다 크거나 같으면 FAT 이고 4096보다 작으면 Mini FAT이다.

Reference

https://whitesnake1004.tistory.com/584 - 점프리스트 포렌식

http://www.forensic-artifact.com/windows-forensics/jumplist - 내가 공부할 리스트

http://www.hanul93.com/ole-fileformat-bbat/ - 음...?

https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-cfb/5af03a5e-66dc-469c-8970-7229a11e2a3f - Microsoft 문서

Shellbags (Windows10)

Shellbag이란?

1-1. 정의

Shellbags란 User Registry Hive 파일 (ntuser.dat/usrclass.dat) 의 ShellBag의 하위키이며 사용자가 로컬, 네트워크 및 이동식 저장장치에서 접근한 폴더 정보가 기록되며 최초로 폴더를 열람시에 생성이 된다. 또한 폴더의 생성, 복사, 압축 프로그램에 의해서 실행되었을 경우에도 생성된다.

 

NTUSER.DAT는 데스크톱, Windows 네트워크 폴더, 원격 컴퓨터 및 원격 폴더에 대한 ShellBags 정보를 저장한다.

 

UsrClass.dat는 데스크톱, ZIP파일, 원격 폴더, 로컬 폴더, Windows 특수 폴더 및 가상 폴더에 대한 ShellBags 정보를 저장한다.

1-2. 포렌식적 의미

​ 가. 사용자가 특정 폴더에 접근한 시간 정보 확인

​ 나. 존재하는 폴더의 삭제/덮어쓰기에 대한 증거 추적

​ 다. Explorer를 통한 폴더 접근에 대한 MAC 타임 추적

1-3. Shellbag & 부가정보

​ 가. 쉘백 정보는 Bags와 BagMRU 두 가지 주요 레지스트리 키로 구성되어 있다.

​ 나. BagMRU 키는 유사한 트리 구조를 생성하여 폴더 이름과 레코드 폴더 경로를 저장한다.

​ 다. Bags 키는 창 크기, 위치 및 보기 모드와 같은 보기 기본 설정을 저장한다.

레지스트리 주요경로 (Windows10)

번호 레지스트리 경로
1 HKEY_CURRENT_USER\Software\Classes\Local Settings\Software\Microsoft\Windows\Shell\Bags
2 HKEY_CURRENT_USER\Software\Classes\Local Settings\Software\Microsoft\Windows\Shell\BagMRU
3 HKEY_CURRENT_USER\Microsoft\Windows\Shell\Bags
4 HKEY_CURRENT_USER\Microsoft\Windows\Shell\BagMRU

1. HKEY_CURRENT_USER\Software\Classes\Local Settings\Software\Microsoft\Windows\Shell\Bags

image

2. HKEY_CURRENT_USER\Software\Classes\Local Settings\Software\Microsoft\Windows\Shell\BagMRU

image

3. HKEY_CURRENT_USER\Microsoft\Windows\Shell\Bags

image

4. HKEY_CURRENT_USER\Microsoft\Windows\Shell\BagMRU

image

Windows10 Shellbag 분석

1-1. HKEY_CURRENT_USER\Microsoft\Windows\Shell\BagMRU

image

위의 구조의 BagMRU는 하위키로 의미있는 값도 가지고 있지 않다. 특히, 해당 컴퓨터를 계속해서 사용해도 위의 경로의 레지스트리 값은 더 이상 변경되지 않는다.

 

BagMRU의 키들은 MRUListEx, NodeSlot, NodeSlots의 키를 가지고 있다. 각각의 의미는 아래와 같다.

  1. MRUListEx : 최근에 열었었던 파일들을 나열 하는 레지스트리 키로 앞에부터 순서대로 가장 마지막에 열었던 폴더를 의미한다. 해당 키에 들어있는 값은 NodeSlot의 값을 가지게 된다.
  2. NodeSlot : Bags의 하위키의 이름을 가지고 있다.
  3. NodeSlots : 2의 고정값을 가진다.

하지만 이 경로에 MRUListEx는 ff ff ff ff인데 그 이유는 이 경로의 MRUListEx는 그저 하위키이며, 해당 경로에는 데이터가 작성되지 않기 때문이다.

1-2. HKEY_CURRENT_USER\Microsoft\Windows\Shell\Bags\1\Desktop

image

Bags 레지스트리 키는 창의 크기, 위치 및 보기 모드 같은 기본 설정을 저장하고 있기 때문에 Desktop 폴더에 사용한 설정 정보를 가지고 있다.

2-1. HKCU\Software\Classes\Local Settings\Software\Microsoft\Windows\Shell\BagMRU

image

앞에서 본 BagMRU와 달리 하위키들이 존재한다. BagMRU의 구조는 아래와 같다.

image

나는 대충 이런 구조로 이해했는데 틀렸다면 댓글을 달아주시길....(제발 진짜 아무나...)

 

BagMRU는 Desktop(바탕화면)을 의미하며 그 외의 키는 상위키에서 각 키를 더블클릭 해보면 어떤 폴더인지 알 수 있다.

image

새로운 폴더를 만들어 키값을 확인했다. 가장 최근에 생긴 폴더이므로 가장 높은 숫자 번호를 가지고 있을것이고 6번이 가장 높은 키값이라서 열자 c0wb3ll폴더라는 것을 알 수 있었다.

 

image

또한 앞서 말했듯이 MRUListEx 또한 06이 가장 맨 앞으로 온 것 또한 확인할 수 있었다.

 

그리고 ComDlg 또는 ComDlgLegacy라는 키가 존재할 때가 있는데 ComDlg는 Dialog Box를 열었을 때 생성되며 ComDlgLegacy 는 Legacy Dialog Box를 열었을 때 생성된다.

image

이제 Bags를 살펴볼건데 찾을 폴더의 NodeSlot을 본 뒤 NodeSlot의 넘버를 가지고 Bags 폴더로 이동하면 된다. 내가 찾아볼 c0wb3ll 폴더의 NodeSlot은 0x59(89) 이므로 89번을 찾아가면 될 것 같다.

2-2. HKCU\Software\Classes\Local Settings\Software\Microsoft\Windows\Shell\Bags

image

c0wb3ll 폴더의 설정 파일이다. SniffedFolderType은 폴더의 타입을 나타낸다. Shell 파일 하위에 {5C4F...}의 GUID값이 나와있을텐데 이 값은 KnownFolderDerivedFolderType 값으로 이 값이 폴더의 타입을 나타낸다. 즉 {5C4F...}가 폴더의 타입이 Generic이라고 알려주는 것이다.

 

Generic Type의 폴더를 제외한 키 값은 https://docs.microsoft.com/en-us/windows/win32/shell/knownfolderid 이 사이트에서 참조하면 될 것 같다.

2-2-1. HKCU\Software\Classes\Local Settings\Software\Microsoft\Windows\Shell\Bags\GUID || HKEY_CURRENT_USER\Software\Microsoft\Windows\Shell\Bags\1\Desktop

image

각각의 값들을 알아내기 위해 직접 실험과 각각의 블로그를 참조한 결과이다.

  1. ColInfo

    • 모든 값들에 대해 알아내진 못했지만 간단하게 설명하자면 우리가 윈도우 탐색기에서 보는 세부정보의 목록에 대한 값인 것 같다.

    •  

      00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
      FD DF DF FD 10 00 00 00 00 00 00 00 00 00 00 00 05 00 00 00 18 00 00 00
      
      30 F1 25 B7 EF 47 1A 10 A5 F1 02 60 8C 9E EB AC 0A 00 00 00 E9 00 00 00
      30 F1 25 B7 EF 47 1A 10 A5 F1 02 60 8C 9E EB AC 0E 00 00 00 7E 00 00 00
      30 F1 25 B7 EF 47 1A 10 A5 F1 02 60 8C 9E EB AC 04 00 00 00 50 00 00 00
      30 F1 25 B7 EF 47 1A 10 A5 F1 02 60 8C 9E EB AC 0C 00 00 00 50 00 00 00
      53 7D EF 0C 64 FA D1 11 A2 03 00 00 F8 1F ED EE 04 00 00 00 A0 00 00 00

      ColInfo를 눌러보면 다음과 같은 헥스 값이 나올텐데 FD DF DF FD 10 00 00 00 00 00 00 00 00 00 00 00 까지는 같은 숫자를 가지는 것 같다.

      다른 부분은 05 00 00 00 부터인데 이 05의 값이 세부정보의 목록 수의 대한 값이다.

      image

      지금 세부정보의 목록은 이름, 수정한 날짜, 유형, 크기, 만든 날짜로 5개이기 때문에 값이 05 00 00 00 이며

      image

      다음과 같이 6개로 바꾸었을 때는 아래와 같이 06 00 00 00 이 되는 것을 볼 수 있었다.

      image

      그 뒤 값이 1 증가할 때 마다 24byte 만큼의 데이터가 추가 되었는데 이 값들이 무엇을 의미하는 지는 모르겠다.

  2. FFlags

    • 이건 아이콘 자동 정렬과 관련된 값인것 같다. \Desktop 과 \GUID의 값은 달랐으며 \Desktop의 값들에 대한 정보는 찾을 수 있었다.

      • 키 : HKEY_CURRENT_USER \ SOFTWARE \ Microsoft \ Windows \ Shell \ Bags \ 1 \ Desktop
        값 : FFlags
        유형 : REG_DWORD
        데이터 :

        1075839520 (아이콘 자동 정렬 = OFF 및 그리드에 아이콘 정렬 = OFF)
        1075839521 (아이콘 자동 정렬 = ON 및 아이콘을 그리드에 정렬 = OFF)
        1075839524 (아이콘 자동 정렬 = OFF 및 아이콘을 그리드에 정렬 = ON)
        1075839525 (자동 정렬 아이콘 = ON 및 그리드에 아이콘 정렬 = ON)

  3. GroupByDirection

    • 이 값은 뷴류 방법이 켜져 있을 때의 오름차순 내림차순에 대한 값이었다. 분류방법이 꺼져있었을 때에는 1의 값을 가지고 있었다.
      • 1 : 오름차순
      • ffffffff : 내림차순
  4. GroupByKey:FMTID

    • image

      다음과 같이 분류방법에 대해 바꿀 때만 값이 바뀌었다.

    • 정확하진 않지만 분류방법이 있을때는 아래와 같은 값을 가졌었다.

      image
    • 또한 분류방법이 없을 때는 아래와 같이 0000..의 값을 가졌었다.

      image
  5. GroupByKey:PID

    • 위에 분류 방법에 대한 PID이며 각 방법에 따른 PID 값은 다음과 같다.

      Category GroupByKey:PID Value
      이름 10
      수정한 날짜 14
      유형 4
      크기 12
      만든 날짜 15
      태그 5
  6. GroupView

    • 이 값 또한 분류 방법을 고를 때마다 0xffffffff(4294967295) 의 값이 지정됐다.

      image
    • 지정 하지 않으면 아래와 같이 0000....의 값으로 바뀌었다.

      image
  7. IconSize

    • 아이콘 사이즈는 이름 그대로 아이콘 사이즈에 대한 값이었다. 아이콘 값은 밑에 LogicalViewMode, Mode를 모두 살펴보고 정리하도록 하겠다.
  8. LogicalViewMode

    • LogicalViewMode는 보기 방법에 따른 값이다.

    • 대략 미리 값들만 살펴보자.

      1 - 자세히

      2 - 타일

      3 - 아이콘

      4 - 간단히

      5 - 내용

  9. Mode

    • Mode값 또한 보기 방법에 따른 값이다. LogicalViewMode와 뭐가 다른지는 모르겠다.;;

    • 대략 값들을 살펴보자

      1 - 아이콘 보기

      3 - 간단히

      4 - 자세히

      6 - 타일

      8 - 내용

    • 여태 나온 IconSize, LogicalViewMode, Mode 의 값들을 정리하면 아래 표와 같다.

      보기 IconSize(in pixels) LogicalViewMode Mode
      아주 큰 아이콘 256 3 1
      큰 아이콘 96 3 1
      보통 아이콘 48 3 1
      작은 아이콘 16 3 1
      간단히 16 4 3
      자세히 16 1 4
      타일 48 2 6
      내용 32 5 8
  10. rev

    • 이 값은 뭔지 모르겠다... 아무리 건들여봐도 0에서 값이 변하질 않는다.
  11. Sort

    • 정렬 기준과 관련된 값이다.

    • 오름차순 정렬을 하면 마지막 4byte가 01 00 00 00의 값을 가진다.

      image
    • 내림차순 정렬을 하면 마지막 4byte가 FF FF FF FF의 값을 가진다.

      image
    • 그 위에 24byte는 정렬 기준 타입(이름, 크기, 등등)과 관련된 헥스값인 것 같다. (정확하게 파악하지 못했다.)

  12. Vid

    • 보기 메뉴와 관련된 값이다. 값에 따른 옵션은 다음 표와 같다.

      보기 Vid
      매우 큰 ~ 보통 아이콘 {0057D0E0-3573-11CF-AE69-08002B2E1262}
      작은 아이콘 {089000C0-3573-11CF-AE69-08002B2E1262}
      간단히 {0E1FA5E0-3573-11CF-AE69-08002B2E1262}
      자세히 {137E7700-3573-11CF-AE69-08002B2E1262}
      타일 {65F125E5-7BE1-4810-BA9D-D271C8432CE3}
      내용 {30C2C434-0889-4C8D-985D-A9F71830B0A9}

Windows10 ShellbagMRU Structure

image

위 사진에 있는 Hex 값 Structure에 대해 분석을 할 예정이다.

 

우선 이 값들은 Block 구조 안에 Extension Block 구조를 가지고 있는 형식이라고 한다.

image

c0wb3ll폴더의 경우 위에 22byte가 Block 구조이며 그 밑에 66byte가 Extension Block 구조이다. 우선 Block 구조 부터 살펴 보도록 하자.

1. Windows10 ShellbagMRU Structure - Block Struture

image

Address Range Size Filed Name Description
0x00 ~ 0x01 2byte Block Size Block Size
0x02 ~ 0x03 2byte Type Type(0x31:Directiory, 0x32:File)
0x04 ~ 0x07 4byte File Size File Size (in the case of Folder, set 0x00)
0x08 ~ 0x0B 4byte Modification Time Modification Time
0x0C ~ 0x0D 2byte Type Type(0x10:Directory, 0x20:ZIP File)
0x0E ~ 0x?? ??byte Short Name Short File Name(different size by Name length)

위에 정보들을 이 구조에 대조해보자. ( 기본적으로 hex값을 쓰겠습니다. 0x생략 )

Block Size == 56byte이며

Type == 31로 Directory 즉 폴더이며

File Size == 00 *4byte 디렉토리이기 때문에 크기가 00으로 설정되며

Modification Time == C1 50 5A 96

image

한국은 UTC+9이기 때문에 9시간을 더해주면 내가 폴더를 만든 시각(따로 수정해주지 않았기 때문에 생성한 시간과 동일)인 3:50분과 일치한다

Short Name == c0wb3ll로 일치한다.

2. Windows10 ShellbagMRU Structure - Block Struture

image

Address Range Size Field Name Description
0x00 ~ 0x01 2byte Extension Block Size Extension Block Size
0x02 ~ 0x03 2byte Version Version
0x04 ~ 0x07 4byte Signature Signature Value (0xBEEF0004)
0x08 ~ 0x0B 4byte Create Time Create Time
0x0C ~ 0x0F 4byte Last Access Time Last Access Time
0x10 ~ 0x13 4byte Identifier Identifier (0x2E:Windows8.1, Windows10)
0x14 ~ 0x17 4byte MFT Entry Number MFT Entry Number
0x18 ~ 0x19 2byte Reserved Area Reserved Area, set 0x00
0x1A ~ 0x1B 2byte MFT Sequence Number MFT Sequence Number
0x1C ~0x29 14Byte Reserved Area Reserved Area, set 0x00
0x2A ~ 0x2D 4byte CheckSum each file/folder unique number
0x2E ~ 0x?? ??byte File Name File Name(different size by Name length)
0x?? ~0x??+4 4byte Extension Block Offset Extension Block Offset (Starting point Extension Block)

으.. 영어....

진짜 제발 모두 영어공부합시다... 깊게 들어갔더니 영어자료밖에 없고 같은 자료를 보고 이해할 수 없느냐는 영어 실력에 달린거 같습니다..... 오픈 채팅방에 질문 했더니 사이트 올려주셨는데 보고 있는 사이트였어요. 너무 쪽팔렸습니다 ㅠㅠ....


Reference

https://blog.forensicresearch.kr/20 - 역시나 가장 많이 참고했습니다. 감사합니다!

http://www.forensic-artifact.com/windows-forensics/shellbags - 앞으로 공부는 이 글을 바탕으로 주제를 잡고 시작할 것 같습니다.

https://forums.ivanti.com/s/article/Auto-Arrange-icons-and-Align-icons-to-grid-setting-not-captured-in-Microsoft-Windows-10 - FFlags 값에 대해 조사한 자료

https://www.stark4n6.com/2019/02/shellbags-folder-views-and-windows.html - 여러가지 Bags 키값에 대해 조사한 자료

https://cyberforensicator.com/2019/02/03/shellbags-forensics-directory-viewing-preferences/ - 여러가지 Bags 키값에 대해 조사한 자료2

섹터 주소 지정 방식

CHS 주소 지정 방식

CHS(Cylinder-Head-Sector) 주소 지정 방식은 이름을 보면 알 수 있듯이 실린더(Cylinder), 헤드(Head), 섹터(Sector) 구조를 기반으로 주소를 지정하는 방식이다.

 

하드 드라이브의 실린더, 헤드, 섹터.

 

이 방식은 물리적으로 주소를 할당하는 방식이고, 각각 실린더, 헤드, 섹터에 번호를 할당해 그 주소를 이용하여 데이터를 찾아 읽고 쓰는 방식이다.

 

예를 들어 CHS(1,2,3)이면 2번째 헤드를 1번째 실린더, 3번째 섹터에 위치 시킨다. 이 후 읽기 명령을 발생시켜 해당 위치부터 지정한 만큼 데이터를 읽게 만든다.

 

초기에 ATA 표준은 28bit 블록 주소 방식으로 실린더 16bit, 헤드 4bit, 섹터 8bit로 할당되었다. 이 후 ATA-1 이 정식으로 소개될 때는 BIOS INT 13h가 지정할 수 있는 최대 비트인 24bit에 맞춰 각각 실린더 10bit, 헤드 8bit 섹터 6bit로 소개하였다.

 

image

 

위에 정보를 토대로 표현 가능한 용량을 계산해 보면 아래와 같이 된다.

2^10(실린더) * 2^4(헤드) * 2^6-1(섹터) * 512(섹터크기) = 504MB

 

섹터 계산 2^6-1 이 부분에서 -1 해준 이유는 헤드와 실린더는 인덱스가 0부터 시작하지만 섹터는 1부터 시작하기 때문이라고 한다. (하지만 왜 1 부터 시작하는지는 어디에서도 이유를 찾을 수 없었다... 왜 1부터 시작하는지 아는 사람이 있다면 댓글로 달아주시면 감사할 것 같다.)

 

어찌됐든 결국 표현 가능한 용량은 504MB이므로 최대 용량의 한계가 존재한다.

 

이후 BIOS와 IDE/ATA를 한계 CHS를 2의 제곱수로 나누고 곱하여 서로 조정하여 용량을 늘렸지만 7.88GB가 한계라서 LBA 주소 지정 방식이 사용되게 된다.

LBA 주소 지정 방식

LBA(Logical Block Addressing)은 CHS와 별개로 생겨난 것은 아니다. ATA-1 명세에 포함되어 있었으며, CHS가 먼저 사용되었고 그 한계점이 들어나며 LBA가 주목받게 된 것이다.

 

LBA의 이름 풀이를 보면 알 수 있듯이 LBA는 논리적인 주소를 가지게 된다.

따라서 CHS와 같이 Cylinder-Head-Sector로 나누어 3차원적으로 실제 물리적 주소를 갖게 하는 것이 아니라 Sector를 일차원으로 배열하여 순서대로 숫자를 지정해 주소를 계산해주는 방식이다.

 

CHS(0,0,1),(0,0,2) 와 같이 계산하는 것이 아닌 0,1,2,3,...,102와 같이 주소를 지정하는 것이다.

 

LBA는 28bit 로 최대 2^28 섹터가 지정이 가능하다. 섹터가 512byte이므로 총 128GB의 용량을 표현할 수 있다는 뜻이다.

그렇다면 128GB보다 큰 용량인 하드는 어떻게 만들어진 것일까?

 

28bit로는 더 큰 용량을 만들 수 없게 되자 48bit LBA 방식이 등장하였다. 48bit를 사용하면 이론적으로 144PB(PeraByte)의 용량까지 사용할 수 있다. 이는 GB로 144,000,000GB의 용량을 표현할 수 있다.

 

그럼 이제 이러한 논리적 주소는 컴퓨터가 어떻게 계산해서 물리적 주소로 접근을 하느냐...? 이것에 대해선 BIOS가 해결해 준다.

이 부분에 대해선 아직 자세히 알아보지 않아서 나중에 더 깊게 공부를 하게되면 적게 될 것 같다.

 

이렇듯 LBA가 사용되면서 CHS는 점점 사용되지 않게 되었으나 CHS 주소 지정 방식이 가지는 용량 한계에 대해 이 한계를 신경쓸 필요가 없는 용량이 작은 임베디드 장비들에서는 경우에 따라 CHS 주소 지정 방식을 사용하고 있기도 해서 LBA와 CHS간에 주소 변환 관계를 이해할 필요가 있다.

 

CHS -> LBA 변환
LBA = ( ( 실린더 * 실린더 당 헤드 수 + 헤드) * 트랙당 섹터 수 ) + 섹터 - 1
LBA -> CHS 변환
실린더 = LBA / ( 실린더 당 헤드 수 * 트랙당 섹터 수 )
헤드 = ( LBA / 트랙당 헤드 수 ) % 실린더 당 헤드 수
섹터 = ( LBA % 트랙당 섹터 수 ) + 1

ZBR 방식

최근 디스크는 이 ZBR(Zone Bit Recording) 방식을 이용한다.

 

물리적으로 트랙 길이가 내부보다 외부가 더 길다는 점에서 착안되어 트랙의 길이가 길수록 더 많은 섹터를 할당하는 방식이다.

이전까지는 모든 트랙이 같은 섹터로 이루어져 있었다.

그렇기 때문에 ZBR을 쓰는 디스크는 ZBR에 따른 각 트랙당 섹터의 수를 알고 있어야 정확히 계산할 수 있다.


Reference

http://blog.naver.com/PostView.nhn?blogId=cksdud1113&logNo=221687484310 - LBA , CHS

https://mamu2830.blogspot.com/2019/10/blog-post_14.html - 하드디스크 구조와 원리

http://forensic-proof.com/archives/355 - 그저 포렌식 푸르프

 

 

HackCTF Forensics Writeup (Let'S get it! Boo*4)

문제

image

Let'S get it ! Boo * 4 대문자가 이상하게 들어가 있는 것이 보인다면 당신은 LSB를 알고 있는 겁니다. ㅎ

풀이

위에 문제에서 대문자가 이상하게 들어가 있는데 대문자로 된 글자들을 나열하면 LSB가 된다. 보통 LSB를 사용한 문제에는 이렇게 문제에서 티를 내주기 때문에 그대로 풀면 되는데 풀기 전에 LSB가 무엇인지 먼저 알아보도록 하자.

LSB (Least Significant Bit)

LSB는 하나의 데이터 형에서 가장 낮은 위치의 Bit를 의미한다. 반대로 하나의 데이터 형에서 가장 높은 위치의 Bit는 MSB라고 한다. 예를 들어 1byte unsigned char 형에서의 LSB와 MSB는 다음과 같다.

image

LSB와 MSB가 어떻게 사용되는지는 나중에 달리는 reference에 블로그를 참조하시면 될 것 같고 이 최하위 비트가 포렌식 분야에서 어떻게 사용되는지를 알아보자.

LSB Steganography

주로 jpeg 및 bmp 같은 24비트 이미지 파일에 적용이 되며 24bit 가장 위치가 낮은 최하위 비트를 조작하여 이미지를 변조한다. 하지만 이렇게 변조된 데이터는 사람의 눈으로 알아채기 힘들정도로 미세한 변화를 주기 때문에 데이터를 숨기는데 사용할 수 있다.

 

자 그럼 이제 문제를 풀어봅시다.

 

image

문제를 받고 연 이미지 파일이다. booboobooboo

 

LSB 문제인 것을 위에서 예측 하였으니 헥스 에디터로 여는건 생략하고 stegsolve를 이용하기로 했다.

 

stegsolve 라는 툴은 LSB를 이용하여 그림을 숨겨두거나 텍스트를 숨겨 놓았을 때 유용하게 사용할 수 있는 툴이다.

그림이 숨겨진 경우 아래 사진과 같이 각각의 색을 조정하여 숨겨진 텍스트를 나타나게 해준다.

 

image

 

다만 이번엔 숨겨진 것이 그림이 아니라 텍스트 인 듯하여 다른 방법을 사용해야 한다.

 

image

 

다음과 같이 Data Extract 메뉴에 옵션을 주고 열면 HackCTF{0U].Bl0C0xCDA9~~~}와 같이 플래그 포멧과 이상한 값들이 보인다.

( 옵션은 최하위 비트를 찾을 것이니 LSB First로 두고 Bitmap이미지는 RGB가 아닌 BGR방식을 따르기 때문에 Bit Plane Order를 BGR로 주었다. 또한 Bit Planes는 최하위 비트인 0번째 RGB비트만 주어서 Extract해주면 된다.)

 

Include Hex Dump in Preview 탭을 꺼주고 Save text를 누르면 txt파일로 저장할 수 있다.

 

image

 

그렇게 해서 생긴 요놈들이 뭘까 하다가 "0x" 가 있길래 무슨 헥스값인가 하여 검색을 하였다.

 

image

 

그 결과 한글 Unicode라는 것을 알 수 있었고 이를 통해 Flag를 구할 수 있었다.


zsteg

stegsolve가 아닌 다른 steganography tool 이다.

 

image

 

다음과 같이 LSB 이미지와 관련된 스테가노 그래피가 사용되었는지 분석하여 뽑아준다.

두번째 줄을 보면 "HackCTF{0U]" 와 같이 일부분을 뽑아주는 것을 확인할 수 있다.

 

image

 

그리고 다음과 같이 옵션을 이용하여 뽑아내면 stegsolve와 같은 결과값을 얻어낼 수 있다.

 

이 문제를 마지막으로 HackCTF Forensics 문제는 다 풀었다! ( 더 추가해주세요. ㅠㅠ )

 

포렌식 공부를 좀 더 해보다가 쉴 때 짬짬히 HackCTF에 포너블 문제도 풀어보도록 해야 겠다.


Reference

https://m.blog.naver.com/PostView.nhn?blogId=ansdbtls4067&logNo=220886567257&proxyReferer=https:%2F%2Fwww.google.com%2F - lsb란?

https://whitesnake1004.tistory.com/91 - zsteg

HackCTF Forensics Writeup (잔상)

문제

image

잔상

풀이

image

 

compare.zip 압축파일을 해제하면 다음과 같이 두장의 사진을 준다.

 

아무리 봐도 같은 사진 같은데 무엇을 비교하라는걸까??

 

비교해야 할 것은 헥스 에디터로 열었을 때 안에 있는 데이터 값인 것 같다. 사람의 눈으로는 미세한 데이터 차이는 판별하지 못하기 때문에 이렇게 숨기기도 하나보다.

 

그럼 헥스 에디터를 열어 데이터를 비교해 보자.

 

image

 

내가 사용하고 있는 헥스 에디터인 010 editor의 경우 compare file 기능을 이용하면 다음과 같이 틀린 부분과 같은 부분을 색깔별로 표시해주며 밑에 Compare 메뉴에 Difference 를 누르면 다른 부분으로 바로 이동시켜주는 편리한 기능이 있어서 사용하였다.

 

afterimage_1.jpeg 와 afterimage_2.jpeg 의 각각 다른 헥스 값은 1이 4E, 2가 48이다. 각각 ascii 코드로 N과 H인데 HackCTF 플래그 포멧 상 HackCTF{any_string_is_Flag}이기 때문에 아마 afterimage_2.jpeg 의 다른 헥스 값이 플래그 일 것이다.

 

플래그는 각자 찾아보고 인증한 뒤 마음속에 간직하도록 하자.

HackCTF Forensics Writeup (Terrorist)

문제

image

현장을 수사했고 단서를 찾게되었으니 다음 범행 장소를 알아내라고 한다.

풀이

image

 

Artifact.7z 이라는 7zip 파일을 압축 해제하면 다음과 같이 mission.jpg라는 사진 파일을 주는데 열리지 않는다.

 

헥스 에디터로 열어서 문제점을 찾아보자.

 

image

 

헥스 에디터로 열어 봤을때 헤더 시그니처가 확장자인 jpg 파일은 아닌것이 분명했고 저것이 어떤 헤더 시그니처 인지 찾는 과정에서 매우 유사한 헤더 시그니처를 가진 것이 많았기 때문에 고민 했지만 대충 그냥 소리가 나오는 파일이면 인식할 수 있었다. (헤더 시그니처는 3gp5 또는 m4a 파일이라고 생각한다.)

 

따라서 필자는 wav로 확장자를 바꾸어 사용하도록할 것이다.

 

확장자를 wav로 바꾸어 주도록 하자.

 

image

 

그럼 다음과 같이 음성이 나오는데 뭐라 말하는지 알 수 가 없다...

 

이 때 사용하는 사운드 편집 프로그램인 audacity를 사용하여 편집을 이리 저리 굴려보자.

 

image

 

그런데 문제가 발생했다.

오다시티에서 무슨 문제인지 파일을 인식하지 못하고 가져오는데 실패하였다.

 

아마 원본 파일이 m4a나 그런 쪽의 파일이라서 그런것이 아닐까 추측했고 온라인 컨버터를 이용해 mp3 파일로 컨버트 시켜주었다.

 

image

 

그 결과 오다시티에서 성공적으로 열 수 있었다.

 

이제 문제만 풀면 되는데 보통 다른 오디오 포렌식 문제들과 달리 간단한 편이었다.

 

image

 

다른 문제들은 속도 조절하고 템포 조절하고 잔향 제거하고 여러가지 건들이는 반면 이 문제는 뒤집기 좌우로 해서 거꾸로 재생만 시켜주면 플래그가 나온다.

HackCTF Forensics Writeup (Magic PNG)

문제

image

풀이

 

image

 

문제를 다운 받고 열게 되면 다음과 같이 파일 형식을 지원하지 않는다며 사진을 보여주지 않는다.

 

헥스 에디터를 열어 문제점을 찾아보자.

 

image

 

우선 첫번째 헤더 시그니처를 보았다.

 

010 editor에서 의미있는 값마다 구분해서 보여주는 구분선 때문에 깜박 속아 넘어갈 뻔 했다.

 

하지만 보면 알 수 있듯이 89 50 4E 47 2E 0A 2E 0A 라 적힌것과 다르게 PNG 파일 헤더 시그니처는 89 50 4E 47 0D 0A 1A 0A 이다.

 

따라서 이 값을 고쳐주면 될 것 같다.

 

image

 

하지만 아직 제대로 다 해결하지 못 한 것 같다.

 

다시 한번 헥스 에디터로 돌아가 보자.

 

image

 

들어가 보면 전과 다르게 제대로 PNG 헤더 시그니처를 인식하고 010 editor가 제대로 구분선을 내주는 것을 확인할 수 있다.

 

image

 

또한 010editor에서 지원하는 기능 중 하나인 Variables 탭에 수상한 친구가 하나 섞여있는 것 같다.

 

image

 

바로 저 친구이다.

PNG Chunk 중 하나인 IDAT이 소문자로 들어가 있다.

 

필자는 010 editor로 간단하게 찾게 되었지만 HxD와 같은 기능을 지원해주지 않는 에디터로 찾으려면 꽤나 노력을 들여야 했을것이다.

 

그럼 idat을 IDAT으로 바꿔보도록 하자.

image

FLAG!

HackCTF Forensics Writeup (나는 해귀다)

 

문제

 

image

 

문제파일을 다운받자.

 


풀이

 

image

 

압축파일을 다운받아 압축을 풀면 다음과 같은 사진을 준다.

 

자막을 보면 오 헥스값을 완전 뒤집어 놓으셨댄다. 헥스 에디터로 열어보자.

 

image

 

헥스 에디터로 열고나서 파일을 찬찬히 보면 89 50 4E 47 부터 png파일의 헤더 시그니처가 존재하고 그 후에 49 45 4E 44 AE 42 60 82 까지 푸터 시그니처까지 제대로 존재하는 것을 확인할 수 있다.

 

이제 문제는 그 다음인데 png 파일의 푸터 시그니처인 49 45 4E 44 AE 42 60 82 가 거꾸로 들어가 있는 모습을 볼 수 있다.

 

image

 

그리고 맨 밑을 보자 png 파일의 헤더 시그니처인 89 50 4E 47 0D 1A 0A 00 이 거꾸로 들어가 있는 것을 확인할 수 있다.

 

부가적으로 png 파일의 chunk들인 IHDR, sRGB, gAMA, pHYs 등 모두 거꾸로 데이터가 입력되어 있는것을 보아 이를 바로 잡아주면 새로운 png 사진 파일 하나를 획득할 수 있다는 것을 알 수 있다.

소스 코드

필자의 경우 파이썬으로 코딩하였으며 소스 코드는 다음과 같다.

data = "거꾸로 뒤집을 헥스값"

data1 = data.split(' ')

print(''.join(data[::-1]))

이렇게 하여 나온 헥스값을 다시 파일로 만들어주면 png파일이 나온다.

image

플래그 마저 뒤집어 놓으셨다.

HackCTF Forensics Writeup (세상에서 잊혀진 날 찾아줘!)

문제

image

 

세상에서 잊혀진 날 찾아달라고 한다. 찾아주러 가봅시다. 문제 파일은 pdf이다.

 


풀이

 

image

 

pdf 파일을 열면 이런 화면이 나온다. 파일을 받아주자.

 

이제 헥스 에디터로 열어보도록 하자. 헥스에디터로 열고 우선 pdf는 사진 파일을 원본 그대로 삽입해 놓는 형식으로 관리를 한다.(?)

대충 무슨 소리냐면 jpg 파일이 들어가면 jpg헤더부터 푸터까지 데이터가 들어가 있다는 뜻이다.

그럼 이 부분을 없애주면?

 

사진이 사라지고 사진으로 가려진 내용이 나오게 된다.

 

대충 정리해보자면

  1. pdf는 사진 파일이 원본 그대로 들어가있다.
  2. jpg 헤더부터 푸터까지 데이터를 없애주면 pdf에서 사진이 사라진다
  3. 사진으로 가려졌던 pdf 파일 속 내용이 나온다.

정도가 되겠다.

image

 

보면 jpg의 헤더인 FF D8과 그 뒷부분에 문자열 JFIF가 있는 것을 확인하여 jpg 사진 파일이 들어가있는것을 확인하였다.

 

image

 

그 뒤 FF D9를 검색하여 푸터를 찾고 이 부분을 제거해주었다.

 

image

Flag!!


꼼수

image

사실 이 문제는 꼼수가 존재한다. 그냥 Ctrl + A를 누르고 복붙하면 플래그가 나온다. Ctrl + A는 모든 내용 선택 단축키이다.

사진을 보면 드래그 된 부분이 보일 것이다. ㅋㅋㅋ;;

HackCTF Forensics Writeup (Secret Document)

문제

image

flag라는 이름을 가진 압축파일을 준다.


풀이

image

 

다음과 같이 Flag.zip을 압축 해제하려고 하자 비밀번호를 입력하라고 한다. 따라서 BruteForce어택을 백그라운드에 실행해놓고 다른 방법이 더 있나 찾아보기로 하였다.

 

image

 

그러던 중 파일 건너뛰기를 하고 압축을 해제했더니 암호가 걸린 flag.txt를 제외한 hint1.txt와 hint2.txt는 압축이 정상적으로 해제되었다. 이 힌트를 읽어보자.

 

image

 

우선 첫번째 힌트이다. Brute-Force NOOOOOOOOOOOOOO!라며 무작위 대입 공격을 사용하는 것이 아님을 알려준다. 나처럼 백그라운드에 돌려두었다면 곱게 켜서 다시 종료시켜주자.

 

image

그리고 두번째 힌트는 과연 패스워드가 존재한다고 생각하냐? 라며 패스워드로 푸는 것이 아니라는 힌트를 준다.

그럼 이제 압축파일의 파일 구조를 찾아보자.

 

압축파일의 암호화 기법은 Central Directory 구조의 Flags 필드를 공부해야한다. ( 그냥 압축파일에 대해 싹 다 공부하자 이김에 ) Central Directory 구조의 Flags 필드는 총 16개의 플래그 값을 가지고 있으며 Bit 00 번째 값이 암호화 된 파일을 나타낸다고 한다.

 

image

 

010editor는 파일 포맷을 기본적으로 지원해주기 때문에 볼때 한결 편하다.

대충 보라색 부분부터 Central Directory 영역이라고 보면 되며, 드래그 한 09 08 부분이 Flags 필드이다.

이 09 08 은 비트로 표현하기 위해 리틀언디언 방식으로 표현하면 08 09 이다. 또한 08 09 를 비트로 나타내면

 

image

 

1000 0000 1001 이며 암호화 부분인 00 번째 bit가 1로 활성화 되어 있는것을 알 수 있다.

 

image

 

따라서 2^0 = 1이니 1을 빼준 값을 보면 암호화 비트가 풀어진 바이트를 얻을 수 있다. 이는 헥스값으로 0808이다.

비트로는 1000 0000 1000 이다.

 

image

 

따라서 헥스값을 0808로 바꾸어 주거나 밑에 010editor에서 지원하는 기능 중 하나인 Inspector 에서 Short 부분을 2056으로 바꾸어주면 된다.

 

이렇게 한 뒤 저장하고 압축을 해제하면

 

image

 

flag.txt를 포함하여 압축이 해제되는 것을 볼 수 있다.

 

image

Flag!!

HackCTF Forensics Writeup (So easy?)

문제

image

qwer.zip파일을 준다. 다운 받아주자.


풀이

image

압축을 해제하면 다음과 같은 사진을 준다. 사진을 보고서는 아무것도 얻을 수 없으니 일단 기본부터 하도록 하자.

image

그럼 다음과 같은 플래그 형식을 지킨 문자열이 나온다. 하지만 이것은 글을 읽으면 알 수 있듯이 속임수용 플래그이다.

진짜 배기는 그 밑에 PK라는 문자열인데 이는 헥스로 50 4B이며 그 뒤에 붙어있는 03 04 까지 하여 50 4B 03 04가 압축파일의 헤더 시그니처 되시겠다.

따라서 이 헥스값을 뜯어 새로운 파일을 만들면 압축파일을 얻을 수 있다.

image

그럼 다음과 같이 hidden.txt라는 텍스트 파일안에서 FLAG를 찾을 수 있다.

HackCTF Forensics Writeup (Question?)

문제

image

딱히 문제는 없고 파일만 떡하니 하나 준다. 다운 받아주자.


풀이

image

다운 받은 파일의 이름이 Do you know HxD이다. 헥스에디터를 이용한 문제인것 같다.

일단 압축을 해제해주자.

image

압축을 해제하면 다음과 같은 사진을 준다. (사진이라기 보다는 추리문제...?) 우리가 이런 추리 문제를 풀러 온것은 아니니 각설하고 헥스에디터로 까주도록 하자.

image

파일을 헥스에디터로 까고난 뒤에 jpg파일의 푸터 시그니처인 FF D9 뒤에 문자열을 발견하였다.

HackCTF Forensics Writeup (Welcome_Forensics)

문제

image

가로 길이가 괴상해서 글자를 알아볼 수 없는 사진을 준다. 하지만 누가 봐도 플래그라는 것은 알 것 같다.

풀이

image

사진 위에 마우스를 올리고 우클릭을 하면 다음과 같이 새 탭에서 이미지 열기라는 목록이 있을것이다. 이 탭을 누르면

image

FLAG!

메모리 보호 기법 (RELRO)

메모리 보호 기법 종류

  1. NX Bit ( MS : DEP )
  2. ASLR
  3. Canaries
  4. RELRO
  5. PIE

RELRO

Explanation

  • RELRO는 RELocation Read-Only의 줄임말이며, ELF 바이너리 / 프로세스의 데이터 섹션의 보안을 강화하는 일반적인 기술이다.

  • RELRO에는 Partial RELRO와 FULL RELRO 두가지 모드가 있다.

    • 각각 RELRO에 대한 특징은 다음과 같다.

      • No RELRO

        1. 명령어 옵션 : gcc -Wl,-z,norelro

        2. Lazy Binding

        3. Write to GOT

      • Partial RELRO

        1. 명령어 옵션 : gcc -Wl,-z,relro
        2. Lazy Binding
        3. Write to GOT
        4. RELRO in the Program Header
        5. Section include in RELRO
          • INIT_ARRAY
          • FINI_ARRAY
      • FULL RELRO

        1. 명령어 옵션 : gcc -Wl,-z,relro,-z,now
        2. Now Binding
        3. RELRO in Program Header
        4. Section include in RELRO
          • INIT_ARRAY
          • FINI_ARRAY
          • PLTGOT

부연 설명

Lazy Binding은 got호출 시점에 라이브러리를 메모리에(?) 저장하는것이다.

Now Binding은 프로그램 실행시 라이브버리를 메모리에(?) 저장하는 것이다.


실습

#include <stdio.h>
#include <string.h>

void main(){

        char address[16];
        size_t *pointer;
        int count = 1;

        while(count != 100)
        {
                printf("----- %d -----\n",count);
                memset(address,0,16);
                printf("Input Pointer address : ");
                fgets(address,16,stdin);

                pointer = strtol(address,0,16);
                printf("Pointer address : %p\n",pointer);

                printf("Input Pointer text : ");
                fgets(pointer,16,stdin);
                printf("Pointer text : %s\n",pointer);
                count++;
        }
        scanf("%s",address);
}

주소를 입력한뒤 그곳에 텍스트를 입력하면 그 주소에 입력된 텍스트를 정수로 바꾸어 넣어주는 소스코드이다.

No RELRO

image

gdb에 있는 기능 중 elfsymbol을 입력하여 각 함수의 @plt 주소를 구하고 입력에 관한 scanf함수를 더 자세히 찾아 got 주소를 알아낼 수 있었다.

got주소에 어떤 값이 들어있는지 확인하고 위 함수를 이용해 해당 주소에 값을 바꾸었을 때 성공적으로 값이 바뀌는 것을 확인하였다.

따라서 GOT Overwrite가 가능하다는 것을 확인할 수 있었다.

Partial RELRO

image

Partial RELRO 또한 같은 과정을 통해 GOT Overwrite 가 가능하다는 것을 확인하였다.

FULL RELRO

image

FULL RELRO는 앞서 보았던 No RELRO, Partial RELRO와 다르게 GOT Overwrite가 일어나지 않는것을 확인했다.

그 이유는 FULL RELRO에 Program Header 에 RELRO 영역에는 PLT GOT가 포함되어 있어서 got가 Read-Only로 작동하기 때문에 값이 수정될 수 없는 것이다.


Reference

http://lazenca.net/display/TEC/04.RELRO

http://lazenca.net/pages/viewpage.action?pageId=1147912

https://hackstoryadmin.tistory.com/entry/Linux-Memory-Protection-RELRO

PLT & GOT

ROP라는 기법에서 그냥 흘러가는 지식으로 대충 감만 잡고 있었는데 RELRO라는 보호기법에 대해 공부하다가 Lazy Binding? 에서 다시 나오길래 이번에 정리하려고 한다.

PLT

PLT란 Procedure Linkage Table의 약자로 외부 프로시저를 연결해주는 테이블이다.

PLT는 실제 호출 코드를 담고 있는 테이블로써 이 내용 참조를 통해 _dl_runtime_resolve가 수행되고, 실제 시스템 라이브러리 호출이 이뤄지게 된다.

GOT

GOT란 Global Offset Table의 약자로 PLT가 참조하는 테이블이다. 프로시저들의 주소가 들어있다.

GOT는 프로시저들의 주소를 가지고 있다. PLT가 어떤 외부 프로시저를 호출하면 이 GOT를 참조하여 해당 주소로 점프하게 된다.


단 PLT와 GOT는 Dynamic Link 방식으로 컴파일 했을때 사용되는데 그 이유는 Static Link 방식으로 컴파일 하면 라이브러리가 프로그램 내부에 있어서 함수의 주소를 알아오는 과정이 필요치 않지만 Dynamic Link 방식으로 컴파일 하면 라이브러리가 프로그램 외부에 있어서 함수의 주소를 알아오는 과정이 필요하다.

이 때 GOT를 처음 호출할 때와 아닐 때 동작과정의 차이가 있다.

image

맨 처음 putchar@plt 의 위치를 보면 0x1030이다.

r 을 눌러 실행하고 난 뒤 putchar@plt의 주소를 확인해보자.

0x7ffff7e6cbc0 으로 바뀐 것을 알 수 있다.

이 처럼 got 호출이 처음일 때는

  1. func() 호출
  2. @plt로 이동
  3. @got 참조
  4. @plt로 이동
  5. _dl_runtime_resolve
  6. @got 저장 후 실제 함수 실행

순으로 동작한다.

반면 got 호출이 처음이 아닐 때는

  1. func() 호출
  2. @plt로 이동
  3. @got 참조
  4. func() 로 점프

에 동작과정이 일어난다.

이러한 이유는 _dl_runtime_resolve를 통해 외부에 있는 라이브러리를 가져와야하는 과정에 차이다 처음 호출 했을 때는 라이브러리를 가져와 저장해야 하지만 저장한 후에는 got에 실제 함수 주소가 들어있기 때문에 바로 함수 사용이 가능하게 된다.

 


Reference

https://hackstoryadmin.tistory.com/61

+ Recent posts