مبحث یکم : مقدمه و تاریخچه
مبحث دوم: مراحل نفوذ کردن / جلوگیری از نفوذ
مبحث سوم: حملات شبکه ای
مبحث چهارم - کار عملی
مبحث پنجم - DHCP
مبحث ششم - وب و حملات مطرح در آن
مبحث هفتم - حملات DoS
مبحث هشتم - سیستم عامل
مبحث نهم - مهندسی اجتماعی
مبحث دهم - Vulnerability (آسیب پذیری)

تمرین

تمرین: فرض کنید query زیر وجود دارد، مقادیری را برای قسمت های uname و email ارائه دهید که حاصل شرط در query، true شود.

;(” “=  Select * from user where (uname=” “) and (email

دقت کنید که شما در تمرین بالا query را می بینید و برای آن یک مقدار پیدا می کنید که آن را bypass کنید. ولی زمانی که می خواهید injection واقعی انجام دهید این گونه نیست که ساختار query را بدانید. ممکن است در syntax (ساختار) query یک آکولاد قرار داده باشد و یا چند پرانتز قرار دهد و یا …. از کجا می توان این ساختار را پیدا کرد؟ باید آن قدر با sql و errorهای آن کار کنیم و Errorها را آنالیز کنیم تا بتوانیم ساختار آن را بدست آوریم. مثلاً در error می گوید کوتیشن باز شده اما بسته نشده است.

یک راه انجام تمرین بالا این است که از uname شروع کنیم هر چه باز شده است ببندیم و مقدارهای مورد نظر خود را هم برای bypass کردن قرار دهیم تا به انتهای عبارت برسیم. کار دیگر این است که بیاییم و comment کنیم. یعنی تا جایی از دستورات را اجازه انجام بدهیم و بقیه را (مثلاً از and به بعد) comment کنیم. هر کدام از DBMDSها (مثل SQL server، My SQL و ….) طریقه ی comment کردن می تواند متفاوت باشد. comment کردن یعنی توضیحاتی را برای یک تکه از کد در کنار آن کد بنویسیم. این توضیحات قرار نیست کامپایل شوند. در زبان C علامت comment، دو اسلش (//) است که باعث می شود تا آن خط کامپایل نشود. در MySQL علامت # تا انتهای خط را comment می کند.

البته نفوذگر می تواند به جای بازی کردن با شرط ها و باز و بسته کردن کوتیشین ها و …. یک سری دستور قرار دهد تا از خروجی آن دستورها استفاده کند. برای مثال دستور version که ورژن MySQL را بر می گرداند و یا دستور shutdown که باعث می شود تا سیستم خاموش شود. قرار دادن دستور shutdown در قسمت شرط یک عبارت SQL باعث می­شود تا سیستم دستور shutdown را اجرا می کند که ببیند آیا نتیجه آن درست است یا نه که بعد بیاید و آن نتیجه را در عبارت where اعمال کند. به محض اینکه تابع shutdown اعمال می شود سیستم خاموش می شود.

یکی از دستوراتی که در SQL Injection کاربرد دارد، دستور union است. کاری که این دستور انجام می دهد این است که (مثلاً بین دو select) اجتماع انجام می دهد.

قالب کلی دستور

………… select * from ………… union all select * from

مثال: یک جدول دیگر به پایگاه داده SSC که در جلسه قبل ایجاد کرده اید، به نام pass ایجاد کنید.

;((mysql> create table pass (id varchar (20), password varchar (20)

حالا چند رکورد با توجه به idهای جدول user در این جدول ایجاد کنید (با مبحث foreign key کاری نداریم). یعنی نگاه کنید به جدول user. مثلاً یک user دارید که id آن 1 است. در اینجا یک id 1 ایجاد کنید و پسورد برای آن قرار دهید.

;(“mysql> insert into pass values (“1” , “1234

تا کنون باید وضعیت پایگاه داده شما مانند شکل 1 باشد.

شکل 1

می خواهیم از دستور union استفاده کنیم. می نویسیم

;select * from user union  select * from pass

اما اگر این دستور را بنویسید با پیغام خطا مواجه می شوید که می گوید تعداد ستون ها فرق می کند. نکته در اینجاست که باید بر روی تعداد columnهای یکسانی union انجام دهید.

یک راه برای انجام union این است که تعداد مورد نیاز از ستون های جدول را انتخاب کنیم. مثال:

;select uname, email from user union select * from pass

که خروجی شکل 2 را می دهد.

شکل 1

نوع ستون هایی که با یکدیگر اجتماع می شوند مهم نیست.

راه دیگر برای یکسان کردن تعداد ستون ها این است که به تعداد ستون های جدول دوم اضافه کنید تا تعداد ستون های دو جدول برابر شوند. که این روش غالباً در injection مورد استفاده قرار می گیرد. چون نمی خواهیم معمولاً داده ای از دست بدهیم و می خواهیم تمام داده را بدست آوریم. مثال:

;select * from user union select * from pass

که این دستور با خطای “متفاوت بودن تعداد ستون ها” مواجه می شود. حال حدس می زنیم که تعداد ستون های جدول دوم را چند تا قرار دهیم که با تعداد ستون های جدول اول برابر شود. مثال:

;select * from user union select *, 1 from pass

همان طور که در دستور بالا می بینید عبارت ,1 را اضافه کردیم و این یعنی برای جبران کمبود، یک چیزی مثل 1 را به این فیلدها اضافه می کنیم (البته به جای 1 می توانیم هر چیز دیگری مثل 2 و یا a و … قرار دهیم). اما دستور بالا هم پس از اجرا، پیغام خطا می دهد. درست است؛ چون هنوز تعداد ستون ها برابر نشده است. پس دو عبارت دیگر به select اضافه می کنیم.

;Select * from user union select *, 1,1,1 from pass

دستور بالا را در شکل 3 می بینید.

شکل 3

در خروجی می بینید که به جای مقدار name، fname و email (که در جدول 2 وجود نداشته اند) مقدار 1 قرار داده است.

توجه: ما فرض کردیم که نام جدول، تعداد ستون هاو نام فیلدها را می دانیم. این در صورتی است که در sql-injection واقعی نیاز است تا اینها را بدست آوریم.

سوال: الان ما به database متصل هستیم و دستورات خود را اجرا می کنیم. این وضعیت در زمان sql-injection چگونه است؟ خیلی از سایت ها دسترسی sql را از راه دور می بندند یعنی اینگونه نیست که هر IP بتواند به پورت sql متصل شود و کنسول بگیرد و select بزند و … اصولاً این موارد نیست. پس این دستورات را نفوذگر چگونه از پشت سیستم خود وارد می کند؟ ما در کنسول وارد کردیم نفوذگر در کجا وارد می کند؟ مثلاً آنها را در فیلد username و password یک فرم login سایت وارد می کند که روش آن قبلاً گفته شد و گفتیم که با استفاده از (نقطه- ویرگول) چند دستور را می توانیم اجرا کنیم.  به طور کلی هر فیلدی که کاربر قابلیت ورود اطلاعات را دارد می توان sql injection انجام داد.

توجه: از روی errorها می توان ساختار database را تا حدی بدست آورد. حتی می توان مثلاً برای بدست آوردن نام جدولی که پسوردها در آن نگهداری می شود تک تک کلماتی که احتمال دارد نام آن جدول باشد مثل password، pass، passwd و …. را به صورت brute force تست کرد.

توجه: البته با استفاده از فایروال، IPS و …. جلوی برخی از این حملات گرفته شده است. مثلاً برخی از عبارت ها (مثل union) را فیلتر می کنند. برخی از عبارت ها را escape می کنند. مثلاً هر جایی که دیدند شما کوتیشین زدید، یک \ (backslash) پشت آن می گذارند. البته نفوذگر هم برای bypass آن دوباره یک \ پشت آن می گذارد که نتیجه \\’ می شود که از آن ‘ (کوتیشین) باقی می ماند.

در حال حاضر ممکن است بر روی خیلی از سایت ها حمله sql injection انجام شود. حتی سایت های بزرگی مثل yahoo (مثلاً در یک زیر شاخه از سایت yahoo).

برمی گردیم به query که می خواستیم در آن inject انجام دهیم. به عنوان تمرین: در دستور زیر به گونه ای inject را انجام دهید که اطلاعات جدول user و pass را بیرون بکشد (با اطلاعاتی که تا به حال بدست آورده اید).

;(” “= Select * from user where (uname=” “) and (emai

دقت کنید که این دستور ثابت است و فقط از مقادیر بین “ “ می توانید inject کنید.

پاسخ:

;(” “= Select * from user where (uname=”1” or 1=1) union select * 1,1,1 from pass; –“) and (email

البته پاسخ های دیگر که خروجی شکل 4 را بدهد هم صحیح است.

توجه: علامت — باعث می شود تا ادامه ی دستور، comment شود (یعنی در نظر گرفته نشود). حاصل query بالا شکل 4 است.

شکل 4

توجه: مقداری که در عبارت بالا برای inject وارد کردیم از کاراکترهای زیادی تشکیل شده بود. اگر طول فیلدهای فرم login محدود باشند (مثلاً برای username 10 کاراکتر باشد) و browser اجازه ندهد بیشتر از 10 کاراکتر وارد بکنیم، آن وقت چه کاری باید انجام داد؟ همان بحثی که جلسه قبل گفته شد یعنی اگر محدودیت فقط از طرف client بود راحت می توانستیم آن را bypass کنیم. راه پیشگیری این حمله نیز این است که سمت سرور هم یک پردازش برای بررسی سایز فیلدهای فرم صورت گیرد.

اسکرول به بالا