짙은 네이비 배경 위의 추상적인 기술 일러스트: 왼쪽의 작고 압축된 서버 큐브가 오른쪽의 에이전트 노드를 향해 세 장의 작은 직사각형 카드를 내보낸다. 앞의 두 카드는 옅은 색으로 정적이며, 세 번째 카드는 열쇠 모양의 긴 그림자를 드리운다. 가는 청록색 필라멘트가 서버에서 뒤쪽의 느슨한 리포지토리 노드 그리드로 이어지고, 하나의 호박색 선이 에이전트 노드를 작은 자격 증명 디스크들이 달린 키링에 연결한다. 인물, 로고, 텍스트는 없다. OrcaRouter 로고가 오른쪽 아래 모서리에 합성되어 있다.
AI Safety Incidents

Deadbugz: 세 번째 도구 호출에서 적대적으로 돌변하는 MCP 서버, 74분 만에 23개의 저장소에 푸시됨

작성자

Magnus Corvin

게시일

최신 모델 · 20모든 모델 보기 →
벤치마크: Artificial Analysis · 매일 업데이트
모든 게시물로 돌아가기

2026년 8월 10일, 하나의 GitHub 계정 zellkernel이(가) 23개의 풀 리퀘스트를 74분 동안 서로 무관한 AI, MCP 및 개발자 도구 저장소들을 대상으로 열었으며, 각각 이름이 productivity-suite인 MCP 서버를 추가했고, 이 서버는 두 가지 평범한 도구인 format_text와 summarize를 홍보했습니다. Pillar Security에 따르면, 이들은 이 캠페인을 Deadbugz라고 명명하고 8월 12일에 분석 글을 게시했으며, 해당 서버는 처음 세 번의 호출에서는 정직한 결과를 반환한 뒤, 에이전트에 전달한 메타데이터를 다시 작성했습니다: 도구 설명과 프롬프트 내용이 모델을 SSH 키, AWS 자격 증명, 셸 기록 및 Kubernetes 구성으로 유도하기 시작했고, 해당 활동을 사용자에게서 숨기라고 지시했습니다. Pillar가 검토했을 당시 23개의 풀 리퀘스트 중 19개는 닫혔고, 4개는 여전히 열려 있었으며, 병합된 것은 없었습니다. 확인된 피해자는 없습니다. 이것은 다른 이들이 보고한 하나의 기록이며, 여기서는 그들에게 인용한 것입니다. 각기 출처, 심각도, 신뢰도 등급 및 이의 제기 플래그를 갖춘 다른 문서화된 에이전트 사건들은 AI 사건 아카이브에 있습니다. 따라서 에이전트 도구를 겨냥한 공급망 캠페인은 실제로 발생한 나머지 사례들과 나란히 읽을 수 있습니다.

아카이브는 이 기록에 높은 심각도와 신뢰도 A를 부여합니다 — 일차 자료들이 일치하는, 잘 문서화된 기록입니다 — 한편으로는 확인된 실제 피해가 없다고 별도로 기록합니다. 두 가지 모두 동시에 사실이며, 그 둘 사이의 간극이 이 기록의 핵심입니다. 누구든 이름을 댈 수 있는 피해자를 배출하기 전에 설계가 이례적으로 상세하게 문서화된 캠페인입니다. 중요한 두 날짜는 이틀 차이입니다. 풀 리퀘스트는 8월 10일에 나갔고, Pillar Security의 Ariel Fogel은 8월 12일에 분석을 발표했으며, 그 게시물에는 검증된 정보가 들어오는 대로 업데이트하겠다는 상시 안내 문구가 붙어 있습니다.

세 번 호출한 다음 메타데이터가 변경됩니다

MCP 서버는 에이전트의 동작을 바꾸기 위해 머신에서 코드를 실행할 필요가 없다. 도구 정의는 매 세션마다 모델에 컨텍스트로 전달되므로, 이를 제공하는 서버는 도구의 이름과 저장소, 매니페스트를 그대로 둔 채 에이전트가 읽는 지침을 다시 쓸 수 있다. Deadbugz는 바로 이 비대칭성을 기반으로 만들어졌으며, Pillar는 이를 런타임 게이트된 MCP 메타데이터 포이즈닝이라고 부른다.

