[하루한줄] CVE-2025-27158: Adobe Acrobat Reader의 Uninitialized Pointer로 인한 RCE 취약점

URL

Target

  • Adobe Acrobat Reader
    • 24.001.30225
    • 20.005.30748
    • 25.001.20428 및 이전 버전

Explain

CVE-2025-27158은 Adobe Acrobat Reader에서 PDF에 포함된 OTF(OpenType Font) 파일을 처리하는 과정에서 발생했습니다.

OTF 파일은 크게 TableDirectory와 TableRecords로 구성되어 있어, 먼저 TableDirectory 구조를 살펴보겠습니다.

Offset Size   Name
------ ----- --------------------------------------
0x00    0x04  sfntVersion (0x00010000 or 0x74727565 or 0x4F54544F  )
0x04    0x02  numTables
0x06    0x02  searchRange
0x08    0x02  entrySelector
0x0c    0x02  rangeShift

sfntVersion 값이 0x00010000 또는 0x74727565인 경우 글꼴에 TrueType 데이터가 포함되고, 0x4F54544F인 경우 CFF 데이터가 포함됩니다.

numTables는 TableRecord 개수로 TableRecord 구조는 아래와 같습니다.

Offset Size   Name
------ ----- ----------------------------------
0x00    0x04  tableTag
0x04    0x04  tableChecksum
0x08    0x04  tableOffset
0x0C    0x04  tableLength

tableTag의 값이 “CFF2”이면 CFF2 테이블을 가리킵니다.

CFF2(Compact Font Format version 2) 테이블의 구조는 헤더, Top DICT, Global Subr INDEX, VariationStore으로 되어 있어 헤더부터 살펴보면 아래와 같습니다.

Offset Size   Name
------ ----- --------------------------------------
0x00    0x01  cff2MajorVersion
0x01    0x01  cfff2MinorVersion
0x02    0x01  cff2HeaderSize
0x03    0x02  topDictLength

여기서 topDictLength는 말 그대로 Top DICT 데이터의 길이를 나타냅니다.

Top DICT는 폰트의 주요 정보를 담은 데이터로 아래와 같이 다양한 정보가 포함될 수 있습니다.

Operator Name   Operator Value    Operand type and meaning
----------------------------------------------------------------------------------------------------------
CharStrings    0x11               number and it gives CharStrings INDEX offset, from start of the CFF2 table.
vstore         0x18               number and it VariationStore structure offset, from start of the CFF2 table.
FDArray        0x0C 0x24          number and it Font DICT (FD) INDEX offset, from start of the CFF2 table.
FDSelect       0x0C 0x25          number and it CharStrings INDEX offset, from start of the CFF2 table. 
FontMatrix     0x0c 0x07          array and default value is (0.001 0 0 0.001 0 0)

취약한 OTF 파일은 아래 3개의 Top DICT 데이터가 존재했습니다.

1D 00 00 00 7A 0C 24  ==>  (operator: FDArray, operand after encoding: 0x7A) 
1D 00 00 00 8A 11     ==>  (operator: CharStrings, operand after encoding: 0x8A)
1D 00 00 00 1C 18     ==>  (operator: vstore, operand after encoding: 0x1C)

이 중 vstore(0x18)의 offset은 0x1C로 CFF2 테이블에서 0x1C만큼 떨어진 곳에 VariationStore가 존재하고 구조는 아래와 같습니다.

 Offset Size                       Name
-----------------------------------------------------------------------
0x00    0x02                       Length
0x02    0x02                       Format
0x04    0x04                       variationRegionListOffset
0x06    0x02                       itemVariationDataCount (N)
0x08    0x04 * N                   itemVariationDataOffsets[N]

itemVariationDataCount는 하위 테이블의 개수(N)를 나타내며 itemVariationDataOffsets는 각 하위 테이블의 offset이 존재합니다.

itemVariationData의 하위 테이블 구조는 아래와 같습니다.

Offset Size                       Name
-----------------------------------------------------------------------
0x00    0x02                      itemCount
0x02    0x02                      shortDeltaCount
0x04    0x02                      regionIndexCount (C)
0x06    0x02 * C                  regionIndexes[C]

