您好,欢迎光临本网站![请登录][注册会员]  
文件名称: Technical Analysis of the Pegasus Exploits on iOS
  所属分类: 系统安全
  开发工具:
  文件大小: 710kb
  下载次数: 0
  上传时间: 2019-03-23
  提 供 者: weixin_********
 详细说明:Technical Analysis of the Pegasus Exploits on iOS This section reports on first stage of the Pegasus exploit of the “Trident” zero­day vulnerabilities on iOS, discovered by researchers at Lookout and Citizen Lab. The first stage of the attack is triggered when the user clicks a spear­phishing link that opens the Safari browser. This enables the exploit of a vulnerability in WebKit’s JavaScriptCore library (CVE­2016­4657).Section 1: Pegasus Exploitation of Safari (CVE2016-4657) The First Stage of Infection This section reports on first stage of the Pegasus exploit of the Trident zero-day vulnerabilities on ioS, discovered by researchers at Lookout and Citizen Lab. The first stage of the attack is triggered when the user clicks a spear-phishing link that opens the Safari browser. This enables the exploit of a vulnerability in Webkit's JavaScriptCore library (CVE-2016-4657) Page 2 Analysis of the Pegasus Safari EXploit The first stage of Pegasus exploits a vulnerability in WebKit's JavaScript Core library CVE-2016-4657) The exploit uses the Safari web browser to run a Java Script payload that exploits the initial vulnerability to gain arbitrary code execution in the context of the Safari Web Content process Background The vulnerability exists within the slow Append method of MarkedArgument Buffer and can be exploited via the usage of a MarkedArgument Buffer in the static define Properties( method.The define Properties( method accepts as input an object whose own enumerable properties constitute descriptors for the properties to be defined or modified on another target object. the algorithm used to associate each of these properties with the target object does two iterations of the provided list of properties In the first pass, each of the property descriptors is checked for proper formatting and a property Descriptor object is created that references the underlying value size t numProperties= proper tyNames size()i Vector descriptors; MarkedArgumentBuffer markBuffer; for (size t i =0; i< numProperties; i++)( USValue prop propercies->get(exec, propertyNamesi])i if(exec->hadException()) return i sNull()i PropertyDescriptor descriptor if(! topropertyDescriptor(exec, prop, descriptor)) return sNull(): descriptors append(descriptor)i The second pass is performed after each property has been validated this pass associates each of the user-supplied properties with the target object, using the type specific define Own Property o method for (size t i=0;i< numProperties; i++)i Identifier propertyName propertyNames [i]i f (exec->propertyNames().isPrivateName (propertyName ) continue object-methodTable(exec->v())->defineownProper-y(object, exec, prcpertyName descriptors[il, true)i This method may result in user-defined JavaScript methods(that are associated with the property being defined)being called. Within any of these user-defined methods, it is possible that a garbage collection cycle may be triggered, resulting in any unmarked heap backed objects being free(ed. Therefore, it is important that each of the temporary references to these Page 3 objects, stored within the individual Property Descriptors in the descriptors vector, be individually marked to ensure that these references to not become stale to achieve this a MarkedArgumentBuffer is used. This class is intended to temporarily prevent the values appended to it from being garbage collected during the period for which it is in scope To understand how Marked argumentBuffers work we must first understand some basics of Java script Core garbage collection. The garbage collector is responsible for deallocating abjects that are no longer referenced and runs at random intervals that increase in frequency as more memory is used by the WebContent process to determine whether an object is referenced, the garbage collector walks the stack and looks for references to the object References to an object may also exist on the application heap, however, so an alternate mechanism (which will be explained in detail below)must be used for these cases A MarkedArgumentBuffer initially attempts to maintain an inline stack buffer containing each value. When the stack is walked within garbage collection each value will be noted and the underlying objects will avoid deallocation class MarkedArgumentBuffer I private: static const size t inlinecapacity =3; MarkedArgumentBuffer( m sIze ty(inlines ty) m buffer(m inlineBuffer m market(0 void append (uSvalue v I(m size n slow Append (v)i lotFor(m size)= JSValue:: encode(v)i 十+ In sIZe int m size int m capa EncodeduSValue m inlineBufier[inlinecapacity]i m buffe Page 4 The size of this inline stack buffer is limited to eight values. When the ninth value is added to a MarkedArgumentBuffer, the underlying buffer is moved to the heap and the capacity is expanded void MarkedArgumentBuffer:: slowAppend (uSvalue v int rewCapacity = m capacity 4 EncodedJsvaluex newBuffer new EncodedJSValue [newCapacity]i for (int i =0, i m capacit rewBuffer[-]= m bufferili if(EncodeduSValue* base maliccBase()) delete base m buffer newBuffer m capacity newCapacityi Once the underlying buffer has moved to the heap, values are not automatically protected from garbage collection. To ensure that these objects are not deallocated the garbage collector performs a MarkingArgumentBuffers phase in which each value contained within a MarkedArgumentBuffer that has been added to the Heap's m marklistSet is marked( marking a cell ensures that it will not be deallocated in a particular garbage collection cycle). For this method of marking to work, the markedArgumentBuffer must be added to the mark List Set at the same time that the markedargumentBuffer's underlying values are moved to the heap // As long as our size stays within our Vector's inline , capacity, a l our values are allocated on the stack, and / trerefore don't need exp_icit marking. Once our size exceeds // our Vector's inline capacity, though, our values move to the // heap, where they do need explicit marking for (int i=0 Eeap* he H if ( heap) heap->markListset() breaki The above code attempts to acquire the heap context for a value and add the MarkedArgumentBuffer to the Heap s markListset However, this is only attempted once for the ninth value added to the MarkedArgumentBuffer inline Heap* Heap: hear(const uSVal f (!v.isdell() return heap( 11()); a USValue contains a tag which describes the type of the value that it encodes In the case of complex objects this tag will be Cell Tag and the Js Value will encode a pointer to an underlying item on the Heap. Alternatively, for simple types where the entire underlying value of the variable can be encoded directly into a JSValue(ex Integers, Booleans, null, and undefined) storing the value on the heap would be redundant and a different identifying tag will be used The function JSValue: is Cello is used to determine whether a Js Value encodes a pointer to a cell on the Heap. Because simple types do not point to the heap, attempting to acquire the Heap (via a call to Heap: heap)for these types has no meaning and will therefore return NULL inline bool JSValue:: isCell() const return !(u. asInt64 TagMask)i } As a result, if the ninth value added to a markedArgumentBuffer is not a heap backed value attempting to acquire the Heap context will return NULL and the marked Buffer will never be added to the Heaps marklistset. This means that the markedArgumentBuffer will no longer serve its purpose(to protect the items that it contains from deallocation) for any item after the ninth. Any reference to a heap backed property(after the ninth )contained within the descriptors vector has the potential to go stale. In reality, at least one other reference to these values still exists(the Java Script variable that was passed to define Properties( ). In order for the eferences within the descriptors vector to go stale, these remaining references to the jsvalue must also be removed before garbage collection occurs He 2. Walk mark ist Hea marksetlist neta-Data Link not MarkedArgumentBuffel I created backing vector Garbage free Collection not number Heap Chunks arr 3. deallocate unreferenced cells target free tack int: 0 not number targ The call to define Own Property(within the second loop of define Properties() may result in calling user-controlled methods defined on property values. As a result, the last marked Page 6 garbage collection can be triggered between the removal of all remaining references to"/ references to a property value could be removed within this user-defined JavaScript code property value and the(now stale)value from the descriptors vector being defined on the target object, a reference to free(ed memory will be defined as a property on the target object Exploitation The Pegasus exploit triggers this vulnerability by passing a specifically crafted sequence of properties to the define Properties method. When these individual properties are subsequently inserted into a MarkedArgumentBuffer the vulnerability is triggered such that a jsarray object will be improperly deallocated if garbage collection can be triggered at a critical point in time Because garbage collection can not be triggered deterministically, the exploit makes repeated attempts to trigger the improper deallocation and subsequent reallocation(for a total of ten attempts), testing each time whether a stale reference has been successfully acquired Assuming garbage collection has been triggered at the correct time, another object is allocated over the top of the now stale JSArray. The exploit then sets up the tools needed to gain arbitrary native code execution, namely a read/write primitive and the ability to leak the address of an arbitrary Java Script object. Once this is complete the exploit can create an executable mapping containing the native code payload. The following sections detail the various stages of this orocess Setting up and triggering the vulnerability In order to achieve arbitrary code execution, the exploit triggers the vulnerable code path using a jSArray object The following pseudo code is used to trigger the vulnerability var arr ew Array(2047) var not number not number tostring function()( null props["stale" // Trigger garbage collection and reallocation over stale object return 10 p0: value :0 J 2: value 2 1 p alue 5} 8: vall stale :i value: fter :i value 666) Page 7 var target =[]i Object. defineproperties(target, props)i The specified props object has been specifically crafted to trigger the vulnerability in slow(. When the ninth property is added to the markedArgumentBuffer(p8), slow Append will fail to acquire a heap context(because the value is simple type, an integer, and not backed by an item on the heap). Subsequent Heap-backed values(not_number and arr) will not be explicitly protected from deallocation by the MarkedArgumentBuffer during garbage collection When defineOwnProperty( is called for the length property, it will attempt to convert the value (not_number)to a number. As part of this code path, the toString( method will be called allowing the last two references to the arr JSArray to be removed. Once removed, this JSArray is no longer marked, and the next garbage collection pass will deallocate the object. Pegasus creates memory pressure(allocates a large amount of memory) within the to String( method in an attempt to force garbage collection to run(and deallocate the arr object var attempts new Array(4250000) var pressure new Array (100); not number toString function() i for (var i=0; - pressure. -ength; i++) pressure[i new Uint32Array (262144)i var buffer new ArrayBuffer(80)i var uirtArray new Uint32Array (buffer aRray[o]=0xAABECCDD; for (i =0; i< attempts. length; i++) attempts[i]= new Uint32Array (buffer)i Each of the 4.25 million Uint32Arrays allocated for the attempts array use the same backing Array Buffer. These objects are used to attempt to reallocate a series of uint32Arrays into the same memory referenced by the jS Array object (arr) Once complete, the exploit checks to see whether garbage collection was successfully triggered var before len arr length Object. defineProperties (targe=, props)i stale target sta e var after len stale length: if (before len after len hrow rew RecoverableException(8)i Page 8 If the length of the jSarray remains the same it means that either garbage collection was not triggered or that none of the allocated Uint 32Arrays were allocated into the same address as the stale object. In these cases, the exploit has failed and the exploit is retried Acquiring an arbitrary read/write primitive Assuming the exploit has succeeded to this point, there are now two objects of different types that are represented by the same memory. The first is the(now stale)JSArray, and the second is one of the many Uint32Arrays that were allocated(in fact, the underlying templated type is JS GenericTypedArray View) By reading from and writing to offsets into the stale object, member variables of the JS Generic TypedArray View can be read or corrupted. Specifically, the exploit writes to an offset into the stale jsarray that overlaps with the length of the JSGenericTypedArray VieW, effectively setting the length of the Uint32Array to OXFFFFFFFF Corrupting this value will allow the array to be treated as a view of the entire virtual address space of the Web Content process (an arbitrary read/write primitive) The exploit still must determine which of the 4.25 million Uint32Arrays that were allocated aligns with the stale object. This can be determined by iterating through each of the arrays and checking whether the length has changed to OXF FFFFFFF. All other arrays will still have the original backing Array Buffer (or a length of 80/4) (x== attempts -ength -l;x>=li x--) if (attempts[x]. ength =80/2) if (attempts[x,length = OXFFFFEFFF) memory view attempts [x]; Leaking an object address The final component needed to complete the exploit is the ability to leak the address of an arbitrary JavaScript object. The Pegasus exploit accomplishes this using the same mechanism that was used to corrupt the length of the Uint 2Array used for the read/write primitive By writing to an offset into the stale object, the buffer of a Uint32Array is corrupted to point to a user-controlled JSArray. By setting the first element of that JSArray to the Java Script object to be leaked(by corrupting the pointer to the underlying storage of the Uint32Array), the object's address can be read back out of the Uint32Array Native code execution All that is left to do for the first stage of the Pegasus exploit is to create an executable mapping that will contain the shellcode to be executed. To accomplish this purpose, a JSFunction object created (containing hundreds of empty try/catch blocks that will later be overwritten). To help ensure that the JavaScript will be compiled into native code by the Jit, the function is Page 9
(系统自动生成,下载前可以参看下载内容)

下载文件列表

相关说明

  • 本站资源为会员上传分享交流与学习,如有侵犯您的权益,请联系我们删除.
  • 本站是交换下载平台,提供交流渠道,下载内容来自于网络,除下载问题外,其它问题请自行百度
  • 本站已设置防盗链,请勿用迅雷、QQ旋风等多线程下载软件下载资源,下载后用WinRAR最新版进行解压.
  • 如果您发现内容无法下载,请稍后再次尝试;或者到消费记录里找到下载记录反馈给我们.
  • 下载后发现下载的内容跟说明不相乎,请到消费记录里找到下载记录反馈给我们,经确认后退回积分.
  • 如下载前有疑问,可以通过点击"提供者"的名字,查看对方的联系方式,联系对方咨询.
 输入关键字,在本站1000多万海量源码库中尽情搜索: