مضى على الشبكة و يوم من العطاء.
  • تحذير: يجب على كل روّاد الشبكة تشغيل برامج الاختراق داخل الأنظمة الوهمية وهي بهدف التعلم وحماية الأعضاء والتوعية بها

[ WalkTh ] حقن برمجيات ضاره في قواعد بيانات مواقع الويب _ Structured Query Language ( sql Injection )

3b0-0d3b0-0d is verified member.

{ || مشرف قسم CTF || }
.:: طاقم المشرفين ::.

السمعة:

03376575e888fd097280c51469c29fbc.png

الـ SQL Injection

86d8d3b6995ddad46f5d9142354b65b1.png

هي اختصار لـ Structured Query Language وهي عبارة عن ثغرة في النظام بتسمح للهاكرز إنهم يتحكموا في قاعدة البيانات يعني لو في موقع على الويب ومبرمجه ما حمى قاعدة البيانات من الهجمات الخارجية هيك بكون فتح باب للهكرز يخترقوا الموقع ويستولوا على بيانات العملاء أو يعدلوها وفي بعض الأحيان يمكن يكون الهدف ببساطة الإضرار بموقع الويب نفسه.

والشغل بهاد الموضوع بتضمن معرفة كيف نكتشف هاي الثغرات ونتستفيد منها لاختراق النظام , واكيد لو أنت مبرمج مواقع لازم تتعلم كيف تحمي برمجياتك من هاي الثغرات



بهاد الموضوع رح نركز على النقاط التالية 👇

  1. ما هي الـ Database
  2. ما هي الـ SQL وكيفيه التعامل معها
  3. ما هو الـ SQL Injection وانواعها و امثله عليهن

الأسئله من TryHackMe | SQL Injection

ما هي الـ Database


الـ Database ( معناها قاعدة البيانات ) هي طريقة لتخزين المعلومات الإلكترونية بشكل منظم بتكون مراقبة بواسطة الـ (Database Management System DBMS ) اللي معناها نظام إدارة قواعد البيانات هاد عبارة عن برنامج بشتغل عليها وبتحكم فيها

يمكن متابعه الموضوع لمعرفه التعامل مع قواعد البيانات او انشائها

قواعد البيانات بتنقسم لنوعين
الـ Relational و الـ Non-Relational
الـ Relational

بكون فيها عدد من الجداول وكل جدول فيه بيانات مترتبطة ببعض الأسماء القواعد الشهيرة MySQL ، Microsoft SQL Server ، PostgreSQL وغيرهم. الجداول هاي هي اللي بتخزن المعلومات وكل جدول بكون فيه عمود وصفوف , كل عامود لازم يكون فيه اسم ونوع للمعلومة اللي فيه زي الأرقام أو النصوص
الصفوف هي البيانات الفعلية كل ما تضيف معلومة جديدة يتم إنشاء صف جديد

الفرق بين النوعين من قواعد البيانات هو إن الـ Relational بتستخدم جداول وترتبط بينها علاقات بينما الثانيه بتخزن البيانات بشكل أكثر مرونة وممكن يكون كل صف بيانات فيه معلومات مختلفة.


cee2844345f5ab5bc704b163797b3604.png


ما هو اختصار البرنامج الذي يتحكم في قاعدة البيانات؟
DBMS
ما اسم البنية الشبيهة بالشبكة التي تحتوي على البيانات؟
table


ما هي الـ SQL وكيفيه التعامل معها


تعتبر الـ SQL (Structured Query Language) لغة برمجة تُستخدم للتعامل مع قواعد البيانات

من أبسط الأوامر في SQL اللي بنستخدمها عادةً للتعامل مع قواعد البيانات
لاسترداد البيانات (SELECT)
دمج / جمع نتائج (UNION)
نعدل عليها (UPDATE)
نحط بيانات جديدة (INSERT)
نمسح بيانات (DELETE)

علما ان في بعض قواعد البيانات بتختلف قليلاً في الصياغة وطريقة العمل هاي أمثلة بناءً على قاعدة بيانات MySQL

الـ SELECT

كود:
select * from users;

هيك احنا بنحكي لقاعده البيانات انو بدنا نسترد كل الاعمده من الجدول اللي اسمه users
idusernamepassword
1jonpass123
2adminp4ssword
3martinsecret123



كود:
select username,password from users;
هيك احنا بنحكي لقاعده البيانات انو بدنا نسترد عامودين ( username , password ) من الجدول اللي اسمه users

برجعلنا 👇

usernamepassword
jonpass123
adminp4ssword
martinsecret123



كود:
select * from users LIMIT 1;
هيك احنا بنحكي لقاعده البيانات انو بدنا نسترد سطر واحد فقط ( الاول )
برجعلنا 👇
idusernamepassword
1jonpass123


كود:
select * from users where username='admin';
هيك احنا بنحكي لقاعده البيانات انو بدنا نسترد كل السطر اللي الـ username اله هو admin
برجعلنا 👇

idusernamepassword
2adminp4ssword


كود:
select * from users where username != 'admin';
هيك احنا بنحكي لقاعده البيانات انو بدنا نسترد كل الاسطر اللي الـ username الها مش admin
برجعلنا 👇

idusernamepassword
1jonpass123
3martinsecret123



كود:
select * from users where username='admin' or username='jon';
هيك احنا بنحكي لقاعده البيانات انو بدنا نسترد كل الاسطر اللي الـ username هو admin او jon
برجعلنا 👇

idusernamepassword
1jonpass123
2adminp4ssword



كود:
select * from users where username='admin' and password='p4ssword';
هيك احنا بنحكي لقاعده البيانات انو بدنا نسترد كل الاسطر اللي الـ username والـ password كما هو مكتوب القيم
برجعلنا 👇

idusernamepassword
2adminp4ssword


يمكن استخدام % لتحديد الجمل التي تبدأ أو تحتوي على أو تنتهي على حرف معين
كود:
select * from users where username like 'a%';
هيك احنا بنحكي لقاعده البيانات انو بدنا نسترد كل الاسطر اللي الـ username الها ببدأ بـ a
برجعلنا 👇

idusernamepassword
2adminp4ssword


كود:
select * from users where username like '%n';
هيك احنا بنحكي لقاعده البيانات انو بدنا نسترد كل الاسطر اللي الـ username الها بتنتهي بـ n
برجعلنا 👇

idusernamepassword
1jonpass123
2adminp4ssword
3martinsecret123



كود:
select * from users where username like '%mi%';
هيك احنا بنحكي لقاعده البيانات انو بدنا نسترد كل الاسطر اللي الـ username الها بتحتوي بنصها على mi
برجعلنا 👇

idusernamepassword
2adminp4ssword



الـ UNION

هي عبارة عن أمر في اللغة الـ SQL بتجمع نتائج أكتر من استعلام SELECT وبترجع بيانات من جداول واحدة أو أكتر

القواعد لاستخدام الـ UNION

1.
لازم يرجع نفس عدد الأعمدة في كل استعلام SELECT ، و
2. الأعمدة لازم تكون من نفس نوع البيانات و
3. ترتيب الأعمدة لازم يكون نفسه في كل استعلام

مثلا شركة بدها تعمل قائمه بالعناوين

عندها جدول اسمه customers وفيه المعلومات التاليه :

idnameaddresscitypostcode
1Mr John Smith123 Fake StreetManchesterM2 3FJ
2Mrs Jenny Palmer99 Green RoadBirminghamB2 4KL
3Miss Sarah Lewis15 Fore StreetLondonNW12 3GH

و جدول ثاني اسمه suppliers وفيه المعلومات التاليه :

idcompanyaddresscitypostcode
1Widgets LtdUnit 1a, Newby EstateBristolBS19 4RT
2The Tool Company75 Industrial RoadNorwichN22 3DR
3Axe Makers Ltd2b Makers Unit, Market RoadLondonSE9 1KK


باستخدام الاستعلام هاد بنقدر نجمع نتيجة الجدولين الثنين في جدول واحد :

كود:
SELECT name,address,city,postcode from customers UNION SELECT company,address,city,postcode from suppliers;

هيك بنجيب نتيجة فيها أسماء العملاء وعناوينهم بالإضافة إلى أسماء الموردين وعناوينهم
برجعلنا 👇
nameaddresscitypostcode
Mr John Smith123 Fake StreetManchesterM2 3FJ
Mrs Jenny Palmer99 Green RoadBirminghamB2 4KL
Miss Sarah Lewis15 Fore StreetLondonNW12 3GH
Widgets LtdUnit 1a, Newby EstateBristolBS19 4RT
The Tool Company75 Industrial RoadNorwichN22 3DR
Axe Makers Ltd2b Makers Unit, Market RoadLondonSE9 1KK


الـ INSERT

العبارة هاي بتخبر قاعدة البيانات إننا بدننا نحط صف جديد من البيانات في الجدول

كود:
insert into users (username,password) values ('bob','password123');

الـ into users بتخبر قاعدة البيانات الجدول اللي بدنا نحط فيه البيانات
الـ (username,password) أسماء الأعمدة اللي بدنا نحط فيها البيانات
الـ ;values ('bob','password') البيانات اللي بدنا نضيفها في الأعمدة اللي حددناها قبل .

الـ UPDATE

