← บทความทั้งหมด

Vulnerability

PHP2Shell (CVSS 9.2) คืออะไร และต้องแพตช์ยังไง ก่อนเซิร์ฟเวอร์ PHP ถูกเจาะ

สรุปช่องโหว่ PHP2Shell (CVE-2026-109618 และ CVE-2026-109619) ใน PHP ที่เปิดให้รันโค้ดบนเซิร์ฟเวอร์ได้โดยไม่ต้อง login ใครโดนบ้าง เวอร์ชันไหนแก้แล้ว และถ้ายังแพตช์ไม่ได้ควรทำอะไรก่อน

ถ้าเว็บของเรายังรันด้วย PHP อยู่ ไม่ว่าจะเป็น WordPress, WooCommerce, Magento, Drupal หรือระบบหลังบ้านที่เขียนด้วย Laravel ช่วงนี้น่าจะต้องเช็กเซิร์ฟเวอร์กันสักรอบแล้วนะครับ

เมื่อวันที่ 21 ตุลาคม 2026 ทีม PHP ออกแพตช์แก้ช่องโหว่ร้ายแรงสองตัว คือ CVE-2026-109618 และ CVE-2026-109619 ซึ่งคนในวงการเรียกรวมกันว่า PHP2Shell เพราะผู้โจมตีสามารถใช้มันเปิด shell บนเซิร์ฟเวอร์ของเราได้ โดยไม่ต้อง login และไม่ต้องรอให้ใครคลิกอะไรเลย ทั้งสองตัวได้คะแนน CVSS v4.0 ที่ 9.2

ปัญหาอยู่ในตัว PHP เอง

ช่องโหว่ส่วนใหญ่ที่เราเคยได้ยินมักอยู่ใน plugin หรือโค้ดของแอป แต่ PHP2Shell อยู่ในตัว PHP engine ที่รันโค้ดทั้งหมดอีกที Sansec อธิบายว่าต่อให้โค้ดของแอปเราสะอาดแค่ไหน ก็ยังโดนได้อยู่ดี และอัปเดต plugin หรือแก้โค้ดของเว็บก็ไม่ช่วยอะไร ต้องอัปเดต PHP บนเซิร์ฟเวอร์อย่างเดียว

ถ้าจะเล่าแบบง่าย ๆ ก็คือ เวลา request หนึ่งใช้หน่วยความจำเกิน memory_limit หรือเจอ fatal error กลางทาง PHP จะหยุดงานของ request นั้นทันที บางจังหวะการหยุดแบบนี้เกิดขึ้นตอนที่ PHP ยังเก็บกวาดหน่วยความจำไม่เสร็จ ข้อมูลที่ควรถูกล้างทิ้งเลยค้างอยู่ใน worker พอ request ถัดไปเข้ามาที่ worker ตัวเดิม PHP ก็หยิบข้อมูลเก่านั้นมาใช้ราวกับว่ายังใช้ได้อยู่ (Imperva อธิบายกลไกนี้ไว้ละเอียด) ผู้โจมตีที่จัดข้อมูลตรงนั้นได้แม่นพอก็จะใช้มันรันโค้ดของตัวเองได้

จุดเริ่มต้นของการโจมตีที่รู้กันตอนนี้คือ request แบบ multipart/form-data ซึ่งก็คือรูปแบบเดียวกับการอัปโหลดไฟล์ทั่วไป PHP จะประมวลผลส่วนนี้ตั้งแต่ตอนอ่าน request ก่อนที่โค้ดของแอปจะได้ทำงานเสียอีก ส่วน Sansec ยังรายงานว่าช่องโหว่ตัวหนึ่งทำให้หน่วยความจำของ request อื่นรั่วออกมาได้ด้วย ซึ่งในนั้นอาจมีรหัสผ่าน session token หรือ API key ปนอยู่

ใครโดนบ้าง

