- บันทึกการตอบสนองรายนาที ที่ตรวจจับและวิเคราะห์การติดเชื้อของ แพ็กเกจอันตราย LiteLLM 1.82.8 ที่เผยแพร่ผ่าน PyPI แบบเรียลไทม์
- การติดเชื้อเกิดขึ้นระหว่าง การอัปเดตอัตโนมัติของ Cursor IDE โดยมีการรันไฟล์
litellm_init.pth ซึ่งนำไปสู่ การขโมยข้อมูลรับรองและการติดเชื้อระบบ
- โค้ดอันตรายมีพฤติกรรมหลายรูปแบบ เช่น เก็บรวบรวมคีย์ SSH และข้อมูลรับรองคลาวด์, พยายามแพร่กระจายไปยัง Kubernetes, และ สร้าง fork bomb
- มีการรายงานต่อทีมความปลอดภัยของ PyPI และผู้ดูแล LiteLLM ทันที จนนำไปสู่ การกักกันแพ็กเกจและการลงทะเบียน CVE
- เครื่องมือวิเคราะห์โค้ดที่ใช้ AI เช่น Claude Code มีบทบาทสำคัญในการตรวจจับการโจมตีครั้งนี้ และชี้ให้เห็นถึง ความจำเป็นในการเสริมความปลอดภัยซัพพลายเชนของระบบนิเวศ AI
บันทึกการตอบสนองต่อการโจมตีซัพพลายเชนของ LiteLLM
- ยืนยันว่า LiteLLM เวอร์ชัน 1.82.8 เป็นแพ็กเกจอันตรายที่ถูกเผยแพร่ผ่าน PyPI และนี่คือ บันทึกการตอบสนองรายนาที ตั้งแต่การตรวจพบการติดเชื้อจนถึงการกักกัน
- การติดเชื้อเกิดขึ้นระหว่างกระบวนการอัปเดตอัตโนมัติของ Cursor IDE โดยไฟล์
litellm_init.pth ที่อยู่ใน dependency ซึ่งติดตั้งผ่าน Claude Code และ ตัวจัดการแพ็กเกจ uv ถูกเรียกใช้งานและทำให้ระบบติดเชื้อ
- การโจมตีประกอบด้วยพฤติกรรมหลายอย่าง ได้แก่ การขโมยข้อมูลรับรอง, การติดตั้งความคงอยู่ในระบบ, ความพยายามแพร่กระจายไปยัง Kubernetes, และ fork bomb
- มีการรายงานต่อทีมความปลอดภัยของ PyPI และผู้ดูแล LiteLLM ทันที จนนำไปสู่ การกักกันแพ็กเกจและการออก CVE
- เครื่องมือวิเคราะห์โค้ดที่ใช้ AI มีบทบาทสำคัญในการ ตรวจจับและวิเคราะห์พฤติกรรมอันตรายแบบเรียลไทม์
การตรวจพบเบื้องต้นและสัญญาณความผิดปกติของระบบ
- เวลาประมาณ 11:13 UTC บนโน้ตบุ๊ก macOS มีการสร้าง โปรเซส Python มากกว่า 11,000 รายการ จนระบบเข้าสู่ภาวะค้าง
- มีการรันคำสั่งในรูปแบบ
exec(base64.b64decode('...')) ซ้ำ ๆ จนใช้ CPU และหน่วยความจำเต็ม
- หลังบังคับปิดและรีบูต ไม่พบร่องรอยที่เกี่ยวข้องกับ ความคงอยู่ในระบบ (persistence)
- ในตอนแรกถูกมองว่าเป็น อาการลูปที่ไม่เป็นอันตราย จากลูปภายในของ Claude Code หรือข้อผิดพลาดของสคริปต์
uv run
- ต่อมาจากภาพหน้าจอ
htop และล็อก ยืนยันได้ว่ามี สคริปต์ Python ที่เข้ารหัสแบบ base64 ถูกเรียกใช้งานซ้ำ ๆ
การระบุสาเหตุของการติดเชื้อ
- เวลาประมาณ 11:40 พบ ไฟล์
litellm_init.pth ภายในเครื่องมือ Python ที่ติดตั้งไว้ และยืนยันว่าเป็นพฤติกรรมอันตราย
- ไฟล์
.pth จะถูกรันอัตโนมัติเมื่อเริ่มต้น Python และ ทำงานในทุกโปรเซส Python
- มีการเก็บรวบรวม คีย์ SSH, ข้อมูลรับรองคลาวด์, รหัสผ่านฐานข้อมูล, ตัวแปรแวดล้อม, ประวัติ shell เป็นต้น
- ข้อมูลที่เก็บได้จะถูก เข้ารหัสด้วย RSA แล้วส่งไปยัง
https://models.litellm.cloud/
- มีความพยายามติดตั้งความคงอยู่ในระบบที่
~/.config/sysmon/sysmon.py แต่ถูกขัดจังหวะด้วยการรีบูตแบบบังคับ
- การติดเชื้อเกิดขึ้นระหว่าง การอัปเดตอัตโนมัติของ Cursor IDE (10:58 UTC)
- ส่วนขยาย
futuresearch-mcp-legacy ดาวน์โหลด litellm 1.82.8 ผ่าน uvx
- เวอร์ชันดังกล่าว มีอยู่เฉพาะบน PyPI และ ไม่มีแท็กรีลีสบน GitHub
- เวลาที่อัปโหลดขึ้น PyPI คือ 10:52 UTC ยืนยันว่าเป็นเวอร์ชันที่ถูกปล่อยออกมาก่อนการติดเชื้อไม่นาน
โครงสร้างของโค้ดอันตราย
- ขั้นที่ 1 (
litellm_init.pth): ถูกรันอัตโนมัติเมื่อ Python เริ่มทำงาน จากนั้นถอดรหัสและรันเพย์โหลดที่เข้ารหัสแบบ base64
- ขั้นที่ 2: มี RSA public key สำหรับเข้ารหัสข้อมูลที่ขโมยมา
- ขั้นที่ 3 (B64_SCRIPT): ทำหน้าที่เก็บรวบรวมและส่งข้อมูลรับรองจริง
- การติดตั้งความคงอยู่ในระบบ: พยายามลงทะเบียน
sysmon.py เป็นบริการ systemd
- โค้ดแพร่กระจายไปยัง Kubernetes: พยายามสร้าง privileged pod บนแต่ละโหนดโดยใช้อิมเมจ
alpine:latest
- สาเหตุของ fork bomb: การเรียก
subprocess.Popen([sys.executable, "-c", ...]) ทำให้ .pth ถูกรันซ้ำอีกครั้งในโปรเซสลูก จนเกิดลูปไม่สิ้นสุด
ขอบเขตความเสียหายและมาตรการตอบสนอง
-
ข้อมูลรับรองที่อาจรั่วไหล
- คีย์ SSH, ข้อมูลรับรอง GCloud และ Kubernetes, API key ในไฟล์
.env, รวมถึงรหัสผ่านของ Supabase, ClickHouse, Grafana เป็นต้น
- คำแนะนำให้ดำเนินการทันที
- หมุนเวียนข้อมูลรับรอง SSH และคลาวด์ทั้งหมด
- ออกความลับใหม่ใน
.env และ .mcp.json
- ลบแคช
~/.cache/uv
- รายงานต่อทีมความปลอดภัยของ PyPI (
security@pypi.org) และผู้ดูแล LiteLLM
-
ผลการตรวจสอบคลัสเตอร์ Kubernetes
- ไม่พบ pod อันตราย (
node-setup-*, sysmon)
- เนื่องจากรันในสภาพแวดล้อม macOS จึงล้มเหลวในการแพร่กระจายเข้าไปในคลัสเตอร์
- อย่างไรก็ตาม เนื่องจากอาจมีการเปิดเผย
~/.kube/config จึง จำเป็นต้องหมุนเวียนข้อมูลรับรอง
การตอบสนองต่อ PyPI และการเปิดเผยสาธารณะ
- 11:58 UTC ดาวน์โหลด litellm 1.82.8 จาก PyPI อีกครั้งในสภาพแวดล้อม Docker ที่แยกออกมา และยืนยันการมีอยู่ของไฟล์
.pth อันตรายซ้ำอีกครั้ง
- มีการรายงานต่อทีมความปลอดภัยของ PyPI และรีโพซิทอรี BerriAI/litellm ทันที
- ต่อมาถูกลงทะเบียนเป็น PYSEC-2026-2 (CVE)
- 12:01 UTC เผยแพร่โพสต์สาธารณะเกี่ยวกับ การโจมตีซัพพลายเชน บนบล็อกของ FutureSearch
- ใช้เวลาเพียง 3 นาทีในการสร้างและรวม PR
- 12:04 UTC มีข้อเสนอให้แชร์ต่อในชุมชน r/Python, r/netsec, r/LocalLLaMA, r/MachineLearning, r/devops
- เพื่อกระตุ้นให้ชุมชน Python และความปลอดภัยตอบสนองอย่างรวดเร็ว
ความหมายของเหตุการณ์นี้
- เครื่องมือวิเคราะห์โค้ดที่ใช้ AI อย่าง Claude Code สามารถระบุพฤติกรรมอันตรายได้แบบเรียลไทม์ และ สร้างคำเตือนได้ก่อนที่นักวิจัยด้านความปลอดภัยจะเข้ามาแทรกแซง
- เป็นกรณีที่การโจมตีซัพพลายเชน มุ่งเป้าโดยตรงไปยังระบบนิเวศนักพัฒนา AI และตอกย้ำถึง ความจำเป็นในการเสริมความปลอดภัยของบัญชี PyPI และการตรวจสอบการอัปเดตอัตโนมัติ
- แสดงให้เห็นว่าเครื่องมือ AI ไม่ได้เป็นเพียงตัวช่วยพัฒนาเท่านั้น แต่ยังสามารถนำมาใช้กับ การตรวจจับภัยคุกคามไซเบอร์และการทำให้การตอบสนองเป็นอัตโนมัติ ได้ด้วย
1 ความคิดเห็น
ความคิดเห็นบน Hacker News
ฉันคือนักพัฒนาที่ค้นพบและรายงานช่องโหว่ของ litellm เป็นคนแรก
ตอนนั้นฉันได้แชร์ บันทึกบทสนทนาวิเคราะห์แบบเรียลไทม์ ไว้ตามที่เกิดขึ้นจริง
Claude ช่วยแนะนำทีละขั้นว่าควรติดต่อใคร และควรดำเนินการตามลำดับไหน จึงเป็น ประสบการณ์ที่ช่วยคนที่ไม่ใช่ผู้เชี่ยวชาญด้านความปลอดภัยได้มาก
ฉันเลยสงสัยว่าการที่คนที่ไม่ใช่มืออาชีพค้นพบและรายงานช่องโหว่ในลักษณะนี้ เป็นประโยชน์ต่อชุมชนความปลอดภัยหรือกลับทำให้เกิดความสับสนกันแน่
แต่ส่วนที่ว่า “ทันทีที่เปิด Cursor อีกครั้ง แพ็กเกจอันตรายก็ทำงาน” ดูค่อนข้างเสี่ยง
ทันทีที่เริ่มสงสัย สิ่งแรกที่ควรทำคือ แยกอุปกรณ์ออกจากระบบและติดต่อทีมความปลอดภัย
ถ้าไฟล์ .pth ไม่ทำงานเหมือน fork bomb ก็น่าจะตรวจพบช้ากว่านี้มาก
การถาม Claude ว่าควรติดต่อผ่านช่องทางไหนถือเป็นการตัดสินใจที่ดี
เพราะไม่รู้ช่องทางติดต่อเกี่ยวกับ PyPI ฉันเลยส่งอีเมลหาผู้ดูแลและโพสต์บน Hacker News ด้วย
ฉันคิดว่าถึงจะไม่ได้อยู่ในชุมชนความปลอดภัย แต่ทุกคนก็ควร สามารถรายงานช่องโหว่ร้ายแรงแบบนี้ได้
ปัญหาส่วนใหญ่เกิดจากคนที่หวังเงินและอ้างอะไรมั่ว ๆ ว่าเป็นช่องโหว่
แต่รายงานของคุณมีคุณภาพสูง และกรณีแบบนี้จะถูกยกขึ้นเป็น ลำดับความสำคัญในการแพตช์ ทันที
ถ้าแก้ได้โดยไม่กระทบต่อธุรกิจ ก็จะจัดการทันที และถ้าร้ายแรงก็จะรายงานต่อ CISO หรือ CTO โดยตรง
รายงานของคุณช่วยป้องกันไม่ให้เกิดเหตุใหญ่กว่านี้
พวกเราก็ได้สรุปประเด็นที่เกี่ยวข้องไว้ในบล็อกสองตอน
บทความบนบล็อก grith.ai
แต่กรณีนี้ฉันคิดว่าเป็นตัวอย่างที่ดีว่าด้วยความช่วยเหลือของ AI การวิเคราะห์สาเหตุและการรายงานทำได้รวดเร็วขึ้นมาก
นี่เป็นครั้งแรกที่ฉันเห็นเครื่องมือ claude-code-transcripts ของฉันถูกฝังเป็นข้อมูลไว้ในบล็อกโพสต์
ปกติฉันจะแชร์ผ่านหน้า HTML ของ Gist ดังนั้นการใช้งานแบบนี้จึงน่าสนใจ
พยายามปรับให้เข้ากับสไตล์บล็อกแล้วแต่ไม่สำเร็จ ทำให้รู้สึกอีกครั้งว่าประสบการณ์พื้นฐานสำคัญแค่ไหน
Claude เหมือนกวาดเอาล็อกจากทั้งเครื่องของฉันไปราวกับสแกนคอมพิวเตอร์ทั้งหมด เลยรู้สึกว่าจำเป็นต้องมี ระบบแก้ไขล็อกอัตโนมัติ
โดยเฉพาะเวลา debug เรื่องเร่งด่วนร่วมกับทีม มันไม่สะดวกมาก
คำขออย่าง “ช่วยแสดงเนื้อหาของสคริปต์อันตรายโดยไม่รันมันได้ไหม?” เป็นเรื่องเสี่ยง
เพราะ LLM agent ไม่มีแนวคิดเรื่องความรับผิดชอบ ดังนั้นถ้าพลาดสั่งให้รันคำสั่งเข้า ก็อาจนำไปสู่อุบัติเหตุใหญ่ได้
เวลาโหลดไฟล์จาก PyPI ต้องทำใน สภาพแวดล้อม sandbox เท่านั้น
ถ้าบอกว่า “ห้ามทำ” กลับยิ่งมีแนวโน้มจะหมกมุ่นกับจุดนั้น
ได้ยินมาว่า PyPI รองรับ digital attestation เลยสงสัยว่าแพ็กเกจนี้มีการเซ็นลายมือชื่อไว้หรือเปล่า
เอกสาร PyPI Trusted Publishers
ฉันคิดว่าแพ็กเกจรีจิสทรีอย่าง GitHub, npm, PyPI ควรมี event stream (firehose) สำหรับการวิเคราะห์ความปลอดภัยแบบเรียลไทม์
การโจมตีแบบนี้น่าจะถูกจับได้ทันทีโดยสแกนเนอร์อัตโนมัติ
พาร์ตเนอร์ด้านความปลอดภัยสามารถสแกนแพ็กเกจและรายงานผ่าน API แบบเชิญใช้งานได้
ดู โพสต์บนบล็อก PyPI
บทความที่เกี่ยวข้อง
จุดประสงค์คือซื้อเวลาให้สแกนเนอร์อัตโนมัติตรวจจับสัญญาณผิดปกติอย่างไฟล์ .pth ได้
เพราะความเสียหายทางเศรษฐกิจอาจสูงมาก และมีผู้ติดเชื้อจาก litellm มากกว่า 47,000 รายแล้ว
ส่วนที่ว่า “ตั้งแต่เขียนบล็อกโพสต์ ทำ PR จนถึง merge ใช้เวลาไม่ถึง 3 นาที” น่าตกใจที่สุด
มันเร็วกว่าที่ใช้เวลาอ่านเสียอีก เลยทำให้รู้สึก กังวลใจ
ถ้าไม่มี fork bomb ที่สร้าง 11,000 โปรเซส การโจมตีนี้อาจซ่อนตัวได้นานกว่านี้มาก
ถ้ามันทำให้ระเบิดช้าลง ความเสียหายน่าจะหนักกว่านี้มาก
บริษัทใหญ่มีอยู่สองวิธีในการรันโค้ดโอเพนซอร์สที่ไม่น่าเชื่อถือ
ในทางปฏิบัติ (1) ปลอดภัยที่สุด
สำหรับบริษัทเล็กหรือผู้ใช้ทั่วไป การ pin dependency และเว้นช่วงเวลารอให้เพียงพอคือแนวป้องกันที่ดีที่สุด
ถ้าใช้ Bazel ก็พอจะเข้าใกล้แบบ (1) ได้ แต่ส่วนใหญ่ก็ยังต้องพึ่งพาซอร์สภายนอกอยู่ดี
การที่ PyPI กักกันแพ็กเกจได้ภายใน 30 นาทีหลังมีรายงาน ถือว่าเร็วมากจริง ๆ
หนึ่งในข้อดีที่สุดของ AI/LLM คือ การทำให้ reverse engineering เป็นเรื่องที่ทุกคนเข้าถึงได้มากขึ้น
แต่ก่อนมันเป็นทักษะที่เรียนยากและให้ผลตอบแทนไม่มากนัก แต่ตอนนี้ AI ช่วยชี้ทางให้ได้
รูปแบบ
exec(base64.b64decode(...))เป็นวิธีที่เครื่องมือ Python ใช้กันบ่อยในการส่งโค้ดแต่โดยพื้นฐานแล้ว โค้ดที่รันจาก /tmp, /var/tmp, /dev/shm ควรถูกมองว่าน่าสงสัยมาก
ถ้ามีเครื่องมือตรวจสอบเครือข่ายอย่าง Lulu หรือ LittleSnitch ก็น่าจะบล็อกทราฟฟิกผิดปกติได้
อย่างไรก็ตาม การอัปโหลดไบนารีให้ Claude วิเคราะห์ก็เป็นความเสี่ยงอีกแบบหนึ่ง