| |

Как 66 строк JavaScript превращают плагин Claude Code в SSH-бэкдор? Полный разбор 6 этапов атаки

Как 66 строк JavaScript превращают плагин Claude Code в SSH-бэкдор? Полный разбор 6 этапов атаки

Примечание автора: разбираем инцидент с вредоносным плагином Claude Code в магазине расширений Cursor. Рассмотрим, как запускается загрузчик из 66 строк, как две пары SSH-ключей работают вместе с обратным туннелем, какие выводы подтверждены, а какие — нет, и как разработчикам проверить свою систему.

29 октября 2026 года в магазине VS Code-расширений Cursor обнаружили подменённое расширение anthropic.claude-code. Исследователи нашли в начале его файла extension.js JavaScript-загрузчик длиной около 66 строк. Как только редактор загружает этот модуль, загрузчик пытается установить на компьютере разработчика SSH-бэкдор, который сохраняется в системе.

Это не слухи. Анализ инцидента опубликовали сама Cursor в официальном уведомлении о безопасности, а также Microsoft Security Research, Phorion, StepSecurity, OpenSourceMalware и Expel. Последняя также расследовала 4 реальных инцидента у своих клиентов. К 1 ноября StepSecurity дополнила анализ точным сравнением образцов, и техническая картина стала в целом ясна.

Главное: за 3 минуты вы узнаете, что делают эти 66 строк кода, почему пользователю не нужно выполнять опасные команды для запуска атаки и почему удаление плагина не гарантирует безопасность.

66-lines-javascript-claude-code-extension-ssh-backdoor-ru-image-0


Кратко об инциденте с бэкдором на 66 строках JavaScript

Сначала обозначим границы инцидента. Это атака на цепочку поставок инструментов разработки, затронувшая канал распространения расширений Cursor. Сама модель Claude не была взломана, а доказательств проникновения во внутренние системы Anthropic нет. Microsoft подтвердила, что Microsoft Visual Studio Marketplace и официальный npm-пакет @anthropic-ai/claude-code не пострадали.

Параметр Подробности
Дата инцидента 29 октября 2026 года
Канал распространения Cursor VS Code Extension Marketplace
Выдавали себя за anthropic.claude-code (Anthropic не собирала и не публиковала эти версии)
Вредоносные версии 2.1.312, 2.1.313
Платформы вредоносных установочных пакетов по официальным данным Windows x64, macOS ARM64
Время публичного распространения Около 11 часов 8 минут
Официальная верхняя оценка числа затронутых пользователей 5000 человек (это верхняя оценка, а не число устройств, захваченных злоумышленниками)
Внедрённый код Загрузчик в строках 1–66 файла extension.js
Последующая исправленная версия Anthropic выпустила 2.1.314

Хронология инцидента с бэкдором на 66 строках JavaScript

Всё время ниже указано по Пекину. Важно различать два момента: когда установочный пакет был доступен для скачивания и когда скачанный пакет фактически запустили. Второе могло произойти значительно позже.

Время по Пекину Событие
29 октября, 17:27 Вредоносное расширение стало доступно для скачивания в магазине Cursor
30 октября, 04:35 Cursor прекратила распространение, окно доступности закрылось
30 октября Cursor опубликовала уведомление о безопасности, вслед за ней свой анализ представили Phorion, OpenSourceMalware и Microsoft
30 октября, 12:45 Expel зафиксировала первый запуск вредоносного кода на Mac одного из клиентов — примерно через 8 часов после удаления расширения из магазина
31 октября, 02:30 Cursor обновила уведомление, добавив 2.1.312 в список затронутых версий и уточнив индикаторы компрометации
1 ноября StepSecurity завершила точное статическое сравнение на основе образца из MalwareBazaar

После обнаружения инцидента Cursor удалила вредоносные версии и временно закрыла весь магазин расширений. Кроме того, компания проверила журналы доступа, провела ротацию ключей, пересобрала магазин и совместно с облачными провайдерами добилась отключения серверов злоумышленников. В открытых источниках пока не объясняется, как атакующие получили право публиковать сборки в магазине Cursor. До завершения расследования не стоит утверждать, что был украден аккаунт Anthropic или что в Cursor существовала какая-либо конкретная уязвимость.


