ĐẠI HỌC THÁI NGUYÊN
TRƯỜNG ĐẠI HỌC CÔNG NGHỆ THÔNG TIN VÀ TRUYỀN THÔNG
BÀI TẬP LỚN
Môn Kiểm Chứng Phần Mềm
ĐỀ TÀI: Tìm hiểu một số công cụ kiểm thử, bảo mật
Ứng dụng vào KTBM trên website
Thành Viên: Nguyễn Văn Thanh
Đào Đình Thiện
Bùi Văn Công
Đỗ Mạnh Hùng
Ngô Tuấn Thịnh
1
CHƯƠNG I: TỔNG QUAN VỀ BẢO MẬT WEBSITE VÀ KIỂM THỬ BẢO
MẬT
1.1. Tổng quan về bảo mật
Bảo mật là sự thỏa hiệp giữa bảo mật và chức năng, khả năng sử dụng. Nếu
bảo mật của hệ thống quá chặt chẽ, nó sẽ trở nên rất khó sử dụng hoặc khó hoạt
động một cách hiệu quả. Nếu bảo mật quá đơn giản, hệ thống dễ bị tấn công và
xâm nhập.
Kiểm thử bảo mật Web, trong nghĩa truyền thống, là kiểm thử hiệu quả sự
bảo vệ toàn bộ hệ thống Web. Nó yêu cầu kết hợp nhiều kiến thức về các công
nghệ bảo mật, công nghệ mạng, lập trình, và kinh nghiệm thực tế về thâm nhập các
hệ thống mạng. Hầu hết các kiểm thử viên phần mềm không có loại kiến thức
này.Tuy nhiên, chúng ta nên hiểu các vấn đề về bảo mật sao cho chúng ta hiểu
được các công việc chúng ta nên làm và các công việc nên được thực hiện bởi các
chuyên gia khác.
Mục đích của bảo mật : Đảm bảo sự an toàn dữ liệu cho hệ thống và bảo
vệ các tài nguyên trên mạng trước sự tấn công nhằm phá vỡ hệ thống hoặc
sử dụng trái phép các tài nguyên của một số người có chủ ý xấu.
1.2. Giới thiệu về kiểm thử bảo mật
- Kiểm thử phần mềm là quá trình khảo sát một hệ thống hay thành phần
dưới những điều kiện xác định, quan sát và ghi lại các kết quả, và đánh
giá một khía cạnh nào đó của hệ thống hay thành phần đó.
- Kiểm thử phần mềm là quá trình thực thi một chương trình với mục đích
tìm lỗi.
- Kiểm thử phần mềm là hoạt động khảo sát thực tiễn sản phẩm hay dịch vụ
phần mềm trong đúng môi trường chúng dự định sẽ được triển khai nhằm
2
cung cấp cho người có lợi ích liên quan những thong tin về chất lượng
của sản phẩm hay dịch vụ phần mềm ấy. Mục đích của kiểm thử phầm
mềm là tìm ra các lỗi hay khiếm khuyết phầm mềm nhằm đảm bảo hiệu
quả hoạt động tối ưu của phần mềm trong nhiều ngành khác nhau.
1.3. Kiểm thử bảo mật
- Mục đích: tìm kiếm các lỗ hổng và rò rỉ thông tin gây nên chủ yếu do lập
trình và do cấu hình sai các trình chủ Web và các trình chủ ứng dụng
khác.
- Kiểm thử bảo mật liên quan đến trách nhiệm của nguồn khác nhau sau
đây:
+ Nhà định nghĩa chính sách (policymaker), định nghĩa các yêu cầu bảo
mật nhằm tang độ tin cậy của người sử dụng và nhà sản xuất hệ thống.
+ Người quản trị mạng, thiết kế và cài đặt các biện pháp bảo mật nhằm
cung cấp bảo mật ở mức hỏa động.
+ Lập trình viên phần mềm, chịu trách nhiệm kiểm thử độ hệ thống nhằm
phát hiện các lỗi chức năng, tương tác cấu hình và khả năng tương thích
khi họ liên quan đến cài đặt bảo mật (chủ yếu ở mức ứng dụng và có thể ở
mức hoạt động), phát hiện các vấn đề do lỗi thiết kế bảo mật.
+ Các chuyên gia và nhà tư vấn bảo mật, giúp kiểm thử và duy trì các
chương trình bảo mật vũng như xử lý các lỗ hổng bảo mật. Thông thường,
nhóm người này vốn trước đây là những kẻ tấn công. Những kẻ tấn công
cũ, là những người có nhiều kinh nghiệm, chịu trách nhiệm điều khiển
các kiểm thử xâm nhập trước khi triển khai một hệ thống. Trừ khi tổ chức
của chúng tôi không có một chuyên gia để thực hiện kiểm thử xâm nhập,
không nên để một kiểm thử viên và lập trình viên chịu trách nhiệm này.
- Những ưu điểm trong kiểm thử bảo mật
+ Kiểm thử bảo mật là kiểm thử chủ động, không bị động.
3
+ Các lỗi không được xử lý là các kho báu để chèn lỗi vào nhằm xác định
các lỗi bảo mật.
+ Các giao diện dữ liệu vào là các kho báu để chèn lỗi nhằm xác định các lỗi
bảo mật.
+ Hãy xem xét mọi dữ liệu vào không hợp lệ có thể xảy ra phái trình khách.
+ Hãy xem xét mọi dữ liệu vào không hợp lệ có thể xảy ra phía trình chủ.
+ Tập trung trên các điều kiện dữ liệu vào mà ở đó dữ liệu được chuyển từ
miền không tin cậyvào miền tin cậy.
+ Thiết kế các ca kiểm thử với sự nhấn mạnh trên các b
+ Tìm kiếm các lỗi cho phép người sử dụng thực thi chương trình trên máy
chủ. iên giữa các miền tin cậy và miền không tin cậy.
+ Tìm kiếm các lỗi cho phép người sử dụng thay đổi nâng cao quyền truy
cập.
+ Luôn ý thức rằng ứng dụng thường xử lý sai một số dữ liệu xấu đến từ phía
trình khách không tin cậy.
+ Tìm kiếm dữ liệu vào mà có thể trở nên thực thi được (ví dụ: khi dữ liệu
vào trở nên dữ liệu ra).
1.4. Đối tượng và hoạt động của Security Testing
Cần chú ý đến các đối tượng và hoạt động Test sau:
- Phân quyền (các vai trò và danh sách quyền tương ứng): chú ý vai trò của
từng đối tượng sử dụng và các quyền cùng việc phân quyền phải chính xác, nếu
không việc thông tin bị lộ một cách không phù hợp là khó tránh khỏi. Thông
thường các ứng dụng luôn có 1 function cho việc Phân quyền nên việc Test bảo
mật ở đây là test function của module Phân quyền và đảm bảo danh sách quyền đi
kèm từng vai trò và danh sách vai trò là đủ và chính xác.
- Độ an toàn của mạng (Network Scanning): thường sử dụng một tool quét tự
động các cổng truy cập để đảm bảo tất cả các host trong mạng lưới có được đảm
4
bảo an toàn trong mạng nội bộ và không bị truy cập bất hợp pháp từ một mạng
ngoài không.
Tool quét thường dùng cho trường hợp này là NMap.
- Rà soát các lỗ hổng tiềm ẩn (Vulnerability Scanning): Tool quét mạng có thể
phát hiện ra các lỗ hổng bảo mật đã có và tồn tại trong mạng hoặc ứng dụng, còn
kiểu test này là phát hiện ra các lỗ hổng bảo mật tiềm ẩn (chưa có ở thời điểm hiện
tại nhưng có thể xảy ra trong tương lai).
- Phát hiện các khả năng ăn trộm/bẻ gãy mật khẩu (Password Cracking)
- Phát hiện lỗ hổng bảo mật từ các bản ghi log (Firewall log, IDS log, Server
log ) => cùng là phát hiện lỗ hổng bảo mật tiềm ẩn hoặc đã có (tương tự phần 2,
và 3 nhưng phương thức thực hiện là khác nhau. Kiểu 2) và 3) là dùng tool quét tự
động và phân tích dựa trên kết quả đã qua sàng lọc của các tool quét tự động. Còn
phương thức 5) này dựa trên các bản ghi log của hệ thống).
- Kiểm tra tính toàn vẹn của hệ thống File (File Integrity Checkers): sự không
đồng nhất về kiểu dữ liệu file trong 1 ứng dụng hay hệ thống có thể tạo kẽ hở để
hacker thâm nhập vào. Rất nhiều virus khai thác qua kẽ hở này đã chứng minh điều
đó.
- Dò tìm và phát hiện virus (virus director)
- War Dialling: là 1 thuật ngữ chỉ 1 hình thức lỗ hổng bảo mật mà hacker có thể
khai thác qua modem mạng khiến gây ra hậu quả lớn. Các modem mạng nặc danh
xuất hiện trong hệ thống mạng cung cấp 1 phương tiện vượt qua được tất cả các
phương thức bảo mật. Có một số phần mềm cho phép hacker và người quản trị
mạng gọi được đến một số lượng lớn số điện thoại mà 1 modem có trong nó (ví dụ:
1 máy tính với 4 modem có thể gọi ra được 10.000 số điện thoại trong ngày, việc
thất thoát dữ liệu là rất lớn).
1.5. Các loại kiểm thử bảo mật
1.5.1 Kiểm thử yêu cầu và thiết kế.
5
Bất kỳ hệ thống nào cũng được xây dựng từ một tập hợp các yêu cầu. Đôi
khi những yêu cầu này được viết một cách rõ rang, nhưng thường chúng là những
phát biểu mật mờ không được định nghĩa rõ ràng. Ví dụ, có thể có phát biểu “Ứng
dụng phải an toàn”. Nhưng “an toàn” nghĩa là gì và nên phải dành bao nhiêu công
sức và thời gian để làm cho sản phẩm an toàn.
1.5.2 Kiểm thử mã nguồn
Phương pháp kiểm tra độ bảo mật của ứng dụng thông qua mã nguồn của
ứng dụng. Phuong pháp kiểm thử này chủ yếu dung để xác định sự an toàn của
thuật toán được dung trong ứng dụng, xác độ nguy cơ rò rỉ thông tin, nguy cơ bị tấn
công chiếm quyền kiểm soát thông qua mã nguồn. Phương pháp này thường ứng
dụng kỹ thuật kiểm thử hộp trắng.
1.5.3 Kiểm thử các thiết lập của trình duyệt
Các thiết lập của trình duyệt có thể được cài đặt trong các trình duyệt như
Mozilla FireFox và Micrrosoft Internet Explorer cho phép giới hạn truy cập đến các
nội dung internet có thể gây hại. Người sử dụng sẽ thường có các chỉnh sửa các
thiết lập này.Hơn nữa, có một sự thay đổi lớn phía người sử dụng về khả năng làm
chủ các thiết lập này.Những người sử dụng Web ngày càng được đào tạo nhiều hơn
cách sử dụng các thiết lập để bảo vệ chính họ. Với tư cách là một đội phát triển
Website hay ứng dụng Web, chúng ta không thể bắt buộc người sử dụng chấp nhận
các thiết bị mặc định. Vì vậy, chúng ta cần phải kiểm thử nhiều sự kết hợp của các
thiết lập.
1.5.4 Kiểm thử bức tường lửa
Cần nhắc lại rằng nhóm kiểm thử phần mềm không chịu trách nhiệm kiểm
thử sự hiệu quả của các tường lửa và sự cấu hình chúng.Kiểm thử tường lửa nhằm
nhận biết các hiệu ứng về chức năng được tạo ra bởi sự chuyển đổi dữ liệu qua các
mạng khác nhau.Một số mạng riêng và một số khác công cộng.
6
1.6. Quy trình kiểm thử bảo mật Website
1.6.1 Quy trình kiểm thử thủ công
Hình 2.4: Quy trình kiểm thử thủ công
7
1.6.2 Quy trình kiểm thử bảo mật đê xuất
Hình 2.5: Quy trình kiểm thử bảo mật đề xuất
8
1.6.3 Mô hình kiểm thử bảo mật phân tích và thiết kế
Hình 2.6: Mô hình kiểm thử bảo mật phân tích thiết kế
9
1.6.4 Mô hình kiểm thử mã nguồn tự động
Hình 2.7: Mô hình kiểm thử bảo mật
10
CHƯƠNG 2. CÁC KỸ THUẬT TẤN CÔNG CƠ BẢN VÀO
ỨNG DỤNG VÀ CÁC KỸ THUẬT KIỂM THỬ
2.1. Tấn công vào các lỗ hổng- điểm yếu (Injection vulnerabilities)
Loại tấn công này thường được sử dụng khi dữ liệu đầu vào chưa được xác nhận
(validated). Những cuộc tấn công này sẽ cung cấp một số dữ liệu đầu vào và đính
kèm thêm dữ liệu độc hại (Những dữ liệu đính thêm này có thể dưới dạng các dòng
lệnh để lấy được thêm các thông tin bảo mật). Tấn công vào các lỗ hổng là một
cách tấn công phổ biến nhất. Và những lỗi trong việc kiểm tra đầu vào (Input
validation) là một điểm yếu mà hầu hết các ứng dụng gặp phải.
Trong kỹ thuật tấn công vào các lỗ hổng lại chia thành nhiều phương pháp khác
nhau mà điển hình bao gồm:
- CRLF Injection.
- SQL Injection.
- Javascript Injection.
- LDAP Injection.
- XSS Injection.
2.2. SQL Injection.
2.2.1 SQL Injection là gì?
Khi triển khai các ứng dụng web trên Internet, nhiều người vẫn nghĩ rằng
việc đảm bảo an toàn, bảo mật nhằm giảm thiểu tối đa khả năng bị tấn công
từ các tin tặc chỉ đơn thuần tập trung vào các cấn đề như chọn hệ điều hành,
hệ quản trị cơ sở dữ liệu, webserver sẽ chạy ứng dụng, …mà quên mất rằng
ngay cả bản thân ứng dụng chạy trên đó cũng tiềm ẩn một lỗ hổng bảo mật
rất lớn. Một trong số các lỗ hổng này là SQL Injection. Tại Việt Nam, đã qua
thời kì các nhà quản trị website lơ là việc quét virus, cập nhật các bản vá lỗi
từ các phần mềm hệ thống, nhưng việc chăm sóc các lỗi của các ứng dụng lại
11
rất ít được quan tâm. Đó là lí do tại sao không ít website tại VN bị tấn công
và đa số đều là lỗi SQL injection. Vậy SQL injection là gì?
SQL injection là một kĩ thuật cho phép những kẻ tấn công lợi dụng lỗ
hổng trong việc kiểm tra dữ liệu nhập trong các ứng dụng web và các
thông báo lỗi của hệ quản trị cơ sở dữ liệu để "tiêm vào" (inject) và thi
hành các câu lệnh SQL bất hợp pháp (không được người phát triển ứng
dụng lường trước).
Dạng lỗi này có thể tìm thấy trên các trang web cho phép submit dữ liệu
ở bất kì một trình tìm kiếm nào trên mạng, chẳng hạn như các trang login, search,
feedback, url có truyền tham số
Hậu quả của nó rất tai hại vì nó cho phép những kẻ tấn công có thể thực hiện
các thao tác xóa, hiệu chỉnh, … do có toàn quyền trên cơ sở dữ liệu của ứng dụng,
thậm chí là server mà ứng dụng đó đang chạy. Lỗi này thường xảy ra trên các ứng
dụng web có dữ liệu được quản lí bằng các hệ quản trị cơ sở dữ liệu như SQL
Server, MySQL, Oracle, DB2, Sysbase.
Sql Injection được mô tả như là một trong những lỗ hổng bảo mật web nguy
hiểm nhất. Khai thác Sql Injection, ngoài việc đoạt được quyền kiểm soát về mặt
dữ liệu như đã nói ở trên, hacker còn có thể cài đặt backdoor trên server mà ứng
dụng đang chạy, qua đó kiểm soát toàn bộ hệ thống…
2.2.2 Các dạng lỗi thường gặp
• Không kiểm tra ký tự thoát truy vấn
Đây là dạng lỗi SQL injection xảy ra khi thiếu đoạn mã kiểm tra dữ liệu đầu
vào trong câu truy vấn SQL. Kết quả là người dùng cuối có thể thực hiện một số
truy vấn không mong muốn đối với cơ sở dữ liệu của ứng dụng. Dòng mã sau sẽ
minh họa lỗi này:
statement = "SELECT * FROM users WHERE name = '" + userName + "';"
12
Câu lệnh này được thiết kế để trả về các bản ghi tên người dùng cụ thể từ
bảng những người dùng. Tuy nhiên, nếu biến "userName" được nhập chính xác
theo một cách nào đó bởi người dùng ác ý, nó có thể trở thành một câu truy vấn
SQL với mục đích khác hẳn so với mong muốn của tác giả đoạn mã trên. Ví dụ, ta
nhập vào giá trị của biến userName như sau:
a’ or ‘t’ = ‘t
Khiến câu truy vấn có thể được hiểu như sau:
SELECT * FROM users WHERE name = 'a' OR 't'='t';
Nếu đoạn mã trên được sử dụng trong một thủ tục xác thực thì ví dụ trên có
thể được sử dụng để bắt buộc lựa chọn một tên người dùng hợp lệ bởi 't'='t' luôn
đúng. Trong khi hầu hết các SQL server cho phép thực hiện nhiều truy vấn cùng
lúc chỉ với một lần gọi, tuy nhiên một số SQL API như mysql_query của php lại
không cho phép điều đó vì lý do bảo mật. Điều này chỉ ngăn cản tin tặc tấn công
bằng cách sử dụng các câu lệnh riêng rẽ mà không ngăn cản tin tặc thay đổi các từ
trong cú pháp truy vấn. Các giá trị của biến "userName" trong câu truy vấn dưới
đây sẽ gây ra việc xoá những người dùng từ bảng người dùng cũng tương tự như
việc xóa tất cả các dữ liệu được từ bảng dữ liệu (về bản chất là tiết lộ các thông tin
của mọi người dùng), ví dụ này minh họa bằng một API cho phép thực hiện nhiều
truy vấn cùng lúc:
a’; DROP TABLE users; SELECT * FROM data WHERE ‘t’ = ‘t
Điều này đưa tới cú pháp cuối cùng của câu truy vấn trên như sau:
SELECT * FROM users WHERE name = 'a';DROP TABLE users; SELECT *
FROM DATA WHERE 't' = 't';
• Xử lý không đúng kiểu.
Lỗi SQL injection dạng này thường xảy ra do lập trình viên hay người dùng
định nghĩa đầu vào dữ liệu không rõ ràng hoặc thiếu bước kiểm tra và lọc kiểu dữ
13
liệu đầu vào. Điều này có thể xảy ra khi một trường số được sử dụng trong truy vấn
SQL nhưng lập trình viên lại thiếu bước kiểm tra dữ liệu đầu vào để xác minh kiểu
của dữ liệu mà người dùng nhập vào có phải là số hay không. Ví dụ như sau:
statement := "SELECT * FROM data WHERE id = " + a_variable + ";"
Ta có thể nhận thấy một cách rõ ràng ý định của tác giả đoạn mã trên là nhập
vào một số tương ứng với trường id - trường số. Tuy nhiên, người dùng cuối, thay
vì nhập vào một số, họ có thể nhập vào một chuỗi ký tự, và do vậy có thể trở thành
một câu truy vấn SQL hoàn chỉnh mới mà bỏ qua ký tự thoát. Ví dụ, ta thiết lập giá
trị của biến a_variable là:
1; DROP TABLE users
khi đó, nó sẽ thực hiện thao tác xóa người dùng có id tương ứng khỏi cơ sở dữ
liệu, vì câu truy vấn hoàn chỉnh đã được hiểu là:
SELECT * FROM DATA WHERE id=1;DROP TABLE users;
• Lỗi bảo mật bên trong máy chủ cơ sở dữ liệu.
Đôi khi lỗ hổng có thể tồn tại chính trong phần mềm máy chủ cơ sở dữ liệu, như
là trường hợp hàm mysql_real_escape_string() của các máy chủ MySQL. Điều
này sẽ cho phép kẻ tấn công có thể thực hiện một cuộc tấn công SQL injection
thành công dựa trên những ký tự Unicode không thông thường ngay cả khi đầu
nhập vào đang được thoát.
• Blind SQL injection.
Lỗi SQL injection dạng này là dạng lỗi tồn tại ngay trong ứng dụng web nhưng
hậu quả của chúng lại không hiển thị trực quan cho những kẻ tấn công. Nó có thể
gây ra sự sai khác khi hiển thị nội dung của một trang chứa lỗi bảo mật này, hậu
quả của sự tấn công SQL injection dạng này khiến cho lập trình viên hay người
dùng phải mất rất nhiều thời gian để phục hồi chính xác từng bit dữ liệu. Những
14
kẻ tấn công còn có thể sử dụng một số công cụ để dò tìm lỗi dạng này và tấn
công với những thông tin đã được thiết lập sẵn.
+ Thay đổi giá trị điều kiện truy vấn: Dạng lỗi này khiến cho kẻ tấn công có thể
thay đổi giá trị điều kiện trong câu truy vấn, làm sai lệch sự hiển thị của một ứng
dụng chứa lỗi này.
SELECT booktitle FROM booklist WHERE bookId = 'OOk14cd' AND 1=1;
Sẽ hiển thị một trang một cách bình thường, trong khi:
SELECT booktitle FROM booklist WHERE bookId = 'OOk14cd' AND 1=2;
Sẽ hiển thị một nội dung khác, hoặc không hiển thị gì nếu ứng dụng web có chứa
lỗi SQL injection dạng này. Lỗ hổng dạng này còn cho phép tin tặc không chỉ gây
ảnh hưởng tới bảng hay dữ liệu hiện tại mà còn ảnh hưởng tới những dữ liệu hay
bảng khác phụ thuộc vào nội dung của dữ liệu hay bảng hiện tại.
+ Điều kiện lỗi: Lỗi SQL injection dạng này dẫn tới việc buộc cơ sở dữ liệu chỉ
được phép đánh giá khi mà giá trị của câu lệnh WHERE là đúng. Ví dụ:
SELECT 1/0 FROM users WHERE username='Ralph';
Phép chia cho 0 chỉ được đánh giá là lỗi khi mà người dùng có tên "Ralph" tồn tại
trong cơ sở dữ liệu.
+ Thời gian trễ: Lỗi SQL injection dạng này tồn tại khi thời gian xử lý của một
hay nhiều truy vấn SQL phụ thuộc vào dữ liệu logic được nhập vào hoặc quá trình
xử lý truy vấn của SQL engine cần nhiều thời gian. Tin tặc có thể sử dụng lỗi SQL
injection dạng này để xác định thời gian chính xác mà trang cần tải khi giá trị nhập
vào là đúng.
2.2.2 Các dạng tấn công bằng SQL Injection
Có bốn dạng tấn công thường gặp bao gồm: vượt qua kiểm tra lúc đăng nhập, sử
dụng câu lệnh SELECT, sử dụng câu lệnh INSERT, sử dụng các stored-procedures.
15
• Dạng tấn công vượt qua kiểm tra lúc đăng nhập.
Với dạng tấn công này, tin tặc có thể dễ dàng vượt qua các trang đăng nhập nhờ
vào lỗi khi dùng các câu lệnh SQL thao tác trên cơ sở dữ liệu của ứng dụng web.
Thông thường để cho phép người dùng truy cập vào các trang web được bảo
mật, hệ thống thường xây dựng trang đăng nhập để yêu cầu người dùng nhập
thông tin về tên đăng nhập và mật khẩu. Sau khi người dùng nhập thông tin vào,
hệ thống sẽ kiểm tra tên đăng nhập và mật khẩu có hợp lệ hay không để quyết
định cho phép hay từ chối thực hiện tiếp.
Ví dụ, trong trường hợp sử dụng ASP, người ta có thể dùng 2 trang: 1 trang
HTML để hiển thị Form nhập liệu và 1 trang ASP để xử lý thông tin nhập vào từ
phía người dùng như sau:
Trang đăng nhập: login.html
<form action="ExecLogin.asp" method="post">
Username: <input type="text" name="fUSRNAME"><br />
Password: <input type="password" name="fPASSWORD"><br />
<input type="submit">
</form>
Trang xử lý đăng nhập: xuly.asp
<%
Dim vUsrName, vPassword, objRS, strSQL
vUsrName = Request.Form("fUSRNAME")
vPassword = Request.Form("fPASSWORD")
strSQL = "SELECT * FROM T_USERS " & _
"WHERE USR_NAME=' " & vUsrName & _
" ' and USR_PASSWORD=' " & vPassword & " ' "
16
Set objRS = Server.CreateObject("ADODB.Recordset")
objRS.Open strSQL, "DSN= "
If (objRS.EOF) Then
Response.Write "Invalid login."
Else
Response.Write "You are logged in as " & objRS("USR_NAME")
End If
Set objRS = Nothing %>
Chỗ sơ hở trong đoạn mã xử lý nhập liệu trên nằm ở chỗ dữ liệu nhập vào từ
người dùng được dùng để xây dựng trực tiếp câu lệnh SQL. Chính điều này
cho phép tin tặc có thể điều khiển câu truy vấn sẽ được thực hiện. Ví dụ, nếu
người dùng nhập chuỗi trong ngoặc sau vào trong cả 2 ô nhập liệu
username/password của trang login.htm là:('OR='). Lúc này, câu truy vấn sẽ
được gọi thực hiện là:
SELECT * FROM T_USERS WHERE USR_NAME =''OR''='' AND
USR_PASSWORD= ''OR''=''
Câu truy vấn này là hợp lệ và sẽ trả về tất cả các bản ghi của T_USERS và
đoạn mã tiếp theo xử lí người dùng đăng nhập bất hợp pháp này như là người
dùng đăng nhập hợp lệ.
• Dạng tấn công sử dụng câu lệnh SELECT.
Dạng tấn công này phức tạp hơn. Để thực hiện được kiểu tấn công này, kẻ tấn
công phải có khả năng hiểu và lợi dụng các sơ hở trong các thông báo lỗi từ hệ
thống để dò tìm các điểm yếu khởi đầu cho việc tấn công. Ví dụ, trong các trang
tìm kiếm. Các trang này cho phép người dùng nhập vào các thông tin tìm kiếm
như Họ, Tên, … Đoạn mã thường gặp là:
17
<%
Dim vAuthorName, objRS, strSQL
vAuthorName = Request("fAUTHOR_NAME")
strSQL = "SELECT * FROM T_AUTHORS WHERE AUTHOR_NAME =' " &
_ vAuthorName & " ' "
Set objRS = Server.CreateObject("ADODB.Recordset")
objRS.Open strSQL, "DSN= "
…
Set objRS = Nothing %>
Tương tự như trên, tin tặc có thể lợi dụng sơ hở trong câu truy vấn SQL để nhập
vào trường tên tác giả bằng chuỗi giá trị:
UNION SELECT ALL SELECT OtherField FROM OtherTable WHERE ‘ ‘=’ (*)
Lúc này, ngoài câu truy vấn đầu không thành công, chương trình sẽ thực hiện thêm
lệnh tiếp theo sau từ khóa UNION nữa. Giả sử đoạn mã nhập vào là:
DROP TABLE T_AUTHORS –
Câu truy vấn sẽ thực hiện việc xóa bảng.
• Dạng tấn công sử dụng câu lệnh INSERT.
Thông thường các ứng dụng web cho phép người dùng đăng kí một tài khoản để
tham gia. Chức năng không thể thiếu là sau khi đăng kí thành công, người dùng có
thể xem và hiệu chỉnh thông tin của mình. SQL injection có thể được dùng khi hệ
thống không kiểm tra tính hợp lệ của thông tin nhập vào. Ví dụ, một câu lệnh
INSERT có thể có cú pháp dạng:
INSERT INTO TableName VALUES('Value One', 'Value Two', 'Value Three')
Nếu đoạn mã xây dựng câu lệnh SQL có dạng:
18
<%
strSQL = "INSERT INTO TableName VALUES(' " & strValueOne & " ', ' " _ &
strValueTwo & " ', ' " & strValueThree & " ') "
Set objRS = Server.CreateObject("ADODB.Recordset")
objRS.Open strSQL, "DSN= "
…
Set objRS = Nothing
%>
Thì chắc chắn sẽ bị lỗi SQLi, bởi vì nếu ta nhập vào trường thứ nhất ví dụ như:
' + (SELECT TOP 1 FieldName FROM TableName) + '
Lúc này câu truy vấn sẽ là:
INSERT INTO TableName VALUES(' ' + (SELECT TOP 1 FieldName FROM
TableName) + ' ', 'abc', 'def')
Khi đó, lúc thực hiện lệnh xem thông tin, xem như bạn đã yêu cầu thực hiện thêm
một lệnh nữa đó là:
SELECT TOP 1 FieldName FROM TableName
• Dạng tấn công sử dụng stored-procedures.
Việc tấn công bằng stored-procedures sẽ gây tác hại rất lớn nếu ứng dụng được
thực thi với quyền quản trị hệ thống 'sa'. Ví dụ, nếu ta thay đoạn mã tiêm vào dạng:
' ; EXEC xp_cmdshell ‘cmdd.exe dir C: '. Lúc này hệ thống sẽ thực hiện lệnh liệt kê
thư mục trên ổ đĩa C:\ cài đặt server. Việc phá hoại kiểu nào tuỳ thuộc vào câu lệnh
đằng sau cmd.exe.
2.2.3 Các cách phòng tránh
Như vậy, có thể thấy lỗi SQL injection khai thác những bất cần của các lập trình
viên phát triển ứng dụng web khi xử lí các dữ liệu nhập vào để xây dựng câu lệnh
SQL. Tác hại từ lỗi SQL injection tùy thuộc vào môi trường và cách cấu hình hệ
19
thống.Nếu ứng dụng sử dụng quyền sa (quyền quản trị hệ thống), nó có thế điều
khiển toàn bộ hệ quản trị CSDL với quyền hạn rộng lớn như vậy nó có thể tạo ra
các tài khoản người dùng bất hợp pháp để điều khiển hệ thống của bạn. Đề phòng
tránh, ta có thế thực hiện ở 2 mức:
• Kiểm soát chặt chẽ dữ liệu nhập vào
Cách phòng chống hiệu quả Sql injection chính là việc kiểm tra kỹ càng tham
số đầu vào. Những tham số mà từ đó người lập trình website sử dụng để xây dựng
lên câu truy vấn tới cơ sở dữ liệu.
Công việc kiểm tra tham số đầu vào (áp dụng phòng tránh lỗi Sql injection)
nên được tiến hành theo nhiều tầng:
- Client: javascript (có thể bypass bằng các phần mềm tamper)
- Server: C#, php, jsp
Kiểm tra kiểu của dữ liệu: đối với dữ liệu kiểu số, kiểu chuỗi … chúng ta phải
có những hàm validate tương ứng.
- Nếu là kiểu int:
+ ASP.NET: Int32.Parse(/*Param*/);
+ PHP: is_numeric($var), is_int($var), is_integer($var)
- Nếu là kiểu chuỗi:
+ Thiết lập độ dài tối đa cần thiết: length <= MAX_LENGTH
+ Lọc bỏ ký tự nguy hiểm (bao gồm các meta characters trong DBMS), lọc
bỏ các từ khóa như union, select, order, information_schema, insert, drop,
load_file… (sử dụng các hàm như mysql_real_escape_string(), preg_replace()…)
+ Kiểm tra xem định dạng chuỗi: email, username, password… đều có một
định dạng nhất định, do đó có thể viết các biểu thức chính qui (Regular Expression)
cho mỗi định dạng này.
C#: System.Text.RegularExpressions;
20
PHP: preg_match();
Java: Pattern.matcher();
- Sử dụng các thư viện hỗ trợ:
+ C#: Parameters
cmd.Parameters.Add("@var", SqlDbType.Int);
cmd.Parameters["@var"].Value = input;
• Thiết lập cấu hình an toàn cho hệ quản trị cơ sở dữ liệu
- Phân quyền SQL.
Tài khoản sử dụng cho ứng dụng web trong cơ sở dữ liệu dĩ nhiên phải có quyền
đọc. Nhưng khi thực hiện thao tác thêm bài viết, thêm user thì nó phải cần thêm
quyền ghi nữa. Do đó, tùy vào mỗi trường hợp mà ta thiết lập role phù hợp cho mỗi
tài khoản web tương tác với cơ sở dữ liệu. Với những ứng dụng web thông thường,
tài khoản cho ứng dụng web trong SQL SERVER nên chỉ được thiết lập quyền đọc
(SELECT) (db_datareader) và quyền ghi (INSERT, UPDATE) (db_datawriter) như
vậy sẽ không có quyền xóa một table.
2.3. XSS Injection.
Cross-Site Scripting (XSS) là một trong những kĩ thuật tấn công phổ biến nhất
hiên nay, đồng thời nó cũng là một trong những vấn đề bảo mật quan trọng đối với
các nhà phát triển web và cả những người sử dụng web. Bất kì một website nào cho
phép người sử dụng đăng thông tin mà không có sự kiểm tra chặt chẽ các đoạn mã
nguy hiểm thì đều có thể tiềm ẩn các lỗi XSS. Trong bài viết này tôi sẽ đề cập sơ
lược tới XSS với một số kinh nghiệm của tôi qua kĩ thuật tấn công này.
2.3.1 XSS là gì?
21
Hình 2.1 Minh họa XSS
Cross-Site Scripting hay còn được gọi tắt là XSS (thay vì gọi tắt là CSS để tránh
nhầm lẫn với CSS-Cascading Style Sheet của HTML) là một kĩ thuật tấn công bằng
cách chèn vào các website động (ASP, PHP, CGI, JSP ) những thẻ HTML hay
những đoạn mã script nguy hiểm có thể gây nguy hại cho những người sử dụng
khác. Trong đó, những đoạn mã nguy hiểm đựơc chèn vào hầu hết được viết bằng
các Client-Site Script như JavaScript, JScript, DHTML và cũng có thể là cả các thẻ
HTML.
Kĩ thuật tấn công XSS đã nhanh chóng trở thành một trong những lỗi phổ biến
nhất của Web Applications và mối đe doạ của chúng đối với người sử dụng ngày
càng lớn. Người chiến thắng trong cuộc thi eWeek OpenHack 2002 là người đã tìm
ra 2 XSS mới. Phải chăng mối nguy hiểm từ XSS đã ngày càng được mọi người
chú ý hơn.
2.3.2 Phân loại XSS
22
- Stored-XSS.
Là lỗi XSS mà đoạn mã chèn thêm vào được lưu trữ trên server, như trong
CSDL dưới dạng các comment trong blog, message trong forum hoặc các visitor
log. Ví dụ dưới đây minh họa cho Stored-XSS. Ta có một trang web mà người
dùng có thể để lại những lời nhắn như sau:
Thay vì nhập vào lời nhắn bình thường, ta nhập vào đoạn mã sau:
Xin <script>alert(“XSS”)</script>chào!
Kết quả:
23
Ở đây, đoạn mã <script>alert(“XSS”)</script> được chèn vào trong lời nhắn, và
ngay lập tức nó được thực thi như hình trên. Vì các lời nhắn được lưu trữ trong
database nên bất cứ người dùng nào khi truy cập vào trang web này sẽ thực thi
đoạn mã trên. Thay vì một đoạn mã vô hại như trên, hacker có thể thay bằng các
đoạn mã nguy hiểm khác nhằm gây hại đến người dùng.
Ví dụ:
Thay vì alert("XSS") như trên, Hacker sẽ chèn đoạn script như bên dưới
Một iframe với kích thước 0×0 được chèn vào trang web và sẽ tự động load
trang lấy cookie của hacker tại địa chỉ Khi có
được cookie, hacker có thể dễ dàng đăng nhập mà không cần biết mật khẩu của
người dùng.
Kiểu tấn công này thường gây hại cho người dùng.
Reflected XSS (phản hồi XSS)
Khác với Stored-XSS, Reflected-XSS đoạn mã khai thác sẽ không được lưu trữ
trên server. Một ví dụ điển hình của Reflected-XSS là kết quả trả về của
module search:
24
Ta thấy từ khóa tìm kiếm mà ta nhập vào ô textbox được hiển thị lại trên trình
duyệt. Lợi dụng việc không kiểm soát giá trị này, Hacker thể chèn thêm đoạn mã
gây hại vào. Đường link sẽ có dạng:
/>Tuy nhiên đoạn mã độc hại này chỉ được kích hoạt khi nạn nhân click đường
link trên.
Do vậy, cách mà Hacker sử dụng lỗi này để tấn công người dùng đó là làm sao
để người đó click vào các link chứa mã độc này.
• Reflected XSS và Stored XSS có 2 sự khác biệt lớn
trong quá trình tấn công:
+ Thứ nhất, để khai thác Reflected XSS, hacker phải lừa được nạn nhân truy
cập vào URL của mình. Còn Stored XSS không cần phải thực hiện việc này, sau
khi chèn được mã nguy hiểm vào CSDL của ứng dụng, hacker chỉ việc ngồi chờ
nạn nhân tự động truy cập vào. Với nạn nhân, việc này là hoàn toàn bình thường vì
họ không hề hay biết dữ liệu mình truy cập đã bị nhiễm độc.
+ Thứ 2, mục tiêu của hacker sẽ dễ dàng đạt được hơn nếu tại thời điểm tấn
công nạn nhân vẫn trong phiên làm việc(session) của ứng dụng web. Với Reflected
XSS, hacker có thể thuyết phục hay lừa nạn nhân đăng nhập rồi truy cập đến URL
mà hắn ta cung cấp để thực thi mã độc. Nhưng Stored XSS thì khác, vì mã độc đã
được lưu trong CSDL Web nên bất cứ khi nào người dùng truy cập các chức năng
liên quan thì mã độc sẽ được thực thi, và nhiều khả năng là những chức năng này
yêu cầu phải xác thực(đăng nhập) trước nên hiển nhiên trong thời gian này người
dùng vẫn đang trong phiên làm việc.
Từ những điều này có thể thấy Stored XSS nguy hiểm hơn Reflected XSS rất
nhiều, đối tượng bị ảnh hưởng có thế là tất cả nhưng người sử dụng ứng dụng web
25