สิ่งที่ทราบเกี่ยวกับแบ็กดอร์ xz Utils ที่เกือบทำให้ทั้งโลกติดเชื้อ
(arstechnica.com)- Andres Freund จาก Microsoft ตรวจสอบ ความผิดปกติด้านประสิทธิภาพของ SSH บนระบบ Debian แล้วพบแบ็กดอร์ที่ฝังอยู่ใน xz Utils ซึ่งถูกใช้ในสภาพแวดล้อมตระกูล Linux/Unix แทบทั้งหมด
- โค้ดอันตรายถูกใส่ไว้ใน xz Utils 5.6.0 และ 5.6.1 และถูกออกแบบให้ผู้โจมตีที่มีคีย์ส่วนตัวเฉพาะสามารถซ่อนโค้ดไว้ในใบรับรองสำหรับล็อกอิน SSH แล้วรันบนอุปกรณ์ที่มีแบ็กดอร์ได้
- ผู้โจมตีพยายามใช้ release tarball แทนซอร์สบน GitHub รวมถึงไฟล์ทดสอบ สคริปต์บิลด์ และ glibc IFUNC เพื่อ hook routine การยืนยันตัวตนของ sshd ผ่าน liblzma
- แบ็กดอร์ตรวจสอบเงื่อนไขการบิลด์แพ็กเกจ เช่น amd64/x86_64, glibc และตระกูล Debian หรือ Red Hat และถูกใส่ใน Fedora Rawhide, Fedora 41, Debian testing/unstable/experimental, openSUSE Tumbleweed/MicroOS และบางรีลีสของ Kali Linux ในช่วงหนึ่ง
- persona ของนักพัฒนาที่ชื่อ Jia Tan มีส่วนร่วมกับการดูแล xz Utils มาหลายปี เหตุการณ์นี้ถูกติดตามในชื่อ CVE-2024-3094 และมีเครื่องมือตรวจจับ/วิเคราะห์ออกมา เช่น หน้าตรวจสอบของ Binarly และ xzbot
การค้นพบและขอบเขตผลกระทบ
- Andres Freund เป็นนักพัฒนาและวิศวกรที่ทำงานเกี่ยวกับ PostgreSQL ที่ Microsoft เขาพบสัญญาณผิดปกติขณะตรวจสอบเหตุที่ การล็อกอิน SSH บนระบบ Debian ใช้ CPU มากเกินไปและเกิดข้อผิดพลาด valgrind
- สาเหตุคือการอัปเดต xz Utils และ Freund เปิดเผยใน Open Source Security List ว่าการอัปเดตนี้เป็น แบ็กดอร์ ที่จงใจฝังไว้ในซอฟต์แวร์บีบอัดข้อมูล
- xz Utils ให้ความสามารถบีบอัดและแตกข้อมูลแบบไม่สูญเสียข้อมูลบนระบบปฏิบัติการตระกูล Unix แทบทั้งหมด รวมถึง Linux และยังรองรับรูปแบบ legacy .lzma ด้วย
- Filippo Valsorda ประเมินว่า นี่อาจเป็น “กรณีตัวอย่างที่ถูกดำเนินการได้ดีที่สุดของการโจมตี supply chain ที่มีการอธิบายต่อสาธารณะ และเป็นสถานการณ์ฝันร้ายของ upstream ที่มุ่งร้าย มีความสามารถ และมีสิทธิ์ในไลบรารีที่ใช้กันอย่างแพร่หลาย”
พฤติกรรมที่แบ็กดอร์ตั้งใจโจมตี
- โค้ดอันตรายถูกเพิ่มเข้าไปใน xz Utils 5.6.0 และ 5.6.1 เพื่อเปลี่ยนวิธีทำงานของซอฟต์แวร์
- แบ็กดอร์ปรับแต่ง sshd ซึ่งเป็นไฟล์ปฏิบัติการที่ใช้สำหรับการเชื่อมต่อ SSH ระยะไกล
- ผู้ที่มีคีย์เข้ารหัสที่กำหนดไว้ล่วงหน้าสามารถซ่อนโค้ดที่ต้องการไว้ในใบรับรองสำหรับล็อกอิน SSH อัปโหลดใบรับรองนั้น แล้วรันโค้ดบนอุปกรณ์ที่มีแบ็กดอร์ได้
- ยังไม่พบโค้ดที่ถูกอัปโหลดจริง จึงไม่ทราบว่าผู้โจมตีพยายามรันโค้ดใด
- ในทางทฤษฎี อาจทำได้แทบทุกอย่าง รวมถึงขโมยคีย์เข้ารหัสหรือติดตั้งมัลแวร์
เส้นทางที่ไลบรารีบีบอัดไปถึง SSH
- ไลบรารีสามารถปรับแต่งการทำงานภายในของไฟล์ปฏิบัติการที่ลิงก์กับมันได้
- implementation ของ sshd ใน OpenSSH ที่เป็นที่รู้จักโดยทั่วไปไม่ได้ลิงก์กับ liblzma ตามค่าเริ่มต้น
- Debian และ Linux distribution หลายตัวเพิ่มแพตช์ที่เชื่อม sshd เข้ากับ systemd
- systemd เป็นโปรแกรมที่โหลดบริการหลายอย่างระหว่างการบูต
- systemd ลิงก์กับ liblzma
- เส้นทางการเชื่อมต่อนี้ทำให้ xz Utils สามารถส่งผลต่อ sshd ได้
ร่องรอยการเตรียมการตลอดหลายปี
- ในปี 2021 ผู้ใช้ชื่อ JiaT75 ทำ commit แรกที่เป็นที่รู้จักในโปรเจกต์โอเพนซอร์ส
- เป็นการเปลี่ยนฟังก์ชัน safe_fprint ในโปรเจกต์ libarchive ไปเป็น variant ที่รู้กันมานานว่าปลอดภัยน้อยกว่า และไม่มีใครสังเกตเห็นในตอนนั้น
- ในปี 2022 JiaT75 ส่งแพตช์ไปยัง mailing list ของ xz Utils
- ไม่นานหลังจากนั้น ผู้ร่วมใหม่ชื่อ Jigar Kumar กดดันว่า Lasse Collin ไม่ได้อัปเดต xz Utils บ่อยหรือเร็วพอ
- Dennis Ens และผู้ร่วมใหม่คนอื่น ๆ ก็กดดันให้ Collin เพิ่มผู้ดูแลรักษาเข้ามา
- ในเดือนมกราคม 2023 JiaT75 ทำ commit แรกใน xz Utils และมีส่วนร่วมกับงานของ xz Utils ลึกขึ้นภายใต้ชื่อ Jia Tan
- เปลี่ยนข้อมูลติดต่อของ Collin ใน oss-fuzz เป็นข้อมูลติดต่อของตนเอง
- ขอให้เปลี่ยนแปลงเพื่อปิดใช้ ฟีเจอร์ IFUNC ระหว่างการทดสอบของ oss-fuzz ทำให้ตรวจไม่พบการเปลี่ยนแปลงอันตรายที่จะถูกใส่ใน xz Utils ภายหลัง
- ในเดือนกุมภาพันธ์ 2024 Tan ทำ commit สำหรับ xz Utils 5.6.0 และ 5.6.1 และการอัปเดตนี้เป็นตัวติดตั้งแบ็กดอร์
- หลังจากนั้น Tan หรือคนอื่น ๆ ขอให้นักพัฒนา Ubuntu, Red Hat และ Debian รวมการอัปเดตดังกล่าวเข้าไปในระบบปฏิบัติการ
distribution ที่รวมไว้และเงื่อนไขการทำงาน
- ตามข้อมูลของ Tenable เวอร์ชันแบ็กดอร์หรือการอัปเดตที่เกี่ยวข้องถูกใส่ในรีลีสต่อไปนี้
- Fedora Rawhide: distribution สำหรับพัฒนาของ Fedora Linux
- Fedora 41
- Debian testing, unstable, experimental: ตั้งแต่ 5.5.1alpha-0.1 ถึง 5.6.1-1
- openSUSE Tumbleweed และ openSUSE MicroOS: รวมเวอร์ชัน xz ที่มีแบ็กดอร์ตั้งแต่ 7 มีนาคมถึง 28 มีนาคม
- Kali Linux: รวม xz-utils 5.6.0-0.2 ตั้งแต่ 26 มีนาคมถึง 28 มีนาคม
- จากการวิเคราะห์ของ Sam James สคริปต์อันตรายตรวจสอบว่าเป้าหมายการบิลด์เป็น amd64/x86_64 หรือไม่ ใช้ชื่อ linux-gnu หรือไม่ และใช้ GCC กับ GNU ld หรือไม่
- นอกจากนี้ยังตรวจสอบว่าเป็นการบิลด์แพ็กเกจ Debian หรือ RPM_ARCH เป็น x86_64 หรือไม่
- การโจมตีดูเหมือนมุ่งเป้าไปที่สภาพแวดล้อมที่ใช้ glibc บนระบบ amd64 และบิลด์ distribution ที่สืบทอดจาก Debian หรือ Red Hat
- ขณะนั้นยังไม่ทราบว่าระบบอื่นมีช่องโหว่หรือไม่
วิธี implementation และเทคนิคซ่อนตัว
- Sam James สรุปว่าแบ็กดอร์ประกอบด้วยหลายส่วน
- release tarball ที่ upstream แจกจ่ายไม่เหมือนกับโค้ดบน GitHub
- build-to-host.m4 ใน release tarball แตกต่างจากของ upstream บน GitHub อย่างมาก
- ในโฟลเดอร์ tests/ ของ git repository มีไฟล์ทดสอบที่ถูกดัดแปลง
tests/files/bad-3-corrupt_lzma2.xztests/files/good-large_compressed.lzma
- สคริปต์ที่ build-to-host.m4 เรียกจะคลายข้อมูลทดสอบอันตรายและแก้ไขกระบวนการบิลด์
- IFUNC ของ glibc ถูกใช้เพื่อ hook หรือ redirect routine การยืนยันตัวตนของ OpenSSH ตอน runtime
- HD Moore ยืนยันว่าขั้นสุดท้ายของแบ็กดอร์จะทำงานเฉพาะเมื่อบิลด์ไลบรารีบน amd64 และสร้างแพ็กเกจ Debian หรือ RPM เท่านั้น
- จากการวิเคราะห์ของนักวิจัย หากในกระบวนการตรวจสอบ public key ของ SSH มีฟังก์ชัน fingerprint และ public key เฉพาะที่ตรงกัน ก็จะถอดรหัสเนื้อหาของคีย์ด้วยคีย์ที่แชร์กันไว้ล่วงหน้าก่อนตรวจสอบ public key จริง
- หากเนื้อหาที่ถอดรหัสตรงกับรูปแบบเฉพาะ จะถูกส่งตรงไปยัง
system - หาก fingerprint ไม่ตรงกัน หรือเนื้อหาที่ถอดรหัสไม่ตรงรูปแบบ ก็จะกลับไปใช้การตรวจสอบคีย์ตามปกติ ทำให้ผู้ใช้สังเกตความแตกต่างได้ยาก
execution chain ที่ Akamai สรุป
- นักวิจัยของ Akamai มองว่าแบ็กดอร์ถูกใส่ไว้เฉพาะใน ซอร์สโค้ด tarball release ไม่ใช่ใน GitHub repository ของ xz เพื่อหลีกเลี่ยงการตรวจจับ
- แบ็กดอร์ถูกประกอบขึ้นผ่านหลาย commit
- ใช้ IFUNC ระหว่างกระบวนการบิลด์เพื่อให้มัลแวร์ดักฟังก์ชัน symbol resolution ได้
- ซ่อน shared object ที่ถูกทำให้อ่านยากไว้ในไฟล์ทดสอบ
- รันสคริปต์ที่ดึง shared object ออกมาระหว่างกระบวนการบิลด์ไลบรารี
- ปิดใช้ landlocking ซึ่งเป็นฟีเจอร์ความปลอดภัยที่จำกัดสิทธิ์ของ process
- execution chain ดำเนินต่อหลายขั้น
build-to-host.m4ถูกเรียกระหว่างการบิลด์ไลบรารี และ decodebad-3-corrupt_lzma2.xzเป็น bash script- bash script นี้ decode
good-large_compressed.lzmaด้วยวิธีที่ซับซ้อนกว่าเพื่อสร้างสคริปต์อีกตัว - สคริปต์นั้นดึง shared object
liblzma_la-crc64-fast.oออกมา และเพิ่มเข้าไปในกระบวนการคอมไพล์ liblzma
- shared object นี้ถูกคอมไพล์เข้าไปใน liblzma และแทนที่กระบวนการ resolve ชื่อฟังก์ชันตามปกติ
- ไลบรารีอันตรายสามารถเปลี่ยน function pointer ของ
RSA_public_decryptใน OpenSSH ให้เป็นฟังก์ชันอันตรายที่สร้างขึ้นเองได้ - จากการวิเคราะห์ของ Filippo Valsorda ฟังก์ชันอันตรายนี้ดึงคำสั่งจากใบรับรองของไคลเอนต์ที่ยืนยันตัวตน ตรวจสอบว่าเป็น threat actor แล้วส่งต่อให้
system()เพื่อทำ remote code execution ก่อนการยืนยันตัวตน
Jia Tan และคำถามที่ยังเหลือ
- มีข้อมูลเกี่ยวกับ Jia Tan น้อยมาก
- persona ของนักพัฒนารายนี้มีส่วนเกี่ยวข้องกับซอฟต์แวร์โอเพนซอร์สอื่นอีกหลายสิบรายการในช่วงไม่กี่ปีที่ผ่านมา
- ยังไม่ทราบว่าหลังชื่อผู้ใช้ Jia Tan มีบุคคลจริงอยู่หรือเป็นตัวตนที่ถูกสร้างขึ้นทั้งหมด
- การวิเคราะห์ทางเทคนิคเพิ่มเติมดูได้จากเธรด Bluesky ของ Filippo Valsorda, การวิเคราะห์ของ Kevin Beaumont และเอกสารเปิดเผยของ Freund เมื่อวันศุกร์
CVE และเครื่องมือตรวจสอบ
- รหัสติดตามของช่องโหว่นี้คือ CVE-2024-3094
- หน้า xz.fail ของ Binarly ตรวจจับ implementation ของ IFUNC และอิงจากการวิเคราะห์พฤติกรรม
- สามารถตรวจจับเงื่อนไขคงที่โดยอัตโนมัติได้แม้มีแบ็กดอร์คล้ายกันถูกฝังที่อื่น
- xzbot มีฟังก์ชันสำหรับวิเคราะห์และทดลอง
- honeypot: เซิร์ฟเวอร์ช่องโหว่ปลอมสำหรับตรวจจับความพยายาม exploit
- ed448 patch: แพตช์
liblzma.soให้ใช้ public key ED448 ของตนเอง - backdoor format: รูปแบบ payload ของแบ็กดอร์
- backdoor demo: CLI ที่ trigger RCE โดยสมมติว่ารู้ private key ED448
1 ความคิดเห็น
ความคิดเห็นจาก Hacker News
เป้าหมายคือทำให้การเขียนเทสต์ของ XZ ง่ายขึ้นด้วยการใช้ เฟรมเวิร์กการทดสอบแบบมาตรฐาน
Jia เคยเขียนไว้เมื่อ 2022-06-17 ว่ายังมีฟีเจอร์ที่ยังไม่ได้ทดสอบอีกมาก และสิ่งนี้น่าจะช่วยเพิ่มจำนวนเทสต์เพื่อเสถียรภาพของโปรเจ็กต์ในระยะยาวได้
จึงนับเป็นการเปลี่ยนแปลงที่เตรียมการกันมานานแล้ว
ดูเหมือนจะยังไม่มีการพูดถึง กลไกการลิงก์ ที่ทำให้ lib สามารถสอดแทรกเข้าไปใน
RSA_public_decryptได้มากนักมีการพูดถึงเรื่องอย่างการแยกโปรเซสเยอะ แต่พูดถึงการรีไดเร็กต์การเรียกฟังก์ชันนั้นน้อยมาก
ถ้าเอาส่วนประกอบสำคัญอย่างโค้ดที่เข้ามาผ่าน SSH ไปเชื่อมกับไลบรารีด้วยความเชื่อถือแบบเป็นลำดับชั้น อาจสร้างโมเดลประมาณว่า “ฉันเชื่อถือ ณ จุดที่ฉันเรียกใช้ แต่ไม่อนุญาตให้มันสอดแทรกตัวเองจากจุดเรียกอื่น” ได้หรือเปล่า
แม้จะกระตุ้นปฏิกิริยาแบบสะท้อนกลับเรื่อง “security through obscurity” ว่าไม่มีความหมายเพราะยังมีทางเลี่ยงอยู่ แต่ก็ยังมองได้ว่าเป็นการ ลดพื้นผิวการโจมตี
แต่ในระบบปฏิบัติการมี security context หลายชั้นซ้อนกันอยู่ สำหรับกรณี XZ backdoor นั้นเกี่ยวกับความปลอดภัยแบบ capability-based ในระดับโมดูลเป็นหลัก แต่ก็ยังมี capability ระดับโปรแกรม การแยกระดับหน่วยความจำ (paging) และการแยกระดับไมโครสถาปัตยกรรมด้วย
การทำให้สิ่งเหล่านี้ทำงานร่วมกันพร้อมยังคงประสิทธิภาพไว้ได้เป็นเรื่องค่อนข้างยาก และการที่สาย Unix จะย้ายไปโมเดลแบบนี้ก็ดูแทบเป็นไปไม่ได้ เพราะต้องแทนที่แนวคิดเรื่องโปรเซสเสียเลย
สิ่งนี้ทำให้เทสต์ของ XZ พัง แล้วจู่ๆ ก็มีแอ็กเคานต์ที่เข้ามาวิ่งเต้นให้ปิดการใช้งานเทสต์นั้น ซึ่งสุดท้ายก็ทำให้ exploit เกิดขึ้นได้
./configure && make) เพื่อแพตช์ ifunc resolver และทำให้มันไปเรียกอ็อบเจ็กต์อันตรายที่เตรียมไว้ไฟล์อ็อบเจ็กต์ที่ถูกทำให้เสียหายจะถูกลิงก์พร้อมแฟล็กลิงเกอร์
nowทำให้ ifunc ถูก resolve ทันทีตอนโหลดไลบรารี และในจังหวะนั้นตารางลิงก์ของโปรเซสยังอยู่ในสถานะที่เขียนได้ จึงมีการเรียก resolver ที่ถูกแพตช์แล้วตรงนี้เองที่สำคัญ เพราะตอนที่ไลบรารีถูกโหลด มันสามารถดัก
RSA_public_decryptในหน่วยความจำได้ตรงๆบทความที่วิเคราะห์กระบวนการฝัง backdoor ได้ดีมาก: https://research.swtch.com/xz-script
dlopenกับไลบรารีบีบอัด: https://github.com/systemd/systemd/pull/31550ในแง่นั้นจึงเป็นวิธีลิงก์ที่ปลอดภัยกว่า
ltraceเพื่อ เฝ้าดูสัญลักษณ์ ที่ถูกเรียกก็น่าจะพอหรือไม่ไม่เข้าใจว่าทำไมถึงใช้คำว่า “เกือบ” ติดเชื้อไปทั่วโลก
อย่างน้อยก็มี Linux distribution ยอดนิยมพอสมควร 3 ตัวคือ Arch, Gentoo, openSUSE Tumbleweed ที่กระจาย backdoor นี้อยู่เป็นเวลาหลายสัปดาห์ และบน Tumbleweed ก็ยืนยันได้ว่ามันทำงานจริง
เมื่อมี SSH ที่ใส่ backdoor อยู่เป็นเวลาหลายสัปดาห์ คำว่า “เกือบ” จึงฟังดูเบาไป
มันทำงานได้เฉพาะบนเป้าหมายแบบ deb/rpm เท่านั้น ดังนั้นในทางปฏิบัติจึงเหมือนถูกหยุดไว้ก่อนถึง production
ไม่ได้แปลว่าโอเคนะ แต่ถ้ามันไม่ถูกพบจนมีเวลาหลุดเข้า RHEL หรือ Debian/Ubuntu stable ได้ สถานที่อย่างธนาคารหรือองค์กรด้านการแพทย์คงได้รับการแจ้งเตือนกันแล้ว
ถ้าเป็น remote code execution ก่อนยืนยันตัวตน ก็ยากจะพูดว่า “ไม่ได้รับผลกระทบ” เว้นแต่ว่าจะมีการจำกัดเครือข่ายอย่างเข้มงวดและมี flow logging ที่ดีมาก
ถ้าเปรียบเทียบ
liblzma.so.5.6.1ของxz-5.6.1-1กับxz-5.6.1-2ด้วยcmp -lจะเห็นความต่างเพียงเล็กน้อยมากดูเหมือนก่อนจะออกคำแนะนำจะยังไม่รู้เรื่องนี้
https://github.com/QubesOS/qubes-issues/issues/9067#issuecom...
แต่ก็ไม่รู้เหมือนกันว่าจะหาข้อมูลมายืนยันเรื่องนี้ได้อย่างไร
ผมขอเดิมพัน 101 ดอลลาร์ ว่าภายใน 12 เดือนข้างหน้า เราจะเจออะไรทำนองเดียวกันนี้ในสภาพแวดล้อมจริง
เพราะผู้ดูแลจะเริ่มย้อนกลับไปตรวจดู commit เก่าๆ ของกันและกันด้วยความสงสัย
แค่มองไปที่ codebase ที่สำคัญแต่ไม่ค่อยมีคนรู้จัก และมีผู้ดูแลน้อยมาก
ถ้าผมมีของแบบนี้และมันใช้งานได้ดี ผมคงให้มีการ “ค้นพบ” มันในภายหลังผ่านอีกแอ็กเคานต์หนึ่งแล้วค่อยแก้
ข้อสรุปส่วนตัวจากเหตุการณ์ครั้งนี้มีหลายข้อ
ข้อแรก source distribution tarball ที่บรรจุโค้ดต่างจาก source repository เป็นสิ่งที่ไม่ดีและควรถอยห่างจากมัน การโจมตี supply chain ใหญ่อีกครั้งอย่าง event-stream ก็อาศัยจุดคล้ายกัน
ผลตามมาคือ artifact ที่สร้างอัตโนมัติควรถูก commit ไว้เสมอ
ข้อสอง artifact ที่สร้างอัตโนมัติซึ่งทุกคนเลื่อนผ่านด้วย Page Down ในการ code review เป็นปัญหา ถ้ามีไฟล์แบบนี้อยู่ใน repository ก็ควรมี automated test ที่ตรวจด้วยว่ามีใครแก้ไขมันหรือไม่ และช่วยไม่ให้ปล่อยไฟล์ generated เก่าค้างไว้
ข้อสาม ซึ่งเป็นผลสรุปจากข้อ 1 และ 2 คือ autotools ไม่ดี และวัฒนธรรมของ autotools ก็ไม่ดี
ข้อสี่ Libsystemd เป็นปัญหาต่อ ecosystem พอพูดแบบนี้ก็มักจะถูกมองว่าเป็นพวกเกลียด systemd แต่มันทั้งใหญ่ ซับซ้อน มี dependency มาก และโปรแกรมส่วนใหญ่ก็ใช้เพียงส่วนน้อยมาก การสนับสนุนให้ทุก service ต้องพึ่งสิ่งนี้เพื่อการแจ้งเตือนการเริ่มต้นระบบเป็นเรื่องบ้าคลั่ง
ข้อห้า มีวัฒนธรรมหนึ่งที่มองว่าการ reuse โค้ดนั้นดีเสมอ และการพึ่งไลบรารีขนาดใหญ่เพราะต้องการฟังก์ชันเล็กน้อยก็ไม่เป็นไร แต่จริง ๆ ไม่ใช่แบบนั้น dependency คือภาระในการบำรุงรักษาและความเสี่ยงด้านความปลอดภัย จึงต้องชั่งน้ำหนักกับประโยชน์ที่ได้
ข้อหก การที่ผู้ดูแลแพ็กเกจของดิสโทรนำแพตช์ขนาดใหญ่มาใช้กับแพ็กเกจก็เป็นปัญหาเช่นกัน มันทำให้เกิด de facto fork ของไลบรารีและแอปพลิเคชันที่ถูกใช้อย่างแพร่หลาย โดยที่ผู้ดูแลตัวจริงไม่ได้ตรวจดู
ข้อเจ็ด ในมุมของนักพัฒนา OSS ต้อง ยั่งยืนทางการเงิน Liblzma และ xz-utils น่าจะถูกติดตั้งอยู่หลายสิบล้านครั้ง แต่กลับพึ่งพาผู้ดูแลเพียงคนเดียวที่กำลังเผชิญปัญหาสุขภาพจิต
ข้อแปด ถึงไม่อยากพูด แต่ตอนนี้ในการ review โค้ดและการถ่ายโอนสิทธิ์การบำรุงรักษา เราคงต้องมี การพิจารณาด้านภูมิรัฐศาสตร์ ด้วย
ไม่มีหลักฐานเลยว่า Jia Tan เป็นชื่อจริง และไม่มีแม้แต่หลักฐานว่าเป็นบุคคลที่มีตัวตนจริง
ถ้าโปรเจกต์ต่าง ๆ เริ่มไม่รับ contribution จากชื่อที่ฟังดูเป็นคนเอเชีย การโจมตีครั้งต่อไปก็แค่ใช้ชื่อ Richard Jones ก็พอ
ถ้ามาจากโลก BSD systemd นั้นชวนช็อก เป็นสัตว์ประหลาด และยื่นหนวดยุ่บยั่บไปทั่ว
ไม่ใช่แค่ผู้บริโภคที่ไร้เดียงสา แต่อุตสาหกรรมซอฟต์แวร์เองก็ไร้เดียงสาต่อภัยคุกคามด้านความปลอดภัย
social exploit ก็เป็นส่วนหนึ่งของ code exploit
หลักการของ FOSS ที่ว่า “ยิ่งมีคนช่วยดูโค้ดมากเท่าไรก็ยิ่งดี” นั้นจริง แต่จะใช้ได้ก็ต่อเมื่อดวงตาเหล่านั้นเป็นดวงตาที่ผ่านการฝึกฝน FOSS ต้องการการสนับสนุนเชิงวัตถุจากอุตสาหกรรม
วิศวกรของ MSFT เป็นคนจับ exploit นี้ได้ แต่ถึงอย่างนั้นมันก็ยังเข้าไปอยู่ในรุ่น public ปกติของ Fedora 41, openSUSE และ Kali
toolchain การพัฒนาและกระบวนการทดสอบไม่เคยถูกออกแบบมาเพื่อทดสอบความปลอดภัย ลองดู SolarWinds ด้วย: https://www.wired.com/story/the-untold-story-of-solarwinds-t...
release artifact ไม่ได้มีแค่ autoconf script
มีเหตุผลมากมายที่จะใส่ binary blob ลงใน release archive เช่น resource ของเกม, image ของเฟิร์มแวร์, test case เป็นต้น เคยมีคนพูดว่า mpv ใส่ media file บางส่วนที่สร้างด้วย encoder แบบ proprietary ไว้เป็น test case ซึ่งนั่นไม่ใช่เรื่องแย่ แต่เป็นเรื่องที่ดี
sqlite ที่ดูแลอย่างดีนั้นถูกใช้ไปทั่วทุกที่และมี test suite ที่ยอดเยี่ยม ในแต่ละ release มันแจก tarball ไม่ใช่หนึ่งแต่สองชุดตามขั้นตอนการคอมไพล์ การจะเลิกทำแบบนี้อาจไม่ยาก แต่มีแต่จะเพิ่มงานให้ผู้ดูแลแพ็กเกจ และไม่ได้ช่วยให้ความปลอดภัยดีขึ้น
เหตุที่ Debian สร้างจาก tarball ที่คัดสรรแล้ว ก็เพราะมันผ่านการคัดเลือกโดยมนุษย์และเซ็นด้วยกุญแจที่เป็นที่รู้จัก แน่นอนว่าจะ build จาก git ก็ได้ แต่ไม่แน่ชัดว่ามันจะทำให้สถานการณ์ดีขึ้นหรือไม่ ไม่ใช่ทุกโปรเจกต์จะเซ็น release tag และถึงจะเซ็น ก็มีแนวโน้มว่าจะเป็นกระบวนการอัตโนมัติมากกว่า
เราต้องการให้การเปลี่ยนแปลงถูกตรวจโดยผู้ดูแล upstream ก่อน แล้วค่อยโดยผู้ดูแลแพ็กเกจ และอยากให้ทั้งสองฝ่ายนี้เป็นอิสระต่อกัน
ครั้งนี้ผู้ดูแล upstream ที่ถูกทำให้เสียหายได้โจมตีกระบวนการนั้น แต่ไม่ได้แปลว่าเราควรกำจัดผู้ดูแล upstream ทิ้ง ช่วงหลายปีที่ผ่านมาโครงสร้างนี้ช่วยหยุดความพยายามฝัง backdoor ได้หลายครั้ง และไม่ใช่กระบวนการที่ควรถูกทิ้งโดยไม่มีการพิจารณาอย่างรอบคอบ
แนวทางการปรับปรุงที่พูดกันมาก็ยังเหมือนเดิม คือควรผลักดัน reproducible build ให้มากขึ้น ลด attack surface และความซับซ้อนของการ build เท่าที่ทำได้ และเชื่อใจผู้ดูแล แต่ก็ต้องตรวจสอบงานของพวกเขาด้วย
ตรงกันข้าม พวกเขาดูสับสนกับจุดนั้น และกำลังเพิ่มเอกสารเกี่ยวกับวิธีทำ datagram แบบเรียบง่ายโดยไม่ต้องใช้ libsystemd
จำนวนการติดตั้งของ liblzma และ xz-utils น่าจะมากกว่าหลายสิบล้านมาก ภาษาอย่าง Python, PHP, Ruby และอีกมากต่างพึ่ง libxml2 และ libxml2 ก็ใช้ liblzma ยังมี dependency อื่นอีกมาก
การพิจารณาด้านภูมิรัฐศาสตร์ไม่ใช่งานของผู้ดูแล OSS ถูกให้มาโดยไม่มีการรับประกัน
ยิ่งไปกว่านั้น “Jia Tan” อาจเป็นตัวตนปลอมทั้งหมดด้วยซ้ำ ดูจาก commit timestamp แม้แต่ในวันเดียวกัน timezone ก็สลับจากยุโรปตะวันออกไปเอเชีย อย่างน้อยก็ชัดเจนว่ามีการเล่น เกมเรื่องตัวตน อยู่
ไม่รู้มาก่อนเลยว่าคนที่พบปัญหานี้เป็นวิศวกร Microsoft ที่ทำงานกับ Azure Postgres
ขอบคุณ Microsoft ตอนนี้ Azure ดูดีขึ้นแล้ว
เพราะปัญหานี้ถูกพบด้วยวิธีนั้น
จากนั้นก็ดูไลบรารีที่เป็นปัญหา และค้นหาความผิดปกติคล้ายกันที่ persona ปลอมเข้ายึดโปรเจกต์
ดูเหมือนการเพิกเฉยต่อข้อผิดพลาดแบบนี้จะเป็นเรื่องปกติเสียด้วย
ทนวิธีห่อเรื่องแบบนี้ไม่ได้จริง ๆ
ดูเหมือนว่าผู้ดูแลเดิมของ xz จะส่งต่อความรับผิดชอบให้ Jia Tan โดยไม่เคยพบตัวจริงหรืออย่างน้อยก็ไม่เคยคุยโทรศัพท์กันโดยตรง
เลยสงสัยว่าการสื่อสารกันแค่ทางอีเมลหรือ GitHub เป็นเรื่องปกติหรือไม่
หลังจากเรื่องนี้ ผู้ดูแลโปรเจกต์โอเพนซอร์สบางส่วนก็น่าจะระมัดระวังมากขึ้น
ผมเองก็เคยรับช่วงหรือส่งต่อการดูแลไลบรารีโดยสื่อสารกันผ่านข้อความอย่างเดียว ทั้งที่ไม่รู้เลยว่าตัวจริงของอีกฝ่ายเป็นใคร
แต่ผมมองว่าข้อสรุปแบบ “ผู้ดูแลต้องระวังให้มากขึ้น” ในกรณีนี้ผิดไปเต็ม ๆ
ความรับผิดชอบต่อคนที่เข้ามาทำงานในโปรเจกต์ไม่ได้อยู่ที่ผู้ดูแล แต่อยู่ที่คนที่ทำงานกับโปรเจกต์นั้น
จะเชื่อใจผู้ดูแลหรือไม่ก็มีแค่สองทาง และทันทีที่เริ่มพึ่งพาไลบรารีหนึ่ง ก็เท่ากับยอมรับโดยนัยอยู่แล้วว่าจะอัปเดตอยู่เรื่อย ๆ ว่ากำลังเชื่อใจใคร
บริษัทนับล้านกำลังอาศัยงานของนักพัฒนาโอเพนซอร์สที่ไม่ได้รับค่าตอบแทนแบบกินแรงฟรี
เพราะแบบนั้นจึงไม่น่าแปลกใจที่พวกเขาจะจากไปและเกิดปัญหาตามมา
มันจะเพิ่มความน่าเชื่อถือเกี่ยวกับเจตนาของคนนั้นได้แค่ไหนกัน?
ผมเคยมีส่วนร่วมกับโปรเจกต์โอเพนซอร์สราว ๆ หกโปรเจกต์ ตั้งแต่ระดับ GitHub stars 100 ไปจนถึง 30,000 แต่ไม่เคยคุยโทรศัพท์กับใครเลย และ การสื่อสารผ่านข้อความ คือมาตรฐาน
แต่การรู้จักกันเป็นการส่วนตัวก็ไม่ได้แปลว่าปัญหาจะถูกแก้เสมอไป
นานมาแล้วผมเคยทำงานในโปรเจกต์โอเพนซอร์สแห่งหนึ่งแบบไม่เปิดเผยตัวตน และไม่อยากเอ่ยชื่อที่นี่ มีผู้ดูแลร่วมคนหนึ่งที่ดูเหมือนจะรู้จักกับโปรแกรมเมอร์หลักค่อนข้างดี
ผู้ดูแลร่วมคนนั้นคอย gaslight ผมและผู้ดูแลคนอื่น ๆ ในภายหลังอยู่เรื่อย ๆ ทั้งกดให้ด้อยค่าและด่าว่าเรื่องบั๊กเล็กน้อยจนหลายคนเลิกทำไป ถ้าตัดคำดูถูกออกไป มันก็ยังต่างจากการตวาดสั่งสอนแบบ Linus Torvalds อยู่ดี
ผู้ดูแลหลักก็หนุนหลังเขา เพราะเห็นด้วยกับแก่นทางเทคนิคของข้อกล่าวหาเหล่านั้น
หลายปีต่อมา ผู้ดูแลร่วมคนนั้นพยายามยึดโปรเจกต์แบบเป็นปฏิปักษ์ แต่สุดท้ายก็ไม่เป็นไปอย่างที่คาด หลังจากนั้นไม่นาน จดหมายส่วนตัวหลายฉบับถูกเปิดเผยออกมา ทำให้เห็นว่าเขาต้องการแบบนั้นมาตลอด และการ gaslight ผู้ดูแลคนอื่นก็เป็นส่วนหนึ่งของเป้าหมายนั้น
เรื่องแบบนี้ก็ยังเกิดขึ้นได้ แม้ว่าทั้งสองคนจะรู้จักกันอยู่แล้วก็ตาม
ทุกคนคิดว่าแบ็กดอร์นี้ถูกจับได้เร็ว แต่ก็เป็นไปได้ว่ามันอาจบรรลุเป้าหมายไปแล้ว
โดยเฉพาะถ้าเป้าหมายเป็นนักพัฒนาที่ใช้ ดิสโทรแบบ rolling release อย่าง Kali หรือ Debian
ต้นสัปดาห์ผมเห็นทราฟฟิก SSH อยู่บ้าง แต่ตอนนั้นไม่ได้ใส่ใจมากนัก
แน่นอนว่านี่อาจเป็นการเดาสุ่มก็ได้: https://www.nubi-network.com/news.php?id=21
มีม ทำนองว่า “Lasse Collin ไม่ได้อัปเดต xz Utils บ่อยพอหรือเร็วพอ” เป็นความผิดพลาด
ไม่เข้าใจว่าทำไม SSH ถึงใช้ xz
มันจำเป็นด้วยหรือ? สำคัญขนาดนั้นเลยหรือ?
สิ่งที่เกิดขึ้นคือ OpenSSH ดึง libsystemd เข้ามาเพื่อรองรับการแจ้งสถานะการเริ่มทำงาน และ libsystemd ก็ดึง liblzma เข้ามาอีกทอดหนึ่ง โดยปกติแล้วโค้ดของ liblzma จะไม่ถูกรวมเข้าไปใน OpenSSH
แต่เพราะมันถูก build ในฐานะ dependency ของ libsystemd สคริปต์ build จึงถูกรันในสภาพแวดล้อมเดียวกับ libsystemd และ OpenSSH
เพย์โหลดของการโจมตีถูกซ่อนอยู่ในไดเรกทอรีทดสอบของ liblzma ในรูปของ binary blob ที่ถูกทำให้เข้าใจยากและปลอมตัวเป็นเคสทดสอบแบบบีบอัด
ถ้าคอมไพล์ lzma จากซอร์สใน git และสร้างสคริปต์ build ด้วย autotools จะไม่มีอะไรน่าสงสัยเกิดขึ้น แต่ใน source tarball ที่ผู้แพ็กเกจของดิสโทรใช้ autotools ถูกสั่งรันไว้ล่วงหน้าแล้ว และผู้โจมตีก็สับเปลี่ยนเอาต์พุตสคริปต์ที่สร้างอัตโนมัติซึ่งอ่านยากอยู่แล้ว
สคริปต์นั้นจะตรวจว่า liblzma กำลังถูกคอมไพล์ในสภาพแวดล้อมแบบเดียวกับ OpenSSH หรือไม่ และจะถูกคอมไพล์เพื่อบรรจุลงแพ็กเกจ
.debหรือ.rpmหรือไม่ ถ้าทั้งสองเงื่อนไขเป็นจริง ก็จะฝังเพย์โหลดโจมตีเข้าไปใน OpenSSHจากนั้นเพย์โหลดจะตรวจหลายอย่างต่ออีก เช่น OpenSSH ถูกเริ่มแบบปกติผ่าน init script หรือถูกรันด้วยมือ มีเครื่องมือดีบักทั่วไปอยู่หรือไม่ เป็นต้น และจะเข้าไปเกาะกับโปรเซสที่กำลังรันอยู่ก็ต่อเมื่อมันดูเหมือนเป็นการบูตแบบ “เป็นธรรมชาติ” โดยไม่มีเครื่องมือดีบัก
ระหว่างทำงาน มันจะ hook เข้าไปที่การตรวจสอบ private key และถ้ามีการพยายามล็อกอินด้วย private key ที่ถูกต้อง มันจะเอาส่วนที่เหลือของแพ็กเก็ตขาเข้าไปเรียกผ่าน
systemเพื่อเปิดให้รันโค้ดจากระยะไกลด้วยสิทธิ์ root