Как 66 строк JavaScript запустили бэкдор в расширении Claude Code

Фразу «66 строк» легко понять неправильно: это не значит, что всё расширение состоит из 66 строк. На самом деле обычный файл extension.js — это большой сжатый файл. Атакующий лишь вставил в его начало вредоносный загрузчик, который занимает строки с 1-й по 66-ю.

Этот код использует немедленно вызываемое функциональное выражение (IIFE). Ему не нужно ждать, пока пользователь отправит сообщение Claude, или выполнения каких-либо других условий. Когда Cursor загружает основной файл расширения в среде Node.js, вредоносный код выполняется раньше штатного.

Изменение на 7 386 байт: точное сравнение образцов

1 ноября StepSecurity получила образец из MalwareBazaar, проверила его SHA-256 и провела статическое сравнение. Результаты показывают, что атакующему вовсе не нужно было переписывать расширение.

Показатель Значение
Обычный extension.js 3 685 536 байт
Вредоносный extension.js 3 692 922 байта
Добавленный загрузчик 7 386 байт
Доля добавленного кода Около 0,20%
Версия во внешнем манифесте 2.1.313
Версия, указанная внутри основного кода 2.1.312

На последние две строки тоже стоит обратить внимание. Атакующий взял за основу обычную сборку 2.1.312, перепаковал её и изменил только внешнюю информацию о версии. Отображаемый номер версии не обязательно соответствует реальному происхождению кода, поэтому судить только по нему ненадёжно. В другом месте статьи StepSecurity при указании «количества оставшихся байт» допущена арифметическая ошибка. При цитировании лучше опираться на общие размеры и разницу из таблицы выше.

Почему пользователю не нужно выполнять опасные команды

Эта атака никак не связана с инъекцией промптов. Исследователи подтвердили, что процесс обладает следующими особенностями:

  • Пользователю не нужно начинать диалог с Claude, а модели — соглашаться на выполнение опасных инструкций;
  • Атака не зависит ни от вредоносного промпта, ни от скриптов жизненного цикла установки npm;
  • На начальном этапе атаки не требуется скачивать дополнительные исполняемые файлы.

Настоящий риск связан с правами, которыми расширение IDE обладает на компьютере разработчика. Расширение работает в Node.js и поэтому может обращаться к файловой системе, считывать сведения о системе, создавать дочерние процессы, выполнять системные команды, отправлять HTTP-запросы и использовать локальные инструменты SSH.

66-lines-javascript-claude-code-extension-ssh-backdoor-ru-image-1


Две пары ключей в SSH-бэкдоре плагина Claude Code

Самое хитрое в этих 66 строках кода — бэкдор целиком построен на SSH, который уже есть в системе. Злоумышленнику не нужно разрабатывать собственную программу удалённого управления: достаточно двух пар SSH-ключей, каждая из которых решает свою задачу.

Первая пара — ключ для авторизации на компьютере жертвы. Вредоносная программа добавляет публичный ключ злоумышленника в файл пользователя authorized_keys. Открытый ключ помечен как svc-telemetry. Если SSH-сервер на компьютере запущен, обладатель соответствующего приватного ключа может получить доступ от имени этого пользователя.

Вторая пара — ключ для подключения к внешнему серверу. Вредоносная программа отдельно сохраняет приватный ключ, с помощью которого устройство жертвы может само подключиться к серверу злоумышленника. Это не приватный ключ пользователя. Проще говоря, первая пара отвечает за то, сможет ли злоумышленник пройти аутентификацию, а вторая — за то, сможет ли компьютер жертвы сначала установить исходящее соединение.

Почему обратный SSH-туннель опасен

Многие корпоративные и домашние сети блокируют прямой доступ к компьютерам из интернета, но исходящие соединения обычно не ограничивают. Обратный туннель использует именно это: компьютер жертвы сначала подключается к серверу злоумышленника, а затем перенаправляет запросы с другого конца соединения на локальный порт 22.

