Tải bản đầy đủ (.docx) (33 trang)

Tìm hiểu cụ thể về tấn công SQL Injection + Demo

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (706.54 KB, 33 trang )

MỤC LỤC

Danh mục hình vẽ.

1


LỜI NÓI ĐẦU
Một trong những phương pháp tấn công lên các ứng dụng Web hiện nay
không thể không nói tới SQL injection. Dựa trên các lỗ hổng trong việc kiểm tra dữ
liệu đầu vào (ví dụ từ form đăng nhập hay form tìm kiếm), kẻ tấn công có thể chèn
thêm (inject) các đoạn mã nguy hiểm để thực thi các câu lệnh SQL trái phép. Các
đoạn mã này có thể là các thao tác xóa, hiệu chỉnh,... gây rò rỉ, mất mát thông tin,
thay đổi cấu trúc hệ thống tin của website.
Để có thể phòng chống tấn công SQL injection một cách hiểu quả, đảm bảo
an toàn cho ứng dụng thì buộc các nhà phát triển phải hiểu rõ được cơ chế hoạt
động, cách thức tấn công của nó. Vì vậy nhóm em đã chọn đề tài: tìm hiểu về tấn
công SQL Injection trên BWapp để có thể tìm hiểu và đưa ra các biện pháp phòng
chống loại tấn công nguy hiểm này.
.

2


1.1.

CHƯƠNG 1. TỔNG QUAN VỀ SQL INJECTION
Cách thức hoạt động của ứng dụng web

Hình 1. Kiến trúc 3 tầng đơn giản
Tầng trình diễn (presentation) là tầng ở mức cao nhất của ứng dụng, hiện thị


thông tin của website cho người dùng. Tầng logic chứa các mã nguồn được đặt sau
tầng trình diễn, kiểm soát chức năng của ứng dụng, thực hiện các quá trình xử lý.
Tầng lưu trữ (storage) chứa máy chủ cơ sở dữ liệu để lữu trữ và tìm kiếm thông tin.
Web browser (tầng trình diễn) gửi các yêu cầu đến tầng giữa (tầng logic).
Tầng logic sẽ gửi các truy vấn đến cơ sở dữ liệu để lấy thông tin. Tầng lưu trữ xử
lý truy vấn, sau đó trả lại các thông tin cho tầng logic. Cuối cùng, tầng logic xử lý
các yêu cầu và trả về kết quả cho tầng trình diễn.
Một nguyên tắc cơ bản trong kiến trúc 3 tầng đó là tầng trình diến không bao
giờ được truyền thông trực tiếp với tầng lưu trữ. Tất cả truyền thông đều phải
thông qua tầng trung gian (tầng logic).
Trong hình 1, người dùng mở trình duyệt web và kết nối đến địa chỉ
. Web server nằm trên tầng logic sẽ tải các kịch bản từ các
tệp tin hệ thống và chuyển các tệp tin này đến công cụ để phân tích và thực thi. Các
3


kịch bản mở một kết nối đến tầng lưu trữ bằng cách sử dụng bộ kết nối cơ sở dữ
liệu (database connector) và thực thi truy vấn SQL. Cở dữ liệu trả dữ liệu về cho
bộ kết nối, bộ kết nối nằm trong tầng logic. Tầng logic thực hiện xử lý các yêu cầu
trước khi trả về trang web trong định dạng HTML tới trình duyệt của người dùng
trong tầng trình diễn. Trình duyệt sẽ hiện thị thông tin cho người dùng có thể đọc
và hiểu.
1.2.

Hiểu về SQL injection

SQL injection là một hình thức tấn công mà trong đó truy vấn SQL của ứng
dụng bị chèn thêm vào các tham số đầu vào “nguy hiểm” từ form người dùng nhập
và sau đó các tham số này sẽ được chuyển đến máy chủ cơ sở dữ liệu để phân tích
cú pháp và thực thi. [1]

Như đã đề cập trong phần trước, người dùng không thể tương tác trực tiếp
với cơ sở dữ liệu. Như vậy, các lệnh SQL mà cơ sở dữ liệu phải thực thi do tầng
logic gửi đến, không có sự can thiệp của người dùng. Vậy làm thế nào để người
dùng có thể thực thi được các truy vấn SQL theo chủ ý của họ? Đó chính là các
tham số đầu vào mà người dùng nhập được kết hợp với câu lệnh SQL trên tầng
logic. Sự kết hợp này tạo thành một câu lệnh SQL nguy hiểm mà nó sẽ được thực
thi trên cơ sở dữ liệu. Kẻ tấn công xây dựng các đoạn mã thích hợp sẽ tạo ra các
lệnh truy vấn theo ý muốn.
SQL Injection thường là kết quả của những sai sót trong ứng dụng web hoặc
trang web chứ không phải vấn đề ở cơ sở dữ liệu. Nguyên nhân thông thường của
lỗ hổng này là dữ liệu đầu vào không hợp lệ hoặc vắng mặt, các truy vấn truyền
vào có thể vượt qua mà không cần kiểm tra. Chính vì thế bất cứ thành phần nào
của ứng dụng mà người dùng có thể tương tác được để điều khiển nội dung (ví dụ:
các Form, tham số URL, cookie, user-agent,…) đều có thể được sử dụng để tiến
hành chèn truy vấn có hại.
Trên cơ sở ứng dụng và cách xử lý dữ liệu người dùng cung cấp, SQL
Injection có thể được sử dụng để thực hiện các cuộc tấn công sau:
4


