Tin An Ninh Mạng

Lỗ hổng CVE-2015-2348 cho phép khai thác form upload trên PHP

1489939945hacker-attack.jpg
Cập nhật 17h00 ngày 3/4/2015: Mặc dù lỗi với hàm move_uploaded_file() là nghiêm trọng, nhưng nếu lập trình an toàn, kiểm tra cẩn thận điều kiện gọi hàm thì vẫn chống được các hình thức tấn công. Đây cũng có thể là lý do mà điểm CVSS của lỗi này chỉ là 5.0, ở mức trung bình. Các bạn có thể đọc bài phân tích chi tiết về lỗi CVE-2015-2348 trên PHP của WhiteHat tại đây

——————————————————–

Theo một bài viết trên blog của nhà nghiên cứu Paulos Yibelo, một lỗ hổng khá nghiêm trọng tồn tại trên PHP có tên CVE-2015-2348 đã được phát hiện.

{

}

1489939942php-bug.jpg

Yibelo cho biết file hợp lệ vẫn có thể cho phép tin tặc tiến hành các cuộc tấn công. Tuy nhiên, kiểm tra lỗ hổng trong đoạn mã của bạn là điều không thể bởi lỗ hổng có thể vượt qua các cơ chế kiểm soát: Loại-Nội dung, Mở rộng, kích thước…

Vấn đề nằm ở hàm move_uploaded_files rất phổ biến của php. Hàm này chủ yếu được sử dụng để xử lý các file được upload. Chức năng của hàm là kiểm duyệt để đảm bảo rằng file được xác định bằng tên là file upload hợp lệ (có nghĩa là file đã được tải lên thông qua cơ chế HTTP POST của PHP). Nếu hợp lệ, file sẽ được đổi tên chỉ định trên trang đích.

Ví dụ:

move_uploaded_file ( string $filename , string $destination )

Tuy nhiên, có 1 cách có thể chèn byte rỗng (lỗi này có tên CVE-2006-7243 và đã được vá từ lâu). Bằng cách sử dụng byte rỗng có ký tự x00, kẻ tấn công có thể đánh lừa upload box là file hợp lệ và upload những file độc hại gây ra lỗi RCE.

Lấy môi trường thực nghiệm DVWA làm ví dụ. Cấp cao nhất của DVWA là mức độ không thể vượt qua. Cấp độ cao nhất của upload box là hướng dẫn các nhà phát triển xử lý công đoạn upload một cách an toàn.

Dưới đây là kết quả thử nghiệm khai thác lỗ hông trên đoạn mã của https://github.com/RandomStorm/DVWA/blob/master/vulnerabilities/upload/source/high.php:

$uploaded_name = $_FILES[‘uploaded’][‘name’];
$uploaded_ext = substr($uploaded_name, strrpos($uploaded_name, ‘.’) + 1); $uploaded_size = $_FILES[‘uploaded’][‘size’];

