
PoC CVE-2023-28205:Apple WebKit 释放后使用漏洞
该漏洞影响 Apple WebKit,可通过恶意构造的 Web 内容加以利用,并有可能在 WebKit 进程上下文中执行任意代码。
本仓库中所分析的受影响 WebKit 构建基于 WebKit-613.1.17.1(PlayStation / Safari 15.4 系列)。
该概念验证通过在结构化克隆操作期间有意延迟注册 Map 和 Date 等 JavaScript 对象,从而触发**释放后使用(UAF)**条件。
这一时间窗口使 JavaScriptCore 垃圾回收器(GC) 得以回收在逻辑上仍处于使用中的对象,导致在继续执行期间解引用悬空指针。
SerializedScriptValueCloneDeserializer::deserialize()该漏洞存在于结构化克隆反序列化逻辑中,具体而言是递归反序列化期间如何跟踪新建 JavaScript 对象的方式。
在 SerializedScriptValue.cpp 中,反序列化器使用了标准的 WebKit 容器,例如:
Vector<JSObject*, 32> outputObjectStack;
Vector<JSMap*, 4> mapStack;
Vector<JSSet*, 4> setStack;
这些 Vector 容器不会被垃圾回收器扫描。如果在反序列化期间触发了垃圾回收周期(例如由于内存压力或重入式 JS 执行),那么仅由这些容器引用的对象可能会被错误回收。
然而,反序列化器仍会继续使用这些悬空指针,从而造成释放后使用情况。
官方 WebKit 安全补丁(提交 c9880de)将这些容器替换为 MarkedVector,这是一种具备 GC 感知能力的结构,可将其内容正确注册为 GC 根。
在所分析的构建中:
MarkedVector 未实现CloneDeserializer 仍使用 Vector这证实该构建完全易受 CVE-2023-28205 影响。
以下崩溃由 PoC 稳定触发,并与 GC 后的悬空指针解引用相吻合。
SIGSEGV (11)0x0000000000000068SceNKWebProcesslibSceNKWebKit.sprx故障地址 0x68 表明发生了带对象字段偏移的 NULL 基指针解引用,这是访问已释放 JavaScript 对象的典型特征。
寄存器状态确认:
RAX = 0x0(NULL 对象基址)该崩溃行为是上述 CloneDeserializer UAF 的直接体现。
#
# A user thread receives a fatal signal
#
# signal: 11 (SIGSEGV)
# thread ID: 101395
# thread name: SceNKWebProcessMain
# proc ID: 88
# proc name: SceNKWebProcess
# reason: page fault (user read data, page not present)
# fault address: 0000000000000068
#
# registers:
# rax: 0000000000000000 rbx: 0000000000000000
# rcx: 000000020017e000 rdx: ffffffff00000000
# rsi: fffe000000000002 rdi: 0000000201d8c000
# rbp: 00000007eeff9f20 rsp: 00000007eeff9dc0
# r8 : 0000000200194c60 r9 : 00000002005ddc70
# r10: 0000000000000004 r11: 0000000000000000
# r12: 0000000200200000 r13: 0000000201d8c000
# r14: 0000000200880a00 r15: 0000000201d8c000
# rip: 0000000804d03bc1 eflags: 00010206
# BrF: 000000080424da9b BrT: 0000000804d03aa0
#
# backtrace:
copyin: SceNKWebProcessMain has nonsleeping lock
# 000000080424daa0
# 00000008052127b1
# 0000000805224b1b
# 0000000805224b1b
# 0000000805224b92
# 0000000805224b1b
# 0000000805208549
# 00000008037cd403
# 0000000803ed90a5
# 0000000804c48bd2
# 00000008045e2295
# 0000000804073b3b
# 000000080337f214
# 0000000802c62f61
# 0000000803e2b04b
# 0000000804645f82
# 000000080306ddc0
# 0000000803a06adb
# 0000000802e77528
# 0000000804281a70
# 0000000803bff887
# 0000000000405181
# 0000000000403d84
# 00000000004045ef
# 0000000000000000
#
# dynamic libraries:
# /goHvLUnT0D/common/lib/NKWebProcess.self
# text: 0000000000400000:0000000000408000 r-x
# data: 000000000040c000:0000000000410000 rw-
# fingerprint: 9f75275c0c9e6a8f512c46351676ba9c00000000
# /goHvLUnT0D/common/lib/libkernel_web.sprx
# text: 0000000800000000:0000000800050000 r-x
# data: 0000000800054000:000000080008c000 rw-
# fingerprint: 5cc7d026be64eb384dc8edd813cf5dff00000000
# /goHvLUnT0D/common/lib/libSceLibcInternal.sprx
# text: 000000080008c000:00000008001c0000 r-x
# data: 00000008001c8000:00000008001e4000 rw-
# fingerprint: 10c2fb20aecfba270ab36512cc6bcd3c00000000
# /goHvLUnT0D/common/lib/libSceSysmodule.sprx
# text: 00000008001e4000:00000008001f0000 r-x
# data: 00000008001f4000:0000000800200000 rw-
# fingerprint: d53329218364300cfc9ac1ce2f5f319000000000
# /goHvLUnT0D/common/lib/libScePosixForWebKit.sprx
# text: 0000000800200000:0000000800204000 r-x
# data: 0000000800208000:000000080020c000 rw-
# fingerprint: 2540b10c69fafebe19bf6c817f06a5dd00000000
# /goHvLUnT0D/common/lib/libcairo.sprx
# text: 000000080020c000:0000000800318000 r-x
# data: 0000000800320000:0000000800324000 rw-
# fingerprint: 66924f66c3b2bcfd5877f0b6b53b17c800000000
# /goHvLUnT0D/common/lib/libcurl.sprx
# text: 0000000800324000:00000008003d0000 r-x
# data: 00000008003d4000:00000008003d8000 rw-
# fingerprint: d07498e9ec79386fc781c8feeea9aa2800000000
# /goHvLUnT0D/common/lib/libfontconfig.sprx
# text: 00000008003d8000:0000000800450000 r-x
# data: 0000000800454000:0000000800458000 rw-
# fingerprint: f588f705527618061e0a9e633018197300000000
# /goHvLUnT0D/common/lib/libfreetype.sprx
# text: 0000000800458000:0000000800500000 r-x
# data: 0000000800508000:000000080050c000 rw-
# fingerprint: 55f0bf21e56f35c305acd791696e05b100000000
# /goHvLUnT0D/common/lib/libharfbuzz.sprx
# text: 000000080050c000:00000008005cc000 r-x
# data: 00000008005d0000:00000008005d4000 rw-
# fingerprint: 0e11f91a091308d571226554af07ce4000000000
# /goHvLUnT0D/common/lib/libicu.sprx
# text: 00000008005d4000:0000000802504000 r-x
# data: 0000000802524000:0000000802528000 rw-
# fingerprint: 1ef63fd860c70ff5f8744411e1ba581800000000
# /goHvLUnT0D/common/lib/libpng16.sprx
# text: 0000000802528000:000000080255c000 r-x
# data: 0000000802560000:0000000802564000 rw-
# fingerprint: 1bb1e4c3acb314d2dd52df2ca6a7a03e00000000
# /goHvLUnT0D/common/lib/libSceIpmi.sprx
# text: 0000000802564000:0000000802570000 r-x
# data: 0000000802574000:0000000802588000 rw-
# fingerprint: d5f95ff9044c26f90ff63c82fb0bbf5c00000000
# /goHvLUnT0D/common/lib/libSceSysCore.sprx
# text: 0000000802588000:0000000802590000 r-x
# data: 0000000802594000:0000000802598000 rw-
# fingerprint: d577567a554a7563ef2327c820bf0ee200000000
# /goHvLUnT0D/common/lib/libSceNet.sprx
# text: 0000000802598000:00000008025d0000 r-x
# data: 00000008025d4000:00000008026e8000 rw-
# fingerprint: 979f14da6d4c7aa75cdd4d4b2f3281c900000000
# /goHvLUnT0D/common/lib/libSceNetCtl.sprx
# text: 00000008026e8000:00000008026f0000 r-x
# data: 00000008026f4000:00000008026f8000 rw-
# fingerprint: 162fbdf7aa83706cc0992108ca3393ae00000000
# /goHvLUnT0D/common/lib/libSceRandom.sprx
# text: 00000008026f8000:00000008026fc000 r-x
# data: 0000000802700000:0000000802704000 rw-
# fingerprint: 976d3ebefe3870b97bfa1d8e82f1df2d00000000
# /goHvLUnT0D/common/lib/libSceLibreSsl3.sprx
# text: 0000000802704000:000000080288c000 r-x
# data: 00000008028ac000:00000008028b0000 rw-
# fingerprint: bd895ec678ab2becafd45e954fba828400000000
# /goHvLUnT0D/common/lib/libSceRegMgr.sprx
# text: 00000008028b0000:00000008028b4000 r-x
# data: 00000008028b8000:00000008028bc000 rw-
# fingerprint: 50fe32bc796e1dbda2337287e42091d100000000
# /goHvLUnT0D/common/lib/libSceSystemService.sprx
# text: 00000008028bc000:00000008028f8000 r-x
# data: 00000008028fc000:0000000802908000 rw-
# fingerprint: 6fead8bbcbbf7002bee44d4d2104c8d300000000
# /goHvLUnT0D/common/lib/libSceMbus.sprx
# text: 0000000802908000:0000000802914000 r-x
# data: 0000000802918000:000000080291c000 rw-
# fingerprint: eaf5e1ec79a60c0293ad42c039a9ff1a00000000
# /goHvLUnT0D/common/lib/libSceAvSetting.sprx
# text: 000000080291c000:0000000802928000 r-x
# data: 000000080292c000:0000000802930000 rw-
# fingerprint: 6a745bdbf97da42d23745852daa2afc700000000
# /goHvLUnT0D/common/lib/libSceVideoOut.sprx
# text: 0000000802930000:0000000802948000 r-x
# data: 000000080294c000:0000000802950000 rw-
# fingerprint: 504c9ecf78fdc9adf3fcd3721dc3975100000000
# /goHvLUnT0D/common/lib/libSceVideoCoreServerInterface.sprx
# text: 0000000802950000:0000000802960000 r-x
# data: 0000000802964000:000000080296c000 rw-
# fingerprint: 4613f400001d613dda147326d8ef133900000000
# /goHvLUnT0D/common/lib/libSceNKWebKitRequirements.sprx
# text: 000000080296c000:0000000802bdc000 r-x
# data: 0000000802be0000:0000000802be8000 rw-
# fingerprint: aa200eff9a5fd90b0c6f12853aa1cbd200000000
# /goHvLUnT0D/common/lib/libSceNKWebKit.sprx
# text: 0000000802be8000:00000008060b8000 r-x
# data: 00000008062c0000:00000008062f8000 rw-
# fingerprint: bc8a78e3ddb906f6d0de352329701c2600000000
# /goHvLUnT0D/common/lib/libSceGLSlimClientVSH.sprx
# text: 00000008062f8000:0000000806318000 r-x
# data: 000000080631c000:0000000806320000 rw-
# fingerprint: 1cea1ecf4ffd91dc02ca2b7bc92c3c0a00000000
<118>[Syscore App] App Crash : PID=0x58, reason=0xb
<118>[Syscore App] Syscore Event Queue Push : SCE_SYSCORE_EVENT_APP_CRASH
<118>[Syscore App] Syscore Event Queue Pop : SCE_SYSCORE_EVENT_APP_CRASH
<118>[SceLncService] AppCrash: pid={0x00000058} appId={0x60000201} appLocalPid={0x102012a5}
<118>[SceLncService] getCoredumpSequence() isDebuggable={0} isKeepProcess={1} isUserDebugRequest={0} isLimitKeepProcess={0} enableCrashReport={1}
<118>[SceLncService] CoredumpSequence = {DUMP_PROCESS}
<118>[SceLncService] getCoredumpMode() isSystem={0x00000001}, reason={0x0000000b}
<118>[SceLncService] notifyAppCrash() pid={0x00000058}, appId={0x60000201}, appLocalPid={0x102012a5}, coredump.path,name,mode={/user/data/sce_coredumps/NPXS20001_1767544376/,NPXS20001_1767544376.sorbisdmp,1}, enableCrashReport={1}, skipVshDump={0}
<118>[SceLncService] enableCrashReport={1}, crashReportMode={1}, isAllowed={0}
<118>[SceLncService] kick coredump is disabled.
<118>[Syscore App] Kill process: 0x58
<118>[VCS]closeSession() [APP->VCS] clientPid = 0x58.
<118>[Syscore App] EVFILT_PROC NOTE_EXIT received : pid=0x58
<118>[Syscore App] Kill process: 0x58 => 0
<118>[Syscore App] process delete event : pid=0x58
<118>[AppMgr Trace]: pid=0x58, deleted.
<118>[Syscore App] Syscore Event Queue Push : SCE_SYSCORE_EVENT_ON_PROCESS_UNLOADED
<118>[AppMgr] checkAppTerminated pid=0x2a is still alive in 0x60000201
<118>[Syscore App] Syscore Event Queue Pop : SCE_SYSCORE_EVENT_ON_PROCESS_UNLOADED
<118>[SceShellUI] W/PSM.UI : ** NOTICE: LoadSync : Parent_BrowserMain : FrameModalScene
<118>[SceShellUI] I/PSM.UI : OnFocusActiveSceneChanged [BrowserMain : MainScene] -> [Parent_BrowserMain : FrameModalScene]
<118>[SceShellUI] I/PSM.UI : Scene [Parent_BrowserMain : FrameModalScene] : Alive
<118>SetDeviceIndexBehavior: mode=SpecificUser, param=0x1a599820
<118>[Theme/I] : Apply [RED] : [Option:111111]: with preloaded user
<118>[SceShellCore] Libc Heap Status: free 38%, in-use 3794.3 KB, trend +18.1 KB/min, peak 4267.3 KB, when 19698 [sec]
<118>[SceShellCore] VM Stats: RSS 533.4, kernel 271.1, wire count 332.2, swap out 24.2, page table CPU 2526/6144 GPU 271/2048
该漏洞通过 postMessage 提供了一个稳定的 UAF 原语:
postMessage 发送复杂的对象图这允许对 JavaScriptCore 内部结构(例如 StructureID、butterfly 指针)进行受控的内存破坏,使该漏洞在适当的堆整形下成为可靠利用的有力候选。
CVE-2023-28205 由 Clément Lecigne(谷歌威胁分析组)和 Donncha Ó Cearbhaill(国际特赦组织安全实验室)发现。
感谢 abc 提供原始概念验证的灵感。
基于 ntfargo 的 PoC 仓库 uaf-2023-28205