- Vượt qua xác thực (Authentication bybass): Bằng cách sử dụng tấn công
này, kẻ tấn công có thể đăng nhập vào ứng dụng mà không cần tên đăng
nhập và mật khẩu hợp lệ, và lấy được quyền quản trị.
- Tiết lộ thông tin (Information disclosure): Bằng cách tấn công này, kẻ tấn
công có thế có được thông tin nhạy cảm (như thông tin cá nhân của khách
hàng: tên, địa chỉ, số điện thoại, chứng minh thư,..) được lưu trong cơ sở
dữ liệu
- Xâm phạm tính toàn vẹn dữ liệu (Compromised data integrity): Kẻ tấn
công sử dụng tấn công này để phá hủy, chèn nội dung độc hại vào trang
web hoặc thay đổi nội dung được lưu trong cơ sở dữ liệu

- Xâm phạm tính sẵn có của dữ liệu (Compromised availability of data):
bằng cách tấn công này, kẻ tấn công có thể xóa các thông tin cơ sở dữ
liệu, hoặc thông tin kiểm toán được lưu trong cơ sở dữ liệu.
- Thi hành lệnh từ xa (Remote code execution): Nó hỗ trợ cho kẻ tấn công
làm nguy hại cho hệ điều hành máy chủ lưu trữ.

1.3. Các dạng tấn công SQL injection
1.3.1. Lỗi dựa trên tiêm vào truy vấn SQL (Error based SQL Injection)
Dạng tấn công này, ứng dụng web sẽ hiển thị thông báo lỗi khi có truy vấn
giả mạo, kẻ tấn công sẽ dựa vào lỗi này để tiếp tục tấn công.
Thông thường các website thường có một trang nhận ID của tin cần hiển thị
rồi sẽ truy vấn nội dung của tin có ID này.
Ví dụ như để thực hiện được
chức năng này ứng dụng web sử dụng truy vấn SQL sau: SELECT * FROM
products WHERE id_product = $id_product. Thông thường, sau khi thực hiện truy
vấn này ứng dụng web sẽ trả về thông tin tương ứng với ID được truyền vào. Kẻ
tấn công có thể thay thế một ID hợp lệ bằng cách gán ID cho một giá trị khác, và từ
đó khởi đầu cho một cuộc tấn công bất hợp pháp.
Ví dụ, kẻ tấn công nối giá trị
UTL_INADDS.GET_HOST_NAME(

ID với kết quả của hàm
)
(tức
là,
5


/>UTL_INADDS.GET_HOST_NAME((SELECT user FROM DUAL) ) ). Chức năng
của hàm này là sẽ trẻ về tên máy chủ của tham số được truyền cho nó, ở đây chính

là tên của người dùng- kết quả của truy vấn được truyền vào. Khi đó cơ sở dữ liệu
sẽ tìm kiếm tên một máy chủ với tên người dùng trong cơ sở dữ liệu, thực thi này
sẽ bị lỗi, và trả về một thông báo như sau: ORA-292257: host SCOTT unknown.
a. Tấn công sử dụng toán tử UNION (UNION SQL Injection)
Các cuộc tấn công dựa trên UNION cho phép kẻ tấn công dễ trích suất
thông tin từ cơ sở sữ liệu. Toán tử UNION trong SQL được sử dụng để kết hợp kết
quả của hai hay nhiều lệnh SELECT mà không trả về bất cứ bản sao nào của bản
ghi. Bởi vì toán tử UNION chỉ có thể được sử dụng nếu cả hai truy vấn có cùng
cấu trúc, kẻ tấn công phải tạo một câu lệnh SELECT giống với truy vấn ban đầu.
Để thực hiện được việc này thì cần phải biết được tên bảng hợp lệ và xác định số
cột và kiểu dữ liệu trong truy vấn đầu tiên. Cách đơn giản nhất để lấy được tên
bảng là đoán, vì thông thường trong các ứng dụng tên bảng thường được đặt giống
nhau để thuận tiện cho người dùng.
Ví dụ như truy vấn: SELECT Name, Phone, Address FROM Users WHERE
Id = $id. Kẻ tấn công sẽ thay thế một ID hợp lệ bằng một giá trị khác để thực hiện
cuộc tấn công. Chẳng hạn, kẻ tấn công gán ID bằng giá trị sau $id = 1 UNION
ALL SELECT creditCardNumber, 1, 1 FROM CreditCardTable. Khi đó ứng dụng
web sẽ thực hiện câu truy vấn sau: SELECT Name, Phone, Address FROM Users
WHERE Id = 1 UNION ALL SELECT creditCardNumber, 1, 1 FROM
CreditCardTable. Kết quả của truy vấn giả mạo sẽ được kết hợp với truy vấn ban
đầu cho ra kết quả cuối cùng là tên, số điện thoại, địa chỉ và số thẻ tín dụng của
người dùng.
b. Tấn công sử dụng công thức hằng đúng (Tautology SQL Injection attack) [2]
Trong cuộc tấn công sử dụng công thức hằng đúng, mã được tiêm vào bằng
cách sử dụng toán tử điều kiện OR sao cho truy vấn luôn luôn đánh giá đúng. Tấn
công này thường được dùng để vượt qua tính xác thực người dùng và trích suất dữ
6


