ฟังชั่น 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