이 메커니즘은 한 문장으로 설명할 수 있을 만큼 단순합니다. 서버는 tools/call 요청을 클라이언트별로 세는 인메모리 카운터를 유지합니다. 처음 세 번까지는 정상적으로 동작합니다. 카운터가 임계값에 도달하면 이후 tools/list 및 prompts/get 응답이 변조되어 돌아옵니다. 도구 설명과 프롬프트 내용이 달라지고, 에이전트를 SSH 키, AWS 자격 증명, 셸 기록, Kubernetes 구성으로 유도하며 사용자에게 해당 활동을 숨기라고 지시합니다. 오염된 프롬프트 텍스트에는 deadbugz 표시와 비트코인 주소가 포함되어 있습니다.

게이트는 일반적인 방어 체계가 이를 탐지하지 못하는 이유이기도 하다. 페이로드는 첫 요청부터 소스 코드에 존재하며, 전환되는 순간 코드나 구성에는 아무 변화도 없다. 정적 스캔, SBOM 항목 또는 설치 시점에 도구 매니페스트를 한 번 읽는 것은 이를 포맷팅 유틸리티로 인식하는데, 카운터가 바뀌기 전까지 유틸리티가 반환하는 것이 바로 그것이기 때문이다. Pillar는 지연된 전환을 연구 회피 기법이라고 설명하며, 자사 연구진이 텍스트 전용 요청을 실행 중인 원격 서비스에 보내고 응답을 공개 소스와 대조함으로써 임계값과 변경된 메타데이터를 모두 확인했다고 말한다.

한 가지 세부 사항은 이 함정을 단일 세션보다 더 넓게 만듭니다. 서버가 알리는 것은 tools.listChanged라는 MCP 기능입니다. 이 기능은 클라이언트에게 도구 목록이 개정되었음을 알려줍니다. 해당 신호를 따르는 클라이언트는 세션 중간에 정의를 다시 읽고 운영자 조치 없이 오염된 버전을 가져오지만, 승인 시 정의를 캐시하는 클라이언트는 그렇게 하지 않습니다. 특정 에이전트가 어떤 동작을 보이는지는 서버가 아니라 클라이언트의 속성이며, Pillar의 글은 클라이언트를 이름별로 열거하지 않습니다.

HTML card titled 'Three calls, then the metadata changes', kicked 'MCP · productivity-suite', with the subtitle 'The payload is present from the first request; the gate is a counter in memory'. Three columns. 'Calls one to three — benign' lists format_text returning formatted text, summarize returning a summary, and tools/list and prompts/get returning honest tool definitions, with a note that nothing on disk differs from what a reviewer approved. 'The gate' lists an in-memory per-client counter of tools/call requests, a threshold of three, altered tool descriptions and prompt content in later tools/list and prompts/get responses, and the advertised tools.listChanged capability that lets compliant clients re-read definitions mid-session. 'What the poisoned metadata asks for' lists SSH keys, AWS credentials, shell history and Kubernetes configuration, an instruction to keep the activity from the user, and the embedded marker deadbugz with a Bitcoin address. A footer reads 'Per Pillar Security's disclosure of 12 August 2026. Pillar says its researchers confirmed the threshold and the altered metadata against the live remote service using text-only requests, matching the public source.'

배포: 74분 동안 풀 리퀘스트 23개

이 배포는 레지스트리에 있는 패키지도, 락파일에 숨겨진 오염된 의존성도 아니었습니다. 그것은 서버의 명목상 기능과 전혀 관계없는 프로젝트들을 대상으로 한 풀 리퀘스트 스팸이었는데, 이는 공격자가 관리자 계정을 얻지 못할 때 저비용 공급망 공격 시도가 취하는 형태입니다. 즉, 구성 변경을 충분히 많이 제출하고 그중 하나가 병합되거나 로컬에서 적용되기를 기다리는 것입니다.

Pillar의 23건 분석은 세 갈래로 나뉜다. 17개는 원격 MCP 엔드포인트를 추가한다: productivity-suite-mcp[.]onrender[.]com/mcp, 이는 Render에서 호스팅된다. 4개는 숨겨진 로컬 Python 파일을 호출한다: ~/.config/.cache/.sys/.deadbug-mcp.py; 2개는 디렉터리 또는 목록 제출물이며, 이 글은 이를 전달이 아니라 정찰이나 분량 채우기로 본다. 시간 범위는 2026년 8월 10일 UTC 기준 오후 9시 52분부터 오후 11시 7분까지로 제시된다 — 공개 자료의 설명 방식에서는 74분이지만, 두 타임스탬프 자체는 75분에 걸쳐 있고, 기록에서 그 1분이 관건이 되지는 않는다. 개별적으로 이름이 지정된 대상 저장소는 하나뿐이다: getsentry/sentry-mcp, 풀 리퀘스트 #1239, 로컬 아티팩트 전달의 사례로 인용된다.