취약점은 itemVariationDataCount를 통해 할당한 메모리 영역을 초기화하지 않고 사용해 발생했습니다.


[...]

0:002> p
Time Travel Position: E92AE:1C21
eax=00000010 ebx=f3a2a970 ecx=00000004 edx=00000100 esi=00001b7c edi=f3a2a970
eip=6ee28da7 esp=052fc4b4 ebp=052fc4dc iopl=0         nv up ei pl nz na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000206
CoolType!CTGetVersion+0xb5877:
6ee28da7 e8b73ee6ff      call    CoolType!CTInit+0x195e3 (6ec8cc63) <- [1]
0:002> p
Time Travel Position: E92AE:1C3B
eax=00000002 ebx=f3a2a970 ecx=00000002 edx=00000100 esi=00001b7c edi=f3a2a970
eip=6ee28dac esp=052fc4b4 ebp=052fc4dc iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000202
CoolType!CTGetVersion+0xb587c:
6ee28dac 66898738020000  mov     word ptr [edi+238h],ax   ds:002b:f3a2aba8=ffff <- [2]
0:002> p
Time Travel Position: E92AE:1C3C
eax=00000002 ebx=f3a2a970 ecx=00000002 edx=00000100 esi=00001b7c edi=f3a2a970
eip=6ee28db3 esp=052fc4b4 ebp=052fc4dc iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000202
CoolType!CTGetVersion+0xb5883:
6ee28db3 0fb7c0          movzx   eax,ax
0:002> p
allocate vuln buffer of size 0x20
Time Travel Position: E92AE:1C3D
eax=00000002 ebx=f3a2a970 ecx=00000002 edx=00000100 esi=00001b7c edi=f3a2a970
eip=6ee28db6 esp=052fc4b4 ebp=052fc4dc iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000202
CoolType!CTGetVersion+0xb5886:
6ee28db6 c1e004          shl     eax,4  <- [3]
0:002> p
Time Travel Position: E92AE:1C3E
eax=00000020 ebx=f3a2a970 ecx=00000002 edx=00000100 esi=00001b7c edi=f3a2a970
eip=6ee28db9 esp=052fc4b4 ebp=052fc4dc iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000202
CoolType!CTGetVersion+0xb5889:
6ee28db9 50              push    eax
0:002> p
Time Travel Position: E92AE:1C3F
eax=00000020 ebx=f3a2a970 ecx=00000002 edx=00000100 esi=00001b7c edi=f3a2a970
eip=6ee28dba esp=052fc4b0 ebp=052fc4dc iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000202
CoolType!CTGetVersion+0xb588a:
6ee28dba e817cee4ff      call    CoolType!CTInit+0x2556 (6ec75bd6) <- [4]
0:002> p
Time Travel Position: E92B1:1394
eax=0a02b330 ebx=f3a2a970 ecx=6ec75bfe edx=00000000 esi=00001b7c edi=f3a2a970
eip=6ee28dbf esp=052fc4b0 ebp=052fc4dc iopl=0         nv up ei pl nz na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000206
CoolType!CTGetVersion+0xb588f:
6ee28dbf 89873c020000    mov     dword ptr [edi+23Ch],eax ds:002b:f3a2abac=00000000<- [5]
0:002> dd eax;                                  <- [6]
0a02b330  e0e0e0e0 e0e0e0e0 e0e0e0e0 e0e0e0e0
0a02b340  e0e0e0e0 e0e0e0e0 e0e0e0e0 e0e0e0e0
0a02b350  a0a0a0a0 a0a0a0a0 00000000 00000000

0:002> p
Time Travel Position: E92B1:1395
eax=0a02b330 ebx=f3a2a970 ecx=6ec75bfe edx=00000000 esi=00001b7c edi=f3a2a970
eip=6ee28dc5 esp=052fc4b0 ebp=052fc4dc iopl=0         nv up ei pl nz na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000206
CoolType!CTGetVersion+0xb5895:
6ee28dc5 0fb78738020000  movzx   eax,word ptr [edi+238h]  ds:002b:f3a2aba8=0002

