🔏Directory traversal

Server Side Vul

Truyền tải thư mục là gì ?

Directory traversal (còn được gọi là file path traversal) là một lỗ hổng bảo mật web cho phép kẻ tấn công đọc các tệp tùy ý trên máy chủ đang chạy một ứng dụng. Điều này có thể bao gồm mã ứng dụng và dữ liệu, thông tin đăng nhập cho hệ thống back-end và các tệp hệ điều hành nhạy cảm. Trong một số trường hợp, kẻ tấn công có thể ghi vào các tệp tùy ý trên máy chủ, cho phép chúng sửa đổi dữ liệu hoặc hành vi của ứng dụng và cuối cùng là toàn quyền kiểm soát máy chủ.

Đọc các file tùy ý thông qua truyền thư mục

Xem xét một ứng dụng mua sắm hiển thị hình ảnh của các mặt hàng được bán. Hình ảnh được tải qua một số HTML như sau:

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

URL loadImage nhận một filename tham số và trả về nội dung của tệp được chỉ định. Bản thân các tệp hình ảnh được lưu trữ trên đĩa ở vị trí /var/www/images/. Để trả về một hình ảnh, ứng dụng sẽ gắn tên tệp được yêu cầu vào thư mục cơ sở này và sử dụng API hệ thống tệp để đọc nội dung của tệp. Trong trường hợp trên, ứng dụng đọc từ đường dẫn tệp sau:

/var/www/images/218.png

Ứng dụng không có biện pháp bảo vệ nào chống lại các cuộc tấn công directory traversal, vì vậy kẻ tấn công có thể yêu cầu URL sau để truy xuất tệp tùy ý từ hệ thống tệp của máy chủ:

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

Điều này khiến ứng dụng đọc từ đường dẫn tệp sau:

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

Trình tự ../ hợp lệ trong đường dẫn tệp và có nghĩa là đi vào một tệp con trong cấu trúc thư mục. Ba cái như này ../ có nghĩa là trình tự liên tiếp đi lên từ /var/www/images/gốc hệ thống tệp và do đó tệp thực sự được đọc là:

/etc/passwd

Trên hệ điều hành dựa trên Unix, đây là một tệp tiêu chuẩn chứa thông tin chi tiết của người dùng đã đăng ký trên máy chủ.

Trên Windows, cả hai ../..\ đều là trình tự duyệt thư mục hợp lệ và một cuộc tấn công tương đương để truy xuất tệp hệ điều hành tiêu chuẩn sẽ là:

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

Đối với hệ điều hành dựa trên Unix :

  • /etc/passwd file: Contains information about all the user’s account

  • /etc/group file: Contains groups to which users belong

  • /etc/profile file: Contains default variables for users

  • /proc/self/environ file: Contains certain environmental variables

  • /etc/issue file: Contains message to be displayed before the login

  • /proc/version file: Contains the Linux kernel version in use

  • /proc/cpuinfo file: Contains the processor information

Đối với hệ điều hành Windows :

  • C:\Windows\repair\system

  • C:\Windows\repair\SAM

  • C:\Windows\win.ini

  • C:\boot.ini

  • C:\Windows\system32\config\AppEvent.Evt

Ví dụ file PHP:

<?php

	$file = $_GET['page']; //Tramg web chúng ta muốn hiển thị

?>

Dưới đây là một URL có chức năng bao gồm dưới dạng yêu cầu phương thức GET:

http://192.168.29.23/dvwa/vulnerabilities/fi/?page=include.php

Sử dụng Directory Traversal Attack, kẻ tấn công có thể nối ../ trực tiếp vào đường dẫn tệp trong URL:

http://192.168.29.23/dvwa/vulnerabilities/fi/?page=../../../

Những trở ngại thường gặp khi khai thác lỗ hổng file path traversal

Nhiều ứng dụng đặt đầu vào của người dùng vào đường dẫn tệp thực hiện một số loại phòng thủ chống lại các cuộc tấn công path traversal và chúng thường có thể bị phá vỡ.