العبارة هاي بتخبر قاعدة البيانات إننا بدنا نعدل على صف أو أكتر في الجدول
بتحدد الجدول اللي بدك تعدل فيه بـ SET " اسم الجدول " update وبعدين بتختار العامود أو العواميد اللي بدك تعدلها باستخدام قائمة منفصلة بـ فاصلة زي " username='root',password='pass123' " وأخيرًا زي الاستعلامات بتحدد بالتحديد أي صفوف بدك تعدل عليها باستخدام الـ where زي ;where username='admin

مثال :

كود:
update users SET username='root',password='pass123' where username='admin';

هيك بكون بدنا نعدل اسم المستخدم لـ root وكلمة السر لـ pass123 في الصف اللي اسم المستخدم فيه admin


الـ DELETE

اذا كننا نريد حذف صف أو أكثر من بيانات المستخدمين من الجدول يتم استخدام عبارة delete from users لتحديد الجدول اللي بدنا حذف البيانات منه. باستعلام SELECT يمكننا تحديد بيانات محددة للحذف باستخدام الـ where


كود:
delete from users where username='martin';

بعد الاستعلام 👆 يتم حذف الصف الذي يحمل اسم المستخدم martin


أما في الاستعلام التالي
كود:
delete from users;

يتم حذف كل البيانات من الجدول users بدون استخدام جملة الـ WHERE. هكذا سيتم حذف جميع الصفوف الموجودة في الجدول


ما عبارة SQL المستخدمة لاسترداد البيانات؟
SELECT
ما عبارة SQL التي يمكن استخدامها لاسترداد البيانات من جداول متعددة؟
UNION
ما عبارة SQL المستخدمة لإضافة البيانات؟
INSERT


ما هو الـ SQL Injection وامثله عليه


معناه إذا دخلت بيانات من المستخدم في قاعدة البيانات مباشرة من خلال المواقع​
مثلاً إذا كان عندك موقع ويب للمدونات وكل مدخل في المدونة عندو رقم تعريفي فريد وفيه إعدادات بتخليك تحدد هل المدخل هاد متاح للعامة ولا لا. الرابط بياخذك لصفحة المدونة بيكون فيه شيء زي هيك
كود:
https://website.thm/blog?id=1
من الرابط اللي فوق إنت شايف إن الرقم 1 هو اللي بدل على المُدخل اللي بدك تفتحه السيرفر بستخدم الرقم هاد في استعلام SQL عشان يجيب المُدخل من قاعدة البيانات.

كود:
SELECT * from blog where id=1 and private=0 LIMIT 1;

مثلا لما يكون زي هيك الادخال عالرابط
بتحكي اجبلي المُدخل اللي عندو رقم 1 والمُدخل اللي هو عام وليس خاص واعرض لي مدخل واحد فقط

لكن المشكلة تبدأ لما يتم استخدام بيانات المستخدم بطريقة غير سليمة في الادخال

في المثال الرقم 2 محصور كمدخل خاص بس إذا كتبت الرابط هيك

كود:
https://website.thm/blog?id=2;--

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

هيك بتشوف المُدخل الخاص هيك بكون بعد ما انت تدخل

كود:
SELECT * from blog where id=2;-- and private=0 LIMIT 1;

هيك بتجيب المدخل رقم 2 والسطر اللي بعده بكون تعليق وما بأثر على الاستعلام.

ما الحرف الذي يشير إلى نهاية استعلام SQL؟
;

In-Band SQLi

نوع من ثغرات الـ Sql Injection اللي هو In-Band يعتبر أسهل نوع لاكتشافو واستغلالو لأنو ببساطة الهاكر بستخدم نفس الطريقة لاستغلال الثغرة وكمان بقدر يستخرج بيانات من قاعدة البيانات ويعرضها على نفس الصفحة.

وفي نوع تاني اسمه Error-Based هاد النوع مفيد جداً لاستخراج معلومات عن هيكل قاعدة البيانات لأنو رسائل الخطأ من قاعدة البيانات بتظهر مباشرة على شاشة المتصفح. يعني بقدر يستخدم رسائل الخطأ ليعرف كل حاجة عن القاعدة.

وعننا كمان Union-Based هاد النوع بستخدم عامل UNION في SQL جنباً إلى جنب مع عبارة SELECT ليرجع نتائج إضافية للصفحة هاد الاسلوب هو أكثر الطرق شيوعاً لاستخراج كميات كبيرة من البيانات عن طريق ثغرة الـ SQL Injection.


أساس اكتشاف Error-Based SQL Injection هو بتجربة بعض الأحرف لحد ما يطلع رسالة خطأ عادةً الأحرف عبارة عن علامة ترقيم أو علامة اقتباس.

جرب تكتب علامة اقتباس بعد id=1 بتشوف رسالة خطأ بتخبرك إنو في مشكلة بالصيغة

الرسالة هاي بتأكد إنو في ثغرة SQL Injection

1707703619692.png
أول شيء لازم نعملو هو نرجع بيانات للمتصفح من غير ما نظهر رسالة خطأ

أول اشي بنجرب نستخدم UNION لنحصل على نتيجة من اختيارنا.

1707703743954.png


تظهر رسالة خطأ معناها إن العدد من الأعمدة في العبارة UNION SELECT مختلف عن الاستعلام الأصلي نجرب نحط عامودين

1707703813166.png


نفس المشكله نجرب 3

1707703856633.png

رسالة الخطأ اختفت والمقالة بتظهر بس

المقالة بتظهر لأنها بتأخذ أول نتيجة رجعت من الاستعلام وبتعرضها علشان نتجاوز هالشيء لازم نخلي الاستعلام الأول ما يرجع نتائج وهذا ممكن يتم ببساطة عن طريق تغيير رقم id من 1 لـ 0.

1707704046758.png

الان اللي نعرض ناتج الاستعلام اللي انا ضفته فقط عن طريق الـ UNION وهي قيم الأعمدة 1،2،3

بنقدر نبدأ نستخدم القيم هاي عشان نجيب معلومات أكتر مثلا أول شيء بدنا نجيب اسم قاعدة البيانات اللي وصلنالها ممكن نعرف اسمها عن طريق الادخال التالي

كود:
0 UNION SELECT 1,2,database()

1707704323451.png

بعدها عن طريق الاستعالام التالي بامكاننا نعرف اسماء الجداول اللي موجوده بقاعده البيانات اللي عرفنا اسمها فوق
كود:
0 UNION SELECT 1,2,group_concat(table_name) FROM information_schema.tables WHERE table_schema = 'sqli_one'


1707704458318.png

طريقة ()group_concat لجمع أسماء الجداول , يعني بدلاً من عرض كل اسم جدول في صف منفرد سيتم جمعها في سلسلة واحدة بفاصلة

قاعدة البيانات ؛information_schema كل مستخدم في القاعدة عنده وصول لها ، وبتحتوي على معلومات عن كل القواعد والجداول اللي المستخدم عنده وصول الها
بالستعالام بنحكي لقاعده البيانات اعرضيلنا كل الجداول في قاعدة البيانات هاي sqli_one

جدول staff_users هو اللي بيهمنا لانو لحل التحدي بدو كلمة المرور الخاصه ب مارتن
بنقدر نستخدم قاعدة البيانات information_schema مرة تانية لنعرف بنية هذا الجدول باستخدام الاستعلام التالي :

كود:
0 UNION SELECT 1,2,group_concat(column_name) FROM information_schema.columns WHERE table_name = 'staff_users'

1707705003693.png

هادا شبيه بالاستعلام اللي قبل بس الفرق هو إنو المعلومات اللي بدنا نجيبها تغيرت من table_name ل column_name ، والجدول اللي بنستعلم عنه في قاعدة البيانات information_schema تغير من tables لـ columns ، وبنبحث عن أي صفوف فيها قيمة column_name هي staff_users .

هيك صار معنا هاي القيم

staff_users
usernamepasswordid


عن طريق group_concat بنقدر كمان نرجع كل الصفوف في سلسلة واحدة

لتسهيل القراءة زيدنا ,': لفصل اسم المستخدم عن كلمة المرور بدل ما تكون مفصولة بفاصلة اخترنا وسم '<br>' اللي بجبر كل نتيجة تطلع في سطر منفصل

كود:
0 UNION SELECT 1,2,group_concat(username,':',password SEPARATOR '<br>') FROM staff_users
1707705539602.png

عند ادخال الباسوورد

1707705604263.png

ما هو العلم بعد الانتهاء من المستوى 1؟
THM{SQL_INJECTION_3840}


Blind SQLi - Authentication Bypass

مقارنة بحقن SQL In-Band ، حيث نستطيع رؤية نتائج هجومنا مباشرة على الشاشة
الـ Blind SQLi هو عندما لا نحصل على أي رد فعل أو تأكيد على نجاح أو فشل الاستعلامات التي حققناها ، لأن رسائل الخطأ تم تعطيلها ولكن الحقن لا يزال يعمل على الرغم من ذلك

أحد أبسط تقنيات حقن Blind SQL هو عند تخطي طرق المصادقة مثل نماذج تسجيل الدخول في هذه الحالة لسنا مهتمين كثيرًا بجلب البيانات من قاعدة البيانات بل نريد فقط تخطي عملية تسجيل الدخول