[1]에서 CoolType!CTInit+0x195e3 함수를 통해 VariationStore 구조체 itemVariationDataCount 값을 가져옵니다. [2]에서 itemVariationDataCount 값(0x02)을 확인할 수 있습니다.

[3]에서 itemVariationDataCount 값을 통해 버퍼 크기(0x20)를 계산합니다. 이후 [4]에서 CoolType!CTInit+0x2556 함수를 호출하여 malloc으로 0x20 바이트 크기의 버퍼를 할당합니다.

[6]에서 할당된 버퍼(0x0a02b330)를 확인하면, 더미 데이터(0xe0e0e0e0)가 존재하는 것을 알 수 있습니다.


[...]

0:002> 
Time Travel Position: E92BA:1BB5
eax=db00d000 ebx=00000000 ecx=0000016b edx=052fc380 esi=0a02b330 edi=f3a2a970
eip=6ee28e65 esp=052fc4a8 ebp=052fc4dc iopl=0         nv up ei pl nz ac po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000212
CoolType!CTGetVersion+0xb5935:
6ee28e65 e8f93de6ff      call    CoolType!CTInit+0x195e3 (6ec8cc63) <-[8]
0:002> p
Time Travel Position: E92BA:1BCF
eax=00000000 ebx=00000000 ecx=00000000 edx=052fc380 esi=0a02b330 edi=f3a2a970
eip=6ee28e6a esp=052fc4a8 ebp=052fc4dc iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
CoolType!CTGetVersion+0xb593a:
6ee28e6a 57              push    edi
0:002> p
Time Travel Position: E92BA:1BD0
eax=00000000 ebx=00000000 ecx=00000000 edx=052fc380 esi=0a02b330 edi=f3a2a970
eip=6ee28e6b esp=052fc4a4 ebp=052fc4dc iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
CoolType!CTGetVersion+0xb593b:
6ee28e6b 668906          mov     word ptr [esi],ax        ds:002b:0a02b330=e0e0 <-[9]
0:002> p
Breakpoint 1 hit
Time Travel Position: E92BA:1BD1
eax=00000000 ebx=00000000 ecx=00000000 edx=052fc380 esi=0a02b330 edi=f3a2a970
eip=6ee28e6e esp=052fc4a4 ebp=052fc4dc iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
CoolType!CTGetVersion+0xb593e:
6ee28e6e e8f03de6ff      call    CoolType!CTInit+0x195e3 (6ec8cc63) <-[10]
0:002> db esi L20
0a02b330  00 00 e0 e0 e0 e0 e0 e0-e0 e0 e0 e0 e0 e0 e0 e0  ................
0a02b340  e0 e0 e0 e0 e0 e0 e0 e0-e0 e0 e0 e0 e0 e0 e0 e0  ................
0:002> p
Time Travel Position: E92BA:1BEB
eax=00000000 ebx=00000000 ecx=00000000 edx=052fc380 esi=0a02b330 edi=f3a2a970
eip=6ee28e73 esp=052fc4a4 ebp=052fc4dc iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
CoolType!CTGetVersion+0xb5943:
6ee28e73 57              push    edi
0:002> p
Time Travel Position: E92BA:1BEC
eax=00000000 ebx=00000000 ecx=00000000 edx=052fc380 esi=0a02b330 edi=f3a2a970
eip=6ee28e74 esp=052fc4a0 ebp=052fc4dc iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
CoolType!CTGetVersion+0xb5944:
6ee28e74 66894602        mov     word ptr [esi+2],ax      ds:002b:0a02b332=e0e0 <-[11]
0:002> p
Breakpoint 1 hit
Time Travel Position: E92BA:1BED
eax=00000000 ebx=00000000 ecx=00000000 edx=052fc380 esi=0a02b330 edi=f3a2a970
eip=6ee28e78 esp=052fc4a0 ebp=052fc4dc iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
CoolType!CTGetVersion+0xb5948:
6ee28e78 e8e63de6ff      call    CoolType!CTInit+0x195e3 (6ec8cc63) <-[12]
0:002> p
Time Travel Position: E92BA:1C07
eax=00008000 ebx=00000000 ecx=00000000 edx=052fc380 esi=0a02b330 edi=f3a2a970
eip=6ee28e7d esp=052fc4a0 ebp=052fc4dc iopl=0         nv up ei ng nz na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000286
CoolType!CTGetVersion+0xb594d:
6ee28e7d b900800000      mov     ecx,8000h
0:002> p
Time Travel Position: E92BA:1C08
eax=00008000 ebx=00000000 ecx=00008000 edx=052fc380 esi=0a02b330 edi=f3a2a970
eip=6ee28e82 esp=052fc4a0 ebp=052fc4dc iopl=0         nv up ei ng nz na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000286
CoolType!CTGetVersion+0xb5952:
6ee28e82 66894604        mov     word ptr [esi+4],ax      ds:002b:0a02b334=e0e0 <-[13]