Однако наличие соединения ещё не означает, что вход выполнен. Удастся ли в итоге войти в систему, зависит от того, запущен ли локальный SSH-сервер, действуют ли настройки аутентификации и как настроено перенаправление на сервере злоумышленника. Если локальный SSH-сервер не запущен, туннель всё равно может установиться, но удалённый вход не получится.


Как 66 строк вредоносного кода скрывают себя и в чём их недостатки

Чтобы снизить вероятность обнаружения, загрузчик использовал несколько приёмов:

  • обычные функции Claude Code продолжали загружаться;
  • ошибки на каждом этапе атаки перехватывались отдельно: после незаметного сбоя выполнение продолжалось;
  • для задач автозапуска использовались названия, имитирующие системные компоненты, например SysMon и com.apple.sysmond;
  • при неудачном подключении повторная попытка выполнялась примерно каждые 60 секунд;
  • примерно через 1,5 секунды после запуска код пытался отправить сведения о системе.

В пользовательском интерфейсе при этом могло не быть никаких признаков проблемы.

У самого вредоносного кода были и заметные недостатки, которые снижали вероятность успешного удалённого входа:

Платформа Недостаток реализации Фактическое влияние
macOS Статус Remote Login проверялся с обычными правами, что приводило к ошибке доступа; код пытался включить функцию только при явно определённом статусе «выключено» На многих Mac, где SSH изначально был отключён, удалённый вход не включался автоматически; если же SSH уже работал, риск сохранялся
Windows Для установки OpenSSH Server использовался PowerShell, но запускался он через вспомогательную функцию, зависящую от /bin/sh В стандартной Windows такого пути нет, поэтому включение SSH-службы могло завершиться неудачей
Linux Для закрепления использовался crontab @reboot; Phorion обнаружила ошибку в проверке crontab При повторном запуске могли пострадать существующие задания пользователя; реальный масштаб распространения на Linux не подтверждён

Недостатки не означают, что код полностью бесполезен. Для записи в собственные файлы пользователя и создания элементов автозапуска на уровне пользователя права администратора зачастую не нужны. Поэтому возможна ситуация, когда служба удалённого входа не запустилась, но авторизованный ключ уже записан, скрипт автозапуска создан, сведения о хосте отправлены, а фоновый процесс продолжает попытки исходящего подключения. Считать, что «без прав администратора всё полностью безопасно», ошибочно.


Как бэкдор в плагине Claude Code повлиял на разработчиков

Последствия для разработчиков

  • Названия переменных окружения, связанных с API-ключами, могли попасть к атакующим: загрузчик отбирает до 40 переменных, в названиях которых встречаются KEY, TOKEN, SECRET, PASS, AWS или GCP. При первой отправке передаются названия, а не значения, но по ним атакующие могут определить, какими API и облачными платформами вы пользуетесь. После активации бэкдора локальные учётные данные тоже могут быть прочитаны.
  • Удалить плагин — не значит избавиться от бэкдора: файлы, обеспечивающие его закрепление в системе, записи автозапуска и публичные SSH-ключи не исчезают автоматически после удаления расширения. В одном из случаев, расследованных Expel, пользователь открыл Cursor уже после того, как плагин удалили из каталога. Вредоносная активность началась сразу после этого и продолжалась почти 10 часов.
  • Проверка по одному индикатору может ничего не выявить: Expel обнаружила на одном компьютере процесс вредоносного туннеля, но маркера публичного ключа svc-telemetry там не было. При проверке нужно сопоставлять версии, хеши файлов, процессы, сетевые соединения и записи автозапуска.

Последствия для отрасли

  • Расширения IDE стали привлекательной целью для атак: с распространением инструментов ИИ-программирования на компьютерах разработчиков одновременно хранятся исходный код, учётные данные облачных платформ и API-ключи моделей. Достаточно вставить 7 КБ кода в начало сжатого файла размером 3,6 МБ, чтобы изменить его свойства с точки зрения безопасности.
  • Процесс публикации в сторонних каталогах расширений стоит пересмотреть: в этом случае пострадал только каталог Cursor, а одноимённое расширение в других источниках оказалось безопасным. Это показывает, что название издателя, которое выглядит как официальное, само по себе не повод доверять расширению.

66-lines-javascript-claude-code-extension-ssh-backdoor-ru-image-2