그 배후의 계정은 생성된 지 얼마 되지 않은 점을 고려하면 규모가 상당했다. Pillar의 수집 당시 zellkernel에는 공개 저장소가 50개 있었고, 그중 20개는 포크였으며, 그 50개 중 21개는 캠페인과 같은 날인 8월 10일에 생성되었다. 해당 프로필은 X 계정 @llmgod와 상호 연결되어 있었고, 이 계정은 다시 GitHub 계정으로 연결되었는데, 이는 탈취된 정체성이라기보다 목적에 맞게 만든 정체성임을 뒷받침하는 상호 연결 방식이다.

기록에서 가장 자주 반복되는 수치는 닫힌 19개, 열린 4개, 병합 0개이며, 이 수치는 또한 가장 자주 '이상 없음' 신호로 읽히는 수치이기도 하지만 그것은 정확히 사실이 아니다. GitHub의 병합 버튼은 호스트의 실행 기록이 아니다. 유지관리자는 브랜치를 가져와 실행할 수 있고, 구성을 수동으로 적용할 수 있으며, 누구도 댓글을 달기 전에 CI 작업이 PR의 head를 가져올 수도 있다. 로컬 스크립트 경로를 호출하는 구성을 작성한 네 개의 풀 리퀘스트가 바로 그 간극이 가장 크게 문제 되는 사례들인데, 그 스크립트는 GitHub의 병합 집계와 완전히 무관하게 가져와져 실행되기 때문이다. Cloud Security Alliance Labs도 9월 2일 노트에서 같은 점을 지적했다. 닫힌 수와 병합되지 않은 수는 아무것도 실행되지 않았음을 증명하지 않는다.

HTML card titled 'Twenty-three pull requests in seventy-four minutes', kicked '10 August 2026 · delivery', subtitled 'Times UTC. Counts are Pillar Security's review snapshot.' Three columns. 'The window' lists the first pull request at 21:52, twenty-three pull requests to unrelated AI, MCP and developer-tooling repositories, the last at 23:07, and a note that the 74-minute framing spans 75 minutes on the clock. 'What each pull request added' lists seventeen adding the remote endpoint productivity-suite-mcp.onrender.com/mcp, four invoking the hidden file at ~/.config/.cache/.sys/.deadbug-mcp.py, two directory or listing submissions, and one named example, getsentry/sentry-mcp pull request 1239. 'At review' lists nineteen closed, four open, zero merged through GitHub's review, zero confirmed victims, and the account zellkernel linked to the X handle llmgod, with fifty public repositories and twenty-one created that day. A footer reads 'Per Pillar Security. Cloud Security Alliance Labs repeated the same figures on 30 August and 2 September 2026 without independent verification. As of 29 October 2026 the GitHub account and the productivity-suite-mcp repository both return 404.'

무엇이 확립되었고, 무엇이 그렇지 않은가

공개에 의해 입증된 사항 — Pillar가 읽은 아티팩트에서, 그리고 한 경우에는 쿼리한 서비스에서 이를 보고한다는 점에서: 서버와 그 소스 저장소, 광고된 두 가지 도구, 카운터와 세 번 호출 임계값, 네 가지 자격 증명 대상, PR 수와 검토 당시의 병합 상태, 그리고 GitHub 계정과 X 핸들 간의 연결. 라이브 엔드포인트에 대한 Pillar 자체 테스트는 소스 코드를 읽는 것이 아니라 재현이기 때문에 목록에서 가장 강력한 항목이다.

피해자라는 점은 확립되지 않았고, 기록은 그 점을 신중하게 다룹니다. 아카이브의 real_harm 필드는 false인데, 이는 의도가 아니라 증거에 관한 진술입니다 — 이 캠페인과 연결된 호스트, 로그 또는 탈취된 자격 증명을 제시한 사람은 아무도 없습니다. zellkernel과 @llmgod 배후의 개인이나 단체도 확인되지 않았습니다. Pillar는 이 작전을 해당 계정들에 귀속시키고 거기서 멈춥니다. 재정적 동기는 페이로드에 내장된 비트코인 주소에 근거하는데, 이는 지표로부터의 추론일 뿐 행위자에 관한 발견이 아닙니다. 그리고 방어자가 가장 답을 원하는 질문 — 캠페인이 아직 진행 중인지 — 에 대한 답은 기록에 없습니다: 해당 게시물은 업데이트될 것이라고 표시되었고, GitHub나 Render의 이후 개정이나 삭제 통지도 보이지 않습니다.