غالبًا ما يتم تطوير نماذج تسجيل الدخول التي تتصل بقاعدة بيانات المستخدمين بطريقة تجعل التطبيق على الويب ليس مهتمًا بمحتوى اسم المستخدم وكلمة المرور بقدر ما هو مهتم بمطابقة الزوجين في جدول المستخدمين ببساطة يطلب التطبيق على الويب من قاعدة البيانات هل لديك مستخدم بالاسم bob وكلمة المرور bob123؟ وتجيب قاعدة البيانات بنعم أو لا (صحيح/خطأ) ويعتمد ذلك الجواب على ما إذا كان التطبيق على الويب يسمح لك بالمتابعة أم لا.

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

مثال

يمكننا رؤية في المربع أن الاستعلام إلى قاعدة البيانات هو الآتي :

1707706216310.png

كود:
select * from users where username='' and password='' LIMIT 1;

لجعل هذا الاستعلام يعود دائمًا بقيمة صحيحة، يمكننا إدخال الآتي في حقل كلمة المرور :


كود:
' OR 1=1;--

الذي يحول الاستعلام SQL إلى الآتي :

كود:
select * from users where username='' and password='' OR 1=1;

بما أن 1=1 عبارة صحيحة وقد استخدمنا عامل OR ، فسيؤدي هذا دائمًا إلى عودة الاستعلام بقيمة صحيحة من ذلك يفهم التطبيق على الويب بأن قاعدة البيانات وجدت زوجًا صحيحًا لاسم المستخدم/كلمة المرور وينبغي السماح بالوصول.


بعد ادخالها

1707706514647.png
1707706509625.png



Blind SQLi - Boolean
هو يعني الرد اللي برجعلنا بكون إما صح أو غلط يعني ما فيه وسط , هاد بفيدنا نشوف إذا كانت الـ Injection اللي عملناها نجحت ولا لأ

مثال
الـ URL زي هيك في الصفحة بظهر {"taken":true} الموقع بتحقق إذا كان اسم المستخدم مستخدم بالفعل أو لا
(حول اسم المستخدم الى admin123 )

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

علشان نكمل الطريق لازم نحلل الردود ونستخدم الاستعلامات بطريقة متسلسلة

1707710141433.png

الان مثل ما عملنا قبل
كود:
' UNION SELECT 1;--
بعطيني رساله خطأ ان الـ select الاعمده فيها مش مثل العدد بالـ UNION
1707710283463.png
بنجرب زي ما عملنا قبل لنوصل لنتيجه دون هاد الخطأ يكون عدد الاعمده هو 3

الآن بدنا نطلع اسم قاعدة البيانات عن طريق الـ '%' like سبق واستخدمناها فوق

1707711330716.png

اكيد راح يعطيك true لانو لسا ما عرفنا الاسم وهاي بتعني انو ممكن تكون اي حرف
بنجرب اكثر من حرف وعلامه حتى نوصل للأسم sqli_three

بعدها زي ما عملنا قبل بنقعد نجرب حتو نوصل لاسم الجدول

عن طريق الادخال التالي
كود:
admin123' UNION SELECT 1,2,3 FROM information_schema.tables WHERE table_schema = 'sqli_three' and table_name like '%';--

بعد التجربه مكان الـ '%' نجد اسم الجدول هو users

نقوم بتكرار العمليه لكن على الباسورد الخاص بالمستخدم admin عن طريق الادخال التالي
كود:
admin123' UNION SELECT 1,2,3 from users where username='admin' and password like 'a%

بعد التجريب والمحاوله عن طريق الـ true والـ false نجد ان كلمه السر هي 3845

ما هو العلم بعد الانتهاء من المستوى الثالث؟​
THM{SQL_INJECTION_1093}


Blind SQLi - Time Based



هون مافي شي بعطيك إشارة واضحة إذا الاستعلام اللي بترسلو صح أو لأ , الشيء الوحيد إللي بعرفك إذا الاستعلام صح هو وقت الاستجابة للطلب يعني لو الاستعلام صح بوخذ وقت أطول ليتم استكماله وهذا الوقت الزائد بكون بسبب استخدام وظائف جاهزة زي SLEEP(x) جنبا إلى جنب مع عبارة UNION

يعني على سبيل المثال إذا كنت بدك تعرف كم عدد الأعمدة في جدول معين بتستخدم الاستعلام التالي :

كود:
admin123' UNION SELECT SLEEP(5);--

إذا ما في أي توقف في وقت الاستجابة يعني الاستعلام مش صح فبتضيف عمود ثاني لحتى تجرب :

كود:
admin123' UNION SELECT SLEEP(5),2;--

هون بتوقع بتحصل على توقف لمدة 5 ثواني في الاستجابة، يعني تأكيد على نجاح الاستعلام وأن في عندك عمودين.

1707713122220.png

وبعدين بتقدر تكرر هالعملية على كل الأعمدة وتحصل على كل المعلومات اللي بدك توصللها

بعد التجربه نجد ان اسم الـ database هو sqli_four

الان مثل ما عملنا بالاعلى نفعل هنا

كود:
admin123' UNION SELECT SLEEP(5),2 FROM information_schema.tables WHERE table_schema = 'sqli_four' and table_name like '%';--

بعد التجربه مكان الـ '%' نجد اسم الجدول هو users

نقوم بتكرار العمليه لكن على الباسورد الخاص بالمستخدم admin عن طريق الادخال التالي
كود:
admin123' UNION SELECT SLEEP(5),2 from users where username='admin' and password like '%

بعد التجريب والمحاوله عن طريق الـزمن ( اذا اخذ وقت فهذا يعني ان الادخال الذي ادخلته هو صحيح ) نجد ان كلمه السر هي 4961
ما هو العلم النهائي بعد الانتهاء من المستوى الرابع؟
THM{SQL_INJECTION_MASTER}

Out-of-Band



الـ Out-of-Band غير شائع زي SQL Injection العادي ، هون بعتمد على ميزات معينة مفعلة ( على السيرفر الخاص بـ قاعدة البيانات ) اللي بعمل مكالمة لشبكة خارجية بناءً على نتيجة الاستعلام

الهجوم هاد بيتميز بان فيه قناتين اتصال مختلفتين ، واحدة لتنفيذ الهجوم والتانية لجمع النتائج

على سبيل المثال قناة التنفيذ ممكن تكون طلب ويب وقناة جمع البيانات تكون رصد لطلبات HTTP/DNS

  1. الهاكر بيبعت طلب لموقع ويب فيه ثغرة SQL Injection باستخدام داتا معدلة.
  2. موقع الويب بعمل استعلام SQL لقاعدة البيانات ببعت الداتا المعدلة للهاكر
  3. الداتا المعدلة فيها طلب يقوم بعمل طلب HTTP راجع لجهاز الهاكر فيه البيانات من قاعدة البيانات
قم بتسمية بروتوكول يبدأ بالحرف D والذي يمكن استخدامه لسرقه البيانات من قاعدة البيانات.
Dns



حل امثله على الـ SQL Injection

حل معظم لابات portswigger من تقديمي
 

المرفقات

  • 1707709596348.png
    1707709596348.png
    8.5 KB · المشاهدات: 152
  • 1707714125370.png
    1707714125370.png
    92 KB · المشاهدات: 161
التعديل الأخير:
عبود يا مبدع ❤️
بارك الله فيك يا صديقي وجزاك الله كل خير
وابدعت واحسنت والله
ننتظر جديدك دايماً
تقبل مروري​
 
عبود يا مبدع ❤️
بارك الله فيك يا صديقي وجزاك الله كل خير
وابدعت واحسنت والله
ننتظر جديدك دايماً
تقبل مروري​
:love: 😇 ❤️
 
  • Love
التفاعلات: STORM
03376575e888fd097280c51469c29fbc.png

الـ SQL Injection

86d8d3b6995ddad46f5d9142354b65b1.png

هي اختصار لـ Structured Query Language وهي عبارة عن ثغرة في النظام بتسمح للهاكرز إنهم يتحكموا في قاعدة البيانات يعني لو في موقع على الويب ومبرمجه ما حمى قاعدة البيانات من الهجمات الخارجية هيك بكون فتح باب للهكرز يخترقوا الموقع ويستولوا على بيانات العملاء أو يعدلوها وفي بعض الأحيان يمكن يكون الهدف ببساطة الإضرار بموقع الويب نفسه.

والشغل بهاد الموضوع بتضمن معرفة كيف نكتشف هاي الثغرات ونتستفيد منها لاختراق النظام , واكيد لو أنت مبرمج مواقع لازم تتعلم كيف تحمي برمجياتك من هاي الثغرات



بهاد الموضوع رح نركز على النقاط التالية 👇

  1. ما هي الـ Database
  2. ما هي الـ SQL وكيفيه التعامل معها
  3. ما هو الـ SQL Injection وانواعها و امثله عليهن

الأسئله من TryHackMe | SQL Injection

ما هي الـ Database


الـ Database ( معناها قاعدة البيانات ) هي طريقة لتخزين المعلومات الإلكترونية بشكل منظم بتكون مراقبة بواسطة الـ (Database Management System DBMS ) اللي معناها نظام إدارة قواعد البيانات هاد عبارة عن برنامج بشتغل عليها وبتحكم فيها

يمكن متابعه الموضوع لمعرفه التعامل مع قواعد البيانات او انشائها

قواعد البيانات بتنقسم لنوعين
الـ Relational و الـ Non-Relational
الـ Relational