Диаграмма выше подготовлена технической командой APIYI apiyi.com на основе открытых исследований. В таблице ниже отдельно обозначены границы известных фактов — учитывайте их при цитировании и пересказе:

Утверждение Статус Пояснение
Через каталог Cursor распространялось изменённое расширение Claude Code Подтверждено Подтверждено официальным объявлением
Вредоносный код способен собирать информацию, внедрять ключи, создавать обратные туннели и закрепляться в системе Подтверждено Анализы образцов, проведённые несколькими организациями, сходятся в выводах
Вредоносная активность наблюдалась на устройствах реальных клиентов Подтверждено Expel обработала 4 случая, все — на Mac
5000 компьютеров были полностью взяты под контроль Не подтверждено 5000 — лишь верхняя оценка числа потенциально затронутых устройств
Фактические значения пользовательских API-ключей были похищены Не подтверждено При первой отправке передавались только названия переменных
Количество успешных взломов по всему миру и размер экономического ущерба Не опубликовано Не следует делать расчёты на основе предположений

Как проверить систему на SSH-бэкдор в расширении Claude Code

Если с 29 по 30 октября вы установили расширение Claude Code через маркетплейс Cursor или оно обновилось автоматически, стоит быстро проверить систему. Следующий скрипт на Node.js только проверяет пути, связанные с публично раскрытыми признаками компрометации, и ничего не изменяет:

// 只读排查:检查公开披露的入侵痕迹(不能单独作为结论)
const fs = require("fs"), os = require("os"), path = require("path");
const home = os.homedir();
const checks = [
  path.join(home, ".ssh", "authorized_keys"),
  path.join(home, ".config", ".smt"),
  path.join(home, ".config", ".smtk"),
  path.join(home, "Library", "LaunchAgents", "com.apple.sysmond.plist"),
  path.join(home, ".config", "smt.cmd"),
  path.join(home, ".config", "smtk"),
];
for (const p of checks) {
  if (!fs.existsSync(p)) continue;
  const hit = p.endsWith("authorized_keys")
    ? fs.readFileSync(p, "utf8").includes("svc-telemetry")
    : true;
  if (hit) console.log("⚠️ 发现可疑痕迹:", p);
}

Если скрипт что-то обнаружил, дополнительно проверьте хеши файлов, запланированную задачу SysMon, процессы и сетевые журналы. Например, выясните, были ли подключения к портам 22 или 8099 адреса 134.209.82[.]225. В официальном уведомлении Cursor также есть скрипты для проверки и устранения последствий на macOS и Windows. Прежде чем запускать их, разберитесь, какие разрешения им нужны.

Если у вас есть подозрительный файл расширения, можно также использовать большую языковую модель для вспомогательной проверки кода. Обратите особое внимание на IIFE в начале файла, которые вызывают child_process, записывают данные в authorized_keys или устанавливают SSH-соединения. Ниже — минимальный пример вызова:

import openai

client = openai.OpenAI(
    api_key="YOUR_API_KEY",
    base_url="https://api.apiyi.com/v1"  # APIYI OpenAI 兼容接口
)

head = open("extension.js", encoding="utf-8", errors="ignore").read(10000)
resp = client.chat.completions.create(
    model="gpt-4o-mini",
    messages=[{"role": "user", "content": "请审查这段 JS 开头是否存在可疑的子进程、SSH、持久化或外连行为:\n" + head}]
)
print(resp.choices[0].message.content)
Посмотреть полный скрипт проверки (включая сравнение хешей)
import hashlib
import sys
import openai

# 公开披露的恶意 extension.js SHA-256
KNOWN_BAD = {
    "ecb58cb29078d9646ad1dcdbe51526f2d9cfea06be5fb2ab183e8ecc3ab6bf15",
}
KEYWORDS = ["child_process", "authorized_keys", "svc-telemetry",
            "LaunchAgents", "schtasks", "crontab", "8099", "-R"]

client = openai.OpenAI(
    api_key="YOUR_API_KEY",
    base_url="https://api.apiyi.com/v1"  # 使用 APIYI 统一接口
)

