التعرف على ثغرة Sql injection Bypass و كيف تصيب هذه الثغرة المواقع و الكود المسبب لها و الحماية منها - Programmer Tech

Programmer Tech

تعلم البرمجة - علوم الكمبيوتر - أمن المعلومات - القرصنة الأخلاقية

إعلان اعلى المقالة

الجمعة، 20 نوفمبر 2020

التعرف على ثغرة Sql injection Bypass و كيف تصيب هذه الثغرة المواقع و الكود المسبب لها و الحماية منها

php sql bypass 


حماية PHP Security

درس جديد من دورة web security هذا المقال الثاني من الدورة, لمتابعة المقال الأول عن كيفية إكتشاف ثغرة html_injection و كيفية حماية الموقع من تلك الثغرة إضغط هنا.

SQL Injection

هي إحدى ثغرات الويب المشهورة تمكن هذه الثغرة من إختراق قواعد البيانات و هي ثغرة مشهورة يعرفها الجميع من أطفال الشبكة و غيرهم لأنها بالكاد تكون هي الثغرة الأشهر في العالم حتى الآن, هناك بعض المواقع المصابة بتلك الثغرة و مطورين الأدوات tools إستطاعوا تطوير مجموعة من الأدوات حتى يكون إختراق تلك الثغرة سهل للغاية و يمكن لشخص من اطفال الشبكة إختراق مجموعة من المواقع بإستخدام إحدى الأدوات فقط بالنسخ و اللصق حتى المبرمج لا يعرف كيف تسبب في هذه الثغرة و هناك العديد من الثغرات سنذكرها بعد قليل.

Sql injection Bypass

ثغرة SQL INJECTION BYPASS هي إحدى أنواع الثغرات الذي تقوم بإختراق قواعد البيانات من خلال form الإدخال و اقصد حقول الإدخال عند تسجيل الأدمن إلى لوحة التحكم و تلك الحقول هي user name password و يتحايل الهكر على حقول الإدخال حتى يحصل على أحد اسماء و كلمات المرور لدى الأدمن او الأشخاص المسؤولين على الموقع, تابع معي حتى تستطيع كمبرمج web php حماية موقعك من هؤلاء الأطفال.

Security Sql injection Bypass 

حماية هذا النوع من الثغرات سهل جداً لكن يحتاج تفكير من المبرمج بشكل جيد أو فريق web php security لدى الشركة, و تلك الثغرة تحدث عند تمرير بيانات غير مفلترة في قواعد البيانات و هنا يكون السبب php لأنها هي الوسيط بين حقول الإدخال لدى المتصفح و قواعد البيانات داخل السيرفر.

لنتعرف على الكود من خلال إنشاء مثال و ذلك المثال يحتوي على حقول user_name و Password بالإضافة إلى زر إرسال بيانات أو login لدى الأدمن.

مثال 1

<form action="<?php echo $_SERVER ["PHP_SELF"]; ?>" method="post">
user: <input type="text" name="username" / ><br><br>

pass: <input type="text" name="password"><br><br>

<input type="submit" value="login">

</form>
<?php
    error_reporting(0);
    $conn = mysqli_connect ("localhost","root","") ;

    $db   = mysqli_select_db($conn,"test") ;

    $user = $_POST['username'];

    $pass = $_POST['password'];

    if (isset($user) and isset($pass) and !empty($user) and !empty($pass)) {
   
    $query = mysqli_query($conn,"SELECT * FROM names WHERE name='$user' AND password='$pass'");

    $results = mysqli_num_rows($query);

    if ($results !=0) {
        $date = mysqli_fetch_assoc($query);

        echo "Hello" ."==>" . $date['name'];
    }}



?>
في المثال السابق قمنا بإنشاء حقول بيانات بشكل طبيعي من خلال form و ذلك form يحتوي على حقل username و ايضاً حقل password و ايضاً حقل إرسال بيانات وهو login كما تم ارسال البيانات من خلال psot من خلال ذالك الكود html

 

قمنا بإنشاء form يحتوي علي حقول بيانات مثل username و password كما تم إنشاء زر إرسال بيانات و هو login ويتم إرسال البيانات عن طريق الدالة get شاهدوا الصورة الذي في الأسفل حتى تفهموا اكثر


<form action="<?php echo $_SERVER ["PHP_SELF"]; ?>" method="post">
user: <input type="text" name="username" / ><br><br>

pass: <input type="text" name="password"><br><br>

<input type="submit" value="login">