ตามข้อมูลของ Sansec โค้ดส่วนที่มีปัญหาอยู่ใน PHP มาตั้งแต่เวอร์ชัน 5.4.0 ปี 2012 และค่าตั้งต้นของ PHP ก็โดนอยู่แล้ว ทั้ง Apache mod_php และ PHP-FPM ส่วน Help Net Security สรุปว่าทุกการติดตั้งที่ใช้ PHP ตอบ request จากเว็บมีความเสี่ยง ไม่ว่าจะเป็น PHP-FPM, mod_php, php-cgi, FrankenPHP หรือ LiteSpeed โดยแบบ mod_php เสี่ยงที่สุด

เวอร์ชันที่แก้แล้วมีดังนี้

  • PHP 8.5.12
  • PHP 8.4.27
  • PHP 8.3.36
  • PHP 8.2.35

ส่วน PHP 8.1 ลงไปไม่มีเวอร์ชันใหม่จากทาง PHP แล้ว ต้องพึ่งแพตช์ backport จาก Linux distribution หรือผู้ให้บริการ LTS แทน ทีม PHP มีแพตช์แบบ source ให้สำหรับ 7.4, 8.0 และ 8.1 ด้วย แต่ก็เหมาะกับคนที่ build PHP เองมากกว่า ข้อนี้น่าจะกระทบหลายองค์กรพอสมควร เพราะ Check Point นับจาก Shodan เจอเครื่องที่หันหน้าออกอินเทอร์เน็ตและโชว์ว่าเป็น PHP 8.1 หรือเก่ากว่าราว 884,000 เครื่อง (นับจาก banner เท่านั้น ยังไม่ได้ยืนยันว่าเครื่องเหล่านี้มีช่องโหว่จริง)

มีการโจมตีจริงแล้ว

แผนเดิมคือจะเปิดเผยพร้อมแพตช์ในวันที่ 21 ตุลาคม แต่รายละเอียดหลุดออกมาก่อนตั้งแต่วันที่ 20 ตุลาคม SecurityWeek รายงานว่า watchTowr ยืนยันได้ว่าทำซ้ำช่องโหว่ได้จริง ไล่ดูไทม์ไลน์คร่าว ๆ ได้แบบนี้

  • 17 ตุลาคม: Amazon Threat Intelligence รายงานว่า honeypot ของตัวเองเจอความพยายามโจมตีแล้ว ทั้งที่ช่องโหว่ยังไม่ประกาศ (ตาม Help Net Security)
  • 20 ตุลาคม: รายละเอียดหลุด และ watchTowr ยืนยันว่ารันโค้ดบนเซิร์ฟเวอร์ได้จริง
  • 21 ตุลาคม 07:43 UTC: Cloudflare เห็นการโจมตีชุดแรก (ตาม Sansec)
  • 21 ตุลาคม 14:00 UTC (21:00 น. เวลาไทย): PHP ออกเวอร์ชันที่แก้แล้ว

ช่องโหว่ชุดนี้มีหลายทีมช่วยกันหา ทั้ง Calif, Wiz Research และ OpenAI ซึ่งทาง Wiz ให้ความเห็นไว้ว่าโมเดล AI รุ่นใหม่ ๆ ช่วยลดความยากในการเขียน exploit จนบั๊กที่ซ่อนอยู่มานานกลายเป็นของที่ใช้โจมตีได้จริง ถ้าเราลองนึกต่อว่าฝั่งผู้โจมตีก็มีเครื่องมือแบบเดียวกัน ช่วงเวลาระหว่างแพตช์ออกจนถึงวันที่โดนสแกนหาก็น่าจะสั้นลงเรื่อย ๆ ใช่ไหมครับ

ถึงอย่างนั้นการโจมตีก็ไม่ได้ง่ายนัก Imperva บอกว่าผู้โจมตีต้องส่ง request ไปเจอ worker ตัวเดิมและวางข้อมูลให้ตรงจุด ถ้าพลาด worker ก็แค่ crash ไป แล้วโค้ดที่รันได้ก็จะได้สิทธิ์เท่ากับ process ของ PHP ไม่ใช่ root ทันที แต่ตอนนี้ทั้งแพตช์และบทวิเคราะห์ออกมาครบแล้ว Sansec จึงคาดว่าจะเห็นการโจมตีแบบหว่านเป็นวงกว้างตามมา