def sha256(path: str) -> str:
    h = hashlib.sha256()
    with open(path, "rb") as f:
        for chunk in iter(lambda: f.read(1 << 20), b""):
            h.update(chunk)
    return h.hexdigest()

def review(path: str, head_size: int = 10000) -> None:
    digest = sha256(path)
    print("SHA-256:", digest)
    if digest in KNOWN_BAD:
        print("⚠️ 命中已公布的恶意哈希,请立即隔离设备并按官方指引处置")

    head = open(path, encoding="utf-8", errors="ignore").read(head_size)
    hits = [k for k in KEYWORDS if k in head]
    print("文件开头命中关键词:", hits or "无")

    prompt = (
        "你是安全审计助手。下面是一个 IDE 扩展入口文件的开头部分,"
        "请判断是否存在在模块加载时立即执行的代码,"
        "并列出涉及子进程、SSH 密钥、持久化、网络外连的可疑片段。\n\n" + head
    )
    resp = client.chat.completions.create(
        model="gpt-4o-mini",
        messages=[{"role": "user", "content": prompt}],
        max_tokens=1200,
    )
    print(resp.choices[0].message.content)

if __name__ == "__main__":
    review(sys.argv[1] if len(sys.argv) > 1 else "extension.js")

Совет: проверка с помощью модели — лишь вспомогательный инструмент. Она не заменяет анализ журналов EDR и сверку с официальными индикаторами компрометации. Если хотите сравнить, как разные модели проверяют код, в APIYI apiyi.com можно переключаться между ними, используя один API-ключ. Новым пользователям доступен бесплатный лимит для тестирования. Перед отправкой кода на проверку убедитесь, что он не содержит конфиденциальной информации компании.

Если подтвердилось, что вредоносное расширение запускалось, выполните следующие шаги по порядку:

  1. Сохраните доказательства для расследования и изолируйте устройство;
  2. Удалите вредоносные файлы, записи автозапуска и публичные SSH-ключи;
  3. Оцените дальнейшие риски для репозиториев, облачных учётных данных, токенов сеансов и API-ключей, к которым имело доступ устройство;
  4. Если восстановить доверенное состояние не удаётся, переустановите систему и замените все учётные данные с доверенного устройства.

Частые вопросы FAQ

Q1: 66 строк JavaScript — это весь плагин Claude Code?

Нет. 66 строк — это вредоносный загрузчик, вставленный в самое начало `extension.js`: с 1-й по 66-ю строку, около 7 386 байт. Обычный код плагина занимает более 3,6 МБ, расположен следом и продолжает работать как прежде.

Q2: Чем это отличается от инъекции промпта?

При инъекции промпта атакующий пытается заставить модель выдать опасный ответ или выполнить опасное действие. В этом же случае код расширения выполняется напрямую при загрузке. Процесс вообще не проходит через Claude: не нужны ни диалог, ни согласие модели. Даже если вы никогда не пользовались ИИ-функциями плагина, код может запуститься при загрузке расширения.

Q3: Затронут ли Claude Code, установленный из официального npm или VS Code Marketplace?

Microsoft подтвердила, что Visual Studio Marketplace и официальный пакет npm `@anthropic-ai/claude-code` не затронуты. В Open VSX соответствующие вредоносные версии тоже не обнаружены. Затронуты только версии 2.1.312 и 2.1.313, распространявшиеся через маркетплейс Cursor. При проверке также нужно учитывать источник и хеш файла.

Q4: Нужно ли менять API-ключи, которые хранятся в переменных окружения?

При первоначальной отправке передавались только имена переменных, но не их значения. Однако если подтверждено, что вредоносный код запускался на вашем устройстве, бэкдор могли использовать для чтения учётных данных. Чтобы перестраховаться, замените ключи с доверенного устройства. API-ключи платформ вроде APIYI apiyi.com, которые хранились в переменных окружения, тоже рекомендуется заменить и перейти на более безопасный способ управления ключами.

Q5: Как снизить подобные риски при разработке ИИ-приложений?