</form>


المرحلة القادمة هي مرحلة الإتصال في السيرفر و قواعد البيانات, يجب أن يكون هناك سيرفر مثل سيرفر xampp ويجب أن يتوفر معك مسار السيرفر و ايضاً كلمة السر phpmyadmin و ايضاً اليوزر الخاص بي phpmyadmin

$conn = mysqli_connect ("localhost","root","") ; 

 

من خلال الكود تم الإتصال بقواعد البيانات على السيرفر و تم تخزين الإتصال في متغير بإسم coon
و المرحلة التالية هي الإتصال بقاعدة البيانات database و في حالتي أنا هنا لدي database بإسم test.

$db   = mysqli_select_db($conn,"test") ; 

 

و هذا كود الإتصال بـ database الذي هي test و تم التخزين داخل متغير بإسم db و كل هذه دوال تقدمها php حتى تستطيع التعامل مع mysql, داخل الـ test يوجد جدول بإسم names يحتوي على الجدول و الجدول يحتوي على مجموعة من الأعمدة و هي username password و ايضاً id صورة من داخل الجدول.

php my admin
صورة من داخل القاعدة


كما تحتوي تلك القاعدة على مجموعة من المستخدمين و تم إدخال المستخدمين بشكل يدوي حتى نستطيع الشرح, هناك مستخدم بإسم kaissar و الباسورد هي 1234 و كما هناك مستخدم بإسم date و الباسورد 123 و هناك ahmed الباسورد 12345 و هناك ali و الباسورد 123456.
 
ناتي الآن إلى تمرير البيانات التي سيتم إدخالها من قبل المستخدم و هي username و password و نحن نعرف إن البيانات ستمر من خلال post كما تم تحديد هذا في method داخل form من خلال تلك الأكواد.

$user = $_POST['username'];
$pass = $_POST['password'];


و ايضاً تم تخزين كود تمرير البيانات username بداخل متغير user و كما تم تخزين كود تمرير البيانات password داخل متغير بإسم pass لكن إلى الآن نريد أن نتأكد إن كان يجب أن يكون حقول البيانات لدى المستخدم غير فارغة بسبب أنه سيتم تخزين البيانات إن كانت الحقول فارغة.

if (isset($user) and isset($pass) and !empty($user) and !empty($pass)) { 


من خلال isset و emoty يمكن التحقق من البيانات إن كانت ليست فارغة سيتم تنفيذ الكود داخل if و إن لم تكن موجودة لم يتم تنفيذ الكود و الكود الذي تحتويه if هو كود إستدعاء الجدول الذي هو names و سيتم التأكد من هذا من خلال user و pass و بالطبع كل هذا تم تخزينه داخل متغير بإسم query.

$query = mysqli_query($conn,"SELECT * FROM names WHERE name='$user' AND                password='$pass'");                                                                                                                      


و إن كانت البيانات التي يمررها الأدمن صحيحه ابحث داخل الأعمدة عن إسم الأدمن و الباسورد من خلاله, و تم حفظ هذا داخل متغير باسم results.

$results = mysqli_num_rows($query);

 
و إن كانت حقيقية سيتم تنفيذ الكود التالي مع رساله ترحيب من السيرفر + إسم الأدمن من خلال الكود

  $results = mysqli_num_rows($query);       
  if ($results !=0) {                                         
        $date = mysqli_fetch_assoc($query);  
        echo "Hello" ."==>" . $date['name'];     
    }}                                                                

?>