liệu bằng cách chèn thêm một công thức hằng đúng trong mệnh đề WHERE của

một truy vấn SQL. Một dạng điển hình của công thức hằng đúng là “OR thức so sánh>”, trong đó biểu thức so sánh sử dụng một hoặc nhiều toán tử quan hệ
để so sánh các toán hạng và tạo ra một điều kiện luôn đúng. Nếu kẻ tấn công nhập
ID người dùng là abcd và mật khẩu là anything’ or ‘x’ = ‘x’ thì truy vấn có dạng
sau: SELECT * FROM Users WHERE Id_user = ‘abcd’AND password =
‘anything’ or ‘x’ = ‘x’;
c. Tấn công sử dụng truy vấn không chính xác, không hợp lệ (Illegal/Logically
Incorrect query)
Dạng tấn công này cho phép kẻ tấn công thu thập thông tin về loại và cấu
trúc của cơ sở dữ liệu của ứng dụng. Cuộc tấn công này được coi là một bước thu
thập thông tin sơ bộ hỗ trợ cho cuộc tấn công khác. Lỗ hổng được tạo ra bởi cuộc
tấn công này là trang lỗi mặc định được trả về bởi ứng dụng thường là thông tin thu
được về lược đồ cơ sở dữ liệu. Khi thực hiện cuộc tấn công này, kẻ tấn công tiêm
những câu lệnh gây ra cú pháp, chuyển đổi kiểu, hoặc lỗi logic trong cơ sở dữ liệu.
Các lỗi này được dùng để suy luận kiểu dữ liệu của một số cột nhất định. Lỗi cú
pháp được sử dụng để xác định các thông số tiêm. Lỗi logic có thể tiết lộ tên của
các bảng và cột gây ra lỗi.
Ví dụ, truy vấn gây ra lỗi chuyển đổi kiểu có thể tiết lộ dữ liệu liên quan sau
đây. Kẻ tấn công sẽ gán password một giá trị sau: AND ‘pin: “convert(int, (select
top 1 name from sysobjects where xtype = ‘u’)). Khi đó cơ sở dữ liệu sẽ thực hiện
truy vấn sau: SELECT name FROM Authors where username = ‘’ AND password
= ‘’ AND ‘pin: “convert(int, (select top 1 name from sysobjects where xtype =
‘u’));
Truy vấn này trích xuất bảng người dùng đầu tiên (xtype = ‘u’) từ bảng siêu
dữ liệu của cơ sở dữ liệu (giả sử ứng dụng đang sử dụng Microsoft SQL Server, mà
bảng siêu dữ liệu được gọi là sysobjects). Sau đó truy vấn cố chuyển đổi tên bảng
này thành một số nguyên. Bởi vì đây là một hành động không hợp pháp nên cơ sở
dữ liệu sẽ ném một thông báo lỗi. Đối với Microsoft SQL Server, lỗi mặc định là
7



“Microsoft OLE DB Provider for SQL Server (0x80040E07) Error converting
nvarchar value ‘creditcards’ to a column of data type int.” Kẻ tấn công cố sử dụng
thông tin này để biết được giản đồ của cơ sở dữ liệu.
d. Dạng tấn công sử dụng Stored-Procedure
Trong dạng tấn công này, kẻ tấn công cố gắng thi hành trên các thủ tục lưu
trữ có trong cơ sở dữ liệu. Hầu hết các doanh nghiệp đều gửi cơ sở dữ liệu qua một
thủ tục lưu trữ tiêu chuẩn để mở rộng các chức năng của cơ sở dữ liệu và cho phép
tương tác với hệ điều hành. Vì vậy, một khi kẻ tấn công xác định được ứng dụng
đang sử dụng cơ sở dữ liệu back-end nào, các cuộc tấn công sẽ được tạo ra để thi
hành trên các thủ tục lưu trữ đã được cung cấp bởi cơ sở dữ liệu vừa xác định.
Ngoài ra, vì các thủ tục lưu trữ được viết trên một ngôn ngữ kịch bản đặc biệt,
chúng có thể còn tồn tại các lỗ hổng khác, chẳng hạn như tràn bộ đệm; lỗ hổng này
cho phép kẻ tấn công thự thi câu lệnh từ xa hoặc thực thi với quyền quản trị của hệ
thống. Việc tấn cống này sẽ gây tác hại rất lớn nếu ứng dụng bị thực thi với quyền
quản trị hệ thống.
Ví dụ: nếu ta thay đoạn mã tiêm vào dạng: ' ; EXEC xp_cmdshell ‘cmd.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. Nếu cài
SQL Server ở chế độ mặc định thì SQL Server chạy trên nền SYSTEM, tương
đương mức truy cập ở Windows.
Dưới đây là một số extended stored procedure mà hacker thường hay sử
dụng để thực thi những câu lệnh xem nội dung thông tin trong máy nạn nhân:
-

