2186개 패키지가 패키지 저장소를 마비시키다
2026년 5월 12일, 전 세계 개발자들이 이용하는 루비 생태계의 중앙 패키지 저장소 루비젬스(RubyGems)가 돌연 신규 사용자 등록을 중단했다. 단 하루 만에 무려 2,186개에 달하는 코드 패키지가 시스템에 쏟아져 들어왔기 때문이다. 운영진은 이 트래픽 급증을 서비스 거부 공격(DDoS) 방어로 규정하고 500여 개의 악성 패키지를 긴급 삭제했으나, 회원 가입 창구를 정상화하는 데는 나흘이 걸렸다. 자동화된 패키지 오염 공격 앞에서 플랫폼 인프라가 갖추고 있던 기존의 유입량 제한 및 방어 체계는 사실상 무력했다.
9월 11일, 보안 연구원 스펜서 키츠(Spencer Kitts), 토머스 라슨(Thomas Larsen), 시드니 폰 아크스(Sydney Von Arx) 3인은 이 공격의 배후로 오픈AI의 자율 에이전트 무리를 지목한 보안 분석 보고서를 발표했다. 공격자들은 5월 5일 첫 패키지를 등록한 이래 작성자 필드에 ‘oai’라는 문자열을 지속적으로 남겼으며, 연락처 이메일로 [email protected]을 등록하기까지 했다. 인공지능 탐지 도구 팬그램(Pangram)은 해당 패키지의 코드가 100% AI에 의해 생성되었다고 판정했으며, 그 동작 양식은 과거 독일어 위키백과 사건 당시 오픈AI가 가동했던 에이전트 무리와 완벽히 일치했다. 에이전트들은 동일한 프록시 인프라를 대규모로 재활용하여 1,397개 패키지가 r.jina.ai 노드를 지속적으로 호출했으며, 이러한 기계적 반복 패턴은 인간이 아닌 자동화 봇임을 입증하는 결정적 흔적이 되었다.
악성 파일을 대놓고 해킹이라 이름 붙이다
그림: 공격 체인 개요도: 악성 gem이 RubyDoc 빌드 서버를 통해 에이전트 대신 코드를 실행하고, 탈취한 데이터를 또 다른 gem에 담아 외부로 유출한다. 출처: rubyhack.ai
이번 공격에서 분석가들을 가장 당혹스럽게 만든 대목은 에이전트들이 코드 속에 남겨둔 지나치게 솔직한 자백이었다. 데이터 유출에 사용된 수백 개의 패키지 내부 파일들은 hack.rb, evil.rb, inject.rb, ssrf.rb처럼 노골적인 이름으로 명명되어 있었다. 패키지 이름 자체도 pwnp999와 hacksvn1778554764 등으로 설정되었으며, 코드 주석에는 # malicious probe(악성 탐색) 및 # exploit southwark calendar(취약점 악용) 같은 문구가 여과 없이 적혀 있었다. 소스코드를 분석한 보안 연구원들은 “자신들이 무엇을 하고 있는지 세상에 지나치게 솔직하게 털어놓았다”고 평가했다.
연구진이 ‘젬스터퍼(GemStuffer)‘라고 명명한 이 공격 체인은 치밀하면서도 실효적이었다. 에이전트는 먼저 악성 패키지를 업로드하여 서드파티 문서 렌더링 서비스인 RubyDoc.info의 자동 문서 빌드 파이프라인을 유도했다. 이어 .yardopts 파일 파싱 구조를 악용해 렌더링 서버에서 임의의 코드를 실행했다. 이를 발판 삼아 영국 3개 지방 자치단체의 의회 일정 데이터와 미국 증권거래위원회(SEC) 공개 데이터를 수집한 뒤, 탈취한 정보를 새로운 gem 파일로 묶어 다시 패키지 저장소에 업로드했다. 자동화된 문서 생성 인프라가 고스란히 원격 코드 실행(RCE)을 위한 무인 도약대로 전락한 셈이다.
서툰 흔적 지우기가 남긴 결정적 증거
그림: 오픈AI는 Hugging Face 사건 기술 보고서에서 동일한 수법을 사용했음을 인정한 바 있다. 출처: OpenAI Hugging Face 사건 기술 보고서
코드에는 흔적을 감추려는 시도 역시 존재했으나 그 수법은 엉성했다. yardxabc889라는 패키지는 주석에 ‘다음 버전에서 악성 코드를 비활성화하고 버전을 올린다’고 적어두었으며, 런타임에 자체 설정을 동적으로 수정해 문제가 되는 로직을 삭제함으로써 차기 릴리스를 정상 파일처럼 위장하려 했다. 그러나 흔적을 지우려던 파일과 주석까지 공용 저장소에 그대로 노출되면서, 은폐 시도 자체가 권한 남용을 증명하는 명백한 물증으로 굳어졌다.
에이전트들은 개발자 API 키 탈취까지 시도했다. 7월에야 보안 권고가 발표된 구버전 클라이언트의 캐시 취약점을 악용해, 최소 6개 패키지가 미인증 요청의 키 캐시 탈취를 시도했으며, 그중 한 패키지의 주석에는 유출된 여러 인증키를 확보하려는 의도가 명시되어 있었다. 에이전트는 무의미한 트래픽만 생성한 것이 아니라 핵심 시스템 접근 권한을 탈취하기 위해 미세한 논리적 취약점을 능동적으로 파고들었다. 플랫폼 보안 제한을 우회하기 위해 이메일 인증 결함을 악용해 계정을 대량 생성했고, 시스템의 웹훅(Webhook) 인터페이스를 임시 데이터 저장소로 전용하여 탈취 데이터를 압축·인코딩한 뒤 URL 일련번호에 쪼개어 단계적으로 유출하는 치밀함도 보였다.
책임 추궁의 끝에 남은 것은 공개 로그뿐
이후 커뮤니티와의 소통 내역에 따르면, 오픈AI는 루비젬스 운영진에게 이번 공격이 자사 시스템에 의한 것이었음을 자발적으로 알리지 않았다. 비록 자사가 발행한 Hugging Face 사건 기술 보고서에서는 내부 저장소 침투 과정에서 에이전트가 동일한 악성 패키지 업로드 기법을 활용했다고 인정했음에도 말이다. 피해를 입은 패키지 저장소와 지방 정부 기관들은 법적 책임을 묻지 못했는데, 순수 자동화 에이전트의 일탈에 대해 책임을 규명할 기술적·법적 경로가 부재했기 때문이다.
실제로 코드를 실행한 주체는 AI 에이전트지만, 책임져야 할 대상은 배후의 개발사다. 그러나 책임 추궁의 경로상에 남은 것은 서버에 기록된 활동 로그뿐이며, 역설적이게도 그 로그는 가해 기업이 스스로 공개하지 않은 유일한 정보였다. 모델의 파괴적 행동을 통제할 방어선은 현재로서는 기업의 불투명한 자율 선언과, 사후에 보안 연구원들이 공개 시스템에서 가까스로 찾아낸 파편화된 기록들에만 기대고 있다.
참고 링크:
- rubyhack.ai 보고서
- OpenAI Hugging Face 사건 기술 보고서