본문으로 건너뛰기

스마트 컨트랙트 컴파일러 퍼징을 통한 100개 이상의 버그 발견 사례

LLM 기반 변이 도구와 Tree-sitter를 활용해 Sui Move, Solidity 등 주요 스마트 컨트랙트 컴파일러에서 100개 이상의 내부 오류(ICE)를 발견한 기술적 방법론을 공유한다.

섹션별 상세

컴파일러 퍼징은 복잡한 구조적 입력을 처리하는 특성상 단순 무작위 바이트 주입보다 문법 인식(Grammar-aware) 접근이 필수적이다. 무작위 데이터는 파서 단계에서 대부분 차단되므로, 문법을 준수하는 유효한 프로그램을 생성해야만 타입 체커나 코드 생성기 같은 심층부의 불변조건 위배를 찾아낼 수 있다.
AFL++와 Tree-sitter를 결합한 afl-ts 변이 도구는 AST 노드를 직접 조작하여 구조적으로 유효한 변이 프로그램을 생성한다. 노드 삭제, 동일 타입 노드 교체, 하위 노드로의 축소 등 10가지 이상의 전략을 통해 문법적 정밀도를 유지하면서도 컴파일러가 예상치 못한 코너 케이스를 탐색한다.
MetaMut 기법을 응용하여 LLM이 특정 언어의 AST 구조에 최적화된 수백 개의 변이 로직을 스스로 설계하고 구현하도록 자동화했다. LLM은 '이진 연산자 교체'나 '가변성 토글' 같은 추상적 아이디어를 실제 Rust 코드로 변환하며, 컴파일 피드백 루프를 통해 유효한 변이 도구만 선별하여 퍼징 효율을 극대화한다.
rust
impl MoveMutator for SwapBinOp {
    fn name(&self) -> &'static str { "SwapBinOp" }
    fn description(&self) -> &'static str { "Swap a binary operator with a compatible one" }
    fn needs(&self) -> u32 { TK_BINOP }
    fn mutate(&self, ctx: &mut MuAstContext) -> bool {
        let binop = ctx.pick_random_binop()?;
        let replacement = ctx.compatible_op(binop.kind);
        ctx.replace_text(binop.loc, replacement);
        true
    }
}

LLM이 생성한 아이디어를 바탕으로 구현된 이진 연산자 교체 변이 도구의 Rust 구현 예시

근거
  • LLM(Sonnet 4.6)을 사용하여 Sui Move를 위한 884개의 고유한 변이 도구를 생성했다. MetaMut-style mutators 섹션의 MetaMove 설명
코퍼스의 품질이 퍼징 성과를 결정하므로 Tree-sitter 문법 파일에서 직접 시드 프로그램을 생성하는 tsgen 도구를 활용했다. 기존 오픈소스 코드뿐만 아니라 문법 정의를 바탕으로 재귀적으로 생성된 다양한 구문 조합을 통해 실제 사용 사례에서 누락된 언어 기능까지 폭넓게 커버할 수 있다.
rust
using {v1 as -, v7 as -, v5 as +} for v0 global;

function v8(v0 v2, v0 v3) {
    v0 v6 = v2 + v3;
    // ...
}

식별자 이름을 v0, v1 등으로 단순화하여 의미적 오류를 줄이고 컴파일러 버그를 유도한 코드

수백 개의 충돌 파일에서 중복을 제거하기 위해 백트레이스(Backtrace) 분석 기반의 자동 분류 스크립트를 도입했다. 패닉 메시지를 정규화하고 발생 위치를 그룹화함으로써 157개의 충돌 데이터를 16개의 고유한 버그 지점으로 압축하여 리포팅 효율을 높였다.
근거
  • Sui Move, Cairo, Solidity 등에서 총 100개의 컴파일러 버그를 발견했다. Evaluation 섹션의 결과 테이블 및 서술

용어 해설

커버리지 기반 퍼징(Coverage-guided Fuzzing)
프로그램의 코드 실행 경로(커버리지)를 추적하며 새로운 경로를 발견하는 입력을 우선적으로 변이시키는 테스트 기법이다. 컴파일러의 깊은 로직에 도달하기 위해 실행 흐름을 피드백으로 삼아 효율적으로 버그를 탐색한다.
내부 컴파일러 오류(Internal Compiler Error (ICE))
컴파일러가 소스 코드의 오류를 정상적으로 처리하지 못하고 컴파일러 자체의 불변조건 위배나 예외로 인해 비정상 종료되는 현상이다. 주로 패닉(Panic)이나 세그멘테이션 폴트로 나타나며 컴파일러의 안정성 결함을 의미한다.
문법 인식 퍼징(Grammar-aware Fuzzing)
단순 바이트 변이가 아닌 대상 언어의 구문 구조(AST)를 이해하고 문법에 맞는 입력을 생성하는 테스트 방식이다. 무작위 데이터가 파서에서 차단되는 것을 방지하여 타입 체커나 코드 생성기 같은 후반부 컴파일 단계를 검증할 수 있다.
추상 구문 트리(Abstract Syntax Tree (AST))
프로그래밍 언어로 작성된 소스 코드의 구조를 트리 형태로 표현한 데이터 구조이다. 컴파일러는 이 트리를 바탕으로 의미 분석과 최적화를 수행하며, 퍼징 시 특정 노드를 교체하거나 삭제하여 구조적 변이를 일으킨다.

기술

  • AFL++
  • Tree-sitter
  • Rust
  • Sui Move
  • Solidity
  • Cairo
  • Claude 3.5 Sonnet

활용 사례

  • 컴파일러 내부 오류(ICE) 탐지
  • 프로그래밍 언어 툴체인 안정성 테스트
  • 자동화된 버그 리포트 생성 및 최소화

언급된 리소스

AI 분석 전체 내용 보기

AI 요약 · 북마크 · 개인 피드 설정 — 무료

출처 · 인용 안내

원문 발행 2026. 05. 01.수집 2026. 05. 01.출처 타입 RSS

인용 시 "요약 출처: AI Trends (aitrends.kr)"를 표기하고, 사실 확인은 원문 보기 기준으로 진행해 주세요. 자세한 기준은 운영 정책을 참고해 주세요.