Skip to content
KitploitKITPLOIT
أدواتعمليات الاستغلالالمدونة
Log in
إرسال
أدواتعمليات الاستغلالالمدونة
إرسال

أدوات الاختراق واختبار الاختراق والأمن السيبراني لترسانتك الأمنية!

Kitploit هو دليل لأدوات الاختراق والأمن السيبراني واختبار الاختراق. اكتشف آخر تحديثات المشاريع للعثور على الثغرات وتحليل الأنظمة وأتمتة الاختبارات وتعزيز أمنك.

··الخلاصات·اتصال·الخصوصية·© 2026 Kitploit

دليل الأدوات

الفئات

عرض جميع الفئات
Loading categories
CVE-2023-39361 — تحليل خطوة بخطوة وإعداد مختبر لـ CVE-2023-39361، حقن SQL غير مصادق عليه في Cacti v1.2.24، مع دليل استغلال وتخفيف. | Kitploit
أدوات/GitHubGitHub/hpt-intern-task-submission/cve-2023-39361
تحليل الثغرات الأمنيةالاستغلالاستغلال تطبيقات الويبالتعلم والتعليممختبرات وتدريب عملي
GitHubhpt-intern-task-submission/cve-2023-39361

CVE-2023-39361

تحليل خطوة بخطوة وإعداد مختبر لـ CVE-2023-39361، حقن SQL غير مصادق عليه في Cacti v1.2.24، مع دليل استغلال وتخفيف.

عرض المستودع
10منذ 2 سنواتلم تتم المراجعة بعد

الأكثر شعبية

عرض الكل →

اكتشف الأدوات الأكثر استخدامًا من قبل مجتمعنا.

استكشف جميع الأدوات

تصفح مجموعتنا من الأدوات

عرض جميع الأدوات →
مشاركة

[CVE-2023-39361] حقن SQL غير موثَّق في Cacti الإصدار 1.2.24

نظرة عامة

Cacti هي أداة مراقبة تشغيلية مفتوحة المصدر مكتوبة بلغة PHP وMySQL/MariaDB، وتوفر واجهة سهلة الاستخدام. تم اكتشاف الثغرة الأمنية في عام 2023 والتي أثرت على جميع الإصدارات قبل 1.2.24. يكمن هذا الخلل الأمني في التنفيذ غير السليم عند إدخال القيم في استعلام SQL. هذه ثغرة حقن SQL حرجة تسمح للمهاجمين بـ تعديل قاعدة البيانات وكذلك تنفيذ الأكواد عن بُعد.

إعداد المختبر:

في هذا التحليل، سأقوم بتشغيل Cacti في Docker للتبسيط. أولاً، سنقوم بإنشاء ملف docker-compose.yml كما هو موضح أدناه وتشغيل الأمر docker-compose up -d.

version: '3.5'

services:

  
  

cacti:

image: "smcline06/cacti"

container_name: CVE-2023-39361

domainname: example.com

hostname: cacti

ports:

- "80:80"

- "443:443"

environment:

- DB_NAME=cacti_master

- DB_USER=cactiuser

- DB_PASS=cactipassword

- DB_HOST=db

- DB_PORT=3306

- DB_ROOT_PASS=rootpassword

- INITIALIZE_DB=1

- TZ=America/Los_Angeles

volumes:

- cacti-data:/cacti

- cacti-spine:/spine

- cacti-backups:/backups

links:

- db

  
  

db:

image: "mariadb:10.3"

container_name: CVE-2023-39361_db

domainname: example.com

hostname: db

ports:

- "3306:3306"

command:

- mysqld

- --character-set-server=utf8mb4

- --collation-server=utf8mb4_unicode_ci

- --max_connections=200

- --max_heap_table_size=128M

- --max_allowed_packet=32M

- --tmp_table_size=128M

- --join_buffer_size=128M

- --innodb_buffer_pool_size=1G

- --innodb_doublewrite=ON