ต้องทำอะไรตอนนี้

ทางที่ปลอดภัยที่สุดคืออัปเดต PHP ทีม PHP เองก็บอกว่าวิธีอื่นเป็นแค่การปิดบางเส้นทางเท่านั้น ลองไล่ตามลำดับนี้ดูนะ

  1. หาให้ครบก่อนว่าเรามีเซิร์ฟเวอร์ PHP อยู่ที่ไหนบ้าง รวมถึงเว็บเก่า เว็บแคมเปญ หรือเซิร์ฟเวอร์ staging ที่อาจลืมไปแล้ว เพราะเครื่องที่ไม่มีใครจำได้ก็จะไม่มีใครไปแพตช์ให้

  2. เช็กเวอร์ชันของ PHP ตัวที่ตอบเว็บจริง คำสั่ง php -v บอกแค่เวอร์ชันของ CLI ซึ่งอาจไม่ใช่ตัวเดียวกับที่เว็บใช้ ควรดูจาก php-fpm -v หรือโมดูลของ Apache ด้วย ถ้าใช้ PHP จาก distribution ให้ดูว่าแพ็กเกจที่ติดตั้งมีแพตช์วันที่ 21 ตุลาคมแล้วหรือยัง ไม่ต้องดูแค่ตัวเลขเวอร์ชัน

  3. อัปเดตแล้ว restart ทุก worker ถ้าใช้ shared hosting หรือ managed hosting ให้ถามผู้ให้บริการว่าอัปเดตแล้วหรือยัง ส่วนใครที่ใช้ repository ของ Remi ทาง Help Net Security แนะนำให้เปลี่ยนไปใช้แพ็กเกจของ distribution หรือ build เอง เพราะวันที่แพตช์ออก repository นี้ยังไม่มีเวอร์ชันใหม่

  4. ถ้ายังอัปเดตไม่ได้ ให้ลดความเสี่ยงไปก่อน

    • ตั้ง session.upload_progress.enabled=0 ใน php.ini หรือใน config ของ FPM pool แล้ว restart worker (ตั้งผ่าน ini_set() หรือ .user.ini ไม่ได้ผล)
    • ทีม PHP แนะนำให้ตั้ง memory_limit=-1 ด้วย แต่วิธีนี้ทำให้ request เดียวกินหน่วยความจำได้ทั้งเครื่อง ต้องคอยดูการใช้หน่วยความจำและเปลี่ยนกลับหลังแพตช์
    • ถ้าเว็บอยู่หลัง WAF เช่น Cloudflare หรือ Imperva ตอนนี้ทั้งสองเจ้ามีกฎกันการโจมตีแบบที่รู้กันแล้ว แต่ก็ควรนับเป็นแค่ด่านเสริมเท่านั้น
    • เครื่องที่สำคัญมากแต่ยังแพตช์ไม่ได้ ควรจำกัดคนเข้าถึง หรือปิดไว้ชั่วคราว ซึ่งก็เป็นสิ่งที่ NCSC ของอังกฤษแนะนำเช่นกัน
  5. ตรวจย้อนหลังว่าเคยโดนไปแล้วหรือยัง Imperva แนะนำให้ดู request แบบ multipart ที่ใหญ่ผิดปกติหรือมีฟิลด์เยอะเกินไป ค่า PHPSESSID ที่ยาวผิดปกติ error เรื่องหน่วยความจำเต็ม และ worker ที่ crash บ่อย ๆ ถ้าเจอร่องรอย ให้เช็กต่อว่ามี process แปลก ๆ มีไฟล์บนเว็บถูกแก้ หรือมีการเชื่อมต่อออกไปข้างนอกที่ไม่คุ้นหรือเปล่า แล้วเปลี่ยนรหัสผ่านและ key ที่เซิร์ฟเวอร์นั้นใช้อยู่ด้วย

ถ้าอยากให้ช่วยไล่ดูว่าองค์กรของเรามีเซิร์ฟเวอร์ PHP ตรงไหนที่ยังเสี่ยงอยู่ ทาง Quackbase ยินดีช่วยดูด้วยกันครับ