成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

Safari信息泄露漏洞分析

安全 漏洞
從某種程度上來說,這個安全問題跟lokihardt在2017年報告的一個 舊漏洞有些相似,只不過利用方式不同。

前言

Javascript中的數組和數組對象一直都是編程人員優化的主要目標,一般來說,數組只會包含一些基本類型數據,比如說32位整數或字符等等。因此,每個引擎都會對這些對象進行某些優化,并提升不同元素類型的訪問速度和密集型表示。

[[248537]]

在JavaScriptCore中,JavaScript引擎是在WebKit中實現的,其中每一個存儲在對象中的元素都代表著一個IndexingType值,一個8位整數代表一套Flag組合,具體的參數定義可以在IndexingType.h中找到。接下來,引擎會檢測一個對象中indexing的類型,然后決定使用哪一條快速路徑,其中最重要的一種indexing類型就是ArrayWithUndecided,它表示的是所有元素均為未定義(undefined),而且沒有存儲任何實際的值。在這種情況下,引擎為了提升性能,會讓這些元素保持未初始化。

分析

下面,我們一起看一看舊版本中實現Array.prototype.concat的代碼(ArrayPrototype.cpp):

  1. EncodedJSValueJSC_HOST_CALL arrayProtoPrivateFuncConcatMemcpy(ExecState* exec)  
  2.  
  3.     ...  
  4.     unsigned resultSize =checkedResultSize.unsafeGet();  
  5.     IndexingType firstType =firstArray->indexingType();  
  6.     IndexingType secondType =secondArray->indexingType();  
  7.     IndexingType type =firstArray->mergeIndexingTypeForCopying(secondType); // [[ 1 ]]  
  8.     if (type == NonArray ||!firstArray->canFastCopy(vm, secondArray) || resultSize >=MIN_SPARSE_ARRAY_INDEX) {  
  9.         ...  
  10.     }  
  11.     JSGlobalObject* lexicalGlobalObject =exec->lexicalGlobalObject();  
  12.     Structure* resultStructure =lexicalGlobalObject->arrayStructureForIndexingTypeDuringAllocation(type);  
  13.     if(UNLIKELY(hasAnyArrayStorage(resultStructure->indexingType())))  
  14.         return JSValue::encode(jsNull());  
  15.    ASSERT(!lexicalGlobalObject->isHavingABadTime());  
  16.     ObjectInitializationScopeinitializationScope(vm);  
  17.     JSArray* result =JSArray::tryCreateUninitializedRestricted(initializationScope, resultStructure,resultSize);  
  18.     if (UNLIKELY(!result)) {  
  19.         throwOutOfMemoryError(exec, scope);  
  20.         return encodedJSValue();  
  21.     }  
  22.     if (type == ArrayWithDouble) {  
  23.         [[ 2 ]]  
  24.         double* buffer =result->butterfly()->contiguousDouble().data();  
  25.         memcpy(buffer,firstButterfly->contiguousDouble().data(), sizeof(JSValue) *firstArraySize);  
  26.         memcpy(buffer + firstArraySize,secondButterfly->contiguousDouble().data(), sizeof(JSValue) *secondArraySize);  
  27.     } else if (type != ArrayWithUndecided) {  
  28. ... 

這個函數主要用來判斷結果數組[[1]]的indexing類型,我們可以看到,如果indexing類型為ArrayWithDouble,它將會選擇[[2]]作為快速路徑。接下來,我們看一看:

mergeIndexingTypeForCopying的實現代碼,這個函數主要負責在Array.prototype.concat被調用時,判斷結果數組的indexing類型:

  1. inlineIndexingType JSArray::mergeIndexingTypeForCopying(IndexingType other)  
  2.  
  3.     IndexingType type = indexingType();  
  4.     if (!(type & IsArray && other& IsArray))  
  5.         return NonArray;  
  6.     if (hasAnyArrayStorage(type) ||hasAnyArrayStorage(other))  
  7.         return NonArray;  
  8.     if (type == ArrayWithUndecided)  
  9.         return other; [[ 3 ]]  
  10. ... 

我們可以看到在這種情況下,有一個輸入數組的indexing類型為ArrayWithUndecided,結果indexing類型將會是另一個數組的indexing類型。因此,如果我們我們用一個indexing類型為ArrayWithUndecided的數組和另一個indexing類型為ArrayWithDouble的數組去調用Array.prototype.concat方法的話,我們將會按照快速路徑[[2]]運行,并將兩個數組進行拼接。

這段代碼并不能保證這兩個“butterfly”(JavaScript引擎攻擊技術里的一種概念,詳情請參考【這篇文章】)在代碼調用memcpy之前能夠正確初始化。這也就意味著,如果我們能夠找到一條允許我們創建一個未初始化數組并將其傳遞給Array.prototype.concat的代碼路徑,那我們就能夠在堆內存中擁有一個包含了未初始化值的數組對象了,而且它的indexing類型還不是ArrayWithUndecided。從某種程度上來說,這個安全問題跟lokihardt在2017年報告的一個舊漏洞有些相似,只不過利用方式不同。

在創建這種數組對象時,可以利用NewArrayWithSize DFG JIT的操作碼來實現,在對FTLLowerDFGToB3.cpp中FTL所實現的allocateJSArray操作碼進行分析之后,我們可以看到這個數組將會包含未初始化的值。引擎根本不需要對數組進行初始化,因為這個數組的indexing類型為ArrayWithUndecided。

  1. ArrayValuesallocateJSArray(LValue publicLength, LValue vectorLength, LValue structure,LValue indexingType, bool shouldInitializeElements = trueboolshouldLargeArraySizeCreateArrayStorage = true 
  2.  
  3.     [ ... ]  
  4.     initializeArrayElements(  
  5.        indexingType,  
  6.        shouldInitializeElements ?m_out.int32Zero : publicLength, vectorLength,  
  7.        butterfly);  
  8. ...  
  9. voidinitializeArrayElements(LValue indexingType, LValue begin, LValue end, LValuebutterfly)  
  10.  
  11.     if (begin == end)  
  12.         return;    
  13.     if (indexingType->hasInt32()) {  
  14.         IndexingType rawIndexingType =static_cast<IndexingType>(indexingType->asInt32());  
  15.         if (hasUndecided(rawIndexingType))  
  16.             return;  // [[ 4 ]] 

語句new Array(n)在被FTL JIT編譯時將會觸發[[4]],然后返回一個indexing類型為ArrayWithUndecided的數組,其中就包含未初始化的元素。

漏洞利用

清楚了之前所介紹的漏洞原理之后,想必觸發這個漏洞也并非難事:我們可以不斷重復調用一個使用new Array()方法來創建數組的函數,然后調用concat方法將這個數組和一個只包含double類型數據的數組進行拼接。在調用夠足夠次數之后,FTL編譯器將會對其進行編譯。

這份【漏洞利用代碼】可以利用這個漏洞來泄漏一個目標對象的內存地址,實現機制是通過我們所創建的對象進行內存噴射,在觸發這個漏洞之后,我們就能夠從代碼所返回的數組中找到目標對象的地址了。

總結

這個漏洞目前已經在iOS 12和macOS Mojave的最新版本(Safari)中修復了,該漏洞的CVE編號為CVE-2018-4358

責任編輯:趙寧寧 來源: FreeBuf
相關推薦

2023-05-06 11:05:50

2022-02-17 11:52:05

?Argo CD漏洞Kubernetes

2022-01-21 13:37:01

蘋果MacSafari 瀏覽器

2010-03-12 16:19:11

Safari漏洞修復

2014-11-27 13:28:55

信息泄露淘寶烏云

2022-01-21 06:54:18

iPhoneiPadiOS

2022-01-27 09:47:20

漏洞蘋果

2013-07-25 11:09:46

網站漏洞梭子魚

2022-01-17 12:46:05

API漏洞應用程序安全

2022-01-27 07:00:12

iPhoneiPadiOS

2022-01-27 23:29:21

iOS蘋果漏洞

2013-10-16 14:13:14

2011-03-07 10:40:15

2017-09-28 10:12:51

2022-04-18 11:46:44

銀行系統SSRF漏洞信息泄露

2010-11-22 12:56:37

2014-06-30 13:51:27

2013-11-18 09:35:38

信息泄露QQ微信

2009-03-07 09:56:01

2014-06-03 10:14:06

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 99精品视频一区二区三区 | 日一日操一操 | 成人午夜电影在线观看 | 国产精品久久国产精品 | 最新91在线| 久久久一二三 | 久久久久久久久毛片 | 极情综合网 | 中文字幕加勒比 | 成人不卡视频 | 日本成人在线播放 | 亚洲一区二区电影在线观看 | 精品欧美一区二区在线观看视频 | 日韩中文字幕视频 | 午夜天堂精品久久久久 | 日韩国产在线观看 | 成人精品免费视频 | 欧美一区二区三区大片 | 成人激情视频 | 日韩在线 | 特黄视频 | 国产黄视频在线播放 | 人人鲁人人莫人人爱精品 | 激情欧美日韩一区二区 | 三级免费毛片 | 午夜精品一区二区三区在线观看 | 久久久久精 | 国产高清视频 | 97偷拍视频| 中文字幕亚洲精品在线观看 | 久久精品91久久久久久再现 | 色爱综合网 | 国产成人精品免费视频大全最热 | 国产欧美精品 | 亚洲国产免费 | 午夜精品 | 黄色国产 | 精品国产欧美一区二区 | 国产成人一区二区 | 成人在线播放 | 日韩欧美一区二区三区四区 |