Skip to content
KitploitKITPLOIT
도구블로그
제출
도구블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

··피드·문의·개인정보·© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
CVE-2022-22629 — CVE-2022-22629 Proof of Concept | Kitploit
도구/GitHubGitHub/lck0/cve-2022-22629
Vulnerability AnalysisExploitationWeb Security
GitHublck0/cve-2022-22629

CVE-2022-22629

CVE-2022-22629 Proof of Concept

저장소 보기
53년 전아직 검토되지 않음

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

CVE-2022-22629 개념 증명

이 글은 Safari 15.4 보안 업데이트에서 패치된 WebGL 버그의 PoC에 관한 것입니다.

bug

WebGL이 어떻게 작동하는지 자세히 배우고 싶다면 이 공식 리소스를 사용할 수 있습니다. 여기서는 버그 관련 세부 사항에 대해 논의할 것이기 때문입니다:

https://webglfundamentals.org/webgl/lessons/webgl-how-it-works.html

이 PoC는 이 버그를 악용하기 위한 프리미티브를 얻는 방법에 관한 것이 아닙니다. 단지 취약점 분석과 웹 콘텐츠를 충돌시키는 방법에 대해 논의할 것입니다 : )

소개

WebGL은 브라우저에서 2D 및 3D 그래픽을 렌더링하는 데 사용되는 JavaScript API입니다. ANGLE 구성 요소를 기본 WebGL 백엔드로 사용하여 다른 브라우저와의 호환성을 크게 개선하고 WebKit에서 적합한 WebGL 2.0을 가능하게 합니다. WebGL은 개발자가 최적화된 렌더링을 수행할 수 있도록 많은 확장 기능을 제공합니다. 따라서 우리는 관심 있는 확장 기능을 살펴보겠습니다.

WebGL의 확장 기능

extension

따라서 이 API는 다양한 목적을 위한 여러 확장 기능을 제공합니다. 우리가 논의할 버그는 EXT_에 있습니다.

확장 기능에 대한 자세한 내용은 여기에서 읽을 수 있습니다:

https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/Using_Extensions

어쨌든, 버그로 넘어가 봅시다 :)

취약점 분석

WEBGL_multi_draw 확장 기능

WEBGL_multi_draw 확장 기능은 WebGL API의 일부이며 단일 함수 호출로 여러 프리미티브를 렌더링할 수 있게 합니다. 이는 렌더러의 바인딩 비용을 줄이고 균일한 데이터로 GPU 스레드 시간을 가속화하여 WebGL 애플리케이션의 성능을 향상시킬 수 있습니다.

이 확장 기능은 OpenGL용 ARB_shader_draw_parameters에서 노출된 버텍스 셰이더 내장 변수 gl_DrawID 외에도 EXT_multi_draw_arrays 기능의 Multi* 드로우 콜 변형을 노출합니다.

이 함수들은 표준 함수 DrawArrays() 및 DrawElements()와 동일하게 동작하지만, 한 번의 호출로 여러 개의 버텍스 리스트를 처리합니다. 주요 목적은 한 번의 함수 호출로 삼각형 스트립, 삼각형 팬 등과 같은 여러 프리미티브를 렌더링하는 것입니다.

또한 이 확장 기능은 셰이딩 언어에 추가 내장 변수인 gl_DrawID를 추가합니다. 이 변수는 드로잉 명령의 Multi* 변형에 의해 현재 처리 중인 드로우의 인덱스를 포함합니다.

https://github.com/WebKit/WebKit/blob/a7f8eacef337cb6691dca0b742d00f80d4f3dd0f/Source/ThirdParty/ANGLE/extensions/ANGLE_multi_draw.txt

확장 기능에 대한 자세한 내용은 여기에서 읽을 수 있습니다:

https://registry.khronos.org/webgl/extensions/WEBGL_multi_draw/

이 확장 기능은 배열 데이터에서 프리미티브를 렌더링하는 WebGL API WebGLRenderingContext.drawArrays() 및 WebGLRenderingContext.drawElements() 등과 유사합니다. 유일한 차이점은 이 확장 기능을 사용하여 여러 배열을 사용하여 렌더링할 수 있다는 것입니다.

