این مقاله قصد داریم بررسی کنیم که چگونه میتوان با استفاده از پروتکل Model Context Protocol (MCP) و Claude آسیبپذیریهای روز صفر (Zero-Day) را در فایلهای اسمبلی داتنت (.NET assemblies) پیدا کرد. فرآیند شامل راهاندازی سرور MCP برای دیکامپایل اسمبلیها، شناسایی آسیبپذیریهای شناختهشده و جدید و ایجاد کد اثبات مفهوم (PoC) برای سوءاستفاده از این آسیبپذیریهاست.
راهاندازی سرور MCP
برای شروع شناسایی آسیبپذیریها، نیاز به یک سرور MCP است که امکان دیکامپایل اسمبلیهای .NET را برای Claude فراهم کند. معمولا برای دیکامپایل فایلهای باینری .NET از ابزار dotPeek استفاده میشود؛ اما این ابزار فقط برای ویندوز در دسترس است. خوشبختانه، ابزار ilspycmd برای سیستمهای مک و لینوکس قابل استفاده است. مخزن ilspycmd-docker یک فایل Dockerfile ارائه میدهد؛ اما نسخه فعلی آن در GitHub قدیمی است و با خطا مواجه میشود.

خطای ساخت به دلیل مشکل در نسخههای وابستگی مشخص است و با تغییر کوچکی در Dockerfile قابل رفع است. فایل اصلاحشده بهصورت زیر است:
FROM mcr.microsoft.com/dotnet/sdk:8.0
RUN useradd -m -s /bin/bash ilspy
USER ilspy
WORKDIR /home/ilspy
RUN dotnet tool install -g ilspycmd
RUN echo 'export PATH="$PATH:/home/ilspy/.dotnet/tools/"' >> /home/ilspy/.bashrc
ENTRYPOINT [ "/bin/bash", "-l", "-c" ]
میتوانیم این تصویر جدید را با دستور زیر بسازیم:
docker build -t ilspycmd .
پس از بهروزرسانی Dockerfile و ساخت کانتینر جدید، سرور MCP سادهای با استفاده از پایتون ایجاد میشود. کد زیر سرور MCP را راهاندازی میکند:
from mcp.server.fastmcp import FastMCP
import subprocess
import os
server = FastMCP("ilspy docker")
@server.prompt()
def setup_prompt() -> str:
return """
You can use the following commands to decompile .NET assemblies, using ilspy:
- decompile(file: str, output_folder: str) -> int: Decompile the file at the provided path.
The returned value is the success code, with 0 indicating a successful run
"""
@server.tool()
def run_ilspycmd_docker(exe_path, output_folder) -> int:
"""
Run ilspycmd in a Docker container to decompile a DLL
Args:
dll_path (str): Path to the DLL file to decompile
output_folder (str): Folder where decompiled code will be placed
Returns:
tuple: (return_code, stdout, stderr)
"""
# Get absolute paths
input_dir = os.path.abspath(os.path.dirname(exe_path))
output_dir = os.path.abspath(output_folder)
exe_filename = os.path.basename(exe_path)
# Ensure output directory exists
os.makedirs(output_dir, exist_ok=True)
# Create input directory inside container
container_input_dir = "/decompile_in"
container_output_dir = "/decompile_out"
ilspy_cmd_path = "/home/ilspy/.dotnet/tools/ilspycmd"
ilspy_command = f"{ilspy_cmd_path} -p -o {container_output_dir} {container_input_dir}/{exe_filename}"
# Build the Docker command
docker_cmd = [
"docker", "run", "--rm",
"-v", f"{input_dir}:{container_input_dir}",
"-v", f"{output_dir}:{container_output_dir}",
"ilspycmd",
ilspy_command
]
# Run the command
process = subprocess.run(
docker_cmd,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True
)
return process.returncode
if __name__ == "__main__":
# Initialize and run the server
server.run(transport='stdio')
این کد مسیرهای فایل را برای اجرای دستور داکر مدیریت میکند. سپس فایل پیکربندی claude_desktop_config.json ویرایش میشود تا سرور MCP جدید اضافه شود:
{
"mcpServers": {
"FS": {
"command": "/Users/james/Library/Python/3.9/bin/uv",
"args": [
"--directory",
"/Users/james/Research/MCP/FS",
"run",
"FS.py"
]
},
"brave-search": {
"command": "docker",
"args": [
"run",
"-i",
"--rm",
"-e",
"BRAVE_API_KEY",
"mcp/brave-search"
],
"env": {
"BRAVE_API_KEY": "try_harder"
}
},
"ilspy": {
"command": "/Users/james/Library/Python/3.9/bin/uv",
"args": [
"--directory",
"/Users/james/Research/MCP/ilspy_docker",
"run",
"ilspy.py"
]
}
}
}
پس از راهاندازی مجدد Claude for Desktop، سرور MCP جدید در دسترس قرار میگیرد.

