ช่องโหว่ CVE-2026-42945 ที่ซุกซ่อนใน Nginx มานาน 18 ปี: เจาะลึกหลักการทำงาน PoC และวิธีแก้ไขอย่างครบถ้วน

🚨 ช่องโหว่ร้ายแรง CVE-2026-42945 ที่ซุกซ่อนใน Nginx มานาน 18 ปี: หลักการทำงาน PoC และวิธีแก้ไข
วันที่ 13 พฤษภาคม 2026 หน่วยงานวิจัยด้านความปลอดภัยdepthfirstร่วมกับ F5 เปิดเผยช่องโหว่ร้ายแรงที่สุดในประวัติศาสตร์ของ NGINX นั่นคือCVE-2026-42945:
- คะแนน CVSS v4.0 อยู่ที่ 9.2: จัดเป็นช่องโหว่ระดับร้ายแรง
- บัฟเฟอร์โอเวอร์โฟลว์บนฮีป: อาจนำไปสู่การรันโค้ดจากระยะไกล (RCE)
- ซุกซ่อนมานาน 18 ปี: ตั้งแต่ถูกเขียนเข้าสู่โค้ดเบสในปี 2008
- กระทบเว็บไซต์ทั่วโลก 9.75 ล้านแห่ง: เว็บไซต์ในจีนกว่า 2.54 ล้านแห่งได้รับผลกระทบ
- PoC เผยแพร่สาธารณะแล้ว: QiAnXin ทดซ้ำสำเร็จแล้ว
นี่คือช่องโหว่ระดับประวัติศาสตร์ในโมดูลแกนกลางของ NGINXผู้โจมตีเพียงส่ง HTTP request ที่ปรุงแต่งเป็นพิเศษเพียงหนึ่งรายการก็สามารถเข้าควบคุมเซิร์ฟเวอร์จากระยะไกลได้
🔍 ภาพรวมช่องโหว่
ข้อมูลพื้นฐาน
| คุณสมบัติของช่องโหว่ | รายละเอียด |
|---|---|
| รหัสช่องโหว่ | CVE-2026-42945 |
| คะแนน CVSS | v4.0: 9.2 | v3.1: 8.1 |
| ประเภทช่องโหว่ | บัฟเฟอร์โอเวอร์โฟลว์บนฮีป (Heap-based Buffer Overflow) |
| ประเภทภัยคุกคาม | การรันโค้ดจากระยะไกล (RCE) และการโจมตีแบบปฏิเสธการให้บริการ (DoS) |
| เงื่อนไขการโจมตี | ไม่ต้องมีการยืนยันตัวตน ต้องการเพียงการสร้าง HTTP request |
| คอมโพเนนต์ที่ได้รับผลกระทบ | ngx_http_rewrite_module (โมดูลที่มีในตัวแกนกลางของ NGINX) |
| หน่วยงานที่ค้นพบ | depthfirst (ระบบอัตโนมัติค้นพบภายใน 6 ชั่วโมง) |
ขอบเขตผลกระทบ
- เว็บไซต์ทั่วโลก 9.75 ล้านแห่งได้รับผลกระทบ
- เว็บไซต์ในจีน 2.54 ล้านแห่งได้รับผลกระทบ
- NGINX รองรับเว็บไซต์ทั่วโลกราว 1 ใน 3 ผลกระทบจึงกว้างขวางอย่างยิ่ง
- โค้ดถูกเขียนตั้งแต่ปี 2008 และซุกซ่อนมาแล้ว18 ปี
⚠️ เงื่อนไขการเกิดช่องโหว่
ทั้งสามเงื่อนไขต้องเป็นจริงพร้อมกัน
การเกิดช่องโหว่ต้องการการตั้งค่าที่ตรงกับเงื่อนไขเฉพาะร่วมกัน:
| เงื่อนไข | คำอธิบาย | ตัวอย่าง |
|---|---|---|
| 1. การแคปเจอร์ PCRE แบบไม่มีชื่อ | คำสั่ง rewrite ใช้ capture group แบบไม่มีชื่อ | $1, $2, $3… |
| 2. สตริงแทนที่มีเครื่องหมายคำถาม | สตริงแทนที่มีอักขระ ? | /profile.php?id=$1&tab=$2 |
| 3. ตามด้วย rewrite/if/set | มีคำสั่งอื่นตามหลังคำสั่ง rewrite ทันที | rewrite … last; if (…) { … } |
ตัวอย่างการตั้งค่าที่เสี่ยงต่อช่องโหว่
# 易受攻击配置
rewrite ^/users/([0-9]+)/profile/(.*)$ /profile.php?id=$1&tab=$2 last;
# 后跟其他指令
if ($arg_debug) {
set $debug_flag 1;
}
การตั้งค่านี้ตรงเงื่อนไขทั้งสามข้อพร้อมกัน:การแคปเจอร์แบบไม่มีชื่อ $1/$2, สตริงแทนที่มี ?, ตามด้วยคำสั่ง if.
🔬 หลักการทำงานของช่องโหว่
สถานะไม่สอดคล้องกันในการประมวลผลสองขั้นตอน
เอนจินสคริปต์ของ NGINXทำงานแบบสองขั้นตอน:
- ขั้นตอนแรก: คำนวณขนาดบัฟเฟอร์ที่ต้องใช้
- ขั้นตอนที่สอง: คัดลอกข้อมูลลงบัฟเฟอร์
แกนหลักของช่องโหว่อยู่ที่การจัดการแฟล็ก is_args ที่ผิดพลาด:
| ขั้นตอน | สถานะ is_args | ตรรกะการประมวลผล | ผลลัพธ์ |
|---|---|---|---|
| ขั้นตอนคำนวณความยาว | is_args = 0 | คืนค่าความยาวของการแคปเจอร์ดั้งเดิม | ประเมินขนาดบัฟเฟอร์ต่ำเกินจริง |
| ขั้นตอนคัดลอกข้อมูล | is_args = 1 | เรียกใช้ ngx_escape_uri แต่ละไบต์ถูกขยายเป็น 3 ไบต์ | บัฟเฟอร์โอเวอร์โฟลว์บนฮีป |
ขั้นตอนโดยละเอียด
- คำสั่ง rewriteมีการแคปเจอร์แบบไม่มีชื่อ $1/$2
- สตริงแทนที่มี ? ทำให้เกิด is_args = 1
- ขั้นตอนคำนวณความยาว: ใช้ซับเอนจินที่เพิ่งถูกกำหนดค่าใหม่ is_args = 0
- คืนค่าความยาวดั้งเดิม: จัดสรรบัฟเฟอร์ฮีปที่เล็กเกินไป
- ขั้นตอนคัดลอกข้อมูล: ใช้เอนจินหลัก is_args = 1
- เรียกใช้ ngx_escape_uri: ขยายไบต์ ทำให้บัฟเฟอร์ล้น
- ข้อมูล URI ที่ผู้โจมตีควบคุมได้ถูกเขียนเข้าสู่พื้นที่ที่ล้นออก
วิธีการโจมตี
Heap Feng Shui แบบข้าม request:
- เนื้อหาของ POST requestใช้ทำ heap spray ลงหน่วยความจำฮีป (เพราะ URI ไม่สามารถมีไบต์ null ได้)
- ข้อมูลที่ล้นออกทำลายพอยเตอร์ cleanup ของ ngx_pool_t ที่อยู่ติดกัน
- ปลอม ngx_pool_cleanup_s ให้ชี้ไปที่ system()
- เมื่อ pool ถูกทำลายจะเกิดการเรียก system()
- ทำให้เกิด RCE ได้
ผลกระทบของ ASLR
- เปิดใช้ ASLR: ทำให้เพียงโปรเซส worker พัง (DoS)
- ปิดใช้ ASLR: สามารถรันโค้ดจากระยะไกลได้ (RCE)
📊 เวอร์ชันที่ได้รับผลกระทบ
NGINX Open Source
| ช่วงเวอร์ชัน | เวอร์ชันที่แก้ไขแล้ว |
|---|---|
| 0.6.27 – 1.30.0 | 1.31.0, 1.30.1 |
NGINX Plus
| ช่วงเวอร์ชัน | เวอร์ชันที่แก้ไขแล้ว |
|---|---|
| R32 – R36 | R36 P4, R35 P2, R32 P6 |
คอมโพเนนต์อื่น ๆ ที่ได้รับผลกระทบ
- NGINX Instance Manager: 2.16.0 – 2.21.1
- NGINX App Protect WAF: 4.9.0 – 5.8.0
- NGINX Ingress Controller: 3.5.0 – 5.4.1
- NGINX Gateway Fabric: 1.3.0 – 2.5.1
- F5 DoS for NGINX: 4.8.0
🔥 สถานะ PoC
PoC เผยแพร่สาธารณะแล้ว
- รีโพซิทอรี GitHub:https://github.com/DepthFirstDisclosures/Nginx-Rift
- QiAnXin ทดซ้ำสำเร็จแล้ว: นักวิจัยด้านความปลอดภัยจากศูนย์ข่าวกรองภัยคุกคามทดซ้ำสำเร็จ
- รายละเอียดทางเทคนิคเผยแพร่แล้ว: depthfirst เผยแพร่บทวิเคราะห์ทางเทคนิค
- การโจมตีในโลกจริง: ยังไม่พบ
วิธีใช้งาน PoC
# 构建容器 ./setup.sh # 启动易受攻击的 NGINX 服务器 docker compose -f env/docker-compose.yml up # 执行 PoC 获取 Shell python3 poc.py --shell
✅ วิธีแก้ไข
วิธีที่ 1: อัปเกรดเวอร์ชัน
# 升级到修复版本 NGINX Open Source >= 1.31.0 NGINX Open Source >= 1.30.1 NGINX Plus >= R32 P6 NGINX Plus >= R36 P4 # 升级后重启 NGINX nginx -s reload
วิธีที่ 2: แก้ไขการตั้งค่า (มาตรการบรรเทา)
เปลี่ยนcapture group แบบไม่มีชื่อเป็นcapture group แบบมีชื่อ:
# 易受攻击配置(未命名捕获) rewrite ^/users/([0-9]+)/profile/(.*)$ /profile.php?id=$1&tab=$2 last; # 修复后配置(命名捕获) rewrite ^/users/(?[0-9]+)/profile/(?.*)$ /profile.php?id=$user_id&tab=$section last;
capture group แบบมีชื่อจะไม่ทำให้เกิดช่องโหว่
วิธีที่ 3: ตรวจสอบการตั้งค่า
ตรวจสอบว่ามีการตั้งค่าที่เสี่ยงต่อช่องโหว่หรือไม่:
# 搜索易受攻击的 rewrite 指令 grep -E "rewrite.*\$[0-9]+.*\?.*(rewrite|if|set)" /etc/nginx/nginx.conf grep -rE "rewrite.*\$[0-9]+.*\?.*(rewrite|if|set)" /etc/nginx/conf.d/
🔍 กระบวนการค้นพบ
ระบบวิเคราะห์ความปลอดภัยอัตโนมัติของ
depthfirst:
- ภายใน 6 ชั่วโมงพบปัญหา 5 รายการ
- 4 รายการได้รับการยืนยันจาก NGINX
- CVE-2026-42945คือช่องโหว่ที่ร้ายแรงที่สุด
- สามารถสืบย้อนไปได้ถึงปี 2008 และมีอยู่ในบิลด์มาตรฐานเกือบทุกเวอร์ชัน
ช่องโหว่อื่นที่เกี่ยวข้อง
- CVE-2026-42946: ปัญหาความเสียหายของหน่วยความจำ
- CVE-2026-40701: ปัญหาความเสียหายของหน่วยความจำ
- CVE-2026-42934: ปัญหาความเสียหายของหน่วยความจำ
📝 สรุป
CVE-2026-42945คือช่องโหว่ร้ายแรงที่สุดในประวัติศาสตร์ของ NGINX:
- ซุกซ่อนมา 18 ปี: ตั้งแต่ถูกเขียนเข้าสู่โค้ดเบสในปี 2008
- CVSS 9.2: บัฟเฟอร์โอเวอร์โฟลว์บนฮีป อาจนำไปสู่ RCE
- เงื่อนไขการเกิด: คำสั่ง rewrite ใช้การแคปเจอร์แบบไม่มีชื่อ + สตริงแทนที่มี ? + ตามด้วยคำสั่งอื่น
- ขอบเขตผลกระทบ: เว็บไซต์ทั่วโลก 9.75 ล้านแห่ง จีน 2.54 ล้านเว็บไซต์
- PoC เผยแพร่แล้ว: รีโพซิทอรี GitHub + QiAnXin ทดซ้ำสำเร็จ
- วิธีแก้ไข: อัปเกรดเวอร์ชัน หรือใช้ capture group แบบมีชื่อ
ช่องโหว่ที่ซุกซ่อนมา 18 ปีได้ระเบิดขึ้นแล้ว แนะนำให้รีบอัปเกรดหรือแก้ไขการตั้งค่าโดยเร็ว
ประกาศอย่างเป็นทางการ:https://my.f5.com/manage/s/article/K000161019
รีโพซิทอรี PoC:https://github.com/DepthFirstDisclosures/Nginx-Rift
บทวิเคราะห์ทางเทคนิค:https://depthfirst.com/research/nginx-rift