- --innodb_flush_log_at_timeout=3

- --innodb_read_io_threads=32

- --innodb_write_io_threads=16

- --innodb_buffer_pool_instances=9

- --innodb_file_format=Barracuda

- --innodb_large_prefix=1

- --innodb_io_capacity=5000

- --innodb_io_capacity_max=10000

environment:

- MYSQL_ROOT_PASSWORD=rootpassword

- TZ=America/Los_Angeles

volumes:

- cacti-db:/var/lib/mysql

  
  

volumes:

cacti-db:

cacti-data:

cacti-spine:

cacti-backups:

بعد بناء الحاوية، يمكننا الوصول إلى Cacti عن طريق التصفح إلى http://localhost:80. الخطوة التالية هي تحديث Cacti إلى الإصدار 1.2.24. يمكنك تنزيل سكريبت التحديث من هنا: https://pastebin.com/NfRiHLjR. احفظ الملف في نفس الدليل مع ملف docker-compose.yml وأعد تسميته إلى upgrade_cacti.sh. ثم قم بتشغيل هذين الأمرين:

docker cp upgrade_cacti.sh CVE-2023-39361:/tmp/upgrade_cacti.sh && docker exec -it CVE-2023-39361 bash -c "bash /tmp/upgrade_cacti.sh"

الآن نحن جاهزون، دعنا نتعمق في الشفرة لنرى ما حدث الذي سمح لنا بهجوم حقن SQL. الملف المعرض للخطر هو graph_view.php ونحتاج فقط إلى مستخدم ضيف للوصول إلى هذا الملف، مما يؤدي إلى السماح للجميع باستغلال هذه الثغرة. في هذا الملف، الدالة غير الآمنة هي grow_right_pane_tree().

grow_right_pane_tree

قبل أن نتعمق في هذه الدالة، نحتاج إلى تتبع المسار العكسي لمعرفة كيف يتم تنفيذ الدوال.

