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

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

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

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

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
fuzzilli — 자바스크립트 엔진 퍼저 | Kitploit
도구/GitHubGitHub/googleprojectzero/fuzzilli
Vulnerability AnalysisFuzzingBinary AnalysisPapers & ResearchLearning & Education
GitHubgoogleprojectzero/fuzzilli

fuzzilli

자바스크립트 엔진 퍼저

저장소 보기
2.3k366571일 전Kitploit 검토 완료

인기

모두 보기 →

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

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유

Fuzzilli

FuzzIL(사용자 정의 중간 언어)을 기반으로 하는 동적 언어 인터프리터용 (커버리지 기반) 가이드 퍼저입니다. FuzzIL은 변형되어 JavaScript로 번역될 수 있습니다.

사용법

이 퍼저를 사용하기 위한 기본 단계는 다음과 같습니다.

  1. 지원되는 JavaScript 엔진 중 하나의 소스 코드를 다운로드합니다. 지원되는 JavaScript 엔진 목록은 Targets/ 디렉토리를 참조하십시오.
  2. 대상 엔진 디렉토리의 해당 패치를 적용합니다. 해당 디렉토리의 README.md도 참조하십시오.
  3. README에 설명된 대로 커버리지 계측을 사용하여 엔진을 컴파일합니다 (clang >= 4.0 필요).
  4. 퍼저를 컴파일합니다: swift build [-c release].
  5. 퍼저를 실행합니다: swift run [-c release] FuzzilliCli --profile=<profile> [기타 cli 옵션] /path/to/jsshell. swift run FuzzilliCli --help도 참조하십시오.

Docker 및 Google Compute Engine 내에서 Fuzzilli와 지원되는 JavaScript 엔진을 빌드하고 실행하는 것도 지원됩니다.

기여하기

main.swift를 확인하여 Fuzzilli 라이브러리의 사용 예를 보고 다양한 구성 옵션을 실험해보세요. 그 다음, Fuzzer.swift에서 상위 수준의 퍼징 로직을 살펴보세요. 거기서부터 흥미로워 보이는 부분을 깊이 파보세요.

이 프로젝트에 대한 패치, 추가 사항, 기타 기여 등을 매우 환영합니다! 그러나 을 빠르게 확인해주세요. Fuzzilli는 대체로 를 따릅니다.

기여자 참고 사항
Google의 Swift 코드 스타일 가이드

이 프로젝트의 도움으로 발견된 취약점이 있으면 [email protected]으로 간단한 노트(CVE 번호 포함 가능)를 보내거나 풀 리퀘스트를 열어주시면 버그 쇼케이스 섹션에 포함될 수 있도록 하겠습니다. 그 외에도 발견한 취약점에 대해 버그 바운티, CVE 크레딧 등을 당연히 청구하실 수 있습니다 :)

개념

JIT 컴파일러와 같은 핵심 인터프리터 버그를 퍼징할 때는 생성된 프로그램의 의미적 정확성이 문제가 됩니다. 이는 런타임 API 퍼징과 같은 대부분의 다른 시나리오와 대조됩니다. 이러한 시나리오에서는 생성된 코드를 try-catch 구문으로 감싸서 의미적 정확성을 쉽게 우회할 수 있습니다. 의미적으로 올바른 샘플의 허용 가능한 비율을 달성하기 위한 여러 가지 가능성이 있으며, 그 중 하나는 코퍼스의 모든 샘플도 의미적으로 유효한 변이적 접근 방식입니다. 이 경우 각 변이는 유효한 샘플을 유효하지 않은 샘플로 바꿀 확률이 낮습니다.

변이 기반 JavaScript 퍼저를 구현하려면 JavaScript 코드에 대한 변이를 정의해야 합니다. AST나 프로그램의 다른 구문 요소를 변이하는 대신, 프로그램의 제어 흐름과 데이터 흐름에 대한 변이를 더 직접적으로 수행할 수 있는 사용자 정의 중간 언어(IL)가 정의됩니다. 이 IL은 나중에 실행을 위해 JavaScript로 번역됩니다. 중간 언어는 대략 다음과 같습니다:

root@kitploit:~
v0 <− LoadInteger '0'
v1 <− LoadInteger '10'
v2 <− LoadInteger '1'
v3 <− LoadInteger '0'
BeginFor v0, '<', v1, '+', v2 −> v4
   v6 <− BinaryOperation v3, '+', v4
   Reassign v3, v6
EndFor
v7 <− LoadString 'Result: '
v8 <− BinaryOperation v7, '+', v3
v9 <− LoadGlobal 'console'
v10 <− CallMethod v9, 'log', [v8]