Xp_availablemedia: Hiển thị những ổ đĩa hiện hành trên máy
Xp_dirtree: Hiển thị tất cả các thư mục kể cả thư mục con
Xp_loginconfig: Lấy thông tin về chế độ bảo mật trên server
Xp_makecab: Cho phép người sử dụng tạo các tập tin lưu trữ trên

Server (hay bất cứ tập tin nào mà server có thể truy xuất)

8


- Xp_ntsec_enumdomain: liệt kê những domain mà server có thể truy
vấn.
1.3.2. Blind SQL Injection
Blind SQL Injection là một phương pháp thực hiện tấn công SQL Injection trong
điều kiện các thông tin khai thác không được trình bày trực tiếp trên nội dung phản
hồi từ database. Cuộc tấn công này không phụ thuộc vào sự có mặt của các thông
báo lỗi, mà dựa vào việc sử dụng các mệnh đề điều kiện để thực hiện suy luận
thông tin cần khai thác. Cụ thể, Blind SQL Injection sử dụng chính xác các thông
tin cần khai thác làm mệnh đề điều kiện (mệnh đề suy luận) và sử dụng các phương
pháp khác nhau để đánh dấu trường hợp đúng/sai của mệnh đề đó. Giống như bất
kỳ tấn công SQL Injection nào, Blind SQL Injection cũng được sử dụng để khai
thác, phá hủy thông tin và trích xuất dữ liệu.
Không giống như các cuộc tấn công SQL Injection thông thường, các cuộc
tấn công Blind SQL Injection tốn nhiều thời gian hơn bởi vì mỗi khi có thông tin
mới thì các câu lệnh mới phải được tạo ra mà không có sự phản hồi từ ứng dụng.
a. Tấn công Blind SQL Injection dựa trên độ trễ phản hồi (Time-based Blind
Injection)
Các kỹ thuật tấn công dựa trên độ trễ phản hồi thường được dùng để kiểm
tra khi không có cách nào khác để lấy được thông tin từ cơ sở dữ liệu. Kẻ tấn công
sẽ chèn một đoạn mã SQL chứa các hàm của hệ quản trị cở dữ liệu hoặc một truy
vấn lớn nhằm tạo ra sự chậm trễ. Kẻ tấn công nhận được thông tin từ cơ sở dữ liệu
bằng cách quan sát thời gian cần để có phản hồi từ máy chủ. Kẻ tấn công đưa truy
vấn vào câu lệnh IF/THEN. Bằng cách đo thời gian phản hồi của cơ sở dữ liệu, kẻ
tấn công có thể suy ra loại tấn công nào cần thực hiện.
Giả sử trong trường hợp ứng dụng sử dụng SQL Server làm hệ quản trị cơ sở

dữ liệu. Để chèn một thời gian trễ trong câu lệnh được thực thi bởi SQL Server, kẻ
tấn công phải sử dụng các truy vấn Stack. Kẻ tấn công sẽ thử thực thi câu lệnh IF
EXIST (SELECT * FROM users) WAITFOR DELAY ‘0:0:10’. Đầu tiên câu lệnh
này sẽ kiểm tra cơ sở dữ liệu users có tồn tại hay không. Nếu không thì sẽ hiển thị
9


“We are unable to process your request. Please try back later.” Nếu cơ sở dữ liệu
này tồn tại, ứng dụng sẽ tạm dừng trong 10 giây. Sau 10 giây, hiển thị thông báo
“We are unable to process your request. Please try back later.” Dựa vào đây kẻ tấn
công sẽ biết được cần phải làm gì tiếp theo.
b. Boolean-based Blind Injection
Boolean-based Blind Injection là một kỹ thuật tấn công SQL Injection suy
luận dựa trên việc gửi một truy vấn SQL tới cơ sở dữ liệu, buộc ứng dụng phải trả
về một kết quả khác nhau tùy thuộc truy vấn trả về một kết quả đúng hay sai. Tùy
thuộc vào kết quả, nội dung trong phản hồi HTTP sẽ thay đổi hoặc vẫn như cũ.
Bằng cách so sánh trang phản hồi giữa các điều kiện mà kẻ tấn công có thể suy
luận truy vấn chèn vào có thành công hay không.

10


CHƯƠNG 2. BỘ CÔNG CỤ HỖ TRỢ THỰC HÀNH TẤN CÔNG
bWAPP viết tắt của Buggy Web Application, được viết bởi Malik Mesellem,
là một phần mềm mã nguồn mở miễn phí và chứa bộ mã nguồn mô phỏng các lỗ
hổng không an trên ứng dụng web. Nó cung cấp cho những người đam mê bảo
mật, những nhà phát triển và cả học sinh, sinh viên một môi trường để khám phá
và ngăn ngừa lỗ hổng web.
bWAPP chứa hơn 100 lỗ hổng, tập hợp các lỗi phổ biến trên ứng dụng web.
bWAPP được viết bằng ngôn ngữ lập trình PHP và sử dụng hệ quản trị cơ sở dữ