إلى الآن انتهينا و يمكن لأي أدمن الإتصال و قم بالتجريب أدخل إسم أدمن صحيح و باسورد صحيح لكن هنا البيانات تمر دون فلترة و هذا يسبب ثغرة sql injection bypass و نحن نعرف أن العلامة الأشهر لمعرفة إن كان الحقل مصاب أو لا هي (') إذهب الآن إلى حقول التسجيل و اكتب داخل user admin و اكتب داخل pass تلك العلامة ' ستجد أحد اشهر الأخطاء الموجودة في عالم الويب وهو

Warning: mysqli_num_rows() expects parameter 1 to be mysqli_result, boolean given in /opt/lampp/htdocs/hrml_web/sql_bypass.php on line 23


إستغلال ثغرة Sql Inejction Bypass

فيعني ان هذا الحقل مصاب و إستغلال الثغرة أمر سهل جداً لكن في حالتي أنا حقل user name مصاب و ايضاً حقل password مصاب و هنا لا أريد أن اكتب اسم admin فقط كل ما علينا هو كتابة كود الإستغلال و سيكون بالشكل

 1' or '1'='1

نضعه بداخل حقل user و حقل pass سيتم الدخول إلى لوحة التحكم لكن تختلف طريقة الإستغلال من موقع إلى آخر و يمكن أن يكون طريقة الإستغلال هي إحدى تلك الأكواد

or 1 = 1 | ' or ' 1 ' = ' 1 ' -- | ' or ' 1 ' = ' 1 ' /* | ' or ' 1 ' = ' 1 '# | ' or ' 1 ' = ' 1 ' %00 | ' or '1'='1' %00


الآن عرفنا كيف يتم إكتشاف الثغرة و كيف يتم الإستغلال و ما هو الكود, نأتي الآن إلى عمل فلترة للبيانات حتى لا تحصل تلك الثغرة في الموقع و يجب تشفير البيانات و عمل تغليف للبيانات, تتيح لنا php مجموعة من الدوال للتعامل مع تلك الثغرات و عمل فلترة لها.
 

دوال التعامل مع ثغرة bypass

 solution php

filter_var

2- دالة FILTER_SANITIZE_STRING
3- دالة FILTER_VALIDATE_INT
4- دالة FILTER_VALIDATE_IP
5- دالة FILTER_SANITIZE_EMAIL
6- دالة FILTER_VALIDATE_URL

FILTER_SANITIZE_STRING

تستخدم تلك الدالة عندما يكون الحقل المصاب هو STRING يعني نصوص مثل حقول USERNAME.
 

FILTER_VALIDATE_INT

تستخدم في تغليف حقل من نوع int و هنا نقصد الأرقام و سيتم إستخدام هذه ايضاً على موقعي لأنه يوجد به حقل pass و مصاب ايضاً و نحن نعرف أنها ارقام.

FILTER_VALIDATE_IP

تستخدم هذه الدالة عندما يكون هناك حقل في الموقع مثل حقل إدخال ip address.
 

FILTER_SANITIZE_EMAIL

تستخدم هذه الدالة أيضاً عندما يكون هناك حقل لإدخال إيميل EMAIL.
 

FILTER_VALIDATE_URL

تستخدم هذه عندما يكون هناك حقل إدخال إسم موقع URL.
 
 
 
لنرى كيف سنقوم بحماية الموقع بإستخدام تلك الدوال الذي توفرها PHP و كما سنقوم بتشفير PASS من خلال هاش MD5, لآحظ شكل الكود كيف سيكون بعد الحماية 
 
<form action="<?php echo $_SERVER ["PHP_SELF"]; ?>" method="post">
user: <input type="text" name="username" / ><br><br>

pass: <input type="password" name="password"><br><br>

<input type="submit" value="login">

</form>
<?php
error_reporting(0);

$conn = mysqli_connect ("localhost","root","") ;
$db = mysqli_select_db($conn,"test") ;
$user = $_POST['username'];
$pass = $_POST['password'];
//--------------------------------------------------------
     if (intval($pass)) {
      if (filter_var($pass , FILTER_VALIDATE_INT)) {
      $pass = md5($pass);


    if (strval($user)) {
     if (filter_var($user , FILTER_SANITIZE_STRING)) {

       //----------------------------------------


if (isset($user) and isset($pass) and !empty($user) and !empty($pass)) {

$query = mysqli_query($conn,"SELECT * FROM names WHERE name='$user' AND password='$pass'")or die('pleass user') ;
$results = mysqli_num_rows($query);
if ($results !=0) {
$date = mysqli_fetch_assoc($query);
echo "Hello" ." " . $date['name'];
}}

}}}}


?>

تم إستخدام strval و هي إختصار string value لأننا سنقوم بفلترة string و القيمة الخاصة بها تستخدم intval و هي إختصار إلى integer value و هذه هي عملية التغليف للبيانات المارة من خلال حقل username و حقل password.

//--------------------------------------------------------
if (intval($pass)) {
if (filter_var($pass , FILTER_VALIDATE_INT)) {
$pass = md5($pass);


if (strval($user)) {
if (filter_var($user , FILTER_SANITIZE_STRING)) {

//----------------------------------------
 

يمكنكم مشاهدة شرح هذا الدرس على يوتيوب من خلال الضغط على تشغيل الفيديو الآتي

ليست هناك تعليقات:

إرسال تعليق

facebook

نموذج الاتصال

الاسم

بريد إلكتروني *

رسالة *