if (($uploaded_ext == “jpg” || $uploaded_ext == “JPG” || $uploaded_ext == “jpeg” || $uploaded_ext == “JPEG”) && ($uploaded_size < 100000)){ if(!move_uploaded_file($_FILES[‘uploaded’][‘tmp_name’], $target_path)) {

$html .= ”;
$html .= ‘Your image was not uploaded.’;
$html .= ”; }
else {
$html .= $target_path . ‘ succesfully uploaded!’;
.
.

Điều này hiển nhiên ảnh hưởng tới một số hình thức khai thác như XSCH, XSS… nhưng không phải RCE bởi byte rỗng của PHP 5.3.1 không được chấp nhận.

Vấn đề của DVWA là người dùng lại cung cấp tên file cho hàm move_uploaded_file().

Khi sử dụng câu lệnh PHP:

move_uploaded_file($_FILES[‘name’][‘tmp_name’],”/file.phpx00.jpg”)

Về lý thuyết sẽ tạo ra file “file.phpx00.jpg”

Nhưng trên thực tế, kết quả lại tải lên file có tên là: file.php

Rõ ràng là lỗ hổng vượt qua được cơ chế kiểm tra phần mở rộng của tên file. Điều này đã được chứng minh rất nhiều lần (như đối với các hàm getimagesize(), imagecreatefromjpeg()… ).

Hầu hết các form upload chạy các phiên bản PHP trước 5.4.39, 5.5 trước 5.5.23 và 5.6.x trước 5.6.7 không lọc byte rỗng đều bị ảnh hưởng bởi cuộc tấn công này.

Nguồn: Paulos Yibelo Blog
Re: Lỗ hổng CVE-2015-2348 cho phép khai thác form upload trên PHP

WhiteHat News #ID:0911;24243 đã viết:
Theo một bài viết trên blog của nhà nghiên cứu Paulos Yibelo, một lỗ hổng khá nghiêm trọng tồn tại trên PHP có tên CVE-2015-2348 đã được phát hiện.

1489939942php-bug.jpg

Yibelo cho biết file hợp lệ vẫn có thể cho phép tin tặc tiến hành các cuộc tấn công. Tuy nhiên, kiểm tra lỗ hổng trong đoạn mã của bạn là điều không thể bởi lỗ hổng có thể vượt qua các cơ chế kiểm soát: Loại-Nội dung, Mở rộng, kích thước…

Vấn đề nằm ở hàm move_uploaded_files rất phổ biến của php. Hàm này chủ yếu được sử dụng để xử lý các file được upload. Chức năng của hàm là kiểm duyệt để đảm bảo rằng file được xác định bằng tên là file upload hợp lệ (có nghĩa là file đã được tải lên thông qua cơ chế HTTP POST của PHP). Nếu hợp lệ, file sẽ được đổi tên chỉ định trên trang đích.

Ví dụ:

move_uploaded_file ( string $filename , string $destination )

Tuy nhiên, có 1 cách có thể chèn byte rỗng (lỗi này có tên CVE-2006-7243 và đã được vá từ lâu). Bằng cách sử dụng byte rỗng có ký tự x00, kẻ tấn công có thể đánh lừa upload box là file hợp lệ và upload những file độc hại gây ra lỗi RCE.

Lấy môi trường thực nghiệm DVWA làm ví dụ. Cấp cao nhất của DVWA là mức độ không thể vượt qua. Cấp độ cao nhất của upload box là hướng dẫn các nhà phát triển xử lý công đoạn upload một cách an toàn.

Dưới đây là kết quả thử nghiệm khai thác lỗ hông trên đoạn mã của https://github.com/RandomStorm/DVWA/blob/master/vulnerabilities/upload/source/high.php:

$uploaded_name = $_FILES[‘uploaded’][‘name’];
$uploaded_ext = substr($uploaded_name, strrpos($uploaded_name, ‘.’) + 1); $uploaded_size = $_FILES[‘uploaded’][‘size’];

if (($uploaded_ext == “jpg” || $uploaded_ext == “JPG” || $uploaded_ext == “jpeg” || $uploaded_ext == “JPEG”) && ($uploaded_size < 100000)){ if(!move_uploaded_file($_FILES[‘uploaded’][‘tmp_name’], $target_path)) {

$html .= ”;
$html .= ‘Your image was not uploaded.’;
$html .= ”; }
else {
$html .= $target_path . ‘ succesfully uploaded!’;
.
.

Điều này hiển nhiên ảnh hưởng tới một số hình thức khai thác như XSCH, XSS… nhưng không phải RCE bởi byte rỗng của PHP 5.3.1 không được chấp nhận.

Vấn đề của DVWA là người dùng lại cung cấp tên file cho hàm move_uploaded_file().

Khi sử dụng câu lệnh PHP:

move_uploaded_file($_FILES[‘name’][‘tmp_name’],”/file.phpx00.jpg”)

Về lý thuyết sẽ tạo ra file “file.phpx00.jpg”

Nhưng trên thực tế, kết quả lại tải lên file có tên là: file.php

Rõ ràng là lỗ hổng vượt qua được cơ chế kiểm tra phần mở rộng của tên file. Điều này đã được chứng minh rất nhiều lần (như đối với các hàm getimagesize(), imagecreatefromjpeg()… ).

Hầu hết các form upload chạy các phiên bản PHP trước 5.4.39, 5.5 trước 5.5.23 và 5.6.x trước 5.6.7 không lọc byte rỗng đều bị ảnh hưởng bởi cuộc tấn công này.

Nguồn: Paulos Yibelo Blog

bàn luận bug này chút xíu, nếu REQUEST qua các hàm truncate null byte trước khi qua move_uploaded_file() thì hóa ra bug này ko pass được, nhưng mà nếu kiểu check như trên bài thì thọt :D , thấy cách bypass để upload file này đâu mới đâu 😐

Đăng ký liền tay Nhận Ngay Bài Mới

Subscribe ngay

Cám ơn bạn đã đăng ký !

Lỗi đăng ký !

Add Comment

Click here to post a comment

Đăng ký liền tay
Nhận Ngay Bài Mới

Subscribe ngay

Cám ơn bạn đã đăng ký !

Lỗi đăng ký !