예를 들어 다음과 같은 JavaScript 코드로 간단히 번역될 수 있습니다:

root@kitploit:~
const v0 = 0;
const v1 = 10;
const v2 = 1;
let v3 = 0;
for (let v4 = v0; v4 < v1; v4 = v4 + v2) {
    const v6 = v3 + v4;
    v3 = v6;
}
const v7 = "Result: ";
const v8 = v7 + v3;
const v9 = console;
const v10 = v9.log(v8);

또는 중간 표현식을 인라인하여 다음과 같은 JavaScript 코드로 번역될 수 있습니다:

root@kitploit:~
let v3 = 0;
for (let v4 = 0; v4 < 10; v4++) {
    v3 = v3 + v4;
}
console.log("Result: " + v3);

FuzzIL에는 여러 가지 속성이 있습니다:

  • FuzzIL 프로그램은 단순히 명령어 목록입니다.
  • FuzzIL 명령어는 입력 및 출력 변수와 잠재적으로 하나 이상의 매개변수(위 표기법에서 작은따옴표로 묶임)를 포함하는 연산입니다.
  • 명령어 입력은 항상 변수이며, 즉시 값은 없습니다.
  • 명령어의 모든 출력은 새 변수이며, 기존 변수는 Reassign 명령어와 같은 전용 연산을 통해서만 재할당할 수 있습니다.
  • 모든 변수는 사용되기 전에 정의됩니다.

그런 다음 이러한 프로그램에 대해 여러 가지 변이를 수행할 수 있습니다:

  • InputMutator: 프로그램의 데이터 흐름을 변이하기 위해 명령어의 입력 변수를 다른 변수로 대체합니다.
  • CodeGenMutator: 코드를 생성하여 변이된 프로그램의 어딘가에 삽입합니다. 코드는 코드 생성기를 실행하거나 코퍼스에 있는 다른 프로그램에서 일부 명령어를 복사(스플라이싱)하여 생성됩니다.
  • CombineMutator: 코퍼스의 프로그램을 변이된 프로그램의 무작위 위치에 삽입합니다.
  • OperationMutator: 연산의 매개변수를 변이합니다. 예를 들어 정수 상수를 다른 값으로 대체합니다.
  • 그리고 더 있습니다...

Fuzzilli 작동 방식에 대한 훨씬 더 자세한 논의는 여기에서 확인할 수 있습니다.

구현

퍼저는 Swift로 구현되었으며, 일부 부분(예: 커버리지 측정, 소켓 상호작용 등)은 C로 구현되었습니다.

아키텍처

퍼저 인스턴스(Fuzzer.swift에 구현됨)는 다음과 같은 핵심 구성 요소로 구성됩니다:

  • MutationFuzzer: 기존 프로그램에 변이를 적용하여 새 프로그램을 생성합니다. 그 후 생성된 샘플을 실행하고 평가합니다.
  • ScriptRunner: 대상 언어의 프로그램을 실행합니다.
  • Corpus: 흥미로운 샘플을 저장하고 핵심 퍼저에 제공합니다.
  • Environment: 런타임 환경(예: 사용 가능한 내장 함수, 속성 이름 및 메서드)에 대한 지식을 가지고 있습니다.
  • Minimizer: 충돌 및 흥미로운 프로그램을 최소화합니다.
  • Evaluator: 샘플이 일부 메트릭(예: 코드 커버리지)에 따라 흥미로운지 평가합니다.
  • Lifter: FuzzIL 프로그램을 대상 언어(JavaScript)로 번역합니다.

또한 여러 모듈을 선택적으로 사용할 수 있습니다:

  • Statistics: 다양한 통계 정보를 수집합니다.
  • NetworkSync: 네트워크를 통해 여러 인스턴스를 동기화합니다.
  • ThreadSync: 동일한 프로세스 내에서 여러 인스턴스를 동기화합니다.
  • Storage: 충돌 프로그램을 디스크에 저장합니다.

퍼저는 이벤트 기반이며, 다른 클래스 간의 대부분의 상호 작용은 이벤트를 통해 발생합니다. 이벤트는 예를 들어 충돌이나 흥미로운 프로그램 발견, 새 프로그램 실행, 로그 메시지 생성 등의 결과로 전달됩니다. 전체 이벤트 목록은 Events.swift를 참조하십시오. 이벤트 메커니즘은 퍼저의 다양한 구성 요소를 효과적으로 분리하고 추가 모듈을 쉽게 구현할 수 있도록 합니다.