بكون فيها عدد من الجداول وكل جدول فيه بيانات مترتبطة ببعض الأسماء القواعد الشهيرة MySQL ، Microsoft SQL Server ، PostgreSQL وغيرهم. الجداول هاي هي اللي بتخزن المعلومات وكل جدول بكون فيه عمود وصفوف , كل عامود لازم يكون فيه اسم ونوع للمعلومة اللي فيه زي الأرقام أو النصوص
الصفوف هي البيانات الفعلية كل ما تضيف معلومة جديدة يتم إنشاء صف جديد

الفرق بين النوعين من قواعد البيانات هو إن الـ Relational بتستخدم جداول وترتبط بينها علاقات بينما الثانيه بتخزن البيانات بشكل أكثر مرونة وممكن يكون كل صف بيانات فيه معلومات مختلفة.


cee2844345f5ab5bc704b163797b3604.png






ما هي الـ SQL وكيفيه التعامل معها


تعتبر الـ SQL (Structured Query Language) لغة برمجة تُستخدم للتعامل مع قواعد البيانات

من أبسط الأوامر في SQL اللي بنستخدمها عادةً للتعامل مع قواعد البيانات
لاسترداد البيانات (SELECT)
دمج / جمع نتائج (UNION)
نعدل عليها (UPDATE)
نحط بيانات جديدة (INSERT)
نمسح بيانات (DELETE)

علما ان في بعض قواعد البيانات بتختلف قليلاً في الصياغة وطريقة العمل هاي أمثلة بناءً على قاعدة بيانات MySQL

الـ SELECT

كود:
select * from users;

هيك احنا بنحكي لقاعده البيانات انو بدنا نسترد كل الاعمده من الجدول اللي اسمه users
idusernamepassword
1jonpass123
2adminp4ssword
3martinsecret123



كود:
select username,password from users;
هيك احنا بنحكي لقاعده البيانات انو بدنا نسترد عامودين ( username , password ) من الجدول اللي اسمه users

برجعلنا 👇

usernamepassword
jonpass123
adminp4ssword
martinsecret123



كود:
select * from users LIMIT 1;
هيك احنا بنحكي لقاعده البيانات انو بدنا نسترد سطر واحد فقط ( الاول )
برجعلنا 👇
idusernamepassword
1jonpass123


كود:
select * from users where username='admin';
هيك احنا بنحكي لقاعده البيانات انو بدنا نسترد كل السطر اللي الـ username اله هو admin
برجعلنا 👇

idusernamepassword
2adminp4ssword


كود:
select * from users where username != 'admin';
هيك احنا بنحكي لقاعده البيانات انو بدنا نسترد كل الاسطر اللي الـ username الها مش admin
برجعلنا 👇

idusernamepassword
1jonpass123
3martinsecret123



كود:
select * from users where username='admin' or username='jon';
هيك احنا بنحكي لقاعده البيانات انو بدنا نسترد كل الاسطر اللي الـ username هو admin او jon
برجعلنا 👇

idusernamepassword
1jonpass123
2adminp4ssword



كود:
select * from users where username='admin' and password='p4ssword';
هيك احنا بنحكي لقاعده البيانات انو بدنا نسترد كل الاسطر اللي الـ username والـ password كما هو مكتوب القيم
برجعلنا 👇

idusernamepassword
2adminp4ssword


يمكن استخدام % لتحديد الجمل التي تبدأ أو تحتوي على أو تنتهي على حرف معين
كود:
select * from users where username like 'a%';
هيك احنا بنحكي لقاعده البيانات انو بدنا نسترد كل الاسطر اللي الـ username الها ببدأ بـ a
برجعلنا 👇

idusernamepassword
2adminp4ssword


كود:
select * from users where username like '%n';
هيك احنا بنحكي لقاعده البيانات انو بدنا نسترد كل الاسطر اللي الـ username الها بتنتهي بـ n
برجعلنا 👇

idusernamepassword
1jonpass123
2adminp4ssword
3martinsecret123



كود:
select * from users where username like '%mi%';
هيك احنا بنحكي لقاعده البيانات انو بدنا نسترد كل الاسطر اللي الـ username الها بتحتوي بنصها على mi
برجعلنا 👇

idusernamepassword
2adminp4ssword



الـ UNION

هي عبارة عن أمر في اللغة الـ SQL بتجمع نتائج أكتر من استعلام SELECT وبترجع بيانات من جداول واحدة أو أكتر

القواعد لاستخدام الـ UNION

1.
لازم يرجع نفس عدد الأعمدة في كل استعلام SELECT ، و
2. الأعمدة لازم تكون من نفس نوع البيانات و
3. ترتيب الأعمدة لازم يكون نفسه في كل استعلام

مثلا شركة بدها تعمل قائمه بالعناوين

عندها جدول اسمه customers وفيه المعلومات التاليه :

idnameaddresscitypostcode
1Mr John Smith123 Fake StreetManchesterM2 3FJ
2Mrs Jenny Palmer99 Green RoadBirminghamB2 4KL
3Miss Sarah Lewis15 Fore StreetLondonNW12 3GH

و جدول ثاني اسمه suppliers وفيه المعلومات التاليه :

idcompanyaddresscitypostcode
1Widgets LtdUnit 1a, Newby EstateBristolBS19 4RT
2The Tool Company75 Industrial RoadNorwichN22 3DR
3Axe Makers Ltd2b Makers Unit, Market RoadLondonSE9 1KK


باستخدام الاستعلام هاد بنقدر نجمع نتيجة الجدولين الثنين في جدول واحد :

كود:
SELECT name,address,city,postcode from customers UNION SELECT company,address,city,postcode from suppliers;

هيك بنجيب نتيجة فيها أسماء العملاء وعناوينهم بالإضافة إلى أسماء الموردين وعناوينهم
برجعلنا 👇
nameaddresscitypostcode
Mr John Smith123 Fake StreetManchesterM2 3FJ
Mrs Jenny Palmer99 Green RoadBirminghamB2 4KL
Miss Sarah Lewis15 Fore StreetLondonNW12 3GH
Widgets LtdUnit 1a, Newby EstateBristolBS19 4RT
The Tool Company75 Industrial RoadNorwichN22 3DR
Axe Makers Ltd2b Makers Unit, Market RoadLondonSE9 1KK


الـ INSERT

العبارة هاي بتخبر قاعدة البيانات إننا بدننا نحط صف جديد من البيانات في الجدول

كود:
insert into users (username,password) values ('bob','password123');

الـ into users بتخبر قاعدة البيانات الجدول اللي بدنا نحط فيه البيانات
الـ (username,password) أسماء الأعمدة اللي بدنا نحط فيها البيانات
الـ ;values ('bob','password') البيانات اللي بدنا نضيفها في الأعمدة اللي حددناها قبل .

الـ UPDATE

العبارة هاي بتخبر قاعدة البيانات إننا بدنا نعدل على صف أو أكتر في الجدول
بتحدد الجدول اللي بدك تعدل فيه بـ SET " اسم الجدول " update وبعدين بتختار العامود أو العواميد اللي بدك تعدلها باستخدام قائمة منفصلة بـ فاصلة زي " username='root',password='pass123' " وأخيرًا زي الاستعلامات بتحدد بالتحديد أي صفوف بدك تعدل عليها باستخدام الـ where زي ;where username='admin

مثال :

كود:
update users SET username='root',password='pass123' where username='admin';

هيك بكون بدنا نعدل اسم المستخدم لـ root وكلمة السر لـ pass123 في الصف اللي اسم المستخدم فيه admin


الـ DELETE

اذا كننا نريد حذف صف أو أكثر من بيانات المستخدمين من الجدول يتم استخدام عبارة delete from users لتحديد الجدول اللي بدنا حذف البيانات منه. باستعلام SELECT يمكننا تحديد بيانات محددة للحذف باستخدام الـ where


كود:
delete from users where username='martin';

بعد الاستعلام 👆 يتم حذف الصف الذي يحمل اسم المستخدم martin


أما في الاستعلام التالي
كود:
delete from users;

يتم حذف كل البيانات من الجدول users بدون استخدام جملة الـ WHERE. هكذا سيتم حذف جميع الصفوف الموجودة في الجدول







ما هو الـ SQL Injection وامثله عليه


معناه إذا دخلت بيانات من المستخدم في قاعدة البيانات مباشرة من خلال المواقع​
مثلاً إذا كان عندك موقع ويب للمدونات وكل مدخل في المدونة عندو رقم تعريفي فريد وفيه إعدادات بتخليك تحدد هل المدخل هاد متاح للعامة ولا لا. الرابط بياخذك لصفحة المدونة بيكون فيه شيء زي هيك
كود:
https://website.thm/blog?id=1
من الرابط اللي فوق إنت شايف إن الرقم 1 هو اللي بدل على المُدخل اللي بدك تفتحه السيرفر بستخدم الرقم هاد في استعلام SQL عشان يجيب المُدخل من قاعدة البيانات.

كود:
SELECT * from blog where id=1 and private=0 LIMIT 1;

مثلا لما يكون زي هيك الادخال عالرابط
بتحكي اجبلي المُدخل اللي عندو رقم 1 والمُدخل اللي هو عام وليس خاص واعرض لي مدخل واحد فقط

لكن المشكلة تبدأ لما يتم استخدام بيانات المستخدم بطريقة غير سليمة في الادخال