Не храните на компьютере для разработки ключи с широкими правами в открытом виде в переменных окружения длительное время. Используйте отдельные ключи для разных проектов и регулярно проверяйте расширения IDE. Если вызывать модели через агрегирующую платформу вроде APIYI apiyi.com, один ключ можно использовать для доступа к моделям разных поставщиков. Это позволит хранить меньше учётных данных на компьютере, а в случае проблем достаточно будет заменить ключ в одном месте.


Главное об инциденте с бэкдором в 66 строк JavaScript

  • Суть атаки: маркетплейс расширений Cursor стал жертвой атаки на цепочку поставок; сама модель Claude взломана не была
  • Способ запуска: загрузчик IIFE из 66 строк выполнялся автоматически при загрузке расширения, без каких-либо действий со стороны пользователя
  • Устройство бэкдора: две пары SSH-ключей и обратный туннель — всё с использованием штатных системных инструментов
  • Что известно: 5000 — верхняя оценка числа затронутых пользователей; кража самих значений API-ключей не подтверждена
  • Что делать: удаление расширения не означает устранение бэкдора — необходимо проверить систему по нескольким направлениям и перевыпустить учётные данные с доверенного устройства
  • Профилактика: храните меньше ключей локально в открытом виде; для централизованного управления учётными данными для вызова моделей можно использовать APIYI apiyi.com

Итоги

Инцидент с бэкдором в 66 строк JavaScript показывает три вещи:

  1. Небольшое изменение — серьёзные последствия: достаточно добавить в начало файла размером 3,6 МБ код, составляющий 0,2% его объёма, чтобы доверенное расширение превратилось в носитель бэкдора.
  2. Риск зависит от привилегий: расширения IDE имеют полный доступ к возможностям Node.js. Даже с правами обычного пользователя они могут записывать ключи и закрепляться в системе.
  3. Удаление из маркетплейса — не конец: установленные вредоносные компоненты могут запускаться с задержкой и продолжать устанавливать исходящие соединения. Их нужно отдельно искать и удалять.

Если вы пользовались расширением Claude Code из маркетплейса Cursor в период распространения вредоносной версии, проверьте систему по официальным индикаторам компрометации и перевыпустите учётные данные, которые могли пострадать. В повседневной разработке стоит сократить количество ключей, хранящихся локально: например, через APIYI apiyi.com можно обращаться к моделям разных поставщиков с единым ключом, уменьшая масштаб последствий возможной утечки.


📚 Источники

  1. Официальное уведомление Cursor о безопасности: хронология инцидента, версии, хеши и скрипт очистки
  2. Ссылка: cursor.com/blog/claude-code-extension-security-notice
  3. Описание: первоисточник для расследования и устранения последствий

  4. Microsoft Security Research: полная цепочка атаки и сопоставление с MITRE ATT&CK

  5. Ссылка: microsoft.com/en-us/security/blog/2026/10/30/inside-malicious-claude-code-branded-cursor-extension-persistent-ssh-backdoor/
  6. Описание: анализ границ цепочки поставок, механизма SSH и закрепления в системе

  7. Phorion: загрузчик из 66 строк и недостатки реализации на разных платформах

  8. Ссылка: phorion.io/blog/offical-claude-code-vsx-compromise/
  9. Описание: подробности фильтрации переменных окружения и ошибки в crontab на Linux

  10. StepSecurity: точное сравнение образцов от 1 ноября

  11. Ссылка: stepsecurity.io/blog/claude-code-extension-trojanized
  12. Описание: различия в размерах файлов и свидетельства подмены обозначения версии

  13. Expel: расследование четырёх реальных инцидентов у клиентов

  14. Ссылка: expel.com/blog/blog-fake-claude-code-extension-cursor-ssh-backdoor/
  15. Описание: случаи отложенного запуска и пропущенных обнаружений

  16. OpenSourceMalware: анализ внутреннего устройства вредоносного расширения

  17. Ссылка: opensourcemalware.com/blog/trojanized-claude-code-extension-plants-persistent-ssh-backdoor
  18. Описание: подтверждение расположения загрузчика и способа его запуска

Автор: техническая команда APIYI
Связь с нами: свяжитесь с нами через главную страницу сайта APIYI apiyi.com. Дополнительные материалы доступны в центре документации docs.apiyi.com

Читайте также

Похожие записи