FuzzIL 프로그램은 ProgramBuilder 인스턴스를 사용하여 구축할 수 있습니다. ProgramBuilder는 새 명령어를 생성하고 추가하고, 다른 프로그램의 명령어를 추가하고, 기존 변수를 검색하고, 현재 위치의 실행 컨텍스트(예: 루프 내부에 있는지 여부)를 쿼리하는 등의 메서드를 제공합니다.

실행

Fuzzilli는 REPRL(read-eval-print-reset-loop)이라는 사용자 정의 실행 모드를 사용합니다. 이를 위해 대상 엔진이 수정되어 파이프 및/또는 공유 메모리를 통해 스크립트 입력을 받아 실행한 다음 내부 상태를 재설정하고 다음 스크립트를 기다립니다. 이렇게 하면 프로세스 생성 오버헤드와 엔진 초기화의 많은 부분이 제거됩니다.

확장성

대상 프로세스당 하나의 Fuzzer 인스턴스가 있습니다. 이를 통해 프로그램의 동기 실행이 가능하며, 연속 변이 및 최소화와 같은 다양한 알고리즘의 구현이 단순화됩니다. 또한 코퍼스와 같은 내부 상태에 대한 스레드 안전 액세스를 구현할 필요가 없습니다. 각 퍼저 인스턴스는 개념적으로 단일 스레드에 해당하는 자체 DispatchQueue를 가지고 있습니다. 일반적으로 퍼저 인스턴스와의 모든 상호 작용은 해당 인스턴스의 디스패치 큐에서 발생해야 합니다. 이는 큐가 직렬이므로 스레드 안전성을 보장합니다. 자세한 내용은 문서를 참조하십시오.

확장을 위해 퍼저 인스턴스는 트리 계층 구조를 형성할 수 있으며, 이 경우 새로 발견된 흥미로운 샘플과 충돌을 상위 노드에 보고합니다. 그러면 상위 노드는 자식 노드와 코퍼스를 동기화합니다. 트리 내 노드 간 통신은 다양한 방식으로 이루어질 수 있으며, 각각 모듈로 구현됩니다:

  • 스레드 간 통신: 다른 퍼저의 DispatchQueue에 작업을 추가하여 동일한 프로세스 내에서 인스턴스를 동기화합니다.
  • 머신 간 통신: 간단한 TCP 기반 프로토콜을 통해 인스턴스를 동기화합니다.

이 설계를 통해 퍼저는 단일 시스템의 여러 코어는 물론 여러 시스템으로 확장할 수 있습니다. 너무 많은 인스턴스가 프로그램을 보내면 하나의 상위 노드가 빠르게 과부하될 수 있으므로, 여러 수준의 인스턴스를 구성할 수 있습니다(예: 하나의 루트 인스턴스, 루트에 연결된 16개의 중간 노드, 중간 노드에 연결된 256개의 "리프" 인스턴스). 분산 퍼징에 대한 자세한 내용은 Cloud/ 디렉토리를 참조하십시오.

리소스

이 퍼저에 대한 추가 자료:

  • Offensive Con 2019에서 발표된 Fuzzilli에 대한 프레젠테이션.
  • 초기 구현이 이루어진 석사 논문.
  • Sensepost의 Fuzzilli를 사용하여 v8에서 버그를 찾는 방법에 대한 블로그 게시물.
  • Doyensec의 Fuzzilli로 JerryScript 엔진을 퍼징하는 방법에 대한 블로그 게시물.
  • NDSS 심포지엄 2023에서 발표된 Fuzzilli와 다른 퍼저와의 비교에 관한 논문.

버그 쇼케이스

다음은 Fuzzilli의 도움으로 발견된 일부 버그 목록입니다. 이 목록에는 적어도 해당 소프트웨어의 베타 릴리스에 존재했던 보안 영향을 미치는 버그만 포함되어야 합니다. Fuzzilli는 종종 개발 중 지속적인 퍼즈 테스트에 사용되므로, 취약한 코드가 베타 릴리스에 도달하기 전에 발견되는 경우가 많아 이 목록에 포함되지 않습니다. 그러나 V8에서 Fuzzilli가 최근에 발견한 모든 문제 목록은 여기에서 확인할 수 있습니다.

Fuzzilli로 발견한 버그를 보고해 주신 모든 Fuzzilli 사용자에게 특별히 감사드립니다!

