สวัสดีครับเข้าเรื่องเลยดีกว่า.. เนื่องจากที่ผ่านมาว่างมาก เลยนั่งอ่านโค้ดของ maxsite 2.5 แล้วไปเจอโค้ดในไฟล์ index.php ในการเรียก template ที่โค้ด
// Calling TEMPLATE require_once( 'templates/'.WEB_TEMPLATES.'/index.php' );
เมื่อตามไปดูที่ไฟล์ index.php ของ template สมมุติว่าเป็น default template แล้วกันครับที่ path นี้ /templates/atomy/index.php จะเห็นว่ามีการใช้ฟังก์ชั่น require_once ซึ่งเป็นฟังก์ชั่นแนวเดียวกับ include อยู่ที่บรรทัดที่ 327
<?} else { OpenTable(); require_once ("".$MODPATHFILE.""); CloseTable(); } ?>เมื่อมีการเรียกใช้ $MODPATHFILE เรามาหาที่มาของตัวแปรนี้ แล้วก็มาเจอที่ไฟล์ /mainfile.php ที่ document root ครับซึ่งถูกเรียกใช้โดย index.php อยู่ในฟังก์ชัน GETMODULE ครับ มาดูฟังก์ชั่น GETMODULE ในไฟล์ mainfile.php กันครับ
function GETMODULE($name,$file){ global $MODPATH, $MODPATHFILE ; if(!$name){$name= "index";} if(!$file){$file = "index";} $modpathfile="modules/".$name."/".$file.".php"; if(file_exists($modpathfile)){ $MODPATHFILE = $modpathfile; $MODPATH = "modules/".$name."/"; }else{ die (""._NO_MOD.""); } }มาดูโค้ดที่เรียกใช้ฟังก์ชั่น GETMODULE ในไฟล์ index.php กันครับ
GETMODULE($name,$file);ซึ่งค่าที่ส่งเข้าฟังก์ชั่น GETMODULE มีการรับมาจาก User ทาง GET Method จะทำให้เข้าเงื่อนไขคือ ตัวแปร $name จะเท่ากับค่าว่างถ้าไม่มีการ GET มาที่ parameter name ซึ่งตัวแปร $file ก็เช่นกันครับ
empty($_GET['name'])?$name="":$name=$_GET['name']; empty($_GET['file'])?$file="":$file=$_GET['file'];เมื่อเข้าไปในฟังก์ชั่น GETMODULE จากบรรทัดที่ 28-29 จะเห็นว่าถ้าตัวแปร $name และ $file ไม่มีค่าจะเท่ากับ index ทั้งคู่แล้วมาอยู่ในตัวแปร $modpathfile โดยมี .php ปิดท้ายครับแต่เมื่อมีการ GET มาที่ parameter name จะกลายเป็นเข้าไปในโฟลเดอร์ของแต่ละ module แล้วระบุไฟล์ที่จะใช้งานโดยการ GET มาที่ parameter file ครับตัวอย่าง
http://localhost/maxsite/index.php?name=knowledge&file=readknowledge&id=2จะหมายความว่าเข้าไปที่โฟลเดอร์ knowledge ในโฟลเดอร์ modules ส่งค่า id=2 ไปที่ไฟล์ readknowledge.php ครับ (สังเกตุจากฟังก์ชั่น GETMODULE บรรทัดที่ 30)
เมื่อได้ข้อสรุปมาแบบนี้แสดงว่า parameter name นั้นก็คือใส่ path เราก็ใช้เทคนิคย้อน path ไปโดย ../../../.. ไปเรื่อยๆ ส่วน parameter file ก็ใส่ไฟล์ที่เราต้องการจะ include ยกตัวอย่าง etc/passwd แต่ในกรณีนี้มีการระบุนามสกุลของไฟล์ชัดเจนว่าเป็น .php สังเกตจากฟังก์ชั่น GETMODULE บรรทัดที่ 30
$modpathfile="modules/".$name."/".$file.".php"; if(file_exists($modpathfile)){ $MODPATHFILE = $modpathfile;
เมื่อเข้าเงื่อนไข if หมายความว่าถ้าไฟล์ที่จะ require_once นั้นมีจริงให้ตัวแปร $MODPATHFILE เท่ากับตัวแปร $modpathfile ดังกล่าว ถึงตอนนี้ก็ต้องใช้เทคนิค Null Byte ในการ Bypass ตัด .php ด้านหลังออกไปก็จะได้เป็น etc/passwd แต่เทคนิค Null Byte นี้จะต้องใช้กับ Linux Web Server และ PHP < 5.3.4 เท่านั้นครับสำหรับ URL ที่จะใช้ดึง etc/passwd ของ Web Server มาดูก็คือ
http://localhost/maxsite/index.php?name=../../../../..&file=etc/passwdผลลัพธ์ที่ได้...
เรียบร้อยครับ,,
Cr: ICheer_No0M