นักพัฒนายุคเก่าๆเขาใช้ฟังชั่นอะไรกันถึงได้ถูกแฮกเว็บอัพโหลด Shell ?

ฟังชั่น PHP เหล่านี้ก็คือฟังชั่นที่ถูกหยิบมาใช้ ในระบบอัพโหลดไฟล์, แต่ถ้ามองในเรื่องความปลอดภัยจะโดนแฮกได้อย่างไรไปชมกันครับ


1.strrchar

ใช้ strrchr ตรวจสอบกับค่านามสกุลที่เป็น White list
การทำ whitelist ก็คิดว่าปลอดภัยกว่าการทำ blacklist ในตัวอยู่แล้ว
เพราะถ้านักพัฒนาเลือกที่จะทำ blacklist ก็ยังมีตัวเลือกอื่นๆมากมาย
ที่ไม่ได้จัดอยู่ในกลุ่ม Blacklist และเป็นตัวเลือกมากมายสำหรับ แฮกเกอร์
สรุปก็คือยัง โดนแฮกเว็บ ได้เหมือนเดิม เพราะอะไร ?

ก็ต้องไปศึกษาการทำงานของฟังชั่นกัน

strrchr คือฟังชั่นที่ใช้ค้นหาข้อความที่กำหนด จาก ข้างหลัง -> ข้างหน้า
คืนค่าข้อความตั้งแต่ตำแหน่งที่พบจนหมด หรือคืนค่า false ถ้าไม่พบข้อความ

ตัวอย่าง : การใช้ฟังชั่น strrchr ค้นหาจุด [.] เพื่อนำไปเช็ค extension

$valid_file_extensions = array(".jpg", ".jpeg", ".gif", ".png");  // กำหนดนามสกุลที่ยอมรับ
$file_extension = strrchr($_FILES["file"]["name"], "."); // จะได้นามสกุลไฟล์ที่ถูกอัพโหลด

List to Bypass : 
shell.jpg.php
shell.jpg.PhP
shell.php;.jpg
shell.php%0delete0.jpg
shell.php.test
shell.php.xxxjpg
.phtml
.php3/.php4/.php5

bla bla bla






2.getimagesize
คือฟังชั่นใช้หาขนาดความกว้าง,สูง ของภาพ
ถ้า ผู้พัฒนาเข้าใจว่าไฟล์จะต้องเป็นชนิดภาพที่แท้จริง
โดยไม่มีการตรวจสอบ Mime Type  หรือการป้องกันอื่นๆเพิ่มเติม
แฮกเกอร์ จะสามารถแฮกเว็บคุณได้ โดยการ Bypass โดยใช้ GIMP เพิ่ม Comment ภาพ





3.เช็คประเภทไฟล์ที่อัพโหลดขึ้นมาด้วย 
$_FILES['some_name']['type'] ?


   if ($_FILES['some_name']['type'] == 'image/jpeg') {  
       //Proceed to accept the file as a valid image
   }


โดยปกติหากนักพัฒนาเช็ค TYPE ของไฟล์ดังนี้ โค้ดนี้จะตรวจสอบประเภทไฟล์
หรือการวิเคราะห์ที่ตรวจสอบข้อมูลได้จริง แต่ใช้วิธีการตรวจสอบจาก จาก HTTP Request ที่ร้องขอเข้ามาเท่านั้น ,  แฮกเกอร์ สามารถ แฮกเว็บโดยการ Upload ไฟล์โดยใช้ script ส่งค่าผ่าน HTTP POST request จะสามารถ fake mime-type ได้สำเร็จ

การตรวจสอบ การอัพโหลดไฟล์รูปภาพ และอื่นๆ
ให้ปลอดภัยจึงแนะนำให้ใช้งาน finfo Class

$finfo = new finfo(FILEINFO_MIME_TYPE);
$mime_type = $finfo->buffer($contents);




4.pathinfo

คือฟังชั่นที่ใช้หา "ที่อยู่ของไฟล์" , "ชื่อไฟล์.นามสกุล" , "ชื่อไฟล์"

### Excample ###
<?php

$result = pathinfo("/var/www/laravel/sell_image/pathfile/ak1");
print_r($result);

echo '<br><br><br>';
echo $result['dirname'].'<br>';
echo $result['basename'].'<br>';
echo $result['filename'].'<br>';
?>


### output ###
Array (
   [dirname] => /var/www/website/image/pathfile
   [basename] => ak1.jpeg
   [extension] => jpeg
   [filename] => ak1
)

/var/www/website/image/pathfile
ak1.jpeg
jpeg
ak1


สำหรับ pathinfo แฮกเกอร์ก็ยังจะสามารถแฮกเว็บ จากการ bypass ได้อย่างง่ายดาย
ดังตัวอย่างต่อไปนี้

สมมุติให้มีไฟล์อยู่ 2 ไฟล์  vulnerable.php and index.php.

vulnerable.php
<?php
    $file = pathinfo($_GET['file']);
    if ($file['extension'] == '.jpg') echo 'เป็นไฟล์นามสกุล jpg !';
       if (file_exists($file['basename'])) echo 'พบไฟล์ภาพ';
       else echo 'ไม่พบไฟล์ภาพ !';
?>

ตามโค้ดตัวอย่างโดยด้านบน เราสามารถเรียกใช้ไฟล์ bug.php
โดยส่งค่า get parameter ไปเพื่อหาไฟล์ที่มี ดังนี้

URL: 'vulnerable.php?file=index.php.jpg'

หรือใช้เทคนิค  "null byte"

ซึ่งจะได้ผลลัพธ์กลับมาว่า :  เป็นไฟล์นามกสุล jpg  + พบไฟล์ภาพ
แล้วถ้านักพัฒนานำฟังชั่นที่ใช้งานง่ายๆตัวนี้

ไปใช้ตรวจสอบไฟล์ภาพจริงในระบบจริง โดยไม่มีการตรวจสอบ Mime Type หรือการป้องกันอื่นๆพื้นเติม ก็อาจเป็นทางเลือกช่วยให้นักพัฒนา Happy กับการ Coding ขึ้นมาบ้างก็จริง

แต่ !  "แฮกเกอร์ ก็ Happy Hacking ด้วยเช่นกัน"




แนะนำบทความถัดไป
( 8 วิธี แฮก Bypass และความปลอดภัยของระบบ FileUpload บนเว็บไซต์)
http://iak1.blogspot.com/2015/07/bypass-fileupload.html


-- ref --
https://www.owasp.org/index.php/PHP_Security_Cheat_Sheet
http://hackers2devnull.blogspot.com/2013/05/how-to-shell-server-via-image-upload.html
http://code.function.in.th/php/string/string_strrchr
http://www.madirish.net/202