Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to analyze the vulnerability of Safari Information leakage

2025-02-24 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Network Security >

Share

Shulou(Shulou.com)06/01 Report--

Today, I will talk to you about how to analyze the vulnerabilities of Safari information disclosure. Many people may not know much about it. In order to make you understand better, the editor has summarized the following contents for you. I hope you can get something according to this article.

Preface

Arrays and array objects in Javascript have always been the main goals for programmers to optimize. In general, arrays contain only basic type data, such as 32-bit integers or characters. As a result, each engine makes some optimizations for these objects and improves access speed and intensive representation for different element types.

In JavaScriptCore, the JavaScript engine is implemented in WebKit, where each element stored in the object represents an IndexingType value, an 8-bit integer represents a set of Flag combinations, and the specific parameter definition can be found in IndexingType.h. Next, the engine detects the type of indexing in an object and then decides which fast path to use. One of the most important indexing types is ArrayWithUndecided, which means that all elements are undefined and no actual values are stored. In this case, the engine keeps these elements uninitialized in order to improve performance.

Analysis.

Next, let's take a look at the code (ArrayPrototype.cpp) that implements Array.prototype.concat in the old version:

EncodedJSValueJSC_HOST_CALL arrayProtoPrivateFuncConcatMemcpy (ExecState* exec) {... Unsigned resultSize = checkedResultSize.unsafeGet (); IndexingType firstType = firstArray- > indexingType (); IndexingType secondType = secondArray- > indexingType (); IndexingType type = firstArray- > mergeIndexingTypeForCopying (secondType); / / [[1]] if (type = = NonArray |! firstArray- > canFastCopy (vm, secondArray) | | resultSize > = MIN_SPARSE_ARRAY_INDEX) {.} JSGlobalObject* lexicalGlobalObject = exec- > lexicalGlobalObject (); Structure* resultStructure = lexicalGlobalObject- > arrayStructureForIndexingTypeDuringAllocation (type) If (UNLIKELY (resultStructure- > indexingType () return JSValue::encode (jsNull ()); ASSERT (! lexicalGlobalObject- > isHavingABadTime ()); ObjectInitializationScopeinitializationScope (vm); JSArray* result = JSArray::tryCreateUninitializedRestricted (initializationScope, resultStructure,resultSize); if (UNLIKELY (! result)) {throwOutOfMemoryError (exec, scope); return encodedJSValue () } if (type = = ArrayWithDouble) {[[2]] double* buffer = result- > butterfly ()-> contiguousDouble (). Data (); memcpy (buffer,firstButterfly- > contiguousDouble (). Data (), sizeof (JSValue) * firstArraySize); memcpy (buffer + firstArraySize,secondButterfly- > contiguousDouble (). Data (), sizeof (JSValue) * secondArraySize);} else if (type! = ArrayWithUndecided) {.

This function is mainly used to determine the indexing type of the resulting array [[1]]. We can see that if the indexing type is ArrayWithDouble, it will choose [[2]] as the fast path. Next, let's take a look:

MergeIndexingTypeForCopying implementation code, this function is mainly responsible for determining the indexing type of the result array when Array.prototype.concat is called:

InlineIndexingType JSArray::mergeIndexingTypeForCopying (IndexingType other) {IndexingType type = indexingType (); if (! (type & IsArray & & other& IsArray)) return NonArray; if (hasAnyArrayStorage (type) | | hasAnyArrayStorage (other)) return NonArray; if (type = = ArrayWithUndecided) return other; [[3]].

We can see that in this case, there is an input array whose indexing type is ArrayWithUndecided, and the result is that the indexing type will be the indexing type of another array. Therefore, if we call the Array.prototype.concat method with an array of type ArrayWithUndecided of indexing and another array of type ArrayWithDouble of Array.prototype.concat, we will follow the fast path [[2]] and concatenate the two arrays.

This code does not guarantee that the two "butterfly" (a concept in the JavaScript engine attack technology, see [this article] for details) will be initialized correctly before the code calls memcpy. This means that if we can find a code path that allows us to create an uninitialized array and pass it to Array.prototype.concat, we can have an array object in heap memory that contains uninitialized values, and its indexing type is not ArrayWithUndecided. To some extent, this security issue is similar to an old vulnerability reported by lokihardt in 2017, but exploited differently.

When creating such an array object, you can use the opcode of NewArrayWithSize DFG JIT. After analyzing the allocateJSArray opcode implemented by FTL in FTLLowerDFGToB3.cpp, we can see that the array will contain uninitialized values. The engine does not need to initialize the array at all because the indexing type of the array is ArrayWithUndecided.

ArrayValuesallocateJSArray (LValue publicLength, LValue vectorLength, LValue structure,LValue indexingType, bool shouldInitializeElements = true, boolshouldLargeArraySizeCreateArrayStorage = true) {[...] InitializeArrayElements (indexingType, shouldInitializeElements? m_out.int32Zero: publicLength, vectorLength, butterfly);... voidinitializeArrayElements (LValue indexingType, LValue begin, LValue end, LValuebutterfly) {if (begin = = end) return; if (indexingType- > hasInt32 ()) {IndexingType rawIndexingType = static_cast (indexingType- > asInt32 ()); if (hasUndecided (rawIndexingType)) return; / / [4]

The statement new Array (n) will trigger [4] when compiled by FTL JIT, and then return an array of indexing type ArrayWithUndecided containing uninitialized elements.

Vulnerability exploitation

After knowing the principle of the vulnerability described earlier, it must not be difficult to trigger this vulnerability: we can repeatedly call a function that uses the new Array () method to create an array, and then call the concat method to concatenate the array with an array that contains only data of type double. After calling enough times, the FTL compiler will compile it.

This [vulnerability exploit code] can use this vulnerability to disclose the memory address of a target object. The implementation mechanism is to spray memory through the object we created. After triggering this vulnerability, we can find the address of the target object from the array returned by the code.

This vulnerability has been fixed in iOS 12 and the latest version of macOS Mojave (Safari), and the CVE number of the vulnerability is CVE-2018-4358.

After reading the above, do you have any further understanding of how to analyze Safari information disclosure vulnerabilities? If you want to know more knowledge or related content, please follow the industry information channel, thank you for your support.

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Network Security

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report