[...]

0:002> p
Time Travel Position: E92BA:1C0D
eax=00008000 ebx=00000000 ecx=00008000 edx=052fc380 esi=0a02b330 edi=f3a2a970
eip=6ee28e95 esp=052fc4b8 ebp=052fc4dc iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
CoolType!CTGetVersion+0xb5965:
6ee28e95 03c0            add     eax,eax <-[14]
0:002> p
Time Travel Position: E92BA:1C0E
eax=00010000 ebx=00000000 ecx=00008000 edx=052fc380 esi=0a02b330 edi=f3a2a970
eip=6ee28e97 esp=052fc4b8 ebp=052fc4dc iopl=0         nv up ei pl nz na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000206
CoolType!CTGetVersion+0xb5967:
6ee28e97 50              push    eax 
0:002> p
Time Travel Position: E92BA:1C0F
eax=00010000 ebx=00000000 ecx=00008000 edx=052fc380 esi=0a02b330 edi=f3a2a970
eip=6ee28e98 esp=052fc4b4 ebp=052fc4dc iopl=0         nv up ei pl nz na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000206
CoolType!CTGetVersion+0xb5968:
6ee28e98 e839cde4ff      call    CoolType!CTInit+0x2556 (6ec75bd6) <-[15]
0:002> p
Time Travel Position: E92C1:108
eax=f2bca0c8 ebx=00000000 ecx=6ec75bfe edx=00000000 esi=0a02b330 edi=f3a2a970
eip=6ee28e9d esp=052fc4b4 ebp=052fc4dc iopl=0         nv up ei ng nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000282
CoolType!CTGetVersion+0xb596d:
6ee28e9d 8365ec00        and     dword ptr [ebp-14h],0 ss:002b:052fc4c8=f3a2e384
0:002> db f2bca0c8
f2bca0c8  e0 e0 e0 e0 e0 e0 e0 e0-e0 e0 e0 e0 e0 e0 e0 e0  ................
f2bca0d8  e0 e0 e0 e0 e0 e0 e0 e0-e0 e0 e0 e0 e0 e0 e0 e0  ................
f2bca0e8  e0 e0 e0 e0 e0 e0 e0 e0-e0 e0 e0 e0 e0 e0 e0 e0  ................
f2bca0f8  e0 e0 e0 e0 e0 e0 e0 e0-e0 e0 e0 e0 e0 e0 e0 e0  ................
f2bca108  e0 e0 e0 e0 e0 e0 e0 e0-e0 e0 e0 e0 e0 e0 e0 e0  ................
f2bca118  e0 e0 e0 e0 e0 e0 e0 e0-e0 e0 e0 e0 e0 e0 e0 e0  ................
f2bca128  e0 e0 e0 e0 e0 e0 e0 e0-e0 e0 e0 e0 e0 e0 e0 e0  ................
f2bca138  e0 e0 e0 e0 e0 e0 e0 e0-e0 e0 e0 e0 e0 e0 e0 e0  ................

0:002> p
Time Travel Position: E92C1:109
eax=f2bca0c8 ebx=00000000 ecx=6ec75bfe edx=00000000 esi=0a02b330 edi=f3a2a970
eip=6ee28ea1 esp=052fc4b4 ebp=052fc4dc iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
CoolType!CTGetVersion+0xb5971:
6ee28ea1 894608          mov     dword ptr [esi+8],eax ds:002b:0a02b338=e0e0e0e0 <-[16]