في المثال الرقم 2 محصور كمدخل خاص بس إذا كتبت الرابط هيك

كود:
https://website.thm/blog?id=2;--

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

هيك بتشوف المُدخل الخاص هيك بكون بعد ما انت تدخل

كود:
SELECT * from blog where id=2;-- and private=0 LIMIT 1;

هيك بتجيب المدخل رقم 2 والسطر اللي بعده بكون تعليق وما بأثر على الاستعلام.



In-Band SQLi

نوع من ثغرات الـ Sql Injection اللي هو In-Band يعتبر أسهل نوع لاكتشافو واستغلالو لأنو ببساطة الهاكر بستخدم نفس الطريقة لاستغلال الثغرة وكمان بقدر يستخرج بيانات من قاعدة البيانات ويعرضها على نفس الصفحة.

وفي نوع تاني اسمه Error-Based هاد النوع مفيد جداً لاستخراج معلومات عن هيكل قاعدة البيانات لأنو رسائل الخطأ من قاعدة البيانات بتظهر مباشرة على شاشة المتصفح. يعني بقدر يستخدم رسائل الخطأ ليعرف كل حاجة عن القاعدة.

وعننا كمان Union-Based هاد النوع بستخدم عامل UNION في SQL جنباً إلى جنب مع عبارة SELECT ليرجع نتائج إضافية للصفحة هاد الاسلوب هو أكثر الطرق شيوعاً لاستخراج كميات كبيرة من البيانات عن طريق ثغرة الـ SQL Injection.


أساس اكتشاف Error-Based SQL Injection هو بتجربة بعض الأحرف لحد ما يطلع رسالة خطأ عادةً الأحرف عبارة عن علامة ترقيم أو علامة اقتباس.

جرب تكتب علامة اقتباس بعد id=1 بتشوف رسالة خطأ بتخبرك إنو في مشكلة بالصيغة

الرسالة هاي بتأكد إنو في ثغرة SQL Injection

أول شيء لازم نعملو هو نرجع بيانات للمتصفح من غير ما نظهر رسالة خطأ

أول اشي بنجرب نستخدم UNION لنحصل على نتيجة من اختيارنا.

مشاهدة المرفق 8390

تظهر رسالة خطأ معناها إن العدد من الأعمدة في العبارة UNION SELECT مختلف عن الاستعلام الأصلي نجرب نحط عامودين

مشاهدة المرفق 8391

نفس المشكله نجرب 3

مشاهدة المرفق 8392

رسالة الخطأ اختفت والمقالة بتظهر بس

المقالة بتظهر لأنها بتأخذ أول نتيجة رجعت من الاستعلام وبتعرضها علشان نتجاوز هالشيء لازم نخلي الاستعلام الأول ما يرجع نتائج وهذا ممكن يتم ببساطة عن طريق تغيير رقم id من 1 لـ 0.


الان اللي نعرض ناتج الاستعلام اللي انا ضفته فقط عن طريق الـ UNION وهي قيم الأعمدة 1،2،3

بنقدر نبدأ نستخدم القيم هاي عشان نجيب معلومات أكتر مثلا أول شيء بدنا نجيب اسم قاعدة البيانات اللي وصلنالها ممكن نعرف اسمها عن طريق الادخال التالي

كود:
0 UNION SELECT 1,2,database()


بعدها عن طريق الاستعالام التالي بامكاننا نعرف اسماء الجداول اللي موجوده بقاعده البيانات اللي عرفنا اسمها فوق
كود:
0 UNION SELECT 1,2,group_concat(table_name) FROM information_schema.tables WHERE table_schema = 'sqli_one'



طريقة ()group_concat لجمع أسماء الجداول , يعني بدلاً من عرض كل اسم جدول في صف منفرد سيتم جمعها في سلسلة واحدة بفاصلة

قاعدة البيانات ؛information_schema كل مستخدم في القاعدة عنده وصول لها ، وبتحتوي على معلومات عن كل القواعد والجداول اللي المستخدم عنده وصول الها
بالستعالام بنحكي لقاعده البيانات اعرضيلنا كل الجداول في قاعدة البيانات هاي sqli_one

جدول staff_users هو اللي بيهمنا لانو لحل التحدي بدو كلمة المرور الخاصه ب مارتن
بنقدر نستخدم قاعدة البيانات information_schema مرة تانية لنعرف بنية هذا الجدول باستخدام الاستعلام التالي :

كود:
0 UNION SELECT 1,2,group_concat(column_name) FROM information_schema.columns WHERE table_name = 'staff_users'


هادا شبيه بالاستعلام اللي قبل بس الفرق هو إنو المعلومات اللي بدنا نجيبها تغيرت من table_name ل column_name ، والجدول اللي بنستعلم عنه في قاعدة البيانات information_schema تغير من tables لـ columns ، وبنبحث عن أي صفوف فيها قيمة column_name هي staff_users .

هيك صار معنا هاي القيم

staff_users
usernamepasswordid


عن طريق group_concat بنقدر كمان نرجع كل الصفوف في سلسلة واحدة

لتسهيل القراءة زيدنا ,': لفصل اسم المستخدم عن كلمة المرور بدل ما تكون مفصولة بفاصلة اخترنا وسم '<br>' اللي بجبر كل نتيجة تطلع في سطر منفصل

كود:
0 UNION SELECT 1,2,group_concat(username,':',password SEPARATOR '<br>') FROM staff_users
مشاهدة المرفق 8398
عند ادخال الباسوورد

مشاهدة المرفق 8399




Blind SQLi - Authentication Bypass

مقارنة بحقن SQL In-Band ، حيث نستطيع رؤية نتائج هجومنا مباشرة على الشاشة
الـ Blind SQLi هو عندما لا نحصل على أي رد فعل أو تأكيد على نجاح أو فشل الاستعلامات التي حققناها ، لأن رسائل الخطأ تم تعطيلها ولكن الحقن لا يزال يعمل على الرغم من ذلك

أحد أبسط تقنيات حقن Blind SQL هو عند تخطي طرق المصادقة مثل نماذج تسجيل الدخول في هذه الحالة لسنا مهتمين كثيرًا بجلب البيانات من قاعدة البيانات بل نريد فقط تخطي عملية تسجيل الدخول

غالبًا ما يتم تطوير نماذج تسجيل الدخول التي تتصل بقاعدة بيانات المستخدمين بطريقة تجعل التطبيق على الويب ليس مهتمًا بمحتوى اسم المستخدم وكلمة المرور بقدر ما هو مهتم بمطابقة الزوجين في جدول المستخدمين ببساطة يطلب التطبيق على الويب من قاعدة البيانات هل لديك مستخدم بالاسم bob وكلمة المرور bob123؟ وتجيب قاعدة البيانات بنعم أو لا (صحيح/خطأ) ويعتمد ذلك الجواب على ما إذا كان التطبيق على الويب يسمح لك بالمتابعة أم لا.

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

مثال

يمكننا رؤية في المربع أن الاستعلام إلى قاعدة البيانات هو الآتي :


كود:
select * from users where username='' and password='' LIMIT 1;

لجعل هذا الاستعلام يعود دائمًا بقيمة صحيحة، يمكننا إدخال الآتي في حقل كلمة المرور :


كود:
' OR 1=1;--

الذي يحول الاستعلام SQL إلى الآتي :

كود:
select * from users where username='' and password='' OR 1=1;

بما أن 1=1 عبارة صحيحة وقد استخدمنا عامل OR ، فسيؤدي هذا دائمًا إلى عودة الاستعلام بقيمة صحيحة من ذلك يفهم التطبيق على الويب بأن قاعدة البيانات وجدت زوجًا صحيحًا لاسم المستخدم/كلمة المرور وينبغي السماح بالوصول.


بعد ادخالها

مشاهدة المرفق 8402مشاهدة المرفق 8401


Blind SQLi - Boolean
هو يعني الرد اللي برجعلنا بكون إما صح أو غلط يعني ما فيه وسط , هاد بفيدنا نشوف إذا كانت الـ Injection اللي عملناها نجحت ولا لأ

مثال
الـ URL زي هيك في الصفحة بظهر {"taken":true} الموقع بتحقق إذا كان اسم المستخدم مستخدم بالفعل أو لا
(حول اسم المستخدم الى admin123 )

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

علشان نكمل الطريق لازم نحلل الردود ونستخدم الاستعلامات بطريقة متسلسلة


الان مثل ما عملنا قبل
كود:
' UNION SELECT 1;--
بعطيني رساله خطأ ان الـ select الاعمده فيها مش مثل العدد بالـ UNION
بنجرب زي ما عملنا قبل لنوصل لنتيجه دون هاد الخطأ يكون عدد الاعمده هو 3

الآن بدنا نطلع اسم قاعدة البيانات عن طريق الـ '%' like سبق واستخدمناها فوق


اكيد راح يعطيك true لانو لسا ما عرفنا الاسم وهاي بتعني انو ممكن تكون اي حرف
بنجرب اكثر من حرف وعلامه حتى نوصل للأسم sqli_three

بعدها زي ما عملنا قبل بنقعد نجرب حتو نوصل لاسم الجدول

عن طريق الادخال التالي
كود:
admin123' UNION SELECT 1,2,3 FROM information_schema.tables WHERE table_schema = 'sqli_three' and table_name like '%';--

