NGINX Rift - ช่องโหว่โจมตี NGINX แบบใหม่
(github.com/DepthFirstDisclosures)- NGINX Rift คือ PoC สำหรับการรันโค้ดจากระยะไกลของ CVE-2026-42945 ซึ่งเป็นช่องโหว่ heap buffer overflow ระดับวิกฤตใน
ngx_http_rewrite_moduleของ NGINX - ช่องโหว่นี้ทำให้เกิด การรันโค้ดจากระยะไกลโดยไม่ต้องยืนยันตัวตน ได้บนเซิร์ฟเวอร์ที่ใช้คำสั่ง
rewriteและset - ปัญหานี้เป็นบั๊กที่ถูกนำเข้ามาตั้งแต่ปี 2008 โดยเกิดจาก length calculation pass และ copy pass ของ NGINX script engine จัดการแฟล็ก
is_argsไม่เหมือนกัน - เมื่อสตริงแทนที่ของ
rewriteมี?อยู่ main engine จะตั้งค่าis_argsแต่การคำนวณความยาวจะไปรันบน sub-engine ที่ถูกรีเซ็ตเป็น 0 ใหม่ ทำให้คืนค่าเฉพาะความยาวของ original capture - ในขั้นตอนการคัดลอก จะมีการเรียก
ngx_escape_uriและNGX_ESCAPE_ARGSขณะis_args = 1ทำให้แต่ละไบต์ที่ต้อง escape ถูกขยายเป็น 3 ไบต์ และทำให้ heap buffer ที่ถูกจัดสรรน้อยเกินไปล้นด้วยข้อมูล URI ที่ผู้โจมตีควบคุมได้ - เอ็กซ์พลอยต์นี้ใช้ heap feng shui ข้ามหลายรีเควสต์เพื่อทำให้ pointer
cleanupของngx_pool_tที่อยู่ติดกันปนเปื้อน และเนื่องจากไม่สามารถใส่ null byte ลงในไบต์ของ URI ได้ จึงใช้การสเปรย์ผ่าน POST body - pointer ที่ถูกปนเปื้อนจะถูกรีไดเร็กต์ไปยัง
ngx_pool_cleanup_sปลอม และถูกจัดให้เรียกsystem()เมื่อพูลถูกทำลาย - นอกจาก CVE-2026-42945 แล้ว ยังมีปัญหา memory corruption อีก 3 รายการ ได้แก่ CVE-2026-42946, CVE-2026-40701 และ CVE-2026-42934 ซึ่งระบบวิเคราะห์ความปลอดภัยของ depthfirst ค้นพบได้เองโดยอัตโนมัติจากการ onboard ซอร์สโค้ด NGINX เพียงครั้งเดียว
- เวอร์ชันที่ได้รับผลกระทบคือ NGINX Open Source 0.6.27–1.30.0 และ NGINX Plus R32–R36 ส่วนเวอร์ชันที่แก้ไขแล้วคือ Open Source 1.31.0/1.30.1 และ Plus R36 P4/R35 P2/R32 P6
- คำแนะนำจากผู้จำหน่ายฉบับเต็มอยู่ที่ https://my.f5.com/manage/s/article/K000160932 และรายละเอียดเชิงเทคนิคอยู่ใน technical write-up
- PoC ถูกทดสอบบน Ubuntu 24.04.3 LTS และมีลำดับการทำงานสำหรับรันคอนเทนเนอร์ NGINX ที่มีช่องโหว่และเปิดเชลล์ดังนี้:
./setup.sh,docker compose -f env/docker-compose.yml up,python3 poc.py --shell
1 ความคิดเห็น
ความเห็นจาก Hacker News
ในฐานะคนทำงานด้านความปลอดภัย รู้สึกเหนื่อยกับปฏิกิริยาที่ฟันธงหรือสื่อเป็นนัยว่าปัญหานี้น่ากลัวน้อยลงมากเพียงเพราะ exploit ที่เผยแพร่ออกมายัง ข้าม ASLR ไม่ได้
ต้นฉบับอ้างว่าการโจมตีนี้มีวิธีข้าม ASLR ได้อย่างเสถียร และต่อให้ยังไม่มีหลักฐาน ก็ควรเชื่อไว้เป็นสมมติฐานตั้งต้น
ASLR เป็นเพียงเทคนิค defense in depth ที่ทำให้การ exploit ยากขึ้น และในกรณีส่วนใหญ่ถ้ามีเวลาและฝีมือมากพอ สุดท้ายก็จะมีการข้าม ASLR ได้
เพราะมี LLM agent อุปสรรคด้านเวลาและทักษะนั้นก็ลดลงทุกไม่กี่สัปดาห์ ดังนั้นการมี exploit ที่ถูกทำให้เป็นอาวุธเต็มรูปแบบจึงเป็นแค่เรื่องของเวลา และมันอาจถูกเปิดเผยต่อสาธารณะหรือเก็บเป็นความลับก็ได้
คำพูดที่ว่า “ถ้าเปิด ASLR ก็ไม่อันตราย” นั้นผิดอย่างชัดเจน และเป็นอันตรายมากสำหรับคนที่เชื่อแบบนั้น
ความเชื่อผิด ๆ ว่าไม่จำเป็นต้องใส่ใจช่องโหว่ด้านความปลอดภัยเพียงเพราะมีมาตรการบรรเทาที่ทำให้ exploit ยากขึ้น ได้ก่อความเสียหายมามากแล้วในอดีต
เป็นเรื่องดีที่มีมาตรการบรรเทาสมัยใหม่ แต่ก็ควรแพตช์ให้เร็วที่สุด และถ้าเป็นฝั่งผู้ขาย ก็ไม่ควรถือว่ารายงานช่องโหว่เป็นโมฆะเพียงเพราะนักวิจัยยังไม่ได้แสดงการข้าม ASLR แต่ควรแก้ที่ต้นตอของปัญหา
แต่ในตอนนี้เงื่อนไขเบื้องต้นก็ดูค่อนข้างเฉพาะอยู่
ใช้ nginx มาหลายรูปแบบตลอด 10 ปี แต่ไม่เคยใช้
rewriteกับsetร่วมกันเลยสักครั้งและยังชอบพูดคำว่า “cyber” ด้วย
ASLR คล้ายกับรหัสผ่านเพิ่มอีกชั้นที่ต้องเดาให้ถูก มี entropy อยู่ระดับหนึ่ง และโดยทั่วไปก็เสถียร
ถ้าช่องโหว่ไม่มีส่วนของการรั่วไหลข้อมูล ASLR ก็สามารถบรรเทาช่องโหว่นั้นได้ทั้งหมด หรือไม่ก็ต้องอาศัยช่องโหว่อีกตัวหนึ่ง
นั่นเป็นอีกประเด็นหนึ่ง
ASLR อาจบรรเทาช่องโหว่รายตัวได้ทั้งหมด แต่ไม่สามารถหยุด exploit chain ได้
ถึงอย่างนั้น ถ้าจะโน้มน้าวให้รีบแพตช์ ก็ควรอ้างความเป็นไปได้ของช่องโหว่ตัวที่สองที่ทำให้เกิดการรั่วไหลของข้อมูลจะเหมาะกว่า
exploit chain นั้นอันตรายกับช่องโหว่ทุกประเภท
สิ่งที่อันตรายจริง ๆ คือการเชื่อ คอมเมนต์สุ่มบนอินเทอร์เน็ต ที่พูดอย่างมั่นใจ
ถ้าฝึกความสามารถในการมองทะลุสิ่งแบบนั้นได้ ก็จะเป็นประโยชน์ไม่ใช่แค่กับเรื่องความปลอดภัย แต่กับเรื่องอื่นด้วย
นั่นคือเหตุผลที่อ่านรายงานแบบนี้ และควรเอาจริงเอาจังกับมัน
ไม่อย่างนั้นเดี๋ยวเครื่องก็โดนเจาะ
ช่วงหลังดูเหมือน exploit แบบ remote code execution ที่เผยแพร่ต่อสาธารณะมักไม่มีการแจ้งล่วงหน้า อย่างน้อยก็น่าจะให้เวลาสักไม่กี่นาทีเพื่ออัปเกรดซอฟต์แวร์
มันชวนให้นึกถึงช่วงปลายทศวรรษ 1980 ถึงต้นทศวรรษ 1990 ที่มีบั๊ก remote exploitable ใน sendmail ออกมาเป็นชุด ซึ่งเป็นยุคที่การเปิดเผยยังไม่มีราวกันความปลอดภัย
ถ้าไม่อ่านรายงานแบบนี้หรืออ่านช้าเกินไป อาจมีเครื่องถูกเจาะเป็นหลักล้านได้
ตอนนี้ nginx ครองตลาดเว็บเซิร์ฟเวอร์สาธารณะราว 39~43% ดังนั้นจึงค่อนข้างร้ายแรง
เคสนี้ค่อนข้างแย่ แต่มีเงื่อนไขเบื้องต้น
ต้องมี directive
rewriteที่มีเครื่องหมายคำถามอยู่ในสตริงแทนที่ และตามด้วย directivesetที่อ้างอิง regex capture groupตัวอย่าง:
set $var $1นอกจากนี้ proof of concept ยังสมมติว่า ปิด ASLR ไว้
ต่อให้ปิดเองแบบแมนนวล nginx ก็ไม่ใช่ตัวเลือกแรกที่ผมนึกว่าจะทำแบบนั้น
rewriteกันแล้วไม่ใช่หรือ?เหมือนเป็นของยุคเก่าในสมัย PHP กับ Apache มากกว่า
หน้าอย่างเป็นทางการของ F5 อยู่ที่นี่: https://my.f5.com/manage/s/article/K000161019
อย่างที่ที่อื่นเขียนไว้ ASLR ช่วยป้องกันได้
ระหว่างรอเวอร์ชันแก้ไขสำหรับแพลตฟอร์มที่ได้รับผลกระทบ ก็มีคำแนะนำบรรเทาว่า “ให้ใช้ named capture แทน unnamed capture ใน
rewritedefinition”ใจความคือ “เพื่อบรรเทาช่องโหว่ในตัวอย่างนี้ ให้เปลี่ยน
$1และ$2เป็น named capture ที่เหมาะสมอย่าง$user_id,$section”F5 แพตช์แล้วใน 1.31.0 และ 1.30.1
OpenResty มีแพตช์สำหรับ 1.27 และ 1.29: https://github.com/openresty/openresty/commit/ee60fb9cf645c9...
ความคืบหน้าของ OpenResty ซึ่งเป็นแอปพลิเคชันเซิร์ฟเวอร์ Lua ที่อยู่บน Nginx ดูได้ที่นี่: https://github.com/openresty/openresty/issues/1119
proof of concept นี้ ปิด ASLR ไว้: https://github.com/DepthFirstDisclosures/Nginx-Rift/blob/mai...
forkมาจาก master จึงได้ memory layout เดียวกันสามารถทำให้ worker แครชได้ไม่จำกัดครั้ง
จึงมีความเป็นไปได้สูงว่าจะใช้สิ่งนี้สร้าง read oracle ได้
อย่างน้อยที่สุดก็ทำให้เกิดการปฏิเสธการให้บริการอย่างเสถียรได้
การวิเคราะห์ฉบับเต็มของ Depth First: https://depthfirst.com/research/nginx-rift-achieving-nginx-r...
มีทางเลือกที่ดีแทน Apache และ Nginx ที่เขียนด้วย ภาษาแบบ memory-safe และไม่ได้มีประวัติช่องโหว่มากมายไหม?
ผมลองดู Jetty ที่เขียนด้วย Java กับ Caddy ที่เขียนด้วย Go แบบคร่าว ๆ แต่ Jetty ก็มีประวัติช่องโหว่คนละแบบ เช่น shell injection เลยไม่แน่ใจว่ามันดีกว่าจริงหรือเปล่า
ทุกวันนี้คนดูแลอินฟราควรคุ้นเคยกับ active defense อย่าง MAC เช่น SELinux และ AppArmor
แต่ก่อนมันมีแรงเสียดทานสูง แต่ตอนนี้มีเครื่องมือที่ช่วยให้ใช้ง่ายขึ้นมาก
https://presentations.nordisch.org/apparmor/
https://github.com/nobody43/apparmor-profiles/blob/master/ng...
https://github.com/nobody43/apparmor-suggest
อนึ่ง ทั้งสอง repository เป็นของที่ผมทำเอง
ที่ทั้งคู่รักษาส่วนแบ่งตลาดไว้ได้นานขนาดนี้ จริง ๆ แล้วกลับเป็นสัญญาณที่ดีเสียมากกว่า
แต่โมเดลที่แทนที่จะมีระบบปลั๊กอินที่ดี กลับกลายเป็นมีไบนารีนับพันตามชุดปลั๊กอินที่ต้องการนั้น ผมไม่ค่อยชอบเท่าไร
ถึงอย่างนั้น ถ้าคอมไพล์จากซอร์สก็ถือว่าค่อนข้างสะอาดและเรียบง่าย
HTTP server ทางเลือกส่วนใหญ่มักลดขอบเขตลงมาก ดังนั้นควรตัดสินใจก่อนว่าต้องการฟีเจอร์อะไร
ผมไม่ค่อยเห็นการพูดถึง HTTP server ที่ใช้ภาษาแบบ memory-safe มากนัก
เซิร์ฟเวอร์ใหญ่สามตัวที่ใช้ C อย่าง Apache, Nginx และ lighttpd นั้นต่างก็แข็งแกร่งพอสมควร และดูเหมือนจะไม่มีคนมากนักที่อยากย้ายไปโปรเจกต์ใหม่เพียงเพราะเรื่องภาษา
อีกอย่าง ถ้าเลือกภาษาแบบ memory-safe ส่วนใหญ่ก็มักต้องรับเอา runtime หรือ virtual machine และองค์ประกอบเสริมของภาษานั้น ซึ่งบางครั้งก็มีขนาดใหญ่ตามไปด้วย
ถ้าเป็น Java web server ก็มีโอกาสจะใช้ log4j เหมือนโปรเจกต์ Java ทั่วไปแบบสุ่ม ๆ ที่มักเป็นกัน
ที่บอกว่า “exploit ใช้ cross-request heap feng shui” นี่ นี่เป็นครั้งแรกที่ผมเห็นคำว่า feng shui ถูกใช้ในลักษณะนี้
Debian 12 แพตช์เรื่องนี้แล้วหรือยัง?
แล้วถ้าไม่ได้ใช้
rewriteหรือsetที่ไหนเลย ก็ถือว่าไม่ได้รับผลกระทบใช่ไหม?ส่วน Debian ดูเหมือนยังไม่ได้แพตช์ trixie
setuse case ของ nginx ส่วนใหญ่คือ terminate TLS แล้วส่งต่อ request ไปยัง node/php/go ฯลฯ
ดังนั้นผมเลยคิดว่าน่าจะมี
setที่ใส่ข้อมูลซึ่งผู้โจมตีควบคุมได้อยู่บ้างสักบรรทัด เช่นproxy_set_header X-Host $host;แก้ไข: ดูเหมือน named capture จะไม่ได้รับผลกระทบ
ถ้าไม่มี
$1อยู่ที่ไหนเลย ก็น่าจะโอเคลิงก์ที่ดีกว่า:
https://depthfirst.com/research/nginx-rift-achieving-nginx-r... (https://news.ycombinator.com/item?id=48126029)
https://depthfirst.com/nginx-rift (https://news.ycombinator.com/item?id=48123365)