
در این بخش از دوره آموزشی SEC542 از موسسه SANS با مبحث حمله Stacked Queries SQLi همراه شما بوده و همچنین به دستورات لازم برای این نوع حمله SQL Injection می پردازیم.
Stacked Queries
stacked queries یا query stacking شاید بهترین و آسانترین تکنیک برای اکسپلویت SQLi است. این تکنیک شبیه یک command injection کلاسیک است که در آن با ورود یک اتمام کننده (command terminator) مانند ; ، دستور جدید و دلخواه خود را وارد میکنیم.
با استفاده از تکنیک stacked queries میتوان چندین کوئری SQL را که با علامت (;) جدا شدهاند، ارسال کرد.
SELECT * FROM Users WHERE lname=’Dent’; CREATE TABLE exfil (data varchar(1000));– ‘;
در دستور بالا، پیلود ما از رشته Dent شروع شده و تا کامنت – ادامه مییابد. به علامت ; دقت کنید. این علامت دستور جاری SELECT را خاتمه داده و (در صورت پشتیبانی شدن از stacked queries ) به ما اجازه میدهد تا یک دستور جدید SQL بنویسیم. قدرت زیاد این تکنیک در این است که ما دیگر محدود به دستور جاری SQL نیستیم.
اطمینان یافتن از این که آیا stacked queries در دیتابیس ما پشتیبانی میشود یا نه، کمی دشوار است. بیشترین احتمال پشتیبانی از این تکنیک در MS SQL Server وجود دارد.
در MySQL اوضاع متفاوت است. دیتابیس دستورات پشت هم در یک خط را قبول میکند اما معمولا نوع و نحوه ارتباط اپلیکیشن با دیتابیس، این قابلیت را تحت تاثیر قرار میدهد. در مورد Oracle نیز، اکثر منابع اشاره میکنند که قابلیت stacking در این دیتابیس پشتیبانی نمیشود.
مثال Stacked Query
در این بخش، یک مثال از حمله Stacked Queries SQLi در دیتابیس mysql را بررسی میکنیم. برای این کار از طریق command line به MySQL متصل شده و جداول موجود را بررسی میکنیم.
mysql> show tables;

همانطور که دیده میشود، فعلا تنها دو جدول Customers و Users وجود دارند.
حال stack query زیر را اجرا میکنیم:
mysql> SELECT * FROM Users WHERE lname=’Dent’; CREATE TABLE exfil(data varchar(1000));– ‘;

نکته: برای شبیهسازی یک SQLi واقعی، به آخر دستور، — ‘ را اضافه نمودیم.
حال می بینیم که یک جدول جدید بنام exfil به جداول ما اضافه شده است. این یعنی stack query ما با موفقیت اجرا شده است.

چرا Stack کردن مهم است
شاید اگر تنها هدف SQL injection بیرون کشیدن دیتا از دیتابیس بود، حمله Stacked Queries SQLi برای ما خیلی مهم نبودند. اما مزیت اصلی stack query ها در این است که به راحتی میتوان از قید و شرط کوئری جاری خارج شد.
اینکه بتوانیم با تزریق در شرط WHERE از یک دستور SELECT، یک جدول جدید بسازیم (یا از دستورات INSERT ، UPDATE ، DROP یا SHUTDOWN استفاده کنیم)، حرکت قدرتمندانه و هیجانانگیزی است.
حتی اگر در دیتابیس ما stack queries پشتیبانی نشود، باز هم ممکن است بتوانیم عملیات خود را با موفقیت انجام دهیم اما این نکته واضح است که stack query ها راهی سریع برای اعمال تاثیرات جدی در injection هستند.
UNIONIZING SQL Injection
رایجترین متد برای بیرون کشیدن دیتا با SQL injection ، استفاده از دستورات UNION است. دستور UNION با اجرای دو SELECT ، امکان نمایش اطلاعات در قالب یک جدول را فراهم میکند.
برای ما، این دستور کمک میکند تا با استفاده از SELECT موجود، به دیتای خارج از جدول جاری دست یابیم. کوئری زیر را در نظر بگیرید:
SELECT * FROM Users WHERE lname=’Dent’ UNION SELECT * FROM Customers;– ‘;
در کوئری بالا، پیلود inject شده ما از Dent’ شروع شده و تا ;– ادامه مییابد. نکته جدید، UNION SELECT * FROM Customers است.
آشنایی با حمله Out-of-Band SQLi
این قسمت از کوئری، دیتا را از جدول Customers گرفته و در ردیفهای بعد از نتایج SELECT اول، اضافه میکند. در واقع دیتای حاصل از کوئری بالا، از دو جدول Users و Customers میباشد.
پیشنیازهای UNION
استفاده از UNION ها، دست ما را برای ارتباط با جداول و دیتابیسهای دیگر از طریق SQL injection، باز میکند. با این حال، برای استفاده از این دستور، شرایط و پیشنیازهایی وجود دارند که ابتدا باید برقرار گردند. این شرایط عبارتند از:
• تعداد ستونهایی که با UNION SELECT افزوده شده ما برمیگردد باید با تعداد ستونهای بازگردانده شده از SELECT اصلی برابر باشد.
• همچنین انواع داده برگردانده شده در ستونهای دو SELECT ، باید با هم سازگار باشند.
• باید جدول/جداول خاصی را برای کوئری زدن، در نظر داشته باشیم.
چگونگی رعایت این پیشنیازها را با هم می بینیم.
SELECT بدون FROM
یکی از روشهای پرکاربرد برای تشخیص تعداد ستونها، استفاده از دستورات SELECT بدون FROM در آنهاست. ممکن است با خود فکر کنید که این عجیب است چون هدف اصلی یک دستور SELECT ، برگرداندن دیتا از (FROM) یک جدول است.
اما واقعیت این است که دستور SELECT الزاما به FROM نیازی ندارد. اما خروجی چنین دستوری چه خواهد بود؟ ساده است. خروجی دستور SELECT بدون FROM ، همان ورودی ما است که تنها توسط دیتابیس ترجمه و تفسیر شده است. به مثالهای زیر دقت کنید:
• SELECT 1; —
Returns 1
• SELECT ‘Zaphod’; —
• SELECT CONCAT(‘Zap’,’hod’); —
Returns Zaphod
در اکثر RDBMS ها میتوانیم از دستور SELECT بدون FROM استفاده کنیم. اما در Oracle اجازه این کار به ما داده نشده است. با این حال در Oracle ، جدولی به نام DUAL برای اهداف خاص قرار داده شده که میتوان با تکنیک هایی که در ادامه میگوییم، از آن استفاده کنیم.
بسیاری دیگر از سازندگان و فروشندگان نیز، جهت سازگاری با Oracle ، یک view پیشفرض برای DUAL در دیتابیسهای خود ساختهاند.
مطالب این بخش توسط سرکار خانم فهیمه رضایی تهیه شده است.