교차 검증은 신뢰도 등급이 시사하는 것보다 빈약하며, 이 점은 분명히 말할 가치가 있습니다. 두 Cloud Security Alliance Labs의 연구 노트(2026년 8월 30일 및 9월 2일자)는 이 캠페인을 다시 서술합니다. 뒤의 노트는 발견, PR 세부 정보, 서버 동작 및 계정 귀속을 Pillar의 공으로 돌린다고 명시하며, 자체적인 독립 검증은 설명하지 않습니다. Armor의 2026년 9월 22일자 블로그 게시물은 방어 지침을 제공하고 Pillar가 서버를 분해했다고 말하지만, 자체적인 포렌식 증거는 제시하지 않습니다. CVE는 할당되지 않았으며, CSA는 이것이 MCP 사양 취약점이 아니라고 밝힙니다. 2026년 10월 29일 현재, 검색해도 GitHub나 Render의 권고가 나오지 않고, 주류 보안 업계 전문 매체 — BleepingComputer, The Register, SecurityWeek 또는 Hackread 기사 — 의 보도도 없습니다. 이는 이런 형태의 공급망 캠페인으로는 이례적이며, 그 자체가 기록이 보여주는 내용의 일부입니다. 여기서 "1차 출처가 일치한다"는 것은 하나의 원천 1차 출처와 그로부터 파생된 일련의 2차 문서를 의미합니다.

더 작은 두 가지 모호성은 매끄럽게 넘기기보다 지적해 두는 것이 좋습니다. 2차 요약본들은 세 번째 호출과 네 번째 호출 중 어느 것이 오염된 메타데이터를 받는 첫 호출인지에 대해 서로 다르며, 이는 카운터가 세 번째 요청에서 트립된다고 설명된 데서 비롯됩니다. 기록과 공개 자료 모두 3을 사용합니다. 그리고 전달 창은 타임스탬프가 75분에 걸쳐 있는데도 74분으로 설명됩니다.

다시 확인할 수 없었던 점 하나: 2026년 10월 29일, GitHub 계정 zellkernel과 저장소 zellkernel/productivity-suite-mcp는 모두 404를 반환하며, 이름이 개별적으로 명시된 단일 풀 리퀘스트인 getsentry/sentry-mcp #1239 역시 더 이상 확인되지 않습니다. 해당 저장소 자체는 이제 getsentry/toolkit으로 리디렉션됩니다. 따라서 PR 수, 병합 상태, 저장소 내용은 오늘 1차 출처로 재검증할 수 없으며, 이는 8월 중순에 수집된 Pillar의 스냅샷으로 남습니다.

HTML card titled 'What is established, and what is not', kicked '2026-08-10-deadbugz-mcp-supply-chain', subtitled 'One record, one originating source, two secondary notes that restate it'. Three columns. 'Established by the disclosure' lists the server, its source repository and the two advertised tools; the counter and the three-call threshold, confirmed against the live endpoint; the four credential targets; twenty-three pull requests, nineteen closed, four open, none merged; and the delivery account linked to the X handle llmgod. 'Not established' lists any victim or executed payload, with the archive recording real harm as false; the actor behind the account and handle; motive, which rests on a Bitcoin address in the payload; and whether the campaign is still running, the post having promised updates that are not visible. 'Corroboration' lists the Cloud Security Alliance Labs notes of 30 August and 2 September 2026 as restatement without independent checks; the Armor blog of 22 September 2026 as guidance without forensic evidence; no CVE assigned; no GitHub or Render advisory found; and no mainstream trade-press coverage found as of 29 October 2026. A footer reads 'The archive grades the record A, well documented with primary sources that agree. The secondary documents here all derive from Pillar Security's post, so agreement between them is not a second measurement.'

공개 내용이 방어자에게 요구하는 것