شناسایی آسیبپذیریهای شناختهشده با Claude
برای آزمایش توانایی Claude در شناسایی آسیبپذیریهای شناختهشده، از نقص عدم دنبالهسازی دادهها در AddinUtil.exe، یک فایل باینری .NET که بهصورت پیشفرض با ویندوز ارائه میشود، استفاده میشود. این آسیبپذیری در سپتامبر ۲۰۲۳ توسط Blue-Prints Blog گزارش شده و در پروژه LOLBAS ثبت شده است. این نقص به دلیل دنبالهسازی ناامن دادهها در یک DLL رخ میدهد؛ اما نقطه ورود آن در یک فایل EXE است. ابتدا بررسی میشود که آیا Claude سرور MCP جدید را شناسایی میکند.

سپس از Claude خواسته میشود تا System.AddIn.dll را دیکامپایل و بررسی کند.

Claude لیستی از آسیبپذیریهای احتمالی را ارائه میدهد، از جمله یک فراخوانی دنباله سازی ناامن داده در .NET Remoting به دلیل استفاده از TypeFilterLevel.Full، که احتمالا با آسیبپذیری AddinProcess.exe گزارششده توسط Nettitude مرتبط است

برای تمرکز روی نقصهای دنباله سازی داده، درخواست ورودی اصلاح میشود؛ اما Claude همچنان در شناسایی آسیبپذیری شناختهشده با مشکل مواجه میشود.

با ارسال درخواست جدید، مشخص میشود که Claude تنها ۱۴ فایل را بررسی کرده است. پس از درخواست بررسی همه فایلها، Claude موفق به شناسایی فراخوانی دنباله سازی ناامن دادهها و تشخیص غیرقابل اعتماد بودن فایل کش میشود.




برای شناسایی مسیر اکسپلویت، به Claude اطلاع داده میشود که DLL توسط AddinUtil.exe ارجاع شده است. Claude مسیرهای ورودی احتمالی، از جمله پرچم pipelineroot که در گزارش Blue-Prints Blog بهعنوان مسیر دنباله سازی داده ذکر شده، را شناسایی میکند. همچنین مسیر حمله را بهدرستی تشخیص میدهد.



برای آزمایش بیشتر، از Claude خواسته میشود تا کد اثبات مفهوم (PoC) برای سوءاستفاده از این آسیبپذیری تولید کند. AddinUtil.exe انتظار دارد فایل کش شامل سری خاصی از بایتها باشد که قبل از دادههای دنبالهسازی شده قرار میگیرند.