بعد التجربه مكان الـ '%' نجد اسم الجدول هو users

نقوم بتكرار العمليه لكن على الباسورد الخاص بالمستخدم admin عن طريق الادخال التالي
كود:
admin123' UNION SELECT 1,2,3 from users where username='admin' and password like 'a%

بعد التجريب والمحاوله عن طريق الـ true والـ false نجد ان كلمه السر هي 3845




Blind SQLi - Time Based



هون مافي شي بعطيك إشارة واضحة إذا الاستعلام اللي بترسلو صح أو لأ , الشيء الوحيد إللي بعرفك إذا الاستعلام صح هو وقت الاستجابة للطلب يعني لو الاستعلام صح بوخذ وقت أطول ليتم استكماله وهذا الوقت الزائد بكون بسبب استخدام وظائف جاهزة زي SLEEP(x) جنبا إلى جنب مع عبارة UNION

يعني على سبيل المثال إذا كنت بدك تعرف كم عدد الأعمدة في جدول معين بتستخدم الاستعلام التالي :

كود:
admin123' UNION SELECT SLEEP(5);--

إذا ما في أي توقف في وقت الاستجابة يعني الاستعلام مش صح فبتضيف عمود ثاني لحتى تجرب :

كود:
admin123' UNION SELECT SLEEP(5),2;--

هون بتوقع بتحصل على توقف لمدة 5 ثواني في الاستجابة، يعني تأكيد على نجاح الاستعلام وأن في عندك عمودين.


وبعدين بتقدر تكرر هالعملية على كل الأعمدة وتحصل على كل المعلومات اللي بدك توصللها

بعد التجربه نجد ان اسم الـ database هو sqli_four

الان مثل ما عملنا بالاعلى نفعل هنا

كود:
admin123' UNION SELECT SLEEP(5),2 FROM information_schema.tables WHERE table_schema = 'sqli_four' and table_name like '%';--

بعد التجربه مكان الـ '%' نجد اسم الجدول هو users

نقوم بتكرار العمليه لكن على الباسورد الخاص بالمستخدم admin عن طريق الادخال التالي
كود:
admin123' UNION SELECT SLEEP(5),2 from users where username='admin' and password like '%

بعد التجريب والمحاوله عن طريق الـزمن ( اذا اخذ وقت فهذا يعني ان الادخال الذي ادخلته هو صحيح ) نجد ان كلمه السر هي 4961

Out-of-Band



الـ Out-of-Band غير شائع زي SQL Injection العادي ، هون بعتمد على ميزات معينة مفعلة ( على السيرفر الخاص بـ قاعدة البيانات ) اللي بعمل مكالمة لشبكة خارجية بناءً على نتيجة الاستعلام

الهجوم هاد بيتميز بان فيه قناتين اتصال مختلفتين ، واحدة لتنفيذ الهجوم والتانية لجمع النتائج

على سبيل المثال قناة التنفيذ ممكن تكون طلب ويب وقناة جمع البيانات تكون رصد لطلبات HTTP/DNS

  1. الهاكر بيبعت طلب لموقع ويب فيه ثغرة SQL Injection باستخدام داتا معدلة.
  2. موقع الويب بعمل استعلام SQL لقاعدة البيانات ببعت الداتا المعدلة للهاكر
  3. الداتا المعدلة فيها طلب يقوم بعمل طلب HTTP راجع لجهاز الهاكر فيه البيانات من قاعدة البيانات




حل امثله على الـ SQL Injection
الله يعطيك الف عافيه ♥️
 
03376575e888fd097280c51469c29fbc.png

الـ SQL Injection

86d8d3b6995ddad46f5d9142354b65b1.png

هي اختصار لـ Structured Query Language وهي عبارة عن ثغرة في النظام بتسمح للهاكرز إنهم يتحكموا في قاعدة البيانات يعني لو في موقع على الويب ومبرمجه ما حمى قاعدة البيانات من الهجمات الخارجية هيك بكون فتح باب للهكرز يخترقوا الموقع ويستولوا على بيانات العملاء أو يعدلوها وفي بعض الأحيان يمكن يكون الهدف ببساطة الإضرار بموقع الويب نفسه.

والشغل بهاد الموضوع بتضمن معرفة كيف نكتشف هاي الثغرات ونتستفيد منها لاختراق النظام , واكيد لو أنت مبرمج مواقع لازم تتعلم كيف تحمي برمجياتك من هاي الثغرات



بهاد الموضوع رح نركز على النقاط التالية 👇

  1. ما هي الـ Database
  2. ما هي الـ SQL وكيفيه التعامل معها
  3. ما هو الـ SQL Injection وانواعها و امثله عليهن

الأسئله من TryHackMe | SQL Injection

ما هي الـ Database


الـ Database ( معناها قاعدة البيانات ) هي طريقة لتخزين المعلومات الإلكترونية بشكل منظم بتكون مراقبة بواسطة الـ (Database Management System DBMS ) اللي معناها نظام إدارة قواعد البيانات هاد عبارة عن برنامج بشتغل عليها وبتحكم فيها

يمكن متابعه الموضوع لمعرفه التعامل مع قواعد البيانات او انشائها

قواعد البيانات بتنقسم لنوعين
الـ Relational و الـ Non-Relational
الـ Relational

بكون فيها عدد من الجداول وكل جدول فيه بيانات مترتبطة ببعض الأسماء القواعد الشهيرة MySQL ، Microsoft SQL Server ، PostgreSQL وغيرهم. الجداول هاي هي اللي بتخزن المعلومات وكل جدول بكون فيه عمود وصفوف , كل عامود لازم يكون فيه اسم ونوع للمعلومة اللي فيه زي الأرقام أو النصوص
الصفوف هي البيانات الفعلية كل ما تضيف معلومة جديدة يتم إنشاء صف جديد

الفرق بين النوعين من قواعد البيانات هو إن الـ Relational بتستخدم جداول وترتبط بينها علاقات بينما الثانيه بتخزن البيانات بشكل أكثر مرونة وممكن يكون كل صف بيانات فيه معلومات مختلفة.


cee2844345f5ab5bc704b163797b3604.png






ما هي الـ SQL وكيفيه التعامل معها


تعتبر الـ SQL (Structured Query Language) لغة برمجة تُستخدم للتعامل مع قواعد البيانات

من أبسط الأوامر في SQL اللي بنستخدمها عادةً للتعامل مع قواعد البيانات
لاسترداد البيانات (SELECT)
دمج / جمع نتائج (UNION)
نعدل عليها (UPDATE)
نحط بيانات جديدة (INSERT)
نمسح بيانات (DELETE)

علما ان في بعض قواعد البيانات بتختلف قليلاً في الصياغة وطريقة العمل هاي أمثلة بناءً على قاعدة بيانات MySQL

الـ SELECT

كود:
select * from users;

هيك احنا بنحكي لقاعده البيانات انو بدنا نسترد كل الاعمده من الجدول اللي اسمه users
idusernamepassword
1jonpass123
2adminp4ssword
3martinsecret123



كود:
select username,password from users;
هيك احنا بنحكي لقاعده البيانات انو بدنا نسترد عامودين ( username , password ) من الجدول اللي اسمه users

برجعلنا 👇

usernamepassword
jonpass123
adminp4ssword
martinsecret123



كود:
select * from users LIMIT 1;
هيك احنا بنحكي لقاعده البيانات انو بدنا نسترد سطر واحد فقط ( الاول )
برجعلنا 👇
idusernamepassword
1jonpass123


كود:
select * from users where username='admin';
هيك احنا بنحكي لقاعده البيانات انو بدنا نسترد كل السطر اللي الـ username اله هو admin
برجعلنا 👇

idusernamepassword
2adminp4ssword


كود:
select * from users where username != 'admin';
هيك احنا بنحكي لقاعده البيانات انو بدنا نسترد كل الاسطر اللي الـ username الها مش admin
برجعلنا 👇

idusernamepassword
1jonpass123
3martinsecret123



كود:
select * from users where username='admin' or username='jon';
هيك احنا بنحكي لقاعده البيانات انو بدنا نسترد كل الاسطر اللي الـ username هو admin او jon
برجعلنا 👇

idusernamepassword
1jonpass123
2adminp4ssword



كود:
select * from users where username='admin' and password='p4ssword';
هيك احنا بنحكي لقاعده البيانات انو بدنا نسترد كل الاسطر اللي الـ username والـ password كما هو مكتوب القيم
برجعلنا 👇

idusernamepassword
2adminp4ssword


يمكن استخدام % لتحديد الجمل التي تبدأ أو تحتوي على أو تنتهي على حرف معين
كود:
select * from users where username like 'a%';
هيك احنا بنحكي لقاعده البيانات انو بدنا نسترد كل الاسطر اللي الـ username الها ببدأ بـ a
برجعلنا 👇

idusernamepassword
2adminp4ssword


كود:
select * from users where username like '%n';
هيك احنا بنحكي لقاعده البيانات انو بدنا نسترد كل الاسطر اللي الـ username الها بتنتهي بـ n
برجعلنا 👇

idusernamepassword
1jonpass123
2adminp4ssword
3martinsecret123



كود:
select * from users where username like '%mi%';
هيك احنا بنحكي لقاعده البيانات انو بدنا نسترد كل الاسطر اللي الـ username الها بتحتوي بنصها على mi
برجعلنا 👇