[...]

0:002> p
Time Travel Position: E92C1:10F
eax=00000000 ebx=00000000 ecx=00010000 edx=00000000 esi=0a02b330 edi=f3a2a970
eip=6ee28eb0 esp=052fc4b8 ebp=052fc4dc iopl=0         ov up ei ng nz na pe cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000a87
CoolType!CTGetVersion+0xb5980:
6ee28eb0 57              push    edi          <-[17]
0:002> p
Time Travel Position: E92C1:110
eax=00000000 ebx=00000000 ecx=00010000 edx=00000000 esi=0a02b330 edi=f3a2a970
eip=6ee28eb1 esp=052fc4b4 ebp=052fc4dc iopl=0         ov up ei ng nz na pe cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000a87
CoolType!CTGetVersion+0xb5981:
6ee28eb1 e8ad3de6ff      call    CoolType!CTInit+0x195e3 (6ec8cc63)
0:002> p
Time Travel Position: E92C1:12A
eax=00000000 ebx=00000000 ecx=00000000 edx=00000000 esi=0a02b330 edi=f3a2a970
eip=6ee28eb6 esp=052fc4b4 ebp=052fc4dc iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
CoolType!CTGetVersion+0xb5986:
6ee28eb6 59              pop     ecx
0:002> u
CoolType!CTGetVersion+0xb5986:
6ee28eb6 59              pop     ecx
6ee28eb7 0fb7d0          movzx   edx,ax
6ee28eba 8b4608          mov     eax,dword ptr [esi+8]
6ee28ebd 0fb7cb          movzx   ecx,bx
6ee28ec0 43              inc     ebx
6ee28ec1 66891448        mov     word ptr [eax+ecx*2],dx
6ee28ec5 663b5e04        cmp     bx,word ptr [esi+4]
6ee28ec9 72e5            jb      CoolType!CTGetVersion+0xb5980 (6ee28eb0) <-[18]

[8], [10], [12]에서 각각 itemCount, shortDeltaCount, regionIndexCount 값을 읽어와 [9], [11], [13]을 통해 0a02b330, 0a02b330+2, 0a02b330+4 주소에 write 합니다.

위 세 가지 값은 첫 번째 하위 테이블의 정보를 나타내며, 특히 regionIndexCount은 regionIndexes 배열의 크기를 결정합니다.

[14]에서 regionIndexCount 값(0x8000)을 통해 버퍼 크기(0x10000)를 계산합니다. 이후 [15]에서 CoolType!CTInit+0x2556을 호출해 regionIndexes 버퍼를 할당합니다.

[16]에서 할당된 regionIndexes 버퍼의 포인터(0xf2bca0c8)를 [4]에서 할당한 버퍼(0a02b330+8)에 기록합니다.

[17]에서 시작해 [18]에서 끝나는 루프는 첫 번째 itemVariationData 하위 테이블 regionIndex를 통해 해당 값을 regionIndexes 버퍼에 write 합니다.

이때, 파일 데이터가 부족해 regionIndexes 데이터를 모두 읽지 못하면 할당된 모든 버퍼를 해제하려고 합니다.

0:002> g
Time Travel Position: E9353:6D
eax=00000000 ebx=00000000 ecx=f3a36e40 edx=09cf0000 esi=f3a2a970 edi=00000000
eip=6ee279d9 esp=052fc1d8 ebp=052fc1e4 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
CoolType!CTGetVersion+0xb44a9:
6ee279d9 8b863c020000    mov     eax,dword ptr [esi+23Ch] ds:002b:f3a2abac=0a02b330
0:002> t
Time Travel Position: E9353:6E
eax=0a02b330 ebx=00000000 ecx=f3a36e40 edx=09cf0000 esi=f3a2a970 edi=00000000
eip=6ee279df esp=052fc1d8 ebp=052fc1e4 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
CoolType!CTGetVersion+0xb44af:
6ee279df ff740708        push    dword ptr [edi+eax+8] ds:002b:0a02b338=f2bca0c8 <-[19]
0:002> dd 0a02b330
0a02b330  00000000 e0e08000 f2bca0c8 e0e0e0e0
0a02b340  e0e0e0e0 e0e0e0e0 e0e0e0e0 e0e0e0e0