Nếu một ứng dụng tách hoặc chặn các trình tự duyệt thư mục từ tên tệp do người dùng cung cấp, thì có thể vượt qua sự bảo vệ bằng nhiều kỹ thuật khác nhau.

Bạn có thể sử dụng một đường dẫn tuyệt đối từ gốc hệ thống tệp, chẳng hạn như filename=/etc/passwd, để tham chiếu trực tiếp đến tệp mà không cần sử dụng bất kỳ trình tự truyền tải nào.

Bạn có thể sử dụng các trình tự duyệt lồng nhau, chẳng hạn như ....// hoặc ....\/, sẽ hoàn nguyên về trình tự duyệt đơn giản khi trình tự bên trong bị loại bỏ.

Trong một số ngữ cảnh, chẳng hạn như trong đường dẫn URL hoặc filename tham số của multipart/form-data yêu cầu, máy chủ web có thể loại bỏ bất kỳ trình tự duyệt thư mục nào trước khi chuyển đầu vào của bạn cho ứng dụng. Đôi khi, bạn có thể bỏ qua loại kiểm tra này bằng cách mã hóa URL, hoặc thậm chí mã hóa URL kép, các ../ ký tự, dẫn đến %2e%2e%2f hoặc %252e%252e%252f tương ứng. Các mã hóa không chuẩn khác nhau, chẳng hạn như ..%c0%af hoặc ..%ef%bc%8f , cũng có thể thực hiện thủ thuật.

Đối với người dùng Burp Suite Professional , Burp Intruder cung cấp danh sách tải trọng được xác định trước ((Fuzzing - path traversal) ), chứa nhiều chuỗi truyền tải đường dẫn được mã hóa mà bạn có thể thử.

Nếu một ứng dụng yêu cầu tên tệp do người dùng cung cấp phải bắt đầu bằng the expected base folder, chẳng hạn như /var/www/images, thì có thể bao gồm thư mục cơ sở bắt buộc theo sau bởi các trình tự truyền tải phù hợp. Ví dụ:

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

Nếu ứng dụng yêu cầu tên tệp do người dùng cung cấp phải kết thúc bằng phần mở rộng tệp dự kiến, chẳng hạn như .png, thì có thể sử dụng byte rỗng để kết thúc hiệu quả đường dẫn tệp trước phần mở rộng được yêu cầu. Ví dụ:

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

%00 ở đây là NULL, nó thường dùng bypass trong XSS

Cách ngăn chặn cuộc tấn công directory traversal

  • Để ngăn chặn việc truyền thư mục trong máy chủ web của bạn, hãy luôn cập nhật máy chủ web và hệ điều hành của bạn.

  • Trang web phải xác thực đầu vào của người dùng trước khi xử lý để ngăn chặn các cuộc tấn công directory traversal.

  • Các quyền được cấp cho người dùng không phải là người dùng cấp cao phải ở chế độ chỉ đọc đối với các tệp mà nó cần để chạy. Người không phải là superuser không được phép viết hoặc sửa đổi bất kỳ tệp nào.

  • Khi bất kỳ yêu cầu URL nào được thực hiện cho một thư mục hoặc tệp, hãy chuẩn hóa tất cả các ký tự. Ví dụ: tất cả %20 phải được chuyển đổi thành dấu cách.

  • Luôn chạy máy chủ web của bạn từ một ổ đĩa riêng biệt khỏi ổ đĩa hệ thống của bạn vì ổ đĩa hệ thống có thông tin nhạy cảm.

  • Nếu bạn cần fetch a file name từ người dùng, hãy đảm bảo rằng nó được quét đúng cách bằng các ký tự hợp lệ.

Dưới đây là ví dụ về một số mã Java đơn giản để xác thực đường dẫn chuẩn của tệp dựa trên thông tin người dùng nhập:

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

Cảm ơn mọi người đã đọc bài viết !

Last updated