ph-sanchat.github.io

Directory traversal

ในส่วนนี้เราจะอธิบายว่า Diractory traversal คืออะไรอธิบายวิธีดำเนินการโจมตีข้ามเส้นทางและหลีกเลี่ยงอุปสรรคทั่วไปและระบุวิธีป้องกันช่องโหว่ path traversal

What is directory traversal?

Directory traversal (หรือที่เรียกว่า file path traversal) เป็นช่องโหว่ด้านความปลอดภัยของเว็บที่อนุญาตให้ผู้โจมตีอ่านไฟล์โดยพลการบนเซิร์ฟเวอร์ที่กำลังเรียกใช้แอปพลิเคชัน ซึ่งอาจรวมถึงรหัสแอปพลิเคชันและข้อมูลหนังสือรับรองสำหรับระบบส่วนหลังและไฟล์ระบบปฏิบัติการที่ละเอียดอ่อน ในบางกรณีผู้โจมตีอาจสามารถเขียนไปยังไฟล์ที่กำหนดเองบนเซิร์ฟเวอร์ทำให้สามารถแก้ไขข้อมูลหรือพฤติกรรมของแอปพลิเคชันและในที่สุดก็สามารถควบคุมเซิร์ฟเวอร์ได้อย่างเต็มที่

การอ่านไฟล์โดยพลการผ่าน Directory traversal

พิจารณาแอปพลิเคชันการช็อปปิ้งที่แสดงรูปภาพของสินค้าสำหรับขาย รูปภาพถูกโหลดผ่าน HTML ดังต่อไปนี้:

<img src="/loadImage?filename=218.png">

loadImage URL รับพารามิเตอร์ filename และส่งคืนเนื้อหาของไฟล์ที่ระบุ ไฟล์ภาพจะถูกเก็บไว้ในดิสก์ในตำแหน่ง /var/www/images/ ในการส่งคืนรูปภาพแอปพลิเคชันจะต่อท้ายชื่อไฟล์ที่ร้องขอเข้ากับไดเร็กทอรีฐานนี้และใช้ระบบไฟล์ API เพื่ออ่านเนื้อหาของไฟล์ ในกรณีข้างต้นแอปพลิเคชันอ่านจากพาธไฟล์ต่อไปนี้:

/var/www/images/218.png

แอปพลิเคชันไม่มีการป้องกันจากการโจมตีแบบข้ามผ่านไดเรกทอรีดังนั้นผู้โจมตีสามารถขอ URL ต่อไปนี้เพื่อดึงไฟล์โดยพลการจากระบบไฟล์ของเซิร์ฟเวอร์:

https://insecure-website.com/loadImage?filename=../../../etc/passwd

สิ่งนี้ทำให้แอปพลิเคชันอ่านจากพาธไฟล์ต่อไปนี้:

/var/www/images/../../../etc/passwd

ลำดับ ../ ถูกต้องภายในเส้นทางไฟล์และหมายถึงการก้าวขึ้นหนึ่งระดับในโครงสร้างไดเร็กทอรี ลำดับ .. / สามลำดับต่อเนื่องกันเพิ่มขึ้นจาก /var/www/images/ ไปยังรูทของระบบไฟล์ดังนั้นไฟล์ที่อ่านจริงคือ:

/etc/passwd

บนระบบปฏิบัติการที่ใช้ Unix นี่คือไฟล์มาตรฐานที่มีรายละเอียดของผู้ใช้ที่ลงทะเบียนบนเซิร์ฟเวอร์ ใน Windows ทั้ง ../ และ .. \ เป็นลำดับการส่งผ่านไดเร็กทอรีที่ถูกต้องและการโจมตีที่เทียบเท่ากันเพื่อดึงไฟล์ระบบปฏิบัติการมาตรฐานคือ:

https://insecure-website.com/loadImage?filename=..\..\..\windows\win.ini

อุปสรรคทั่วไปในการใช้ช่องโหว่ path traversal

แอพพลิเคชั่นจำนวนมากที่ใส่อินพุตของผู้ใช้ลงในพาธไฟล์ใช้การป้องกันบางประเภทจากการโจมตีแบบข้ามเส้นทางและสิ่งเหล่านี้มักจะหลีกเลี่ยงได้ หากแอปพลิเคชันตัดหรือบล็อกลำดับการข้ามผ่านไดเร็กทอรีจากชื่อไฟล์ที่ผู้ใช้จัดหามาอาจเป็นไปได้ที่จะข้ามการป้องกันโดยใช้เทคนิคต่างๆ คุณอาจสามารถใช้พาธสัมบูรณ์จากรูทระบบไฟล์เช่น filename = /etc/passwd เพื่ออ้างอิงไฟล์โดยตรงโดยไม่ต้องใช้ลำดับการข้ามผ่านใด ๆ

คุณอาจสามารถใช้ลำดับการข้ามผ่านที่ซ้อนกันได้เช่น …. // หรือ …. \ / ซึ่งจะเปลี่ยนกลับเป็นลำดับการข้ามผ่านแบบง่ายเมื่อมีการถอดลำดับภายใน

คุณอาจสามารถใช้การเข้ารหัสที่ไม่ได้มาตรฐานต่างๆเช่น .. % c0% af หรือ .. % 252f เพื่อข้ามตัวกรองอินพุต

หากแอปพลิเคชันต้องการให้ชื่อไฟล์ที่ผู้ใช้จัดหาต้องขึ้นต้นด้วยโฟลเดอร์ฐานที่คาดไว้เช่น /var/www/images อาจเป็นไปได้ที่จะรวมโฟลเดอร์ฐานที่ต้องการตามด้วยลำดับการส่งผ่านที่เหมาะสม ตัวอย่างเช่น:

filename=/var/www/images/../../../etc/passwd

หากแอปพลิเคชันต้องการให้ชื่อไฟล์ที่ผู้ใช้จัดหาต้องลงท้ายด้วยนามสกุลไฟล์ที่คาดหวังเช่น. png อาจเป็นไปได้ที่จะใช้ null byte เพื่อยุติเส้นทางไฟล์ก่อนนามสกุลที่ต้องการ ตัวอย่างเช่น:

filename=../../../etc/passwd%00.png

How to prevent a directory traversal attack?

วิธีที่มีประสิทธิภาพที่สุดในการป้องกันช่องโหว่ path traversal คือ หลีกเลี่ยงการส่งอินพุตที่ผู้ใช้จัดหาไปยัง API ของระบบไฟล์โดยสิ้นเชิง ฟังก์ชันแอปพลิเคชันจำนวนมากที่ทำเช่นนี้สามารถเขียนใหม่เพื่อให้มีลักษณะการทำงานเดียวกันได้อย่างปลอดภัยยิ่งขึ้น

หากถือว่าหลีกเลี่ยงไม่ได้ที่จะส่งอินพุตที่ผู้ใช้จัดหาไปยัง API ของระบบไฟล์ควรใช้การป้องกันสองชั้นร่วมกันเพื่อป้องกันการโจมตี:

ด้านล่างนี้เป็นตัวอย่างโค้ด Java แบบง่าย ๆ เพื่อตรวจสอบความถูกต้องของพาธ Canonical ของไฟล์ตามอินพุตของผู้ใช้:

File file = new File(BASE_DIRECTORY, userInput);
if (file.getCanonicalPath().startsWith(BASE_DIRECTORY)) {
    // process file
}

References:

Author