کد تولیدشده توسط Claude، که بهصورت کامل ارائه نشده، به این اشاره دارد که فایل AddIns.store باید در فرمت مورد انتظار ReadCache ایجاد شود:
# Create the AddIns.store file with the format expected by ReadCache print("[+] Creating malicious AddIns.store file")
cache_file_path = os.path.join(output_dir, "AddIns.store")
with open(cache_file_path, 'wb') as f:
# Write the format version (int32 = 1)
f.write(struct.pack("
Claude توضیح میدهد که پدینگ ۱۲ بایتی لازم است؛ اما هدف دقیق این بایتها را بهدرستی شناسایی نمیکند، زیرا در کد دیکامپایلشده استفاده نمیشوند.

شناسایی آسیبپذیریهای جدید
برای شناسایی مسیر حمله مرتبط با فلگ pipelineroot، که در گزارش Blue-Prints Blog بهصورت کامل توضیح داده نشده، از Claude خواسته میشود کد اثبات مفهوم تولید کند. Claude کد پایتون تولید میکند و توضیح مفصلی درباره آسیبپذیری ارائه میدهد.


برای آزمایش، از پیلود ysoserial.net برای اجرای calc.exe بهعنوان اثبات مفهوم استفاده میشود:
ysoserial.exe -f BinaryFormatter -g TypeConfuseDelegate -c calc -o raw > e:\tools\payload.bin
کد اثبات مفهوم تولیدشده توسط Claude اجرا میشود.

اجرای AddinUtil.exe با پرچم -pipelineroot تولیدشده، همانطور که انتظار میرفت، موفقیتآمیز نبود. با این حال، دیباگ این مشکل با استفاده از Visual Studio و dotPeek بهسادگی امکانپذیر است. ابتدا اطمینان حاصل میشود که dotPeek فایلهای EXE و DLL را بارگذاری کرده و سرور نمادهای آن(symbol server) فعال شده است. سپس، AddinUtil.exe با استفاده از dotPeek دیکامپایل شده و یک فایل پروژه ایجاد میشود. این فایل در Visual Studio بارگذاری شده و dotPeek بهعنوان سرور نمادها اضافه میشود. در نهایت، تنظیمات دیباگ پروژه تغییر میکند تا فایل EXE کامپایلشده اجرا شود و فلگ pipelineroot بهعنوان آرگومان ارسال شود.

با افزودن یک نقطه توقف (breakpoint) به کد دیکامپایلشده، فایل باینری اجرا شده و امکان دیباگ گامبهگام فراهم میشود. پس از بررسی سریع، مشخص میشود که Claude یک مرحله را نادیده گرفته است.

Claude از ایجاد پوشه AddIns و نامگذاری صحیح فایل .store غفلت کرده بود، که باعث شد بررسی مربوطه با شکست مواجه شود و تابع BuildAddInCache فراخوانی نشود. با بهروزرسانی سریع کد پایتون تولیدشده، ساختار پوشهای ایجاد شد که تمام بررسیها را با موفقیت پشت سر گذاشت و در نهایت با اجرا، برنامه calc.exe راهاندازی شد.

این اکسپلویت در مقایسه با پرچم -AddinRoot کمتر کاربردی است؛ زیرا نیاز به ایجاد ساختار کامل پوشه روی دیسک دارد. تاکنون پیادهسازی عمومی برای این مسیر حمله مشاهده نشده است، که آن را به گزینهای مناسب برای آزمایش با Claude تبدیل میکند.
جمعبندی
این مقاله نشان داد که چگونه میتوان از سرور MCP برای ارائه قابلیت تحلیل اسمبلیهای .NET به Claude استفاده کرد. این توانایی برای شناسایی یک آسیبپذیری شناختهشده در یک فایل باینری امضاشده توسط مایکروسافت به کار رفت و نشان داد که باید دستورات صریحی به Claude داده شود (مانند بررسی همه فایلها). همچنین، کد اثبات مفهوم برای مسیر حملهای که در گزارش اولیه بهعنوان تمرین برای خواننده باقی مانده بود، تولید شد.
اگرچه نیاز به راهنماییهایی برای Claude وجود داشت، این فرآیند برای تحلیل فایل و نزدیک شدن به یک اکسپلویت عملی بسیار سریعتر از روشهای دستی بود. گام بعدی بررسی امکان اجرای این فرآیند در مقیاس بزرگتر است که موضوع مقالههای آینده خواهد بود.
کد اثبات مفهومی(PoC) در این لینک وجود دارد.