LLM 에이전트 기반 취약점 자동 발견 — Mythos가 바꾼 보안 테스트 패러다임
Mozilla CTO Bobby Holley가 “vertigo(현기증)“이라고 표현한 결과다. 2026년 4월, Anthropic Mythos Preview는 Firefox 150의 소스코드를 읽고 271개의 취약점을 발견했다 — fuzzing harness 한 줄 없이.
이 숫자보다 더 흥미로운 건 방식이다. AFL은 byte-level mutation을 반복한다. Mythos는 코드가 왜 취약한지를 추론한다. 같은 “자동화 보안 테스트"라는 말 아래 근본적으로 다른 레이어에서 작동한다. 이 차이가 무엇인지, 어디서 역전이 일어나고 어디서 한계가 드러나는지를 파고든다.
목차
- Coverage-Guided Fuzzing의 구조적 한계
- Harness 병목: 실제로 얼마나 느린가
- Mythos 작동 방식: 단계별 분석
- AFL vs Mythos: 무엇이 구조적으로 다른가
- Firefox 271건: 무엇을 발견했고 무엇을 놓쳤는가
- Mythos 이후 자본이 움직인 곳
- 한계와 열린 질문들
Coverage-Guided Fuzzing의 구조적 한계
AFL(American Fuzzy Lop)과 libFuzzer는 2014년 이후 오픈소스 보안의 기반이 됐다. Google OSS-Fuzz는 이 기반 위에서 10,000개 이상의 프로젝트를 지속적으로 퍼징하며 수만 건의 취약점을 발견했다. 여전히 강력하다. 하지만 구조적 병목이 하나 있다.
Fuzzing은 실행할 수 있어야 한다. Coverage-guided fuzzing이 작동하려면 두 가지가 필요하다.
첫째, 프로그램이 실행돼야 한다 — 단순히 컴파일되는 것이 아니라 임의 입력을 받아 처리할 수 있어야 한다. 둘째, 그 실행 경로가 instrumentation으로 관찰 가능해야 한다. 즉, 어떤 코드 edge가 실행됐는지 fuzzer가 추적할 수 있어야 한다.
이 두 조건을 충족시키는 작업이 harness 작성이다. Fuzzing harness는 대상 함수나 라이브러리를 “fuzzing 가능한 단위"로 감싸는 래퍼 코드다.
Harness 병목: 실제로 얼마나 느린가
libFuzzer 기반의 기본적인 harness는 이런 형태다.
// my_parser_fuzzer.cc
// libFuzzer entry point: LLVMFuzzerTestOneInput
#include <stddef.h>
#include <stdint.h>
#include "my_parser.h"
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
// fuzzer가 생성한 임의 바이트 스트림을 파서에 주입
MyParser parser;
parser.ParseBuffer(data, size);
return 0; // non-zero는 crash로 처리됨
}
이 정도면 간단하다. 하지만 실제로 harness 작성이 복잡해지는 경우가 훨씬 많다.
// 네트워크 프로토콜 파서 harness — 실전 예시
#include "net/http/http_response_headers.h"
#include "base/strings/string_piece.h"
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
// 1. raw bytes를 프로토콜이 기대하는 형식으로 변환해야 함
if (size < 4) return 0;
// 2. 상태 초기화 — 파서가 의존하는 전역 상태나 컨텍스트 설정
base::StringPiece input(reinterpret_cast<const char*>(data), size);
// 3. 메모리 관리 — sanitizer와 충돌하지 않게
scoped_refptr<net::HttpResponseHeaders> headers =
base::MakeRefCounted<net::HttpResponseHeaders>(std::string(input));
// 4. 관심 있는 메서드들을 모두 호출해 코드 경로 열기
headers->GetNormalizedHeaders(nullptr);
std::string value;
headers->GetNormalizedHeader("content-type", &value);
return 0;
}
이 harness를 작성하려면 net::HttpResponseHeaders의 내부 구조, base::StringPiece의 메모리 의미론, 어떤 메서드가 보안상 관련 있는 코드 경로를 열어주는지를 알아야 한다. 즉, 코드를 먼저 읽고 이해해야 한다.
OSS-Fuzz 기여자들의 공통적인 고충: “harness 없어서 커버리지 낮음” 상태인 entry point가 수천 개다. 대형 코드베이스(Firefox, Chrome, OpenSSL)에는 취약점을 가질 수 있는 함수가 수백 개 있지만, 각각에 대한 harness는 존재하지 않는다. 작성하는 데 걸리는 시간이 수 시간에서 며칠이기 때문이다.
Mythos 작동 방식: 단계별 분석
Mythos는 이 harness 작성 단계를 우회한다. 실행 경로를 무작위로 탐색하는 대신, 소스코드를 읽고 어디에 버그가 있을 것인지를 먼저 추론한다.
┌─────────────────────────────────────────┐
│ Mythos 실행 파이프라인 │
└─────────────────────────────────────────┘
소스코드 + 바이너리
│
▼
┌─────────────┐ 파일별 취약점 잠재력 점수화
│ 파일 우선순위 │ 1 (낮음) ~ 5 (높음)
│ 점수화 │ 메모리 조작, 파싱 로직, 권한 경계
└──────┬──────┘
│ 고점수 파일 우선
▼
┌─────────────┐ 병렬 격리 컨테이너
│ 병렬 ephemeral│ 각 VM: 독립 소스+바이너리 환경
│ VM 분산 │ 실패해도 다른 VM에 영향 없음
└──────┬──────┘
│
▼
┌─────────────┐ 코드 정독 → 가설 수립
│ 코드 추론 │ "이 경계 검사가 부족해 보인다"
│ + 가설 │ "이 형식 변환에서 정수 오버플로 가능"
└──────┬──────┘
│
▼
┌─────────────┐ 실제 빌드·실행으로 검증
│ 실행 검증 │ AddressSanitizer, UBSan 활성화
│ + PoC 작성 │ 재현 가능한 PoC 코드 생성
└──────┬──────┘
│
▼
┌─────────────┐ 별도 에이전트가 결과 재검토
│ Adversarial │ "이 PoC가 실제로 crash를 일으키는가?"
│ Self-Review │ False positive 필터링
└─────────────┘파일 우선순위 점수화는 정적 분석과 코드 이해를 결합한다. 메모리를 직접 조작하는 파일, 외부 입력을 파싱하는 파일, 권한 경계를 처리하는 파일이 높은 점수를 받는다. 에이전트는 7,000개의 Firefox entry point 전체를 균등하게 처리하지 않는다 — 고위험 파일을 먼저 파고든다.
Adversarial self-review는 false positive를 줄이는 핵심 단계다. 취약점을 찾은 에이전트가 아닌 별도 에이전트가 “이 PoC가 진짜인가"를 검토한다. Mozilla에 보고된 112건 메모리 안전 버그는 모두 진성으로 확인됐다 — “almost no false positives"는 이 단계 덕분이다.
AFL vs Mythos: 무엇이 구조적으로 다른가
| 구분 | Coverage-Guided Fuzzing (AFL/libFuzzer) | LLM 에이전트 (Mythos) |
|---|---|---|
| 탐색 방식 | Byte-level mutation → 새 edge 커버리지 | 코드 의미론적 추론 → 가설 수립 |
| harness 필요 여부 | 필수 — 함수별 수작업 | 불필요 — 소스코드 직접 분석 |
| 발견 가능한 버그 유형 | 주로 메모리 안전 (buffer overflow, use-after-free) | 메모리 안전 + 로직 버그, 인증 우회, 암호 오용 |
| 코드 이해 | 없음 — 실행 결과만 관찰 | 있음 — 의도와 구현 차이를 추론 |
| 병렬화 단위 | 입력 생성 (CPU bound) | 코드 분석 작업 (에이전트 인스턴스) |
| False positive | 낮음 (crash = 재현 가능) | 낮음 (adversarial self-review 후) |
| 비용 | 저렴 — 대규모 CPU 클러스터 | 높음 — 대형 LLM 호출 반복 |
| 확장성 | 수평 확장 쉬움 | 에이전트 병렬화로 확장 가능하나 비용 높음 |
| 대표 도구 | AFL++, libFuzzer, Honggfuzz, OSS-Fuzz | Anthropic Mythos, XBOW |
이 표에서 가장 중요한 행은 **“발견 가능한 버그 유형”**이다. Coverage-guided fuzzing이 입력 처리 경로를 무작위로 탐색하는 방식은 메모리 오류를 잘 잡는다. 하지만 비즈니스 로직 버그 — “인증 토큰 검증을 특정 순서로 호출하면 우회된다” 같은 — 는 코드를 이해하지 않으면 발견할 수 없다. Mythos가 열어놓은 공간이 여기다.
Firefox 271건: 무엇을 발견했고 무엇을 놓쳤는가
Firefox 150 분석 결과를 세 층위로 나눠볼 수 있다.
Layer 1 — 확인된 성과 (메모리 안전 버그)
112건의 취약점이 외부 보안 연구자에게 위탁해 트리아주됐다. 모두 진성으로 확인. 그 중 “완전한 원격 코드 실행(Full RCE)이 가능한 티어"에 해당하는 버그가 10건으로, Mythos 없이 Claude Opus 4.6 단독 사용 시 발견된 1건과 비교된다.
Palo Alto Networks의 표현이 인상적이다: “1년치 pentest를 3주에” — 이들이 Mythos를 프로덕션 환경에서 실험한 결과다.
Layer 2 — 논쟁이 있는 부분 (로직 버그 false positive)
SecurityWeek는 “외부 CVE로 등록된 건은 3건"이라는 점을 지적했다. 271건 중 다수는 외부 CVE로 이어지지 않았다 — 이는 두 가지로 해석될 수 있다. 하나, 로직 버그는 트리아주 과정에서 “실제 공격 가능성 낮음"으로 하향 분류되는 경우가 많다. 둘, LLM이 코드를 읽고 의심스럽다고 판단했지만 실제 공격 체인 구성이 안 되는 경우. Adversarial self-review가 메모리 안전 버그에는 효과적이었지만, 로직 버그의 실제 악용 가능성 판단에서는 아직 인간 리뷰어 의존이 높다.
Layer 3 — 여전히 사람이 필요한 것
Mozilla 측의 명시적 발언: “패치 자동화는 현실적이지 않다고 본다.” 취약점 발견과 패치 작성은 요구하는 능력이 다르다. 취약점은 의심스러운 패턴을 찾는 작업이지만, 패치는 해당 코드베이스의 설계 의도와 부작용을 모두 이해하고 최소 변경으로 고치는 작업이다. 현 시점에서 Mythos의 역할은 “발견과 PoC까지” — 패치는 엔지니어가 한다.
Mythos 이후 자본이 움직인 곳
Mythos의 데모가 공개된 직후 스타트업 펀딩 시장이 반응했다. “AI가 더 빠른 SAST를 만든다"는 이전 투자 논리가 “AI가 기존 도구가 구조적으로 하지 못했던 것을 한다"로 전환됐다.
XBOW ($155M Series C, 2026년 3월, 유니콘) CEO Oege de Moor는 GitHub Copilot의 공동 창립자다. XBOW는 LLM 기반 자동 침투 테스트 에이전트를 빌드하는 회사다. 취약점을 발견하는 것에서 한 단계 더 나아가 전체 공격 체인을 자동으로 생성·검증한다. Mythos가 “코드에서 취약점 발견"이라면 XBOW는 “실제 시스템에서 익스플로잇 검증"에 집중한다.
ZeroPath ($5M Seed, 2026년 2월) LLM + 정적 분석의 결합에 집중한다. 특히 인증 우회 패턴 탐지에 강점이 있다고 알려져 있다. 시리즈 A를 준비 중. Mythos가 대형 모델 제공사의 내부 도구라면, ZeroPath는 엔터프라이즈가 자체 코드베이스에 적용할 수 있는 SaaS를 빌드한다.
Pixee ($15M Seed) 포지셔닝이 다르다. “발견"이 아닌 “수정"에 집중한다. 취약점 발견 → 자동 패치 제안 → 코드 리뷰 연동 워크플로우를 빌드한다. Mozilla가 “패치 자동화는 현실적이지 않다"고 말하는 공간을 Pixee가 채우려 한다.
셋의 포지셔닝을 한 줄로 요약하면:
- Mythos: 발견 (Anthropic 내부 도구, 파트너십 기반)
- XBOW: 발견 + 공격 체인 검증 (엔터프라이즈 SaaS)
- ZeroPath: 발견 + CI/CD 통합 (엔터프라이즈 SaaS)
- Pixee: 수정 + 워크플로우 통합
한계와 열린 질문들
비용이 지속 가능한가
Coverage-guided fuzzing은 한 번 harness를 작성하면 수십억 회 실행해도 추가 비용이 거의 없다. CPU 클러스터만 있으면 된다. LLM 에이전트는 추론당 비용이 발생한다. Firefox 150 분석에서 병렬 ephemeral VM을 수천 개 돌렸다면 비용은 얼마인가 — Anthropic은 공개하지 않았다. 현재 비용 구조는 대형 기업이나 고가치 타겟에는 정당화되지만, OSS-Fuzz처럼 전체 오픈소스 생태계를 커버하는 방식으로는 아직 작동하지 않는다.
재현성 문제
Coverage-guided fuzzing은 결정론적이다 — 같은 seed corpus에서 같은 실행이 보장된다. LLM 에이전트의 추론은 비결정적이다. 같은 코드베이스를 두 번 돌리면 다른 취약점이 나올 수 있다. 이는 “발견하지 못했다"가 “없다"를 의미하지 않는다는 뜻이기도 하다.
Google OSS-Fuzz의 LLM harness 자동 생성
Google은 다른 방향을 선택했다. LLM으로 fuzzing harness를 자동 생성한다. 즉, LLM이 코드를 읽고 harness를 작성하면, 실제 취약점 발견은 여전히 AFL/libFuzzer가 한다. 이 접근은 기존 fuzzing 인프라를 그대로 활용하면서 harness 병목을 줄인다. Mythos의 완전한 에이전트 방식과 대비된다.
두 접근 모두 “코드를 이해하는 AI"를 쓰지만 어디에 쓰는지가 다르다:
- Google: LLM → harness 생성 → AFL/libFuzzer로 실행
- Mythos: LLM → 직접 취약점 가설·검증
어느 쪽이 더 효과적인지는 아직 열려있다. harness 자동 생성 방식은 비용이 낮고 기존 도구 체인을 쓸 수 있다. Mythos 방식은 harness로 커버되지 않는 로직 버그 영역을 열 수 있다.
이 분야의 진화 방향을 보면, 두 패러다임이 경쟁이 아닌 보완 관계로 정착할 가능성이 높다. AFL/libFuzzer는 “실행 가능한 입력 처리 경로의 메모리 오류"를 싸고 확장 가능하게 커버하고, LLM 에이전트는 “코드 이해가 필요한 로직·인증 버그"를 고비용으로 커버하는 구조다. 실제로 Mozilla의 접근도 Mythos 단독이 아니라 기존 fuzzing 인프라와의 병행이었다.
보안 엔지니어링 관점에서 가장 큰 변화는 도구보다 전문성의 재정의에 있다. Mythos가 대중화되면 “harness 잘 쓰는 능력"보다 “LLM 에이전트 파이프라인 설계·운영"과 “로직 버그 트리아주"가 보안 엔지니어의 핵심 역량이 된다.
참고
- Mozilla Hacks: Behind the Scenes Hardening Firefox with Claude Mythos Preview
- TechCrunch: How Anthropic’s Mythos has rewritten Firefox’s approach to cybersecurity
- Ars Technica: Mozilla says 271 vulnerabilities found by Mythos have “almost no false positives”
- SecurityWeek: The Limits of LLM-Based Vulnerability Discovery
- Google OSS-Fuzz: LLM-Based Fuzzing Harness Generation