liệu MySQL. Nó có thể được cài đặt trên các nền tảng phổ biến như hiện nay như
Window/Linux

11


.

Hình 2. Giao diện bộ công cụ bWAPP

12


CHƯƠNG 3. KIỂM THỬ SQL INJECTION
3.1. Xác định lỗ hổng trong việc kiểm tra thông tin đầu vào
Tham số được nhập vào sẽ được sử dụng để xây dựng các truy vấn SQL nên
nó sẽ cần thỏa mãn các ràng buộc cú pháp với thành phần trước và sau trong truy
vấn gốc. Xét đoạn mã PHP xử lý đăng nhập sau:
$uname = isset($_POST[‘uname’]) ? $_POST[‘uname’]: “”;
$passwd = isset($_POST[‘passwd’]) ? $_POST[‘passwd’]: “”;
$query = “SELECT * FROM tbl_uers WHERE username = “ ” +
$uname + “” AND password = “” +$passwd + “”;
$qr = @mysql_query($query);
?>
Xâu truy vấn SQL được sinh ra trong trường hợp trên sử dụng trực tiếp giá
trị người dùng nhập vào, do đó mô hình xây dựng truy vấn dạng này được gọi
chung là xây dựng truy vấn động (dynamic query). Truy vấn thu được sẽ có dạng
như sau:
SELECT * FROM tbl_users WHERE username = ‘$uname’ AND passwd =

‘$passwd’;
Trong đó hai giá trị $uname và $passwd do người dùng nhập vào. Khi thực
hiện nhập giá trị username là admin’ OR ‘1’ = ‘1 , password là 1234’ OR ‘1’ = ‘1
truy vấn động thu được sẽ như sau: SELECT * FROM tbl_users WHERE username
= ‘admin’ OR ‘1’ = ‘1’ AND passwd = ‘123’ OR ‘1’ = ‘1’;Trường hợp này việc xác
thực đã thành công vì mệnh đề WHERE luôn đúng.

13


