누군가 경고 없이 오픈 소스 도구들에 대한 20개의 제로데이(zero-days)를 공개했습니다. 퍼징(fuzzing)은 AI에 의해
요약
익명의 사용자가 nmap, Docker, FFmpeg 등 주요 오픈 소스 소프트웨어의 20개 이상의 제로데이 취약점(PoC)을 사전 경고 없이 공개했습니다. 이번 사건은 오픈 소스 인프라의 보안 위협과 취약점 공개 방식에 대한 논쟁을 불러일으키고 있습니다.
핵심 포인트
- 주요 오픈 소스 도구 대상 20개 이상의 제로데이 PoC 공개
- 유지 관리자에게 사전 보고 없이 즉시 공개되어 보안 위험 증대
- nmap, Docker, FFmpeg 등 광범위한 인프라 도구 포함
- 공개된 취약점의 실제 유효성과 심각성에 대한 전문가 논쟁 발생
지난주 bikini라는 익명의 GitHub 계정이 exploitarium이라는 이름의 저장소(repository)를 푸시했으며, 불과 며칠 만에 인기 있는 오픈 소스 소프트웨어들을 대상으로 20개 이상의 개념 증명(proof-of-concept) 익스플로잇(exploits)을 공개했습니다. nmap, Ghidra, FFmpeg, VLC, Firefox, libssh2, c-ares, OpenVPN, Docker, PHP, ImageMagick 등이 포함되었습니다. 어떤 버그도 사전에 유지 관리자(maintainers)에게 보고되지 않았습니다. 패치된 것도 없었습니다. README에는 다음과 같이 명확하게 적혀 있었습니다: 게시 시점에 아무것도 보고되지 않았으며, 여러분이 직접 보고하고 "CVE에 대한 공로를 가져가도 좋다."라고 말입니다.
이 소식은 Hacker News의 상단에 올랐고 스레드가 빠르게 채워졌으며, 그 아래에서 벌어진 논쟁은 익스플로잇 자체보다 더 흥미롭습니다.
만약 여러분이 오픈 소스 인프라를 구축, 배포 또는 의존하고 있다면 이 사건은 주목할 가치가 있습니다. 우리 대부분이 그러하듯이 말입니다.
실제로 공개된 것들
해당 저장소는 하나의 통합된 아카이브입니다. 23개의 폴더가 있으며, 각 폴더는 서로 다른 대상을 향한 독립적인 개념 증명(proof of concept)입니다. 일부는 여러분이 생각 없이 실행하고 있을 네트워크 배관(network plumbing) 관련 도구들입니다: c-ares (curl 및 기타 긴 도구 목록 뒤에 있는 DNS 리졸버 라이브러리), libssh2, nghttp2, OpenVPN. 일부는 개발자들이 직접 사용하는 도구들입니다: 역공학(reverse engineering)을 위한 Ghidra 및 objdump, 스캐닝을 위한 nmap, 그리고 이 특정 저장소에 있지는 않더라도 정신적으로는 Wireshark와 인접한 디섹터(dissectors)들입니다. 여러 개는 미디어 디코더(media decoders)로, 이는 지난 20년 동안 조용히 위험해 온 카테고리입니다: FFmpeg, VLC, ImageMagick, 7-Zip의 RAR5 처리 기능.
몇몇 항목은 이미 CVE 번호를 가지고 있습니다. libssh2-cve-2026-55200이 이름 그대로 포함되어 있습니다. 다른 것들은 심각한 발견처럼 보입니다: Use-after-free 버그, RCE(원격 코드 실행) 후보, MyBB에서의 권한 상승(privilege escalation), SystemInformer에서의 로컬 권한 상승(local privilege escalation). nmap 관련 항목은 IPv6 확장 길이 파싱(extension-length parsing)을 대상으로 하며, 스레드의 여러 사람들은 이것이 파서(parser) 코드 내에 위치하기 때문에 잠재적으로 높은 심각도를 가진 것으로 표시했습니다. 파서는 바로 원격 코드 실행(remote code execution)이 숨어 있기 쉬운 곳이기 때문입니다.
따라서 이것은 한 명의 연구자가 벤더(vendor)에게 책임감 있게 귀띔해 주는 상황이 아닙니다. 누군가가 자신의 노트를 공용 인터넷에 한꺼번에 쏟아부어 버린 것입니다.
일부는 실제이며, 일부는 그렇지 않습니다.
여기서부터 이야기가 복잡해지며, 왜 Hacker News 스레드가 승전보를 울리는 자리가 아닌 포렌식(forensic) 논쟁의 장으로 변했는지 알 수 있습니다.
해당 코드베이스를 실제로 잘 아는 사람들이 조사에 착수했고, 그 결과는 엇갈렸습니다. 한 Ghidra 사용자는 Ghidra에서 발견된 세 가지 항목 중 하나가 Swift 도구 디렉터리의 바이너리(binaries)를 이미 덮어쓸 수 있는 권한이 있어야 한다고 지적했습니다. 프로그램이 실행하는 바이너리를 덮어쓸 수 있다면, 네, 코드 실행(code execution)이 가능합니다. 하지만 그것은 취약점(vulnerability)이 아닙니다. 그것은 컴퓨터가 작동하는 방식 그 자체입니다. 다른 누군가는 Docker 관련 항목을 악용 가능한 결함(exploitable flaw)이라기보다 "그저 이상한 버그"라고 불렀으며, VLC의 개념 증명(proof of concept)은 임의 코드(arbitrary code)를 실행할 경로 없이 단순한 충돌(crash)로 끝났습니다.
하지만 모든 것이 부정된 것은 아닙니다. Ghidra를 일축했던 동일 인물이 c-ares, libssh2, 그리고 FFmpeg를 확인한 후, 그곳의 버그들은 "최신 업스트림 커밋(upstream commit) 기준으로 모두 작동하는 것으로 보인다"라고 말했습니다. nmap 파서(parser) 버그는 심각한 우려를 불러일으켰습니다. private-data 및 untrusted-input 플래그(flags)와 관련된 Firefox 관련 건은 Firefox 내부 구조를 다루지 않는 사람들에게는 그럴듯하게 들렸지만, 완전히 사실로 확정하거나 배제할 수는 없었습니다.
이것이 이와 같은 정보 유출이 가진 혼란스러운 현실입니다. 단 한 명의 전문가가 모든 코드베이스에 정통할 수는 없습니다. FFmpeg의 유지 관리자(maintainer)가 OpenVPN의 유지 관리자이기도 하지는 않습니다. 따라서 20개의 버그가 한꺼번에 터지면, 보안 커뮤니티 전체가 이를 병렬적으로 분류(triage)하기 위해 서둘러 움직여야 하며, 그 분류 작업의 상당 부분이 시간이 촉박하게 흘러가는 와중에 포럼이라는 공개적인 장소에서 서투르게 이루어집니다.
퍼징(fuzzing)은 AI에 의해 수행되었습니다
이 부분이 제가 계속해서 되짚어보게 되는 지점입니다.
초기 비판의 물결이 지나간 후, 해당 계정은 성명서를 게시했는데, 그 방법론에 대해 이례적일 정도로 솔직했습니다. 퍼징 (fuzzing) 워크플로우는 자동화되었습니다. 전부 다 말이죠. 그들은 GPT-5.5-3-Codex-Spark를 사용하여 엄격한 하네스 (harness)를 대상으로 퍼징을 실행했으며, AI가 후보 버그들을 플래그 (flag)하면 사람이 이를 조사하고 확인했습니다.
그 성명서에서 두 가지 사항이 눈에 띄었습니다. 첫째, 저자는 이러한 문제를 찾기 위해 프런티어 모델 (frontier model)이 필요하다는 생각에 강력히 반박합니다. 그들은 "이러한 문제들을 식별하는 데 도움을 받기 위해 SOTA (State-of-the-Art) 모델이 필요한 것은 아니다"라고 적었습니다. 그들의 주장에 따르면, 적절한 인간의 감독을 좋은 하네스 (harness)와 결합하면 모델의 선택은 미미한 수준이라고 합니다. 둘째, 그들은 무엇이 AI에 의해 생성되었고 무엇이 그렇지 않은지에 대해 명확히 밝혔습니다. 개념 증명 (proof of concept)은 직접 타이핑했으며, RustDesk의 경우 해당 언어에 능숙하지 않아 AI에 의존했습니다. README 작성물은
조율된 공개 (Coordinated disclosure) 방식은 유지 관리자에게 먼저 알리고, 수정 사항을 배포할 수 있도록 보통 60일에서 90일 정도의 합리적인 기간을 준 뒤에만 공개해야 한다고 말합니다. 논거는 간단합니다. 패치되지 않은 버그에 대한 작동 가능한 익스플로잇 (exploit)을 공개하는 것은 공개되는 즉시 모든 사용자를 위험에 빠뜨리며, 가장 먼저 피해를 입는 사람들은 유지 관리자가 아니라는 점입니다. 그들은 이 문제에 대해 아무런 결정권이 없었던 관리자(admins)와 최종 사용자들입니다.
전체 공개 (Full disclosure) 방식은 그 반대를 말합니다. 즉시 공개하라는 것입니다. 논거는 몇 가지 형태가 있지만, 핵심은 비밀로 유지되는 버그는 안전하지 않다는 것입니다. 버그가 공개되었는지 여부와 상관없이 코드 안에 존재하며, 버그가 조용히 유지됨으로써 이득을 보는 유일한 사람들은 이미 그 사실을 알고 있는 공격자들뿐입니다. 전체 공개를 지지하는 사람들은 공공의 압력이 문제를 해결할 수 있는 유일하고 신뢰할 수 있는 방법이라고 주장합니다. 벤더(Vendors)들은 시간을 끌기 마련이며, 90일의 기간은 몇 년으로 늘어지기도 합니다. 침묵은 그 누구도 보호하지 못합니다.
bikini 계정은 전체 공개의 가장 극단적인 버전을 택했습니다. 비공개 보고도 없었고, 유예 기간도 없었으며, 경고도 없었습니다. 버그들은 작동하는 익스플로잇과 함께 GitHub로 직행했으며, 저자는 커뮤니티가 직접 책임감 있는 보고를 수행하도록 권유했습니다.
Hacker News 스레드에서는 이러한 견해 차이가 실시간으로 드러났습니다. 한 댓글 작성자는 이러한 정보가 "어떤 정부나 기업의 도구 상자" 안에 머물러 있는 것보다 공개되는 편이 낫다고 단호하게 말했습니다. 또 다른 작성자는 비록 아무도 후속 조치를 취하지 않더라도, 공개가 여전히 더 나은 소프트웨어가 존재할 수 있게 한다고 반박했습니다. 제가 가장 솔직하다고 느낀 세 번째 작성자는 이 상황 자체가 그저 최악이라고 말했습니다. 즉, 자신의 코드베이스에 해당 내용이 포함되어 있을지도 모른다는 만약의 가능성 때문에, 전 세계의 모든 오픈 소스 프로젝트가 멈춰 서서 이 저장소 하나를 감사(audit)해야 하는 상황이 온 것 같다는 것이었습니다.
이에 대해 명확한 답을 내릴 수는 없습니다. 조율된 공개 (Coordinated disclosure)가 성숙한 선택이며 저 또한 그쪽으로 기울어 있지만, 완전 공개 (full-disclosure) 논거가 틀렸다고 가정할 수도 없습니다. 제가 확신하는 것은, 아무런 예고 없이 한 사람이 20개의 버그를 GitHub에 쏟아붓는 이 모델이 모방될 것이라는 점입니다. AI 퍼징 (fuzzing) 덕분에 이를 수행하는 비용이 방금 낮아졌기 때문입니다.
파서(parsers)가 계속 패배하는 이유
이번 사례에서 한 발짝 물러나 보면 명확한 패턴이 보이며, 이는 새로운 것이 아닙니다.
해당 저장소의 거의 모든 타겟은 C 언어로 신뢰할 수 없는 입력값을 파싱 (parsing)합니다. 네트워크 프로토콜 파서 (Network protocol parsers). 컨테이너 포맷 (Container formats). 이미지 및 비디오 디코더 (Image and video decoders). DNS 메시지. SSH 핸드셰이크 (SSH handshakes). Wireshark가 이 저장소에 직접 포함되어 있지 않음에도 불구하고 토론에서 Wireshark 디섹터 (dissectors)가 반복적으로 언급된 이유는, 디섹터가 거의 전적으로 C로 작성된 프로토콜 디코더 (protocol decoders)이며 패킷을 보낼 수 있는 사람이라면 누구나 어떤 디코더를 실행할지 선택할 수 있기 때문입니다. 미디어 플레이어도 마찬가지입니다. VLC에 잘못된 형식의 VP9 스트림을 전달하면, 공식적으로 검증되지 않았고 마감 압박 속에서 작성되었으며 수백 페이지에 달하는 포맷 명세서를 처리하는 C 코드를 실행하게 됩니다.
C가 적은 아닙니다. 세상에서 가장 중요한 소프트웨어 중 상당수가 C로 작성되었습니다. 하지만 C는 경계 검사 (bounds check)를 하지 않으며, 메모리를 해제 (free)한 후에도 그 메모리 사용을 거부하지 않고, 정수 (integer)가 최대치를 넘어 오버플로 (wrap)되었을 때 알려주지도 않습니다. C로 작성된 모든 파서는 이 저장소를 가득 채우고 있는 바로 그 부류의 버그들을 향한 상시적인 초대장과 같습니다: Use-after-free, out-of-bounds write, 메모리 오염 (memory corruption)으로 이어지는 정수 오버플로 (integer overflow).
이것이 Rust 재작성 (Rust rewrite) 운동이 존재하는 이유입니다. curl이 이제 선택 사항으로 Rust 기반의 DNS 리졸버 (DNS resolver)를 제공하는 이유이기도 합니다. 사람들이 파서를 메모리 안전 언어 (memory-safe languages)로 옮기려고 계속 시도하는 이유이기도 합니다. exploitarium에 있는 버그들은 생소한 것이 아닙니다. 그것은 우리가 40년 동안 배포해 온 것과 동일한 버그들이며, 인간이 잠든 동안 실행되는 루프에 의해 더 빠르게 발견된 것뿐입니다.
당신이 실제로 해야 할 일
만약 당신이 영향을 받은 소프트웨어 중 하나라도 유지 관리하거나 운영하고 있다면, 실질적인 조치들은 그리 화려하지 않습니다.
패치가 출시되는 대로 적용하십시오. 유지 관리자들은 앞으로 몇 주 동안 공개적으로 우선순위를 정하는 작업 (triaging)을 수행할 것이며, 다른 모든 이들이 해야 할 책임 있는 행동은 그들의 권고 사항을 따르고 신속하게 업데이트하는 것입니다. "테스트"를 목적으로 무작위 GitHub 저장소에서 개념 증명 (proof-of-concept, PoC) 코드를 가져와 운영 서버 (production machine)에 실행하지 마십시오. 몇몇 댓글 작성자들은 보안 취미가들이 익스플로잇 (exploit)을 서둘러 다운로드하다가 그 과정에서 스스로를 위험에 빠뜨리는 아이러니에 대해 농담을 던졌습니다. 이것은 결코 농담이 아닙니다.
만약 당신이 신뢰할 수 없는 입력값 (untrusted input)을 허용하는 서비스를 운영하고 있다면 — 아마 대부분 그러할 것입니다 — 파서 (parser)를 샌드박스 (sandbox)화 하십시오. 미디어 디코더 (media decoder)와 프로토콜 파서 (protocol parser)를 컨테이너 (container)나 seccomp로 제한된 프로세스에서 실행하십시오. nmap과 같은 네트워크 파서 (network parser)나 프로토콜 분석기 (protocol dissector)는 당신의 SSH 키가 들어있는 노트북이 아니라, 신뢰 경계 (trust boundary) 뒤에 위치해야 합니다.
그리고 만약 당신이 C 기반의 파싱 코드를 유지 관리하는 사람이라면, 이번 주는 속성 기반 테스트 (property-based testing)와 자체적인 지속적 퍼징 (continuous fuzzing)을 살펴보기 좋은 시기입니다. 이번 취약점을 공개한 저자는 여가 시간에 AI 지원 하네스 (AI-assisted harness)를 구축했습니다. 실제 예산이 있는 조직들은 누군가 대신 해주고 경고 없이 결과를 발표하기 전에 똑같은 일을 할 수 있습니다.
내 기억에 남는 부분
나는 계속해서 이 비대칭성 (asymmetry)에 대해 생각하게 됩니다. 익명의 개인 한 명, AI 퍼징 (fuzzing) 루프, GitHub 계정 하나만으로 갑자기 20개의 오픈 소스 프로젝트가 모든 일을 중단하고 자신들이 불길에 휩싸였는지 확인해야 하는 상황이 벌어집니다. 작은 라이브러리의 유지 관리자는 보안 팀을 가지고 있지 않습니다. 그들에게는 저녁 시간과 주말, 그리고 본업이 있습니다. 이를 23개의 코드베이스로 곱해보면, 오픈 소스 세계의 상당 부분이 자신들에게 없는 사이클을 태우며 불타고 있다는 의미가 됩니다.
그 버그들은 실재하며, 혹은 그중 일부는 실재합니다. 공개 윤리(disclosure ethics)는 논쟁의 여지가 있으며, 합리적인 사람들도 서로 다른 입장에 서게 됩니다. 하지만 새롭게 느껴지는 부분은 그 속도와 규모, 그리고 이를 뒷받침하는 루프(loop)가 앞으로 더 비싸지는 것이 아니라 더 저렴해질 것이라는 사실입니다. 다음번 공개는 더 클 것입니다. 또한 아마도 더 혼란스러울 것입니다.
우리는 수십 년 동안 파서(parser)의 메모리 버그(memory bugs)를 컴퓨팅의 배경적인 사실로 취급해 왔습니다. 그 배경 소음이 곧 더 커질 것입니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기