<?php
switch (get_nfilter_request_var('action')) {
//.... 
// حالات أخرى كثيرة
case  'tree_content':
	//..... بعض الشيفرات هنا
	// ---------
	if (isset_request_var('node')) {
		$parts = explode('-', sanitize_search_string(get_request_var('node')));
		// التحقق من مرساة الشجرة
		if (strpos(get_nfilter_request_var('node'), 'tree_anchor') !== false) {
			$tree_id = $parts[1];
			$node_id = 0;
		} 
	//..... بعض الشيفرات هنا

	if ($tree_id > 0) {
		if (!is_tree_allowed($tree_id)) {
			header('Location: permission_denied.php');
			exit;
		}
		// يتم استدعاء الدالة المعرضة للخطر هنا
		grow_right_pane_tree($tree_id, $node_id, $hgdata);
	}

من مقتطف الشفرة أعلاه، يمكننا أن نرى أن الدالة سيتم تنفيذها إذا كان $tree_id > 0. يمكن شرح جميع الخطوات على النحو التالي:

  • أولاً، يقوم البرنامج بأخذ قيمة معامل action من إدخال المستخدم والدخول في جملة switch/case.

  • في حالة tree_content، تأخذ الشفرة معامل الطلب node من المستخدم. بعد ذلك، تقوم بتقسيم الإدخال بواسطة الحرف -، وحفظه في $part وأخيراً التحقق مما إذا كان tree_anchor موجوداً في node. إذا تم استيفاء جميع الشروط، سيتم تعيين $tree_id كعنصر ثانٍ في $part. على سبيل المثال، tree_content-1 أو 1-2-tree_content ستكون صالحة وستكون قيمة $tree_id على التوالي.

من هذه النقطة، سيبدو عنوان URL الخاص بنا هكذا: http://localhost:80?action=tree_content&node=tree_anchor-1. الآن حان الوقت لتحليل الدالة grow_right_pane_tree() لاستغلال الخلل.

grow_right_pane_tree_analyze

المعامل المعرض للخطر هو rfilter والذي يتم تمريره مباشرة إلى عامل RLIKE داخل جملة WHERE. ما يجعله عرضة للخطر هو أن rfilter محاط بعلامتي اقتباس مزدوجة "، ومع ذلك يتم التحقق من المعامل بواسطة الدالة html_validate_tree_vars()، والتي تبدو هكذا:

function  html_validate_tree_vars() {
/* ================= التحقق من الإدخال وتخزين الجلسة ================= */
$filters = array(
	// .......
	'rfilter' => array(
			'filter' => FILTER_VALIDATE_IS_REGEX,
			'pageset' => true,
			'default' => '',
			),
	// ..........
	);

	validate_store_request_vars($filters, 'sess_grt');
	/* ================= التحقق من الإدخال ================= */
	// ........
}

تم تعيين نوع الفلتر الخاص بـ rfilter إلى FILTER_VALIDATE_IS_REGEX وتخزينه داخل $filters، ثم يتم تمرير $filter إلى الدالة validate_store_request_vars(). دعنا نتعمق في هذه الدالة، سيكشف هذا باقي تحليلنا:

function validate_store_request_vars($filters, $sess_prefix = '') {
	// .......
	if (cacti_sizeof($filters)) {
		foreach($filters as $variable => $options) {
		// ....
		elseif ($options['filter'] == FILTER_VALIDATE_IS_REGEX) {
					if (is_base64_encoded($_REQUEST[$variable])) {
						$_REQUEST[$variable] = base64_decode($_REQUEST[$variable]);
					}
					$valid = validate_is_regex($_REQUEST[$variable]);
					if ($valid === true) {
						$value = $_REQUEST[$variable];
					} else {
						$value = false;
						$custom_error = $valid;
					}
				}
// ........
function validate_is_regex($regex) {
// ........
    if (@preg_match("'" . $regex . "'", NULL) !== false) {
		ini_set('track_errors', $track_errors);
		return true;
	}

الدالة validate_store_request_vars() مسؤولة عن التحقق من صحة إدخال المستخدم. عندما يكون نوع filter هو FILTER_VALIDATE_IS_REGEX، تستدعي الدالة validate_is_regex() مع الدالة preg_match للتحقق مما إذا كان إدخالنا صالحاً. وفقاً لوثائق PHP:

preg_match() ترجع 1 إذا كان النمط يطابق الموضوع المحدد، و0 إذا لم يطابق، أو false عند الفشل.

تستخدم جملة if مقارنة صارمة مما يعني أنه فقط عند حدوث خطأ لا يمكننا الدخول إلى جملة if. إن $regex، وهو إدخالنا، محاط بين علامتي اقتباس مفردة '. كان نية المطورين تجنب قيام المستخدم بحقن علامة الاقتباس المفردة '، والتي غالباً ما تستخدم لبدء هجوم حقن SQL. يبدو هذا وكأنه تنفيذ أمني قوي، لكن دعنا نلقي نظرة مرة أخرى على كيفية تمرير rfilter إلى جملة WHERE:

$sql_where  .=  ' (gtg.title_cache RLIKE "'  .  get_request_var('rfilter') .  '" OR gtg.title RLIKE "'  .  get_request_var('rfilter') .  '")';

آه، لقد أصبح جهد التحقق من صحة إدخال المستخدم بلا معنى حيث أن rfilter محاط بعلامات اقتباس مزدوجة "، مما يسمح للمهاجمين بحقن " بسهولة للخروج من الجملة.

بعد أن فهمنا لماذا هي عرضة للخطر، سنتعمق الآن في الاستعلام حيث يتم تمرير $sql_where إليه.

grow_right_pane_tree_analyze

بعد تعيين $sql_where، سيقوم البرنامج باستدعاء الدالة get_allowed_tree_header_graphs(). ستبدو الدالة هكذا:

تنزيل الأداة