0:002> p
Time Travel Position: E9353:6F
eax=0a02b330 ebx=00000000 ecx=f3a36e40 edx=09cf0000 esi=f3a2a970 edi=00000000
eip=6ee279e3 esp=052fc1d4 ebp=052fc1e4 iopl=0         nv up ei pl zr na pe nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000246
CoolType!CTGetVersion+0xb44b3:
6ee279e3 e82a4ce5ff      call    CoolType!CTInit+0x8f92 (6ec7c612) <-[20]
0:002> p
Time Travel Position: E935D:2382
eax=00000001 ebx=00000000 ecx=f2bca0c8 edx=09cf0000 esi=f3a2a970 edi=00000000
eip=6ee279e8 esp=052fc1d4 ebp=052fc1e4 iopl=0         nv up ei pl nz na po nc
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000202
CoolType!CTGetVersion+0xb44b8:
6ee279e8 0fb78638020000  movzx   eax,word ptr [esi+238h]  ds:002b:f3a2aba8=0002
0:002> dd f2bca0c8  <-[21]
f2bca0c8  f0f0f0f0 f0f0f0f0 f0f0f0f0 f0f0f0f0
f2bca0d8  f0f0f0f0 f0f0f0f0 f0f0f0f0 f0f0f0f0
f2bca0e8  f0f0f0f0 f0f0f0f0 f0f0f0f0 f0f0f0f0
f2bca0f8  f0f0f0f0 f0f0f0f0 f0f0f0f0 f0f0f0f0
f2bca108  f0f0f0f0 f0f0f0f0 f0f0f0f0 f0f0f0f0
f2bca118  f0f0f0f0 f0f0f0f0 f0f0f0f0 f0f0f0f0
f2bca128  f0f0f0f0 f0f0f0f0 f0f0f0f0 f0f0f0f0
f2bca138  f0f0f0f0 f0f0f0f0 f0f0f0f0 f0f0f0f0

[...]

0:002> t
Time Travel Position: E935D:2389
eax=0a02b330 ebx=00000001 ecx=f2bca0c8 edx=09cf0000 esi=f3a2a970 edi=00000010
eip=6ee279df esp=052fc1d8 ebp=052fc1e4 iopl=0         nv up ei ng nz ac pe cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000297
CoolType!CTGetVersion+0xb44af:
6ee279df ff740708        push    dword ptr [edi+eax+8] ds:002b:0a02b348=e0e0e0e0  <-[22]
0:002> t 
Time Travel Position: E935D:238A
eax=0a02b330 ebx=00000001 ecx=f2bca0c8 edx=09cf0000 esi=f3a2a970 edi=00000010
eip=6ee279e3 esp=052fc1d4 ebp=052fc1e4 iopl=0         nv up ei ng nz ac pe cy
cs=0023  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000297
CoolType!CTGetVersion+0xb44b3:
6ee279e3 e82a4ce5ff      call    CoolType!CTInit+0x8f92 (6ec7c612) <-[23]

[19]에서 첫 번째 regionIndexes 버퍼의 주소(0xf2bca0c8)를 스택에 push 합니다.

[20]에서 CoolType!CTInit+0x8f92를 호출해 첫 번째 버퍼를 해제합니다.

[22]에서 두 번째 하위 테이블의 regionIndexes 버퍼 주소를 push 하려 하지만, 할당이 안되었기 때문에 더미 데이터(0xe0e0e0e0)를 push 해 [23] 실행 시 크래시가 발생합니다.

따라서, 공격자는 [4]에서 할당된 버퍼(0x0a02b330)를 조작할 수 있으면 임의의 코드를 실행할 수 있습니다.



본 글은 CC BY-SA 4.0 라이선스로 배포됩니다. 공유 또는 변경 시 반드시 출처를 남겨주시기 바랍니다.