WebKit/JavaScriptCore

  • Issue 185328: DFG 컴파일러가 NumberIsInteger 연산에 대해 잘못된 출력 레지스터를 사용함
  • CVE-2018-4299: performProxyCall이 내부 객체를 스크립트로 유출함
  • CVE-2018-4359: compileMathIC이 잘못된 기계어 코드를 생성함
  • CVE-2019-8518: LICM이 경계 검사 전에 배열 액세스를 이동하여 FTL JIT에서 OOB 액세스 발생
  • CVE-2019-8558: 매달린 Watchpoint로 인한 CodeBlock UaF
  • CVE-2019-8611: AIR 최적화가 레지스터 할당을 잘못 제거함
  • CVE-2019-8623: DFG JIT의 루프 불변 코드 이동(LICM)으로 스택 변수가 초기화되지 않은 채 남음
  • CVE-2019-8622: DFG의 doesGC()가 HasIndexedProperty 연산의 StringObjects 동작에 대해 부정확함
  • CVE-2019-8671: DFG: 루프 불변 코드 이동(LICM)으로 객체 속성 액세스가 보호되지 않은 채 남음
  • CVE-2019-8672: ValueProfiles에서 JSValue use-after-free
  • CVE-2019-8678: 일부 프로토타입이 수정될 때 JSC가 haveABadTime()을 실행하지 못하여 타입 혼동 발생
  • CVE-2019-8685: JSPropertyNameEnumerator가 잘못된 구조 ID를 사용함
  • CVE-2019-8765: DFG 컴파일 중 GetterSetter 타입 혼동
  • CVE-2019-8820: 인수 객체 재구성 중 베일아웃 시 타입 혼동
  • CVE-2019-8844: ObjectAllocationSinkingPhase가 더 이상 유효하지 않은 할당에 대한 힌트를 삽입해서는 안 됨
  • CVE-2020-3901: FTL JIT 코드에서 GetterSetter 타입 혼동 (항상 안전하지 않은 LICM으로 인해)
  • CVE-2021-30851: 동시 HashTable 조회 중 잠금 누락
  • CVE-2021-30818: DFG OSR 종료 시 인수 재구성 중 타입 혼동
  • CVE-2022-46696: JIT 컴파일된 코드에서 예외 검사 누락으로 인한 어설션 실패
  • CVE-2022-46699: IC에서 특수 속성의 잘못된 캐싱으로 인한 어설션 실패
  • CVE-2022-46700: Intl.Locale.prototype.hourCycles가 빈 JSValue를 스크립트로 유출함
  • CVE-2025-43214: 스택을 반복하는 동안 JSToWasmEntry에서 메모리 손상
  • CVE-2025-43213: NewRegExpUntyped 연산의 잘못된 타입 지정

Gecko/Spidermonkey

  • CVE-2018-12386: IonMonkey 레지스터 할당 버그로 타입 혼동 발생
  • CVE-2019-9791: OSR을 통해 진입한 생성자에 대한 IonMonkey의 타입 추론이 부정확함
  • CVE-2019-9792: IonMonkey가 JS_OPTIMIZED_OUT 매직 값을 스크립트로 유출함
  • CVE-2019-9816: ObjectGroupDispatch 연산에서 예상치 못한 ObjectGroup 발생
  • CVE-2019-9813: IonMonkey 컴파일된 코드가 추론된 속성 유형을 업데이트하지 못하여 타입 혼동 발생
  • CVE-2019-11707: IonMonkey가 Array.prototype.pop의 반환 유형을 잘못 예측하여 타입 혼동 발생
  • CVE-2020-15656: IonMonkey에서 특수 인수에 대한 타입 혼동
  • CVE-2021-29982: 잘못된 레지스터 할당 (JIT-Picker에 의해 발견됨)
  • CVE-2021-29984: 예기치 않은 GC와 결합된 명령어 재정렬로 메모리 손상 발생 가능
  • CVE-2022-28285: MLoadTypedArrayElementHole에 대한 AliasSet이 너무 허용적임
  • CVE-2022-31745: 증분 GC 오류
  • CVE-2022-42928: 일부 BigInt 연산에 대한 KeepAlive 주석 누락으로 메모리 손상 발생 가능
  • CVE-2022-45406: JavaScript 영역의 use-after-free
  • CVE-2023-4577: GC와 정규식 상호 작용으로 인한 메모리 손상
  • CVE-2023-5171: 컴파일 중 GC로 인한 use-after-free 조건 발생
  • CVE-2023-25735: 컴파트먼트 불일치로 인한 잠재적 use-after-free
  • CVE-2023-25751: JIT 코드 손상
  • CVE-2023-29535: 약한 맵 GC 중 메모리 손상
  • CVE-2023-29543: 디버거 내 메모리 손상
  • CVE-2023-29544: 병렬 마킹 중 메모리 손상
  • CVE-2023-29549: 잘못된 영역에 할당된 객체
  • CVE-2024-0744: JIT 컴파일된 코드가 와일드 포인터 값을 역참조할 수 있었음
  • CVE-2024-3854: JIT가 switch 문을 잘못 최적화하여 경계 외 읽기가 있는 코드 생성
  • CVE-2024-3855: JIT가 MSubstr 연산을 잘못 최적화하여 경계 외 읽기 발생
  • CVE-2024-3857: JIT가 잘못된 코드를 생성하여 가비지 수집 중 use-after-free 발생
  • CVE-2024-3858: GC 추적 중 JavaScript 객체 변이로 JIT 코드 충돌
  • CVE-2024-6613: WASM 스택 프레임의 잘못된 목록
  • CVE-2024-6614: WASM 스택 프레임의 잘못된 목록
  • CVE-2024-7521: 불완전한 WebAssembly 예외 처리
  • CVE-2024-7652: AsyncGeneratorPrototype 사양의 버그
  • CVE-2024-8381: "with" 블록에서 속성 이름 조회 시 타입 혼동
  • CVE-2024-9396: 특정 객체 복제 시 잠재적 메모리 손상 발생 가능
  • CVE-2025-0240: JavaScript JSON 모듈 구문 분석 시 컴파트먼트 불일치
  • CVE-2025-0241: JavaScript 텍스트 분할 사용 시 메모리 손상
  • CVE-2025-1012: 동시 지연 해제 중 use-after-free
  • CVE-2025-1934: RegExp 베일아웃 처리 중 예기치 않은 GC