idusernamepassword
2adminp4ssword



الـ UNION

هي عبارة عن أمر في اللغة الـ SQL بتجمع نتائج أكتر من استعلام SELECT وبترجع بيانات من جداول واحدة أو أكتر

القواعد لاستخدام الـ UNION

1.
لازم يرجع نفس عدد الأعمدة في كل استعلام SELECT ، و
2. الأعمدة لازم تكون من نفس نوع البيانات و
3. ترتيب الأعمدة لازم يكون نفسه في كل استعلام

مثلا شركة بدها تعمل قائمه بالعناوين

عندها جدول اسمه customers وفيه المعلومات التاليه :

idnameaddresscitypostcode
1Mr John Smith123 Fake StreetManchesterM2 3FJ
2Mrs Jenny Palmer99 Green RoadBirminghamB2 4KL
3Miss Sarah Lewis15 Fore StreetLondonNW12 3GH

و جدول ثاني اسمه suppliers وفيه المعلومات التاليه :

idcompanyaddresscitypostcode
1Widgets LtdUnit 1a, Newby EstateBristolBS19 4RT
2The Tool Company75 Industrial RoadNorwichN22 3DR
3Axe Makers Ltd2b Makers Unit, Market RoadLondonSE9 1KK


باستخدام الاستعلام هاد بنقدر نجمع نتيجة الجدولين الثنين في جدول واحد :

كود:
SELECT name,address,city,postcode from customers UNION SELECT company,address,city,postcode from suppliers;

هيك بنجيب نتيجة فيها أسماء العملاء وعناوينهم بالإضافة إلى أسماء الموردين وعناوينهم
برجعلنا 👇
nameaddresscitypostcode
Mr John Smith123 Fake StreetManchesterM2 3FJ
Mrs Jenny Palmer99 Green RoadBirminghamB2 4KL
Miss Sarah Lewis15 Fore StreetLondonNW12 3GH
Widgets LtdUnit 1a, Newby EstateBristolBS19 4RT
The Tool Company75 Industrial RoadNorwichN22 3DR
Axe Makers Ltd2b Makers Unit, Market RoadLondonSE9 1KK


الـ INSERT

العبارة هاي بتخبر قاعدة البيانات إننا بدننا نحط صف جديد من البيانات في الجدول

كود:
insert into users (username,password) values ('bob','password123');

الـ into users بتخبر قاعدة البيانات الجدول اللي بدنا نحط فيه البيانات
الـ (username,password) أسماء الأعمدة اللي بدنا نحط فيها البيانات
الـ ;values ('bob','password') البيانات اللي بدنا نضيفها في الأعمدة اللي حددناها قبل .

الـ UPDATE

العبارة هاي بتخبر قاعدة البيانات إننا بدنا نعدل على صف أو أكتر في الجدول
بتحدد الجدول اللي بدك تعدل فيه بـ SET " اسم الجدول " update وبعدين بتختار العامود أو العواميد اللي بدك تعدلها باستخدام قائمة منفصلة بـ فاصلة زي " username='root',password='pass123' " وأخيرًا زي الاستعلامات بتحدد بالتحديد أي صفوف بدك تعدل عليها باستخدام الـ where زي ;where username='admin

مثال :

كود:
update users SET username='root',password='pass123' where username='admin';

هيك بكون بدنا نعدل اسم المستخدم لـ root وكلمة السر لـ pass123 في الصف اللي اسم المستخدم فيه admin


الـ DELETE

اذا كننا نريد حذف صف أو أكثر من بيانات المستخدمين من الجدول يتم استخدام عبارة delete from users لتحديد الجدول اللي بدنا حذف البيانات منه. باستعلام SELECT يمكننا تحديد بيانات محددة للحذف باستخدام الـ where


كود:
delete from users where username='martin';

بعد الاستعلام 👆 يتم حذف الصف الذي يحمل اسم المستخدم martin


أما في الاستعلام التالي
كود:
delete from users;

يتم حذف كل البيانات من الجدول users بدون استخدام جملة الـ WHERE. هكذا سيتم حذف جميع الصفوف الموجودة في الجدول







ما هو الـ SQL Injection وامثله عليه


معناه إذا دخلت بيانات من المستخدم في قاعدة البيانات مباشرة من خلال المواقع​
مثلاً إذا كان عندك موقع ويب للمدونات وكل مدخل في المدونة عندو رقم تعريفي فريد وفيه إعدادات بتخليك تحدد هل المدخل هاد متاح للعامة ولا لا. الرابط بياخذك لصفحة المدونة بيكون فيه شيء زي هيك
كود:
https://website.thm/blog?id=1
من الرابط اللي فوق إنت شايف إن الرقم 1 هو اللي بدل على المُدخل اللي بدك تفتحه السيرفر بستخدم الرقم هاد في استعلام SQL عشان يجيب المُدخل من قاعدة البيانات.

كود:
SELECT * from blog where id=1 and private=0 LIMIT 1;

مثلا لما يكون زي هيك الادخال عالرابط
بتحكي اجبلي المُدخل اللي عندو رقم 1 والمُدخل اللي هو عام وليس خاص واعرض لي مدخل واحد فقط

لكن المشكلة تبدأ لما يتم استخدام بيانات المستخدم بطريقة غير سليمة في الادخال

في المثال الرقم 2 محصور كمدخل خاص بس إذا كتبت الرابط هيك

كود:
https://website.thm/blog?id=2;--

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

هيك بتشوف المُدخل الخاص هيك بكون بعد ما انت تدخل

كود:
SELECT * from blog where id=2;-- and private=0 LIMIT 1;

هيك بتجيب المدخل رقم 2 والسطر اللي بعده بكون تعليق وما بأثر على الاستعلام.



In-Band SQLi

نوع من ثغرات الـ Sql Injection اللي هو In-Band يعتبر أسهل نوع لاكتشافو واستغلالو لأنو ببساطة الهاكر بستخدم نفس الطريقة لاستغلال الثغرة وكمان بقدر يستخرج بيانات من قاعدة البيانات ويعرضها على نفس الصفحة.

وفي نوع تاني اسمه Error-Based هاد النوع مفيد جداً لاستخراج معلومات عن هيكل قاعدة البيانات لأنو رسائل الخطأ من قاعدة البيانات بتظهر مباشرة على شاشة المتصفح. يعني بقدر يستخدم رسائل الخطأ ليعرف كل حاجة عن القاعدة.

وعننا كمان Union-Based هاد النوع بستخدم عامل UNION في SQL جنباً إلى جنب مع عبارة SELECT ليرجع نتائج إضافية للصفحة هاد الاسلوب هو أكثر الطرق شيوعاً لاستخراج كميات كبيرة من البيانات عن طريق ثغرة الـ SQL Injection.


أساس اكتشاف Error-Based SQL Injection هو بتجربة بعض الأحرف لحد ما يطلع رسالة خطأ عادةً الأحرف عبارة عن علامة ترقيم أو علامة اقتباس.

جرب تكتب علامة اقتباس بعد id=1 بتشوف رسالة خطأ بتخبرك إنو في مشكلة بالصيغة

الرسالة هاي بتأكد إنو في ثغرة SQL Injection

أول شيء لازم نعملو هو نرجع بيانات للمتصفح من غير ما نظهر رسالة خطأ

أول اشي بنجرب نستخدم UNION لنحصل على نتيجة من اختيارنا.

مشاهدة المرفق 8390

تظهر رسالة خطأ معناها إن العدد من الأعمدة في العبارة UNION SELECT مختلف عن الاستعلام الأصلي نجرب نحط عامودين

مشاهدة المرفق 8391

نفس المشكله نجرب 3

مشاهدة المرفق 8392

رسالة الخطأ اختفت والمقالة بتظهر بس

المقالة بتظهر لأنها بتأخذ أول نتيجة رجعت من الاستعلام وبتعرضها علشان نتجاوز هالشيء لازم نخلي الاستعلام الأول ما يرجع نتائج وهذا ممكن يتم ببساطة عن طريق تغيير رقم id من 1 لـ 0.


الان اللي نعرض ناتج الاستعلام اللي انا ضفته فقط عن طريق الـ UNION وهي قيم الأعمدة 1،2،3

بنقدر نبدأ نستخدم القيم هاي عشان نجيب معلومات أكتر مثلا أول شيء بدنا نجيب اسم قاعدة البيانات اللي وصلنالها ممكن نعرف اسمها عن طريق الادخال التالي

كود:
0 UNION SELECT 1,2,database()


بعدها عن طريق الاستعالام التالي بامكاننا نعرف اسماء الجداول اللي موجوده بقاعده البيانات اللي عرفنا اسمها فوق
كود:
0 UNION SELECT 1,2,group_concat(table_name) FROM information_schema.tables WHERE table_schema = 'sqli_one'



طريقة ()group_concat لجمع أسماء الجداول , يعني بدلاً من عرض كل اسم جدول في صف منفرد سيتم جمعها في سلسلة واحدة بفاصلة

قاعدة البيانات ؛information_schema كل مستخدم في القاعدة عنده وصول لها ، وبتحتوي على معلومات عن كل القواعد والجداول اللي المستخدم عنده وصول الها
بالستعالام بنحكي لقاعده البيانات اعرضيلنا كل الجداول في قاعدة البيانات هاي sqli_one