Pillar가 권장하는 대응은 대부분 메타데이터를 보안 표면으로 취급하는 것에 관한 것이지, 보안 표면을 설명하는 것에 관한 것이 아닙니다. 호스트의 경우 구체적으로 요구되는 사항은 다음을 차단하거나 헌팅하는 것입니다: productivity-suite-mcp[.]onrender[.]com/mcp, 캠페인의 이전 trycloudflare.com 엔드포인트를 Pillar가 현재 활성 상태가 아니라고 말하더라도 거부 및 헌팅 목록에 유지하는 것, 그리고 deadbug-mcp.py를 실행하지 않는 것입니다 — 숨겨진 파일 경로 ~/.config/.cache/.sys/.deadbug-mcp.py는 홈 디렉터리, 리포지토리 및 MCP 클라이언트 구성 전반에서 검색해야 할 아티팩트입니다.

조사 순서는 차단 목록보다 더 중요합니다. 호스트가 연결했을 수 있다면 Pillar는 무엇이든 정리하기 전에 MCP 클라이언트 로그를 보존하고, 그다음 도구 정의 새로 고침과 세 번째 호출 이후 에이전트가 수행한 작업을 검토하라고 말합니다. 자격 증명은 로컬 증거가 노출을 뒷받침하는 경우에만 교체해야 하며, 이는 의심만으로 모든 것을 교체하려는 반사적 행동과 정반대입니다. 서버 구성은 또한 선택적 텔레메트리를 다음 주소로 허용했습니다: WEBHOOK_URL, 연결 시, 첫 호출 시, 트리거 이벤트 시 비콘을 전송하며 — 클라이언트 로그와 엔드포인트 트래픽 너머에서 조사할 세 번째 장소를 제공하는 세부 사항입니다.

MCP 클라이언트를 구축하는 사람들에게 이 권고는 구조적인 것이며, 이 기록에서 가장 오래 유효한 부분입니다:

• 서버의 이름과 리포지토리를 신뢰하기보다는, 승인 시점에 도구 정의의 지문을 생성하고 새로 고침할 때마다 비교하세요.

• 이미 승인된 서버의 정의 변경은 운영자가 확인하고 재승인하는 보안 이벤트로 취급해야 하며, 조용히 묻혀버리는 일상적인 메타데이터 변동으로 취급해서는 안 됩니다.

• 자격 증명 접근, 코드 실행, 외부 이메일 발송, 저장소 쓰기 같은 민감한 작업은 서버가 제공하는 설명이 아니라 정책을 통해 강제하십시오.

세 번째 항목이 Deadbugz를 단순한 호기심거리가 아닌 하나의 기록으로 만든다. 위의 모든 통제는 서버가 도구에 붙이는 텍스트를 통해 에이전트가 설득될 수 있으며, 그 텍스트가 신뢰 결정이 내려진 뒤에 바뀔 수 있다고 가정한다. Pillar는 이 캠페인을 Invariant Labs의 2025년 MCP 슬리퍼 공격, 위조 postmark-mcp 패키지, 그리고 업데이트를 통해 무기화된 Koi 문서화 MCP 패키지를 포함한 계보에 놓는다. 이들 모두는 해당 기법의 선례로서, Pillar가 그 점을 위해 인용한 것이지 이번 전달에 관한 증거로 인용한 것은 아니다.

왜 게이트가 피해자 수보다 더 중요한가

전송 시도가 23회 있었고 병합이 없으며 확인된 피해자도 없는 캠페인은 'attempted'로 분류하고 넘어가기 쉽습니다. 이 캠페인이 높은 심각도로 아카이브에 속하는 이유는, 그 회피가 대규모로 전송이 성공하는 데 의존하지 않기 때문입니다. 그 회피는 오늘날 대부분의 MCP 배포가 공유하는 한 가지 속성에 의존합니다. 승인은 설치 시 한 번 이루어지고, 승인된 정의가 앞으로 제공될 정의라고 가정된다는 점입니다. Deadbugz는 세 번의 호출 동안 그 가정을 그대로 유지한 뒤 이를 깨뜨립니다.

이 문제의 해결책은 특정 서버에 대한 패치가 아니며, 추적해야 할 CVE도 없다. 핵심은 "승인됨"이 그 배후에 비교를 동반하는 지속적 조건이 되어야 한다는 것 — 이는 스캐너가 찾는 대상이 달라지는 것이 아니라, 클라이언트와 그 운영자가 행동하는 방식이 달라지는 것이다. 8월에 실제로 누군가 그 서버를 운영했는지는 여전히 알 수 없다; 현재 기록 그대로라면, 발견된 것은 바로 그 메커니즘 자체다.