วันนี้จะพูดถึงช่องโหว่ Local File Inclusion (LFI) และ Remote Code Execution (RCE) จากการทำ LFI

ตัวอย่าง code

โดยปกติจะเป็นการเรียกใช้งานเป็น

ทีนี้ถ้าเป็นการโจมตี LFI ก็จะเป็น

โดยจาก code จะเห็นว่ามีการใช้งาน function include นำ content ของไฟล์ file ท่ีได้รับจาก GET Method มาแสดงผล ทีนี้ ../ คือการ back ไปยัง path ก่อนหน้า 1 path นั่นเอง

Null Byte Injection

ตัว %00 เป็น http encoded ของ 0x00 ซึ่งมีความหมายว่า null byte ซึ่งหมายความว่าตัวตัดตัวอักษรที่เหลือหลังจากนั้นทิ้งนั่นเอง

Null byte injection ถูก fixed ใน PHP 5.3.4

Filter Evasion

หากมีการเขียน code ป้องกันเป็น

เราสามารถ URL encoding ในการ bypass ได้

แต่วิธีนี้จะใช้ไม่ได้ในปัจจุบัน แต่ถ้าเป็น

ก็จะได้ผลเป็น

Double encoding

หากมีการใช้งานตรวจสอบโดยการ urldecode() ครั้งเดียวก็จะจับ request ที่เป็น%2E%2E%2Fetc%2Fpasswdได้

ทีนี้หากเราเปลี่ยน % ให้กลายเป็น %252E%252E%252Fetc%252Fpasswd พอผลลัพธ์ออกจาก urldecode() ก็จะได้ผลลัพธ์เป็น %2E%2E%2Fetc%2Fpasswd แล้ว ซึ่งก็คือ ../../etc/passwd นั่นเอง

Path truncation

ก่อนอื่นต้องทำความเข้าใจก่อนว่า

  • ใน UNIX /./etc/passwd มีค่าเท่ากับ /etc/passwd
  • ใน PHP ตัด / หลังตัวอักษรสุดท้ายทิ้ง /etc/passwd/ มีค่าเท่ากับ /etc/passwd และ /etc/passwd////// มีผลเดียวกับ  /etc/passwdเช่นกัน
  • ใน PHP ./ใส่ไปต่อท้าย /etc/passwd/กี่ครั้งก็ได้ ไม่ว่าจะเป็น /etc/passwd/./, /etc/passwd/././. ก็มีค่าเท่ากับ /etc/passwd.

ซึ่งตัว ../../../etc/passwd/././././././ กี่ครั้งก็แล้วแต่ก็จะผลเท่ากับ ../../../etc/passwd เนื่องด้วย php จะกำหนดไฟล์ให้มีขนาดความยาวได้มากสุดแค่ 4096 byte เท่านั้น หากมากว่านั้นก็จะตัดส่วนที่เกินทิ้ง ซึ่งทำให้สามารถ filter บางอันที่คอยดูชื่อไฟล์ได้

แต่วิธีนี้จะไม่ได้ผลกับ PHP version ที่มากกว่า 5.3.4 ครับ

การทำ RCE ผ่าน LFI

เราสามารถทำได้โดยให้รับค่าโดยตรงจาก php code ที่ inject เข้าไปเลย

ซึ่ง php://filter ก็คือหนึ่งใน PHP Wrapper นั่นเอง

การใช้งาน php://filter/convert.base64-encode/resource เป็นการบังคับให้อ่านไฟล์ที่เป็นเป้าหมายออกมาเป็น base64 แล้วนำมาแสดงผลนั่นเอง

หากใช้เป็น php://expect จะทำให้สามารถทำเป็น RCE ได้ แต่ php://expect ไม่ได้ถูก enable มาโดย default

หากใช้ php://input เราจะสามารถส่ง payload ผ่านไปทาง POST Method ได้

หากใช้เป็น data:// เราสามารถ include PHP code จากส่วน Request ได้เลยทันที

Source::