جدول staff_users هو اللي بيهمنا لانو لحل التحدي بدو كلمة المرور الخاصه ب مارتن
بنقدر نستخدم قاعدة البيانات information_schema مرة تانية لنعرف بنية هذا الجدول باستخدام الاستعلام التالي :

كود:
0 UNION SELECT 1,2,group_concat(column_name) FROM information_schema.columns WHERE table_name = 'staff_users'


هادا شبيه بالاستعلام اللي قبل بس الفرق هو إنو المعلومات اللي بدنا نجيبها تغيرت من table_name ل column_name ، والجدول اللي بنستعلم عنه في قاعدة البيانات information_schema تغير من tables لـ columns ، وبنبحث عن أي صفوف فيها قيمة column_name هي staff_users .

هيك صار معنا هاي القيم

staff_users
usernamepasswordid


عن طريق group_concat بنقدر كمان نرجع كل الصفوف في سلسلة واحدة

لتسهيل القراءة زيدنا ,': لفصل اسم المستخدم عن كلمة المرور بدل ما تكون مفصولة بفاصلة اخترنا وسم '<br>' اللي بجبر كل نتيجة تطلع في سطر منفصل

كود:
0 UNION SELECT 1,2,group_concat(username,':',password SEPARATOR '<br>') FROM staff_users
مشاهدة المرفق 8398
عند ادخال الباسوورد

مشاهدة المرفق 8399




Blind SQLi - Authentication Bypass

مقارنة بحقن SQL In-Band ، حيث نستطيع رؤية نتائج هجومنا مباشرة على الشاشة
الـ Blind SQLi هو عندما لا نحصل على أي رد فعل أو تأكيد على نجاح أو فشل الاستعلامات التي حققناها ، لأن رسائل الخطأ تم تعطيلها ولكن الحقن لا يزال يعمل على الرغم من ذلك

أحد أبسط تقنيات حقن Blind SQL هو عند تخطي طرق المصادقة مثل نماذج تسجيل الدخول في هذه الحالة لسنا مهتمين كثيرًا بجلب البيانات من قاعدة البيانات بل نريد فقط تخطي عملية تسجيل الدخول

غالبًا ما يتم تطوير نماذج تسجيل الدخول التي تتصل بقاعدة بيانات المستخدمين بطريقة تجعل التطبيق على الويب ليس مهتمًا بمحتوى اسم المستخدم وكلمة المرور بقدر ما هو مهتم بمطابقة الزوجين في جدول المستخدمين ببساطة يطلب التطبيق على الويب من قاعدة البيانات هل لديك مستخدم بالاسم bob وكلمة المرور bob123؟ وتجيب قاعدة البيانات بنعم أو لا (صحيح/خطأ) ويعتمد ذلك الجواب على ما إذا كان التطبيق على الويب يسمح لك بالمتابعة أم لا.

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

مثال

يمكننا رؤية في المربع أن الاستعلام إلى قاعدة البيانات هو الآتي :


كود:
select * from users where username='' and password='' LIMIT 1;

لجعل هذا الاستعلام يعود دائمًا بقيمة صحيحة، يمكننا إدخال الآتي في حقل كلمة المرور :


كود:
' OR 1=1;--

الذي يحول الاستعلام SQL إلى الآتي :

كود:
select * from users where username='' and password='' OR 1=1;

بما أن 1=1 عبارة صحيحة وقد استخدمنا عامل OR ، فسيؤدي هذا دائمًا إلى عودة الاستعلام بقيمة صحيحة من ذلك يفهم التطبيق على الويب بأن قاعدة البيانات وجدت زوجًا صحيحًا لاسم المستخدم/كلمة المرور وينبغي السماح بالوصول.


بعد ادخالها

مشاهدة المرفق 8402مشاهدة المرفق 8401


Blind SQLi - Boolean
هو يعني الرد اللي برجعلنا بكون إما صح أو غلط يعني ما فيه وسط , هاد بفيدنا نشوف إذا كانت الـ Injection اللي عملناها نجحت ولا لأ

مثال
الـ URL زي هيك في الصفحة بظهر {"taken":true} الموقع بتحقق إذا كان اسم المستخدم مستخدم بالفعل أو لا
(حول اسم المستخدم الى admin123 )

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

علشان نكمل الطريق لازم نحلل الردود ونستخدم الاستعلامات بطريقة متسلسلة


الان مثل ما عملنا قبل
كود:
' UNION SELECT 1;--
بعطيني رساله خطأ ان الـ select الاعمده فيها مش مثل العدد بالـ UNION
بنجرب زي ما عملنا قبل لنوصل لنتيجه دون هاد الخطأ يكون عدد الاعمده هو 3

الآن بدنا نطلع اسم قاعدة البيانات عن طريق الـ '%' like سبق واستخدمناها فوق


اكيد راح يعطيك true لانو لسا ما عرفنا الاسم وهاي بتعني انو ممكن تكون اي حرف
بنجرب اكثر من حرف وعلامه حتى نوصل للأسم sqli_three

بعدها زي ما عملنا قبل بنقعد نجرب حتو نوصل لاسم الجدول

عن طريق الادخال التالي
كود:
admin123' UNION SELECT 1,2,3 FROM information_schema.tables WHERE table_schema = 'sqli_three' and table_name like '%';--

بعد التجربه مكان الـ '%' نجد اسم الجدول هو users

نقوم بتكرار العمليه لكن على الباسورد الخاص بالمستخدم admin عن طريق الادخال التالي
كود:
admin123' UNION SELECT 1,2,3 from users where username='admin' and password like 'a%

بعد التجريب والمحاوله عن طريق الـ true والـ false نجد ان كلمه السر هي 3845




Blind SQLi - Time Based



هون مافي شي بعطيك إشارة واضحة إذا الاستعلام اللي بترسلو صح أو لأ , الشيء الوحيد إللي بعرفك إذا الاستعلام صح هو وقت الاستجابة للطلب يعني لو الاستعلام صح بوخذ وقت أطول ليتم استكماله وهذا الوقت الزائد بكون بسبب استخدام وظائف جاهزة زي SLEEP(x) جنبا إلى جنب مع عبارة UNION

يعني على سبيل المثال إذا كنت بدك تعرف كم عدد الأعمدة في جدول معين بتستخدم الاستعلام التالي :

كود:
admin123' UNION SELECT SLEEP(5);--

إذا ما في أي توقف في وقت الاستجابة يعني الاستعلام مش صح فبتضيف عمود ثاني لحتى تجرب :

كود:
admin123' UNION SELECT SLEEP(5),2;--

هون بتوقع بتحصل على توقف لمدة 5 ثواني في الاستجابة، يعني تأكيد على نجاح الاستعلام وأن في عندك عمودين.


وبعدين بتقدر تكرر هالعملية على كل الأعمدة وتحصل على كل المعلومات اللي بدك توصللها

بعد التجربه نجد ان اسم الـ database هو sqli_four

الان مثل ما عملنا بالاعلى نفعل هنا

كود:
admin123' UNION SELECT SLEEP(5),2 FROM information_schema.tables WHERE table_schema = 'sqli_four' and table_name like '%';--

بعد التجربه مكان الـ '%' نجد اسم الجدول هو users

نقوم بتكرار العمليه لكن على الباسورد الخاص بالمستخدم admin عن طريق الادخال التالي
كود:
admin123' UNION SELECT SLEEP(5),2 from users where username='admin' and password like '%

بعد التجريب والمحاوله عن طريق الـزمن ( اذا اخذ وقت فهذا يعني ان الادخال الذي ادخلته هو صحيح ) نجد ان كلمه السر هي 4961

Out-of-Band



الـ Out-of-Band غير شائع زي SQL Injection العادي ، هون بعتمد على ميزات معينة مفعلة ( على السيرفر الخاص بـ قاعدة البيانات ) اللي بعمل مكالمة لشبكة خارجية بناءً على نتيجة الاستعلام

الهجوم هاد بيتميز بان فيه قناتين اتصال مختلفتين ، واحدة لتنفيذ الهجوم والتانية لجمع النتائج

على سبيل المثال قناة التنفيذ ممكن تكون طلب ويب وقناة جمع البيانات تكون رصد لطلبات HTTP/DNS

  1. الهاكر بيبعت طلب لموقع ويب فيه ثغرة SQL Injection باستخدام داتا معدلة.
  2. موقع الويب بعمل استعلام SQL لقاعدة البيانات ببعت الداتا المعدلة للهاكر
  3. الداتا المعدلة فيها طلب يقوم بعمل طلب HTTP راجع لجهاز الهاكر فيه البيانات من قاعدة البيانات




حل امثله على الـ SQL Injection
ما شاء الله ✨
الله يعطيك العافية
 
يعطيك الف عافية بحس كان لازم نزلت شرحه قبل ما اسلم المشروع تبعه 😂كان فهمت تفاصيله اكتر شرح جبار الصراحة 🙏🏻 مشكور
 
يعطيك الف عافية بحس كان لازم نزلت شرحه قبل ما اسلم المشروع تبعه 😂كان فهمت تفاصيله اكتر شرح جبار الصراحة 🙏🏻 مشكور
دايما الاشياء اللي منيح فيها بخليها براحتي بعملها 😅:ROFLMAO:
 

آخر المشاركات

فانوس

رمضان
عودة
أعلى