Tùy thuộc vào câu truy vấn gốc mà các tham số được chèn vào sẽ có vị trí
khác nhau trong truy vấn đó. Ứng với từng trường hợp đó, có các mô hình chèn
tham số sau:
- Chèn vào giữ truy vấn: là mô hình chỉ đơn thuần thao tác với các tham
số, không hề tác động đến cấu trúc và các thành phần của truy vấn
gốc.
- Chèn và ngắt truy vấn: là mô hình chèn truy vấn phổ biến nhất, truy
vấn được chèn vào sẽ bao gồm thêm ở cuối các ký tự chú thích nhằm
ngắt truy vấn tại đó, vô hiệu hóa các phần từ trong truy vấn gốc nằm ở
phía sau vị trí tham số. Đoạn mã PHP được cải tiến như sau:
$uname = isset($_POST[‘uname’]) ? $_POST[‘uname’]: “”;
$passwd = isset($_POST[‘passwd’]) ? $_POST[‘passwd’]: “”;
If ($uname == “” || $passwd == “”){
Echo “username or password id missing”;}
Else{
If ($passwd == “”)
Echo “password is missing”;
Else if ($uname == “”)
Echo “username is missing”;

Else {
$query = “SELECT * FROM tbl_uers WHERE username = “ ”
+ $uname + “” AND password = “” +$passwd + “”;
$qr = @mysql_query($query);

14


?>
Với đoạn xử lý trên, các trường username và password không được để
trống, tuy nhiên không nhất thiết phải chèn nhiều mệnh để OR, ta chỉ cần đảm một
trong hai trường này không bị trống, và sử dụng ký tự chú thích để ngắt truy vấn
sau mệnh đề OR đầu tiên. Ví dụ trường password để trống, truy vấn có thể là
SELECT * FROM tbl_users WHERE username = ‘admin’ OR ‘1’ = ‘1--’ AND
passwd = ‘’;
Một số ký tự chú thích hay được sử dung:

Hình 3. Các ký tự chú thích thường gặp.
Ngoài ra có thể chèn các chuỗi sau để kiểm tra:
- ' or 1=1-- " or 1=1-- or 1=1-- ' or 'a'='a
- " or "a"="a
3.2. Xác định điểm yếu SQL Injection dựa trên phản hồi
Ứng dụng Web là một ví dụ sử dụng kiến trúc Client/Server. Trình duyệt
của người dùng (Client) gửi tới máy chủ một yêu cầu và chờ đợi phản hồi. Máy
15


chủ nhận được yêu cầu, và tạo ra một phản hồi gửi lại cho người dùng. Rõ ràng
phải có một sự thống hiểu biết nào đó giữa hai bên, nếu không người dung gửi một
yêu cầu lên máy chủ sẽ không biết đó là yêu cầu gì để phản hồi. Ở đây ứng dụng sẽ

dùng một giao thức để dùng làm trao đổi giữa hai bên, trong trường hợp này sử
dụng giao thức HTTP. Hai phương thức thông điệp yêu cầu phổ biến nhất là GET
và POST.
Cấu trúc thông điệp GET và POST có nhiều điểm khác nhau, song khi tiến
hành sửa đổi và chènn nội dung cần chú ý tới vị trí của chuỗi truy vấn. Chuỗi truy
vấn này chứa các tham số được gửi lên máy chủ, chuỗi này có dạng sau: ?var_1 =
val_1 and var_2 &…&var_n = val_n.
Trong thông điệp GET chuỗi truy vấn nằm ở đầu thông điệp, còn trong
POST nó nằm ở cuối thông điệp.
Xet một trang thông tin có đường dẫn:
/>Trang showprodcts.php sẽ nhận được một tham số category khi bạn nhấp
vào đường link này. Ứng dụng Web sẽ dựa vào tham số này để phản hồi lại cho
người dùng, tùy thuộc vào tham số category ứng dụng sẽ trả về các sản phẩm khác
nhau. Giả sử, khi truyền vào một tham số category là attacker mà trong ứng dụng
không có, đường dẫn lúc này là :
/>Phản hổi của máy chủ lúc này là:
Warning: mysql_fetch_assoc(): supplied argument is not a valid MySQL
result resource in /var/www/victim.com/showproducts.php on line 34
Một cách khác để phát hiện Web có mắc lỗi SQL Injection hay không là
thêm các siêu ký tự vào câu truy vấn trong hệ quản trị cơ sở dữ liệu, chẳng hạn dấu
nháy đơn (‘), các ký tự chú thích (--, #, /**?)… và chờ sự phản hồi của ứng dụng.

16


Sau khi thử thêm dấu nháy đơn (‘) vào cuối giá trị tham số category, máy
chủ phản hồi lại như sau:
Error: 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
''attacker''' at line 1


17


CHƯƠNG 4. CÁC KỸ THUẬT TẤN CÔNG SQL INJECTION
4.1. Tấn công khai thác dữ liệu thông qua toán tử UNION
Trong trường hợp này dùng toán tử UNION để tìm số cột của một bảng dữ
liệu, dựa vào số cột tìm được để tấn công trích xuất dữ liệu.
Xét một đường dẫn chứa điểm yếu SQL Injection trên biến id như sau:
=10
Có hai cách để tìm ra số cột của bảng hiện thời, đầu tiên bao gồm việc chèn
truy vấn thứ hai nhiều lần, dần dần tăng số cột cho đến khi truy vấn thực hiện
chính xác. Trên hầu hết hệ quản trị cơ sở dữ liệu đều có thể chèn giá trị NULL cho
mỗi cột. Nếu muốn tìm chính xác số cột của product.asp có thể yêu cầu các URL
sau cho đến khi không có thông báo lỗi:
/>id=10+union+select+null+from+dual-dual là một bảng có thể truy cập được bởi tất cả người dùng và cho phép sử
dụng câu lệnh SELECT ngay cả khi không quan tâm đến việc trích xuất dữ liệu từ
một bảng cụ thể, chẳng hạn như trong trường hợp này.
Một cách khác để tái tạo lại thông tin giống nhau là sử dụng mệnh đề
ORDER BY thay vì chèn một truy vấn khác. ORDER BY có thể cho phép một tên
cột như một tham số, nhưng cũng có một số đơn giản để xác định một cột cụ thể.
Vì vậy, có thể xác định số cột trong truy vấn bằng cách tăng số cột ORDER BY.
Mệnh đề ORDER BY được sử dụng để sắp xếp kết quả trả về bởi truy vấn theo cột
được chỉ định. Nếu cột đó không tồn tại, một thông báo lỗi trả về. Giả sử muốn sắp
xếp theo cột thứ 2 ta chèn tham số ORDER BY 2 vào giá trị tham số id, lúc này
ứng dụng sẽ thực thi truy vấn sau: SELECT * FROM dueal WHERE id =12
ORDER By 2-- -;
Nếu kết quả trả về là: Result. The data returned is sorted by description. tức
là hiện tại có ít nhất 2 cột. Ta tiếp tục sử dụng truy vấn này bằng cách tang dần số
18



cột lên cho đến khi gặp một thông báo lỗi. Ví dụ với mốc 6 cột, ứng dụng trả về kết
quả: Error Returned. ORA-01785: ORDER BY item must be the number of a
SELECT-list expression.
Có nghĩa là truy vấn đang thực hiện có chính xác 5 cột. Phương pháp thứ
hai này tốt hơn. Đầu tiên, phương pháp ORDER BY nhanh hơn, đặc biệt nếu bảng
có nhiều cột. Nếu số cột chính xác là n, thì phương pháp đầu tiên phải thực hiện n
truy vấn. Vì phương pháp này luôn tạo ra lỗi, trừ phi chọn đúng giá trị. Mặt khác,
phương pháp thứ hai tạo ra lỗi chỉ khi sử dụng con số lớn hơn n. Điều này có nghĩa
là có thể sử dụng thuật toán tìm kiếm nhị phân để thực hiện phương pháp này. Ví
dụ bản đang kiểm tra có 13 cột, ta thực hiện các bước sau:
1. Bắt đầu thử với ORDER BY 8, ứng dụng không trả về lỗi. Điều này có nghĩa
là số cột chính xác là 8 hoặc lớn hơn.
2. Tiếp tục thử với ORDER BY 16, ứng dụng trả về lỗi. Điều này có nghĩa là
số cột sẽ nằm trong khoảng từ 8 đến 15.
3. Thử lại với ORDER BY 12, mà ứng dụng không trả về một lỗi. Lúc này có
nghĩa là số cột sẽ nằm trong khoảng 12 đến 15.
4. Hãy thử với ORDER BY 14, lúc này ứng dụng trả về lỗi. Bây giờ có thể biết
chính xác rằng số cột là 12 hoặc 13.
5. Thử với ORDER BY 13, ứng dụng không trả về một lỗi. Lúc này biết được
chính xác số cột của bảng này là 13.
Có thể thấy rằng phương pháp ORDER BY này nhanh hơn rất nhiều so với
cách đầu tiên. Thay vì phải thử 13 lần, ta chỉ cần thử 5 lần truy vấn.
4.2. Tấn công sử dụng mệnh đề điều kiện
4.2.1. Tấn công dựa trên độ trễ phản hồi
Một cách tiếp cận đầu tiên trong cuộc tấn công SQL Injection sử dụng mệnh
đề điều kiện là dựa trên thời gian phản hồi của ứng dụng Web. Ví dụ trên SQL
Server, một trong những điều đầu tiên kẻ tấn công muốn biết liệu người dùng thực
hiện truy vấn có phải là tài khoản quản trị hệ thông ‘SA’ hay không. Điều này khá

quan trong, vì tùy thuộc vào đặc quyền trên hệ thống, kẻ tấn công có thể thực hiện
các cuộc hành động khác nhau trên cơ sở dữ liệu từ xa. Do đó, kẻ tấn công sẽ chèn
truy vấn sau: IF (system_user = 'sa') WAITFOR DELAY '0:0:5' –
19


Đường dẫn lúc này sẽ là :
/>+WAITFOR+DELAY+'0:0:5'-system_user chỉ đơn giản là một hàm Transact-SQL (T-SQL) trả về tên đăng
nhập hiện tại (ví dụ như sa). Tùy thuộc vào giá trị của system_user truy vấn sẽ thực
thi WAITFOR (và sẽ đợi 5 giây). Bằng cách đo thời gian ứng dụng phản hồi về
trang HTML, kẻ tấn công có thể xem tài khoản này là sa hay không.
Giá trị được sử dụng (trong 5 giây) là tùy ý; kẻ tấn công có thể sử dụng bất
kỳ giá trị nào khác trong khoảng một giây (WAITFOR DELAY '0: 0: 1') và 24 giờ
(WAITFOR DELAY '23: 59: 59 'là sự chậm trễ dài nhất mà lệnh này sẽ chấp nhận).
Năm giây đã được sử dụng bởi vì nó là một sự cân bằng hợp lý giữa tốc độ và độ
tin cậy; một giá trị ngắn hơn sẽ cho kẻ tấn công một phản hồi nhanh hơn, nhưng nó
có thể ít chính xác hơn trong trường hợp sự chậm trễ mạng không mong đợi.
Nếu kẻ tấn công có quyền quản trị, kẻ tấn công có thẻ sử dụng thủ tục
xp_cmdshell để có được kết quả tương tự bằng cách chạy một lệnh mất khoảng vài
giây để thực thi. Như trong ví dụ sau sẽ là ping tới gia diện loopback trong 5 giây:
EXEC master..xp_cmdshell 'ping -n 5 127.0.0.1'
4.2.2. Tấn công dựa trên thông báo lỗi
Phương pháp tiếp cận dựa trên độ trễ phản hồi rất linh hoạt và nó được đảm
bảo hoạt động trong kịch bản tấn công vì nó chỉ dựa vào thời gian chứ không phải
tên đầu ra của ứng dụng.
Tuy nhiên, nó không thích hợp để thực hiện truy xuất nhiều bit thông tin.
Giả sử mỗi bit có cùng xác suất là 1 và 0. Kẻ tấn công sẽ sử dụng hàm
is_srvrolemember () để thực hiện cuộc tấn công này.
is_srvrolemember () là một hàm trong T-SQL, hàm này sẽ trả về kết quả sau:
- 1 nếu người dùng thuộc nhóm được chỉ định

- 0 nếu người dùng không thuộc trong nhóm
- Null nếu nhóm được chỉ định không tồn tại trong cơ sở dữ liệu
Hãy xem truy vấn sau:
/>Nếu người dùng thuộc nhóm sysadmin, tham số id sẽ bằng 12/1, bằng 12 và
ứng dụng sẽ trở lại trang cũ mô tả sách Syngress. Tuy nhiên nếu người dùng hiện
tại không là thành viên của nhóm sysadmin, thì tham số id sẽ bằng 12/0, và chắc
chắn đây không phải là một con số. Điều này sẽ làm cho truy vấn thất bại, và ứng
20


dụng sẽ trả về một lỗi. Nó có thể chỉ đơn giản là ‘500 Internal Server Error’ được
trả về từ ứng dụng web.

21


CHƯƠNG 5. CÁCH PHÒNG TRÁNH TẤN CÔNG SQL INJECTION
Để tránh các cuộc tấn công SQL Injection cần phải:
- Hạn chế và kiểm soát dữ liệu đầu vào: kiểm tra dữ liệu được nhập vào có tốt
hay không bằng cách xác nhận loai, chiều dài, định dạng, và phạm vi của dữ
liệu
- Sử dụng các tham số SQL an toàn để truy cập dữ liệu: có thể sử dụng các
tham số này với các thủ tục được lưu trữ hoặc các chuỗi lệnh SQL được tạo
động. Các bộ sưu tập thông số như SqlParameterCollection cung cấp kiểm
tra kiểu và xác nhận độ dài. Nếu sử dụng một bộ sưu tập các thông số, đầu
vào được coi là một giá trị văn bản, và SQL Server không coi nó như mã
thực thi. Lợi ích bổ sung của việc sử dụng bộ sưu tập thông số là bạn có thể
thực thi kiểm tra loại và thời lượng. Giá trị bên ngoài phạm vi kích hoạt một
ngoại lệ. Đây là một ví dụ tốt về phòng thủ sâu.
- Sử dụng tài khoản có giới hạn quyền trong cơ sở dữ liệu. Lý tưởng hơn, chỉ

nên cấp quyền thực thi cho các thủ tục được lưu trữ đã chọn trong cơ sở dữ
liệu và không cung cấp truy cập bảng trực tiếp
- Tránh tiết lộ thông tin lỗi cơ sở dữ liệu. Trong trường hợp lỗi cơ sở dữ liệu,
đảm bảo chắc chắn không tiết lộ thông báo lỗi chi tiết cho người dùng.
Kiểm soát chặt ché dữ liệu nhập vào
Để phòng tránh các nguy cơ có thể xảy ra, hãy bảo vệ các câu lệnh SQL
bằng cách kiểm soát chặt chẽ tất cả các dữ liệu nhập được gửi từ đối tượng Request
(Request.QueryString, Request.Cookies, và
Request.ServerVariables). Ví dụ,
có thể giới hạn chiều dài của chuỗi nhập liệu, hoặc xây dựng hàm EscapeQuote để
thay thế các dấu nháy đơn bằng dấu hai dấu nháy đơn như:
<%
Function EscapeQuotes(sInput)
sInput = replace(sInput, “ ‘ ”, “ ‘’ ”)
EscapeQuotes = sInput
22


End Function
%>
Trong trường hợp dữ liệu nhập vào là số, lỗi xuất phát từ việc thay thế một
giá trị được tiên đón là dữ liệu số bằng chuỗi chứa các câu lệnh SQL bất hợp pháp.
Để tránh điều này, đơn giản hãy kiểm tra dữ liệu có đúng kiểu hay không bằng hàm
IsNumeric().
Ngoài ra có thể xây dựng hàm loại bỏ một số ký tự và từ khóa nguy hiểm
như: ;, -, select, insert, xp-,… ra khỏi chuỗi dữ liệu nhập từ phía người dùng để hạn
chế các tấn công này. Hàm được sử dụng có dạng như sau:
<%
Function KullChars(sInput)
Dim badChars

Dim newChars
badChars = array(“select”, “drop”, “;”, “insert”, “delete”, “xp_”)
for i = 0 to uBound(badChars)
newChars = replace(newChars, badChar(i), “”)
next
KillChars = newChars
End Function
%?

23


Chương 6. Hướng dẫn một số tấn công SQL Injection với BWapp.

Hình 4. Các kiểu SQL Injection có trong Bwapp.
Trên đây là danh sách các lỗi SQL Injection mà bộ công cụ BWAPP cung cấp.
6.1. SQL Injection (Login Form/Hero).
Đây là dạng tấn công vượt qua kiểm tra đăng nhập.
Bài toán: làm sao để có thể vượt qua đăng nhập bằng kỹ thuật tấn công SQL
Injection.
Các bước thực hiện như sau.
Bước 1: Chọn dạng tấn công.
24


Hình 5. Chọn SQL Injection (GET/Search).
Tại Choose your bug chọn SQL Injection (Login Form/Hero) và mức bảo
mật low. Sau đó click vào Hack để bắt đầu thực hiện tấn công. Giao diện sau khi
click vào hack.


Hình 6. Giao diện đăng nhập SQL Injection (Login Form/Here).
Bước 2: Chèn đoạn mã sql vào form để vượt qua đăng nhập.
Tại khung Login điền: superhero
Tại khung Password điền: ‘ OR ‘1’=1
Sau đó click vào Login và xem kết quả.

25


×