이 확장 기능을 사용하여 다음 작업을 수행할 수 있습니다: [1]

  1. ext.multiDrawArraysWEBGL()는 배열 데이터에서 여러 프리미티브를 렌더링합니다 (drawArrays를 여러 번 호출하는 것과 동일).

  2. ext.multiDrawElementsWEBGL()는 요소 배열 데이터에서 여러 프리미티브를 렌더링합니다 (drawElements를 여러 번 호출하는 것과 동일).

  3. ext.multiDrawArraysInstancedWEBGL()는 배열 데이터에서 여러 프리미티브를 렌더링합니다 (drawArraysInstanced를 여러 번 호출하는 것과 동일).

  4. ext.multiDrawElementsInstancedWEBGL()는 요소 배열 데이터에서 여러 프리미티브를 렌더링합니다 (drawElementsInstanced를 여러 번 호출하는 것과 동일).

패치

patch

https://github.com/WebKit/WebKit/commit/c087ca07c9125093ca62e8e44024b738bb7d46dc

이 취약점은 Safari 15.0부터 15.3까지만 존재합니다. Apple의 경우 이 확장 기능이 Safari 15(iOS)에서만 지원되기 때문입니다.

패치는 이해하기 매우 쉽고 렌더링 중 힙 버퍼 오버플로우임을 명확히 명시하고 있습니다. 이 함수는 위에서 언급한 모든 작업 [1]에서 WebGLMultiDraw.cpp의 여기에서 호출됩니다. 이 함수가 호출되기 전에 어떤 일이 발생하는지 이해해 봅시다. 위 함수 중 하나의 구현을 살펴보겠습니다:

root@kitploit:~
void WebGLMultiDraw::multiDrawArraysWEBGL(GCGLenum mode, Int32List firstsList, GCGLuint firstsOffset, Int32List countsList, GCGLuint countsOffset, GCGLsizei drawcount)
{
    if (!m_context || m_context->isContextLost())
        return;

    if (!validateDrawcount("multiDrawArraysWEBGL", drawcount)
        || !validateOffset("multiDrawArraysWEBGL", "firstsOffset out of bounds", firstsList.length(), firstsOffset, drawcount)
        || !validateOffset("multiDrawArraysWEBGL", "countsOffset out of bounds", countsList.length(), countsOffset, drawcount)) {
        return;
    }

    m_context->graphicsContextGL()->multiDrawArraysANGLE(mode, makeSpanWithOffset(firstsList, firstsOffset), makeSpanWithOffset(countsList, countsOffset), drawcount);
}

JS에서 함수 사양은 다음과 같이 정의됩니다:

root@kitploit:~
void ext.multiDrawArraysWEBGL(mode,
    firstsList, firstsOffset,
    countsList, countsOffset,
    drawCount);
  • mode:

    • gl.POINTS: 단일 점을 그립니다.
    • gl.TRIANGLES: 세 개의 꼭짓점 그룹에 대해 삼각형을 그립니다.
  • firstsList:

    • 벡터 점 배열의 시작 인덱스 목록을 지정하는 Int32Array 또는 배열 (GLint).
  • firstsOffset:

    • firstsLists 배열의 시작 지점을 정의하는 GLuint.
  • countsList:

    • 렌더링할 인덱스 수의 목록을 지정하는 Int32Array 또는 배열 (GLsizei).
  • countsOffset:

    • countsList 배열의 시작 지점을 정의하는 GLuint.
  • drawCount:

    • 실행할 요소 범위의 인스턴스 수를 지정하는 GLsizei.

구현을 살펴보면 오프셋과 drawcount를 제어하여 버퍼 크기를 초과하여 그리기 모드로 그릴 수 있음을 알 수 있습니다 : )

따라서 PoC는 여기에 있습니다 ...

테스트

11pro

보시다시피, multiDrawArraysWEBGL()에서 호출된 validateOffset()이 firstsOffset이 [0, size-drawcount] 범위 내에 있는지 확인하지 않기 때문에 웹페이지가 충돌했습니다. 그리고 실제 버퍼 크기를 초과하여 그리고 있습니다. 함수 호출 m_context->graphicsContextGL()->multiDrawArraysANGLE()은 ANGLE로 알려진 WebKit의 타사 구성 요소에 구현되어 있으며 렌더링 전에 검사가 없으므로 메모리 영역에 잘못된 값을 쓰면서 충돌이 발생합니다.

참고로, multiDrawArraysANGLE() 의사 코드는 다음과 같이 작동합니다:

root@kitploit:~
      for(i=0; i<drawcount; i++) {
        if (*(counts+i)>0) DrawArrays(mode, *(firsts+i), *(counts+i));
      }

그리고 패치가 적용되면 validateOffset() 함수 호출을 통해 아무것도 렌더링하지 않고 false를 반환합니다:

12pro

js) ...

크레딧

PARS Defense Team

새 팀원을 모집 중입니다. 연락처: info[at]parsdefense.com

도구 다운로드