Sql injection tutorials hướng dẫn đầy đủ về sql injection năm 2024
SQL Injection không còn là khái niệm quá mới, nhưng nó vẫn là một trong những kiểu tấn công mạng khá phổ biến. Bài viết này gồm 12 mục, đi từ khái niệm, các bước diễn ra SQL Injection với một ví dụ minh họa (trang web được dùng làm ví dụ chỉ là minh họa, không có thực) đến cách phòng chống tấn công SQL Injection để bạn đọc hiểu về cách thức tấn công này, từ đó có những biện pháp phòng ngừa, bảo vệ website và hệ thống của mình. Show
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. Bài viết chỉ nhằm mục đích giúp bạn hiểu về kiểu tấn công SQL Injection và có những biện pháp phòng tránh cho ứng dụng web của mình. Tìm hiểu về SQL Injection1. SQL Injection là gì?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, ... Bài labs SQL InjectionBạn có thể hình dung toàn bộ quá trình tấn công bằng SQL Injection thông qua một bài labs về SQL injection đơn giản dưới đây. Bài lab sẽ đưa ra ví dụ về một ứng dụng có lỗ hổng để sử dụng SQL Injection, bạn chỉ cần làm theo các bước trong hướng dẫn để tiến hành kiểu tấn công này. Sau khi thực hiện bài labs, bạn đã có những hình dung cơ bản về SQL Injection, nhưng nếu muốn hiểu rõ và chi tiết hơn, bạn hãy đọc những phân tích cụ thể tiếp theo nhé. 2. Các bước tiến hành SQL Injection2.1. Tìm kiếm mục tiêuCó thể tìm 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, ... Ví dụ:
Một số trang web chuyển tham số qua các field ẩn, phải xem mã HTML mới thấy rõ. Ví dụ như ở dưới.
2.2. Kiểm tra chỗ yếu của trang webThử submit các field username, password hoặc field id, .. bằng hi' or 1=1--
Nếu site chuyển tham số qua field ẩn, hãy download source HTML, lưu trên đĩa cứng và thay đổi lại URL cho phù hợp. Ví dụ:
Nếu thành công, thì có thể login vào mà không cần phải biết username và password 2.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 liên kết đến một ASP trang khác với URL như sau:
Trong URL trên, biến 'category' được gán giá trị là 'food'. Mã ASP của trang này có thể như sau (đây chỉ là ví dụ thôi):
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à:
Dòng query trên sẽ trả về một tập resultset chứa một hoặc nhiều dòng phù hợp với điều kiện WHERE PCategory='food' Nếu thay đổi 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à:
Dòng query trên sẽ select mọi thứ trong bảng product bất chấp 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ỏ qua. Đối với MySQL, hãy thay "--" thành "#" Ngoài ra, cũng có thể thử cách khác bằng cách submit ' or 'a'='a. Dòng SQL query bây giờ sẽ là:
Một số loại dữ liệu khác mà cũng nên thử submit để biết xem trang web có gặp lỗi hay không:
2.4. Thi hành lệnh từ xa bằng SQL InjectionNếu cài đặt với chế độ mặc định mà không có điều chỉnh gì, MS SQL Server sẽ chạy ở mức SYSTEM, tương đương với mức truy cập Administrator trên Windows. Có thể dùng store procedure xp_cmdshell trong CSDL master để thi hành lệnh từ xa:
0 Hãy thử dùng dấu nháy đôi (") nếu dấu nháy đơn (') không làm việc. Dấu chấm phẩy (sẽ kết thúc dòng SQL query hiện tại và 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, có thể listen các ICMP packet từ 10.10.1.2 bằng tcpdump như sau:
1 Nếu nhận được ping request từ 10.10.1.2 nghĩa là lệnh đã được thi hành. 2.5. Nhận output của SQL queryCó thể dùng sp_makewebtask để ghi các output của SQL query ra một file HTML
2 Chú ý: folder "share" phải được share cho Everyone trước. 2.6. Nhận dữ liệu qua 'database using ODBC error message'Các thông báo 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, bây giờ chúng ta thử hợp nhất integer '10' với một string khác lấy từ CSDL:
3 Bảng INFORMATION_SCHEMA.TABLES của hệ thống SQL Server chứa thông tin về tất cả các 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ó bởi vì chúng ta biết rằng nó luôn tồn tại. Query của chúng ta là:
4 Dòng query này sẽ trả về tên của bảng đầu tiên 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:
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 đầu tiên trong CSDL mà chúng ta đang muốn có. Để lấy tên của tên của bảng tiếp theo, có thể dùng query sau:
6 Cũng có thể thử tìm dữ liệu bằng cách khác thông qua statement LIKE của câu lệnh SQL:
7 Khi đó thông báo lỗi của SQL Server có thể là:
8 Mẫu so sánh '%25login%25' sẽ tương đương với %login% trong SQL Server. Như thấy trong thông báo lỗi trên, chúng ta có thể xác định được tên của một table quan trọng là "admin_login". 2.7. Xác định tên của các column trong tableTable INFORMATION_SCHEMA.COLUMNS chứa tên của tất cả các column trong table. Có thể khai thác như sau:
9 Khi đó thông báo lỗi của SQL Server có thể như sau:
0 Như vậy tên của column đầu tiên là "login_id". Để lấy tên của các column tiếp theo, có thể dùng mệnh đề logic NOT IN () như sau:
1 Khi đó thông báo lỗi của SQL Server có thể như sau:
2 Làm tương tự như trên, có thể lấy được tên của các column còn lại như "password", "details". Khi đó ta lấy tên của các column này qua các thông báo lỗi của SQL Server, như ví dụ sau:
3 Khi đó thông báo lỗi của SQL Server có thể như sau:
4 2.8. Thu thập các dữ liệu quan trọngChúng ta đã xác định được các tên của các table và column quan trọng. Chúng ta sẽ thu thập các thông tin quan trọng từ các table và column này. Có thể lấy login_name đầu tiên trong table "admin_login" như sau:
5 Khi đó thông báo lỗi của SQL Server có thể như sau:
6 Dễ dàng nhận ra được admin user đầu tiên có login_name là "neo". Hãy thử lấy password của "neo" như sau:
7 Khi đó thông báo lỗi của SQL Server có thể như sau:
8 Và bây giờ là đã có thể login vào với username là "neo" và password là "m4trix". 2.9. Nhận các numeric stringCó một hạn chế nhỏ đối với phương pháp trên. Chúng ta không thể nhận được các error message nếu server có thể chuyển text đúng ở dạng số (text chỉ chứa các 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:
9 Thì khi đó chỉ nhận được thông báo lỗi "Page Not Found". Lý do bởi vì server có thể chuyển passoword "31173" sang dạng số trước khi UNION với integer 10. Để giải quyết vấn đề này, chúng ta có thể thêm một vài kí tự alphabet vào numeric string này để làm thất bại sự chuyển đổi từ text sang số của server. Dòng query mới như sau:
0 Chúng ta dùng dấu cộng (+) để nối thêm text vào password (ASCII code của '+' là 0x2b). 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:
1 Và nghĩa là bây giờ ta cũng có thể login vào với username 'trinity' và password là '31173' 2.10. Thay đổi dữ liệu (Update/Insert) của CSDLKhi đã có tên của tất cả các column trong table, 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. Để thay đổi password của "neo", có thể làm như sau:
2 Hoặc nếu bạn muốn một record mới vào table:
3 Và bây giờ có thể login vào với username "neo2" và password là "newpas5" 3. Ngăn chặn SQL InjectionCác tổ chức có thể tập trung vào những bước sau đây để bảo vệ mình khỏi những cuộc tấn công SQL Injection:
Ngăn chặn SQL Injection trong ASP.NETCá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 kiểm soát tốt các thông báo lỗi. Và mặc định trong ASP.NET là thông báo lỗi sẽ không được thông báo chi tiết khi không chạy trên localhost. |