تصور کن داخل یک سایت فقط یک IP وارد میکنی تا سرور آن را بررسی کند.
مثلاً:
192.168.56.20
همهچیز عادی به نظر میرسد.
اما اگر برنامه بدون اعتبارسنجی مناسب، ورودی تو را مستقیماً وارد یک فرمان سیستمعامل کند، داستان کاملاً عوض میشود.
اینجاست که Command Injection وارد صحنه میشود.
☠️ یک ورودی ساده میتواند باعث شود برنامه، بهجای اجرای فقط دستور موردنظر توسعهدهنده، بخش دیگری از فرمان را هم اجرا کند.
در این قسمت یاد میگیریم:
- Command Injection چیست؟
- چرا به وجود میآید؟
- تفاوت Command Injection و Code Injection چیست؟
- چگونه در یک آزمایشگاه قانونی آن را شناسایی کنیم؟
- چگونه با Burp Suite درخواست را بررسی کنیم؟
- چگونه متوجه شویم ورودی ما وارد یک Command سیستم شده؟
- Blind Command Injection چیست؟
- چگونه این آسیبپذیری را گزارش کنیم؟
- و مهمتر از همه: چگونه از آن جلوگیری کنیم؟
⚠️ تمام آزمایشهای این آموزش را فقط روی DVWA یا محیطی که مالک آن هستید انجام دهید. سیستم آسیبپذیر را هرگز مستقیماً روی اینترنت قرار ندهید.
🔥 Command Injection چیست؟
Command Injection نوعی آسیبپذیری است که در آن ورودی کنترلشده توسط کاربر، بدون کنترل و جداسازی مناسب، وارد یک فرمان سیستمعامل میشود.
فرض کنیم برنامهای برای بررسی اتصال یک IP چنین کاری انجام میدهد:
$ip = $_GET['ip'];
$output = shell_exec("ping -c 4 " . $ip);
در حالت عادی کاربر میفرستد:
192.168.56.20
و برنامه در نهایت فرمانی شبیه این اجرا میکند:
ping -c 4 192.168.56.20
مشکل از جایی شروع میشود که برنامه به ورودی کاربر اعتماد کند.
یعنی:
User Input
↓
Application
↓
OS Command
↓
Server
در این حالت، مرز بین داده و فرمان ممکن است از بین برود.
☠️ چرا Command Injection خطرناک است؟
شدت این آسیبپذیری به سطح دسترسی پردازشی که فرمان را اجرا میکند و قابلیتهای برنامه بستگی دارد.
در یک سناریوی واقعی، سوءاستفاده موفق میتواند زمینهساز مواردی مثل:
- افشای اطلاعات
- خواندن فایلهای قابل دسترس برای سرویس
- دستکاری دادهها
- اجرای دستورات ناخواسته
- دسترسی به سرویسهای داخلی
- حرکت به سمت آسیبپذیریهای دیگر
شود.
به همین دلیل Command Injection میتواند یک آسیبپذیری جدی سمت سرور باشد.
🧠 Command Injection چگونه اتفاق میافتد؟
معمولاً یک زنجیره ساده وجود دارد:
Input
↓
Validation ضعیف
↓
String Concatenation
↓
Shell / OS Command
↓
Command Injection
مشکل اصلی معمولاً این نیست که برنامه اصلاً نباید فرمان اجرا کند.
مشکل این است که دادهی کاربر به شکل ناامن وارد فرمان شده است.
🆚 Command Injection در برابر Code Injection
این دو اصطلاح شبیه هم هستند اما یکی نیستند.
Command Injection
هدف اصلی:
OS / Shell Command
مثلاً برنامه یک فرمان سیستمعامل را اجرا میکند.
Code Injection
هدف:
Application Code / Interpreter
یعنی مهاجم تلاش میکند کد را در محیط اجرایی برنامه وارد کند.
پس:
Command Injection
↓
Operating System
Code Injection
↓
Application / Interpreter
🧪 ساخت آزمایشگاه
برای این قسمت میتوانیم از همان ساختار آموزشی قبلی استفاده کنیم:
┌─────────────────────┐
│ Kali Linux │
│ │
│ Burp Suite + Tools │
└──────────┬──────────┘
│
│ HTTP
▼
┌─────────────────────┐
│ DVWA │
│ │
│ Command Injection │
└─────────────────────┘
مثلاً:
Kali Linux
192.168.56.10
DVWA
192.168.56.20
این IPها صرفاً نمونهای برای یک شبکه آزمایشگاهی خصوصی هستند.
🔎 مرحله اول: بررسی ارتباط با هدف آزمایشگاهی
از Kali ابتدا ارتباط را بررسی میکنیم:
ping -c 4 192.168.56.20
اگر پاسخ دریافت شد، ارتباط شبکهای برقرار است.
حالا میتوانیم سرویسهای در دسترس آزمایشگاه را بررسی کنیم:
nmap 192.168.56.20
هدف این مرحله فقط شناسایی سیستم آزمایشگاهی است.
🎯 مرحله دوم: ورود به بخش Command Injection در DVWA
در DVWA وارد بخش:
Command Injection
شوید.
در سطح امنیتی پایین، معمولاً یک ورودی برای انجام عملیاتی مانند Ping وجود دارد.
برای مثال:
IP Address:
192.168.56.20
بعد از ارسال درخواست، برنامه خروجی فرمان را نمایش میدهد.
مثلاً:
PING 192.168.56.20 ...
64 bytes from 192.168.56.20
اینجا یک سؤال مهم داریم:
آیا مقدار واردشده فقط به عنوان «داده» استفاده شده یا وارد یک Command سیستم شده است؟
🕵️ مرحله سوم: بررسی درخواست با Burp Suite
Burp Suite را باز کنید.
در:
Proxy → HTTP History
درخواست مربوط به Command Injection را پیدا کنید.
ممکن است چیزی شبیه این ببینید:
GET /dvwa/vulnerabilities/exec/?ip=192.168.56.20 HTTP/1.1
Host: 192.168.56.20
قسمت مهم:
ip=192.168.56.20
این همان ورودی کنترلشده توسط کاربر است.
💀 مرحله چهارم: تست رفتار ورودی
در محیط آزمایشگاهی، هدف ما این نیست که فوراً سراغ دستورات مخرب برویم.
ابتدا باید رفتار برنامه را بفهمیم.
مثلاً بررسی کنیم آیا تغییر ساده ورودی روی خروجی اثر میگذارد یا خیر.
در Burp درخواست را به:
Repeater
ارسال کنید.
حالا مقدار:
192.168.56.20
را تغییر دهید و Response را بررسی کنید.
این کار به ما کمک میکند بفهمیم:
Input
↓
Application
↓
Command
↓
Output
واقعاً چه اتفاقی میافتد.
⚠️ مفهوم Command Separator
در بسیاری از Shellها کاراکترهایی وجود دارند که میتوانند برای جدا کردن بخشهای یک Command استفاده شوند.
نمونههای مفهومی:
;
&&
||
|
برای درک آسیبپذیری در آزمایشگاه میتوان رفتار این جداکنندهها را بررسی کرد.
مثلاً اگر برنامه در پشت صحنه چیزی شبیه:
ping -c 4 USER_INPUT
بسازد، کنترلنشدن مناسب ورودی میتواند باعث شود ساختار فرمان تغییر کند.
نکته مهم اینجاست:
مشکل خودِ کاراکتر نیست؛ مشکل این است که برنامه اجازه میدهد دادهی کاربر ساختار Command را تغییر دهد.
🧪 یک تست بیخطر در آزمایشگاه
برای مشاهده رفتار Command Injection، میتوان از یک فرمان غیرمخرب و ساده مانند:
whoami
در یک محیط کاملاً تحت کنترل استفاده کرد.
هدف این تست این است که ببینیم آیا برنامه واقعاً Command اضافی را اجرا میکند یا خیر.
اگر خروجی نام کاربری سرویس وب ظاهر شود، یک نشانه بسیار مهم داریم:
User Input
↓
Shell
↓
Command Execution
یعنی ورودی ما از مرز داده عبور کرده و وارد مسیر اجرای فرمان شده است.
🧠 چرا whoami مهم است؟
در تست نفوذ، همیشه لازم نیست برای اثبات آسیبپذیری سراغ اقدامات مخرب برویم.
یک تست ساده میتواند نشان دهد:
Command Execution = Possible
و در عین حال کمترین اثر را روی سیستم آزمایشگاهی داشته باشد.
در یک گزارش حرفهای بهتر است:
کمخطرترین اثبات قابل اتکا را انتخاب کنیم.
🕶️ Blind Command Injection چیست؟
همیشه برنامه خروجی Command را به کاربر نمایش نمیدهد.
مثلاً:
User Input
↓
Application
↓
Command
↓
Execution
اما خروجی حذف میشود.
در این حالت ممکن است با Blind Command Injection مواجه باشیم.
یعنی:
Command اجرا میشود
↓
Output نمایش داده نمیشود
پس تستر باید از نشانههای غیرمستقیم برای بررسی رفتار استفاده کند.
🌑 تفاوت Command Injection و Blind Command Injection
| نوع | خروجی نمایش داده میشود؟ |
|---|---|
| Command Injection | معمولاً بله |
| Blind Command Injection | معمولاً خیر |
در حالت Blind، تحلیل زمان پاسخ، رفتار برنامه و شواهد آزمایشگاهی میتواند اهمیت بیشتری پیدا کند.
🧩 ورودیهای مشکوک را کجا پیدا کنیم؟
Command Injection فقط در فیلدی با نام:
command
اتفاق نمیافتد.
ممکن است در قابلیتهایی مانند:
ping
traceroute
nslookup
DNS lookup
network diagnostics
file processing
image processing
backup tools
system utilities
وجود داشته باشد.
همچنین پارامترهایی مثل:
host
ip
domain
target
filename
path
file
query
گاهی ارزش بررسی دارند.
البته وجود چنین پارامتری بهتنهایی به معنی آسیبپذیری نیست.
🚨 اشتباه رایج: هر Shell Command یعنی آسیبپذیری؟
خیر.
ممکن است برنامهای واقعاً از یک Command سیستمعامل استفاده کند اما کاملاً امن باشد.
مثلاً اگر برنامه:
- ورودی را محدود کند
- از API مناسب استفاده کند
- آرگومانها را جداگانه ارسال کند
- Shell را دور بزند
- دسترسی سرویس را محدود کند
ریسک بسیار کمتر میشود.
پس:
Command Execution
≠
Command Injection
🛡️ چگونه Command Injection را جلوگیری کنیم؟
1. از Shell تا حد امکان استفاده نکنید
اگر یک API یا Library مناسب وجود دارد، استفاده از آن معمولاً بهتر از ساختن یک String برای Shell است.
2. از Allowlist استفاده کنید
اگر برنامه فقط باید IPv4 دریافت کند، نباید هر رشتهای را قبول کند.
مثلاً:
192.168.56.20
مجاز است.
اما ورودی باید با قواعد مورد انتظار برنامه مطابقت داشته باشد.
3. ورودی را به Command تبدیل نکنید
این الگو خطرناک است:
$command = "ping " . $_GET['ip'];
shell_exec($command);
چون دادهی کاربر مستقیماً وارد String فرمان شده است.
4. از APIهای ساختاریافته استفاده کنید
تا حد امکان به جای:
String → Shell
از:
Input
↓
Validation
↓
Structured API
↓
Operation
استفاده کنید.
5. دسترسی سرویس را محدود کنید
حتی اگر آسیبپذیری وجود داشته باشد، محدود کردن سطح دسترسی Process میتواند Impact را کاهش دهد.
اصل مهم:
Least Privilege
یعنی سرویس فقط همان دسترسیهایی را داشته باشد که واقعاً نیاز دارد.
6. خروجی و خطاها را مدیریت کنید
نمایش مستقیم خروجی سیستمعامل به کاربر میتواند اطلاعات اضافی افشا کند.
به جای:
Raw OS Output
بهتر است برنامه خروجی کنترلشده و مناسب برای کاربر تولید کند.
🔥 Chain Attack؛ خطر واقعیتر
گاهی Command Injection به تنهایی پایان داستان نیست.
ممکن است یک مهاجم از یک آسیبپذیری برای رسیدن به مرحله بعد استفاده کند:
Command Injection
↓
Information Disclosure
↓
Credential Exposure
↓
Access to Another Service
یا:
Web Vulnerability
↓
Command Injection
↓
Server Compromise
به همین دلیل در تست نفوذ باید فقط یک آسیبپذیری را جداگانه نبینیم.
باید به Attack Chain هم توجه کنیم.
📊 ارزیابی ریسک
شدت Command Injection به عوامل مختلف بستگی دارد:
Impact
- چه کارهایی امکانپذیر است؟
- Process با چه سطح دسترسی اجرا میشود؟
- چه اطلاعاتی قابل دسترسی است؟
Exploitability
- آیا احراز هویت لازم است؟
- آیا ورودی از اینترنت قابل دسترسی است؟
- آیا محدودیت ورودی وجود دارد؟
Scope
- فقط یک قابلیت آسیبپذیر است؟
- یا میتواند روی بخشهای دیگر سیستم اثر بگذارد؟
بنابراین نمیتوان صرفاً با دیدن نام «Command Injection» یک شدت ثابت تعیین کرد.
📝 ساخت گزارش حرفهای
یک گزارش مناسب میتواند این ساختار را داشته باشد:
عنوان
OS Command Injection
Severity
High / Critical
شدت باید بر اساس شرایط واقعی آزمایشگاه و Impact تعیین شود.
Affected Component
Command Injection Module
Parameter
ip
Description
The application processes user-controlled input
as part of an operating system command without
sufficient validation or isolation.
Evidence
اسکرینشاتهای:
- ورودی
- Request در Burp
- Response
- نتیجه تست کنترلشده
Impact
توضیح دهید که اجرای فرمان در چه سطحی امکانپذیر است و Process با چه دسترسیای اجرا میشود.
Root Cause
مثلاً:
Unsafely concatenating user input into
an operating system command.
Remediation
Avoid shell execution where possible.
Use structured APIs.
Implement strict allowlist validation.
Apply least privilege.
🧪 تمرین قسمت ۱۴
حالا وقت آزمایش است.
در محیط DVWA:
مرحله ۱
یک ورودی عادی وارد کنید:
192.168.56.20
مرحله ۲
Request را در Burp پیدا کنید.
مرحله ۳
آن را به Repeater بفرستید.
مرحله ۴
تغییرات ورودی و Response را بررسی کنید.
مرحله ۵
در سطح آزمایشگاهی، یک Command غیرمخرب برای اثبات اجرای فرمان استفاده کنید.
مرحله ۶
بررسی کنید Command با چه User یا Process Context اجرا شده است.
مرحله ۷
سطح امنیتی DVWA را تغییر دهید.
مرحله ۸
دوباره تست کنید.
حالا سؤال اصلی:
چه چیزی بین نسخه آسیبپذیر و نسخه امن تغییر کرده است؟
🧠 چکلیست تست Command Injection
قبل از ثبت Finding این موارد را بررسی کنید:
☑ Input قابل کنترل است؟
☑ Input وارد Command میشود؟
☑ Validation وجود دارد؟
☑ Shell استفاده میشود؟
☑ Command Separator قابل تفسیر است؟
☑ خروجی Command قابل مشاهده است؟
☑ Blind Execution وجود دارد؟
☑ Process با چه User اجرا میشود؟
☑ دسترسی Process چقدر است؟
☑ آیا راه امنتری برای انجام عملیات وجود دارد؟
☑ آیا Least Privilege رعایت شده؟
☠️ نکته مهم برای تسترهای تازهکار
یکی از اشتباهات رایج این است که تستر از همان ابتدا سراغ Payloadهای پیچیده برود.
روش حرفهایتر:
Understand
↓
Observe
↓
Test
↓
Confirm
↓
Document
↓
Remediate
اول بفهم.
بعد مشاهده کن.
بعد با کمترین اثر، فرضیه را آزمایش کن.
و در نهایت آن را مستند کن.
🔥 Command Injection در مسیر یادگیری ما
تا اینجا تقریباً یک مسیر کامل را طی کردهایم:
Reconnaissance
↓
Scanning
↓
Vulnerability Analysis
↓
SQL Injection
↓
XSS
↓
File Upload
↓
Authentication & Session Security
↓
Broken Access Control / IDOR
↓
SSRF
↓
Command Injection
اینجا دیگر فقط با «پیدا کردن باگ» طرف نیستیم.
داریم یاد میگیریم:
چطور یک آسیبپذیری را پیدا کنیم، اثبات کنیم، تحلیل کنیم و حرفهای گزارش کنیم.
💀 جمعبندی
Command Injection زمانی اتفاق میافتد که ورودی کنترلشده توسط کاربر بتواند ساختار یا اجرای یک Command سیستمعامل را تحت تأثیر قرار دهد.
مهمترین مفاهیمی که در این قسمت یاد گرفتیم:
Command Injection
Shell
Input Validation
Command Separator
Burp Repeater
Blind Command Injection
Least Privilege
Allowlist
Structured APIs
Attack Chain
Reporting
و مهمترین اصل:
هر چیزی که از کاربر میآید، نباید مستقیماً وارد Shell شود.
در آزمایشگاه میتوانیم این آسیبپذیری را بهصورت کنترلشده مشاهده کنیم؛ اما در محیط واقعی، حتی یک Command کوچک میتواند پیامد بسیار بزرگتری داشته باشد.

دیدگاه شما