Chromium/v8* 이슈 939316: Turbofan이 Reflect.construct를 최적화할 때 Map 포인터를 범위 밖에서 읽을 수 있음

  • 이슈 944062: JSCallReducer::ReduceArrayIndexOfIncludes가 Map 검사를 삽입하지 않음
  • CVE-2019-5831: V8의 잘못된 맵 처리
  • 이슈 944865: V8의 잘못된 값 표현
  • CVE-2019-5841: 인라인 휴리스틱의 버그
  • CVE-2019-5847: V8 봉인/고정 요소로 인한 크래시
  • CVE-2019-5853: 정규식 길이 검사의 메모리 손상
  • 이슈 992914: Map 마이그레이션이 요소 종류를 존중하지 않아 타입 혼동 발생
  • CVE-2020-6512: V8의 타입 혼동
  • CVE-2020-16006: DescriptorArray에서 해시 충돌을 부적절하게 처리하여 발생한 메모리 손상
  • CVE-2021-37991: 동시 JIT 컴파일 중 경쟁 조건
  • 이슈 1359937: BigInt 역직렬화 시 잘못된 -0n 값이 발생할 수 있음
  • 이슈 1377775: Turbofan에서 Array.prototype.at을 인라인할 때 잘못된 타입 검사

Duktape

  • 이슈 2323: putprop에서 불안정한 valstack 포인터
  • 이슈 2320: 문자열 내장 함수의 Memcmp 포인터 오버플로우

JerryScript

  • CVE-2020-13991: 전개 인자의 잘못된 해제
  • 이슈 3784: 잘못된 속성 열거로 인한 메모리 손상
  • CVE-2020-13623: Proxy 객체의 속성 키를 통한 스택 오버플로우
  • CVE-2020-13649 (1): OOM 상황에서 오류 처리로 인한 메모리 손상
  • CVE-2020-13649 (2): OOM 상황에서 오류 처리로 인한 메모리 손상
  • CVE-2020-13622: Proxy 객체의 속성 키를 잘못 처리하여 발생한 메모리 손상
  • CVE-2020-14163: 키/값 쌍 추가 시 가비지 컬렉션으로 인한 경쟁 조건으로 발생한 메모리 손상
  • 이슈 3813: SerializeJSONProperty 함수의 잘못된 오류 처리
  • 이슈 3814: ecma_op_function_has_instance 단언문에서 예상치 못한 Proxy 객체
  • 이슈 3836: 잘못된 TypedArray 초기화로 인한 메모리 손상
  • 이슈 3837: getOwnPropertyDescriptor에서 잘못된 메모리 처리로 인한 메모리 손상

Hermes

  • CVE-2020-1912: 느리게 컴파일된 내부 제너레이터 함수를 실행할 때 메모리 손상
  • CVE-2020-1914: SaveGeneratorLong 명령어 처리 시 바이트코드 손상

면책 조항

이는 공식적으로 지원되는 Google 제품이 아닙니다.

도구 다운로드