Kỹ thuật vượt qua kiểm tra tải file lên (các phương pháp khác)

Giới thiệu

Bài viết trước đã giới thiệu sơ lược về cách vượt qua kiểm tra phía client. Bài viết này sẽ tổng hợp các phương pháp vượt qua khác.

Nội dung chính

1.1 Vượt qua kiểm tra MIME phía máy chủ

Nguyên lý kiểm tra: Khi người dùng tải file lên, máy chủ sẽ lấy giá trị MIME của file và so sánh với danh sách cho phép. Nếu không khớp, file được coi là không hợp lệ.

Xem mã nguồn (ví dụ từ DVWA):

<?php
if( isset( $_POST[ 'Upload' ] ) ) {
    $target_path  = DVWA_WEB_PAGE_TO_ROOT . "hackable/uploads/";
    $target_path .= basename( $_FILES[ 'uploaded' ][ 'name' ] );
    $uploaded_name = $_FILES[ 'uploaded' ][ 'name' ];
    $uploaded_type = $_FILES[ 'uploaded' ][ 'type' ];
    $uploaded_size = $_FILES[ 'uploaded' ][ 'size' ];
    if( ( $uploaded_type == "image/jpeg" || $uploaded_type == "image/png" ) &&
        ( $uploaded_size < 100000 ) ) {
        if( !move_uploaded_file( $_FILES[ 'uploaded' ][ 'tmp_name' ], $target_path ) ) {
            echo 'Your image was not uploaded.';
        } else {
            echo "{$target_path} succesfully uploaded!";
        }
    } else {
        echo 'Your image was not uploaded. We can only accept JPEG or PNG images.';
    }
}
?>

Phân tích dòng 16, chỉ cần thay đổi giá trị content-type thành image/jpeg hoặc image/png là có thể vượt qua. Cần sử dụng công cụ bắt gói tin (như Burp Suite) để sửa đổi.

1.2 Vượt qua kiểm tra phần mở rộng file phía máy chủ

1.2.1 Vượt qua danh sách đen

Trong ứng dụng web, thường có file blacklist chứa các phần mở rộng nguy hiểm (như .php, .asp, .jsp). Tuy nhiên, danh sách đen thường không đầy đủ và có thể bị vượt qua bằng nhiều cách.

  • Thay đổi chữ hoa/chữ thường: Đổi phần mở rộng thành .pHp, .Asp, v.v.
  • Sử dụng phần mở rộng khác: Thử các đuôi không có trong danh sách đen như .asa, .cer, .cdx (với IIS).
  • Tên file đặc biệt: Đặt tên như xxx.asp. hoặc xxx.asp_ (có dấu chấm hoặc gạch dưới). Hệ thống Windows có thể tự động loại bỏ ký tự thừa sau khi vượt qua kiểm tra. Lưu ý: Unix/Linux không có đặc tính này.
  • Kỹ thuật chèn null byte (0x00): Trong hex, 0x00 tương đương ký tự null. Khi server đọc đường dẫn, nó sẽ dừng lại tại ký tự này. Ví dụ: upload file php.php.png chứa mã độc, nhưng sửa byte thứ hai (dấu chấm giữa php và png) thành 0x00 (trong hex là 2e -> 00). Kết quả server chỉ đọc php.php và thực thi.
  • Tấn công file .htaccess: Nếu có thể upload file .htaccess, thêm nội dung:
    <FilesMatch "shell">
    SetHandler application/x-httpd-php
    </FilesMatch>
    Sau đó upload một file không có phần mở rộng, nhưng trong nội dung phải chứa từ khóa shell. File sẽ được thực thi như PHP.

1.2.2 Vượt qua danh sách trắng

Danh sách trắng an toàn hơn danh sách đen, nhưng vẫn có thể bị tấn công bằng file .htaccess nếu được phép upload.

1.3 Vượt qua kiểm tra nội dung file phía máy chủ

Nếu máy chủ kiểm tra kỹ nội dung file (ví dụ chỉ chấp nhận ảnh), có thể nhúng mã độc vào file ảnh. Công cụ edjpgcom (hỗ trợ JPG) cho phép nhúng mã một cách dễ dàng mà không làm hỏng cấu trúc ảnh. Kéo file ảnh vào công cụ, một hộp thoại sẽ hiện ra để nhập mã (ví dụ <?php eval($_POST['cmd']);?>). Kết quả là file ảnh vẫn hiển thị bình thường nhưng chứa mã độc.

2.1 Lỗ hổng phân tích cú pháp

IIS 5.x/6.x

  • Phân tích cú pháp thư mục: Nếu có thư mục kết thúc bằng .asp (ví dụ /haha.asp/), mọi file trong thư mục đó (dù là .png, .txt) đều được thực thi như ASP.
  • Phân tích cú pháp file: File ha.asp;.png sẽ được thực thi như ha.asp vì server dừng phân tích tại dấu chấm phẩy.
  • Các phần mở rộng mặc định: IIS 6.0 mặc định thực thi các file .asp, .asa, .cer, .cdx.

Apache

Apache phân tích cú pháp từ phải sang trái. Nếu gặp phần mở rộng không xác định, nó sẽ bỏ qua và tiếp tục. Ví dụ: file test.php.rar.zip sẽ được thực thi như PHP vì Apache không biết .rar và .zip.

Nginx

  • Lỗi cấu hình PHP (cgi.fix_pathinfo): Khi gửi yêu cầu /upload/shell.png/random.php, Nginx chuyển cho PHP xử lý. PHP thấy random.php không tồn tại, bỏ qua và thực thi shell.png (nếu có chứa mã PHP). Lỗi này thường gặp ở các phiên bản PHP cũ, đã được khắc phục bằng tùy chọn security.limit_extensions.
  • Lỗ hổng Nginx < 8.03 (FAST-CGI): Upload file shell.jpg chứa mã:
    <?php file_put_contents('backdoor.php', '<?php eval(\$_POST[cmd])?>');?>
    Truy cập shell.jpg/.php, file backdoor.php sẽ được tạo.
  • Lỗ hổng null byte (Nginx < 8.03): Upload file ảnh chứa mã, đặt tên shell.jpg, truy cập shell.jpg%00.php để thực thi.

Cuối cùng, sơ đồ dưới đây (không hiển thị) minh họa quy trình kiểm thử có thể áp dụng.

Thẻ: Bảo mật web upload file lỗ hổng MIME chèn null byte .htaccess

Đăng vào ngày 24 tháng 6 lúc 10:33