Bypassing Client-Side Filtering

Có thể trang web sử dụng client-side filtering dựa trên MIME type1, chẳng hạn như sau:

Để bypass, ta cần bắt được response của request và xóa đoạn code filtering đó đi. Cụ thể, chuột phải vào request đã capture được và dùng tính năng “Do intercept” > “Response to this request” của Burp Suite.

Hoặc, ta có thể upload file bình thường, nhưng khi gửi request đi thì ta lại capture và thay extension của file cũng như MIME type lại như sau:

Bypassing Server-Side Filtering: File Extensions

Có thể server filter exact match như sau:

<?php
    //Get the extension
    $extension = pathinfo($_FILES["fileToUpload"]["name"])["extension"];
    //Check the extension against the blacklist -- .php and .phtml
    switch($extension){
        case "php":
        case "phtml":
        case NULL:
            $uploadFail = True;
            break;
        default:
            $uploadFail = False;
    }
?>

Ta bypass bằng cách dùng một extension khác của PHP: .php3, .php4, .php5, .php7, .phps, .phtml, .php-s, .pht.phar.

Trong trường hợp luồng xử lý của server là:

ACCEPT FILE FROM THE USER -- SAVE FILENAME IN VARIABLE userInput
IF STRING ".jpg" IS IN VARIABLE userInput:
    SAVE THE FILE
ELSE:
    RETURN ERROR MESSAGE

Thì ta đổi extension thành .jpg.php.

Bypassing Server-Side Filtering: Magic Numbers

Trong trường hợp server filter dựa trên magic numbers (hay file signature), ta có thể ghi vào file cần upload các ký tự tùy ý:

Và chỉnh sửa chúng bằng hexeditor:

Cũng có thể sử dụng giá trị ASCII nếu magic numbers có dạng readable.

Methodology:

Các bước để khai thác lỗ hổng upload file:

  1. Tìm ra công nghệ được sử dụng ở phía server.
  2. Tìm các client-side filter.
  3. Upload một file hợp lệ và tìm thư mục chứa file bằng các tool brute force directory2. Nếu sử dụng Gobuster thì có thể thêm option sau: -x php,txt,html. Option này đặc biệt hữu ích khi server thay đổi tên của file được upload.
  4. Upload payload và xem hành vi của server dựa trên một số trường hợp sau:
    • Nếu ta upload một file có extension lung tung chẳng hạn testingimage.invalidfileextension mà server vẫn accept thì có thể xác định được server sử dụng black list. Ngược lại là white list.
    • Thay magic numbers của một file hợp lệ nào đó và upload. Nếu server deny thì tức là nó filter dựa trên magic number.
    • Tương tự với cách trên, nhưng lần này ta intercept request gửi đi và thay MIME type.
    • Upload một file lớn để xem có tồn tại file length limit hay không. Nếu có thì ta cần chú ý trong việc sử dụng payload sao cho thỏa mãn giới hạn này.

Challenge

Bắt response của file upload.js và phát hiện filtering code:

//Check File Size
if (event.target.result.length > 50 * 8 * 1024){
	setResponseMsg("File too big", "red");			
	return;
}
//Check Magic Number
if (atob(event.target.result.split(",")[1]).slice(0,3) != "ÿØÿ"){
	setResponseMsg("Invalid file format", "red");
	return;	
}
//Check File Extension
const extension = fileBox.name.split(".")[1].toLowerCase();
if (extension != "jpg" && extension != "jpeg"){
	setResponseMsg("Invalid file format", "red");
	return;
}

Xóa đoạn code này đi và forward request.

Sau đó, khi upload file thì vẫn bị lỗi “Invalid file type”. Capture request upload file rồi sửa MIME type thành image/jpeg và extension của file thành .jpg. Upload lại lần nữa thì thành công.

Ta dùng payload của PayloadsAllTheThings để tạo reverse shell.

Dùng Feroxbuster scan file dựa trên wordlist sẵn có, phát hiện được một danh sách các tập tin có đuôi là jpg ở thư mục content. Tuy nhiên, khi nhập tên các tập tin này vào /admin thì ta lại nhận được lỗi “không tìm thấy module”:

Để ý một chút thì thấy là page /admin sẽ chạy những file ở trong thư mục /modules. Mà thư mục này cùng cấp với /content (khám phá được thông qua Feroxbuster) nên ta cần path traversal ra 1 cấp để đến file cần thực thi.

Payload có dạng như sau (tên file có thể khác):

Success

THM{NzRlYTUwNTIzODMwMWZhMzBiY2JlZWU2}

Resources

Footnotes

  1. Là quy chuẩn mô tả loại file khi truyền tải với email ngày xưa, nay còn được sử dụng bởi HTTP

  2. Xem thêm Finding Hidden Contents.