اگر آموزشهای قبلی صفر و یک سایبر را دنبال کرده باشید، حالا آزمایشگاه ما آماده است:
Kali Linux + DVWA + Burp Suite
در این مرحله میخواهیم یکی از معروفترین آسیبپذیریهای امنیت وب یعنی SQL Injection یا SQLi را در یک محیط کاملاً قانونی و کنترلشده بررسی کنیم.
هدف این آموزش فقط اجرای یک Payload نیست؛ میخواهیم بفهمیم SQL Injection چرا اتفاق میافتد، چطور آن را تشخیص میدهیم، چگونه در آزمایشگاه اعتبارسنجی میکنیم و مهمتر از همه، چطور جلوی آن را میگیریم.
⚠️ هشدار: تمام مراحل زیر فقط برای DVWA یا آزمایشگاه شخصی شماست. این تکنیکها را روی سایتها و سامانههایی که مجوز تست آنها را ندارید اجرا نکنید.
SQL Injection چیست؟
SQL Injection زمانی رخ میدهد که ورودی کاربر بدون کنترل و جداسازی مناسب وارد یک Query پایگاه داده شود.
بهصورت ساده:
ورودی کاربر
↓
Web Application
↓
SQL Query
↓
Database
↓
Response
اگر برنامه ورودی کاربر را به شکل ناامن وارد Query کند، کاربر ممکن است بتواند منطق Query را تغییر دهد.
یک مثال ساده
فرض کنید برنامهای Query زیر را ایجاد میکند:
SELECT * FROM users WHERE id = 'USER_INPUT';
اگر مقدار USER_INPUT مستقیماً از کاربر گرفته شود و هیچ محافظتی وجود نداشته باشد، ورودی کاربر میتواند روی ساختار Query تأثیر بگذارد.
مشکل اصلی اینجاست:
داده کاربر نباید بتواند به بخشی از منطق SQL تبدیل شود.
آزمایشگاه ما
ساختار آزمایشگاه:
┌─────────────────────┐
│ Kali Linux │
│ │
│ Browser + Burp │
│ Nmap + Tools │
└──────────┬──────────┘
│
Host-Only Network
│
┌──────────▼──────────┐
│ DVWA │
│ Vulnerable Web App │
│ │
│ 192.168.56.20 │
└─────────────────────┘
IP بالا فقط نمونه است.
برای پیدا کردن IP ماشین آزمایشگاهی میتوانید در سیستم هدف از:
ip addr
یا:
ifconfig
استفاده کنید.
مرحله اول: بررسی ارتباط
از Kali ابتدا ارتباط با DVWA را بررسی کنید:
ping 192.168.56.20
اگر پاسخ دریافت شد، ارتباط برقرار است.
سپس سرویس وب را بررسی کنید:
nmap -sV -p 80 192.168.56.20
مرحله دوم: ورود به DVWA
در مرورگر Kali آدرس آزمایشگاه را باز کنید:
http://192.168.56.20
پس از ورود به DVWA، بخش:
SQL Injection
را انتخاب کنید.
برای اولین تمرین، سطح امنیتی را روی:
Low
قرار دهید.
Low عمداً برای آموزش آسیبپذیری طراحی شده است و نباید با تنظیمات یک برنامه واقعی مقایسه شود.
مرحله سوم: تست رفتار عادی برنامه
فرض کنید صفحه از شما یک شناسه میخواهد.
ابتدا یک مقدار عادی وارد کنید؛ مثلاً:
1
برنامه ممکن است اطلاعات مربوط به شناسه واردشده را نمایش دهد.
حالا سؤال مهم:
چه اتفاقی پشت صحنه افتاد؟
احتمالاً برنامه چیزی شبیه این Query ساخته:
SELECT first_name, last_name
FROM users
WHERE user_id = '1';
ما این Query را مستقیماً نمیبینیم، اما رفتار برنامه به ما سرنخ میدهد.
مرحله چهارم: بررسی درخواست با Burp Suite
Burp Suite را اجرا کنید و Proxy مرورگر را فعال کنید.
دوباره مقدار 1 را ارسال کنید.
در Burp ممکن است درخواست مشابه زیر را ببینید:
GET /dvwa/vulnerabilities/sqli/?id=1&Submit=Submit HTTP/1.1
Host: 192.168.56.20
Cookie: ...
قسمت مهم:
id=1
این همان پارامتری است که کاربر کنترل میکند.
مرحله پنجم: یک تست ساده SQL Injection
در محیط DVWA و سطح Low، بهجای مقدار عادی، میتوانیم یک ورودی آزمایشی وارد کنیم:
1'
اگر برنامه رفتار متفاوتی نشان داد، مثلاً خطای SQL یا تغییر غیرمنتظره در پاسخ، میتواند نشانهای از این باشد که ورودی ما مستقیماً روی Query تأثیر گذاشته است.
اما:
نمایش خطای SQL بهتنهایی اثبات قطعی SQL Injection نیست.
باید رفتار برنامه را دقیقتر بررسی کنیم.
مرحله ششم: تست منطقی
یکی از روشهای آموزشی برای تشخیص SQLi، مقایسه شرایط منطقی متفاوت است.
در آزمایشگاه میتوان ورودیهایی از جنس:
1' AND '1'='1
و
1' AND '1'='2
را مقایسه کرد.
در حالت آسیبپذیر، ممکن است پاسخ برنامه بین دو وضعیت تفاوت داشته باشد.
چرا؟
چون:
'1'='1'
یک شرط درست است، در حالی که:
'1'='2'
نادرست است.
این روش به ما کمک میکند بفهمیم آیا ورودی کاربر روی منطق Query تأثیر گذاشته است یا خیر.
مرحله هفتم: درک اتفاق پشت صحنه
فرض کنید برنامه به شکل ناامن Query را بسازد:
SELECT * FROM users
WHERE id = 'INPUT';
اگر ورودی ما باعث شود Query به شکل منطقی متفاوتی تفسیر شود، نتیجه Query نیز تغییر میکند.
این همان اصل بنیادی SQL Injection است:
Input
↓
String Concatenation
↓
SQL Query
↓
Database interprets input as SQL
مشکل در واقع خود SQL نیست؛ مشکل نحوه ساخت Query است.
مرحله هشتم: SQL Injection در برابر Prepared Statement
روش امنتر:
User Input
↓
Prepared Statement
↓
Database
در Prepared Statement، ساختار Query از داده جدا میشود.
برای مثال در PHP، بهجای ساختن Query با اتصال مستقیم رشتهها، از APIهایی مانند PDO Prepared Statements یا MySQLi Prepared Statements استفاده میشود.
به شکل مفهومی:
$stmt = $pdo->prepare(
'SELECT * FROM users WHERE id = :id'
);
$stmt->execute([
'id' => $userInput
]);
در این مدل، مقدار کاربر بهعنوان داده پردازش میشود، نه بخشی از ساختار SQL.
SQL Injection چه خطری دارد؟
شدت SQL Injection به معماری برنامه و سطح دسترسی حساب دیتابیس بستگی دارد.
در یک برنامه آسیبپذیر، پیامدهای احتمالی میتواند شامل:
- مشاهده اطلاعات غیرمجاز
- تغییر دادهها
- حذف دادهها
- دور زدن برخی کنترلهای برنامه
- دسترسی به اطلاعات حسابهای دیگر
- در شرایط خاص، پیامدهای گستردهتر در زیرساخت
باشد.
به همین دلیل SQL Injection یک آسیبپذیری جدی محسوب میشود.
مرحله نهم: بررسی سطح امنیتی بالاتر در DVWA
حالا یکی از قسمتهای جذاب تمرین:
سطح امنیتی DVWA را تغییر دهید.
مثلاً از:
Low
به:
Medium
یا:
High
سپس همان ورودیهای آزمایشی را دوباره بررسی کنید.
هدف این قسمت این نیست که صرفاً Payload جدید پیدا کنیم.
از خودتان بپرسید:
چه تغییری در برنامه باعث شد حمله سختتر شود؟
این دقیقاً همان ذهنیت یک متخصص امنیت است.
مرحله دهم: SQL Injection را مثل یک مدافع تحلیل کنیم
یک تست نفوذکار فقط نمیگوید:
«این صفحه SQL Injection دارد.»
بلکه باید بتواند توضیح دهد:
Root Cause
ورودی کاربر بهصورت ناامن وارد Query شده است.
Impact
ممکن است مهاجم بتواند روی Query تأثیر بگذارد.
Evidence
تفاوت قابل مشاهده در پاسخ برنامه به ورودیهای کنترلشده.
Remediation
استفاده از Prepared Statements و کنترل مناسب ورودی.
🛡️ چگونه SQL Injection را برطرف کنیم؟
۱. Prepared Statements
مهمترین راهکار.
۲. استفاده از ORM یا Database API امن
به شرطی که Queryها همچنان بهصورت امن ساخته شوند.
۳. اعتبارسنجی ورودی
اگر پارامتر باید فقط عدد باشد، برنامه باید آن را بهعنوان عدد پردازش کند.
مثلاً:
id = 123
نباید بدون کنترل مانند یک رشته SQL وارد Query شود.
۴. حداقل سطح دسترسی دیتابیس
حساب دیتابیس برنامه نباید دسترسیهای غیرضروری داشته باشد.
اگر برنامه فقط نیاز به SELECT دارد، نباید دسترسیهای مدیریتی گسترده داشته باشد.
۵. عدم نمایش خطاهای دیتابیس به کاربر
بهجای نمایش خطای خام SQL:
SQL syntax error...
به کاربر پیام عمومی نمایش دهید و جزئیات خطا را در لاگهای امن ثبت کنید.
🧪 تمرین کاربران صفر و یک سایبر
حالا یک تمرین برای شما:
مرحله ۱
در DVWA سطح Low را انتخاب کنید.
مرحله ۲
یک درخواست عادی ارسال کنید.
مرحله ۳
در Burp درخواست را مشاهده کنید.
مرحله ۴
پارامتر قابلکنترل را پیدا کنید.
مرحله ۵
رفتار ورودیهای منطقی مختلف را مقایسه کنید.
مرحله ۶
سطح امنیتی DVWA را افزایش دهید.
مرحله ۷
همان آزمایش را دوباره انجام دهید.
مرحله ۸
پاسخ دهید:
چه چیزی باعث شد رفتار برنامه تغییر کند؟
📝 تمرین حرفهایتر
یک گزارش تست نفوذ کوچک برای آزمایشگاه بنویسید:
Target:
DVWA
Vulnerability:
SQL Injection
Affected Parameter:
id
Security Level:
Low
Root Cause:
Unsafe SQL Query Construction
Evidence:
...
Impact:
...
Recommended Remediation:
Prepared Statements
این تمرین را جدی بگیرید؛ چون گزارشنویسی یکی از بخشهای مهم کار واقعی تست نفوذ است.
❌ اشتباهات رایج
«هر خطای SQL یعنی SQL Injection»
خیر.
باید رفتار برنامه و نحوه پردازش ورودی بررسی شود.
«SQL Injection فقط مربوط به MySQL است»
خیر.
SQL Injection میتواند در برنامههایی که با انواع مختلف سیستمهای مدیریت پایگاه داده کار میکنند رخ دهد.
«با فیلتر کردن چند کاراکتر مشکل حل میشود»
معمولاً راهکار قابل اتکایی نیست.
راهکار اصلی، جدا کردن داده از Query با استفاده از Prepared Statements است.
«بعد از پیدا کردن SQLi باید سراغ سایت واقعی برویم»
❌ خیر.
تمرین را در آزمایشگاه ادامه دهید.

دیدگاه شما