Drupal Consultant
Started my career as a drupal8 developer in EM Solutions . I love learning Web technologies like HTML, CSS, PHP, Jquery Ajax and Drupal backend . Currently working as a drupal backend developer.
Trong phần lớn người sử dụng chúng ta, chắc hẳn nhiều người đã nghe nói tới khái niệm tấn công, chiếm quyền điều khiển website bằng phương pháp SQL Injection – SQLI và (Distributed) Denial of Service – DDoS. Vậy thực sự quá trình này được tin tặc sử dụng như thế nào, dựa vào đâu mà hacker có thể xác định được những lỗ hổng bảo mật trên website để tấn công vào đó... Trong bài viết dưới đây, Quản Trị Mạng sẽ giới thiệu một vài điểm cơ bản để mọi người hiểu thêm về bản chất của cách thức tấn công khá phổ biến này.
Để dễ hình dung hơn về DDoS, các bạn hãy tham khảo hình minh họa bên dưới:
Denial of service (hay còn gọi là distributed denial of service hoặc DDoS) là hình thức tấn công thường xảy ra khi 1 hệ thống (ở đây chúng ta đang đề cập tới web server) nhận được quá nhiều yêu cầu truy cập trong cùng 1 thời điểm, do vậy hệ thống sẽ lâm vào tình trạng quá tải, và dẫn tới việc hoạt động không ổn định, phát sinh thêm nhiều vấn đề khác. Mục đích chung của phương pháp tấn công DDoS này là khiến cho website của nạn nhân lưu trữ trên server vượt quá lượng truy cập thông thường.
Để hiểu rõ về quá trình này, chúng ta sẽ cùng tham khảo qua 1 ví dụ phổ biến.
Chẳng hạn, có hàng ngàn người (đảm nhận việc tấn công – vai trò chính của hacker) cùng tham gia vào quá trình làm cản trở việc kinh doanh của công ty X nào đó bằng cách liên lạc, gọi điện thoại tới trung tâm hỗ trợ, chăm số khách hàng của họ. Thời gian cụ thể được xác định vào lúc 9 giờ sáng ngày thứ 3, và trong hầu hết các trường hợp xảy ra thì hệ thống điện thoại của công ty X sẽ không thể chịu được hàng triệu cuộc gọi đến vào lúc 9h, khác hẳn so với ngày thường. Bên cạnh đó, những khách hàng thực sự muốn gọi điện đến thì lại không thể thực hiện được cuộc gọi... và tất nhiên, uy tín của công ty X đó sẽ bị ảnh hưởng rất nhiều.
Về bản chất thì quá trình tấn công DDoS cũng được tiến hành tương tự như vậy. Bởi vì gần như không có cách nào có thể xác định được nguồn gốc của những yêu cầu truy cập tới là của tin tặc hay khách hàng thực sự cho tới lúc server xử lý kịp, cho nên hiệu quả và tỉ lệ thành công của phương pháp này rất cao.
Do tính chất vô cùng “bạo lực” của DDoS, những tên hacker đã phải chuẩn bị rất nhiều máy tính để thực hiện cuộc tấn công vào mục tiêu trong cùng 1 thời điểm. Quay trở lại ví dụ của công ty X ở trên, điểm mấu chốt của tin tặc là đồng loạt gọi điện tới trung tâm chăm sóc khách hàng đúng vào lúc 9 giờ sáng. Nhưng nếu xét về khía cạnh kỹ thuật thì quá trình này sẽ đơn giản và dễ dàng khi tất cả các máy tính của nạn nhân đã ở trong trạng thái zombie – nghĩa là đã bị lây nhiễm và ảnh hưởng bởi virus của hacker.
Và như tất cả chúng ta đã biết, có rất nhiều biến thể đa dạng của malware và trojan xuất hiện trong thời gian qua. Sau khi bí mật xâm nhập thành công vào bên trong hệ thống, chúng sẽ âm thầm chờ đợi đúng thời điểm để hoạt động. Ví dụ tại đây, lệnh thực hiện các yêu cầu tấn công sẽ được tin tặc gửi tới malware, trojan, và mục tiêu là hệ thống webserver của công ty X lúc 9 giờ sáng ngày thứ 3. Do vậy, chỉ cần 1 hacker cũng có thể tạo ra được rất nhiều lệnh tấn công từ nhiều địa điểm khác nhau tương ứng với các máy tính đã bị lây nhiễm bởi malware.
Lợi ích của việc tận dụng hệ thống máy tính đã bị nhiễm mã độc tỏ ra vô cùng hiệu quả, vì hacker sẽ có nhiều cơ hội để che dấu tung tích của chúng, mặt khác hiệu quả và tỉ lệ thành công khi tiến hành tấn công lại đảm bảo hơn rất nhiều.
Cơ chế tấn công SQL injection – SQLI là cách thức tận dụng hoặc khai thác triệt để những khuyết điểm, thiếu sót về mặt công nghệ được sử dụng để xây dựng website, và thông thường hacker sẽ kết hợp với những lỗ hổng trong quy trình bảo mật cơ sở dữ liệu. Nếu thành công trong việc xâm nhập này, hacker hoàn toàn có thể mạo danh tài khoản chính thức của người sử dụng, truy cập vào cơ sở dữ liệu và lấy cắp thông tin cá nhân. Không giống như cách làm của DDoS, SQLI hoàn toàn có thể ngăn chặn được nếu người quản trị nhận thức được tầm quan trọng của việc bảo mật cơ sở dữ liệu.
Mỗi khi người dùng tiến hành đăng nhập vào tài khoản trực tuyến, họ sẽ phải cung cấp thông tin về Username và Password. Trong quy trình kiểm tra và xác nhận tính hợp pháp của tài khoản đó, hệ thống hoặc ứng dụng web tương ứng sẽ chạy 1 câu lệnh truy vấn có dạng như sau:
SELECT UserID FROM Users WHERE UserName='myuser' AND Password='mypass';
Lưu ý rằng các phần giá trị trong câu lệnh query SQL phải kết thúc bằng dấu nháy đơn ( ' ) và đó cũng là lý do tại sao chúng xuất hiện quanh phần giá trị được nhập.
Quy trình yêu cầu sự trùng khớp giữa tên tài khoản được nhập vào (myuser) và mật khẩu (mypass) với bản ghi lưu trữ thông tin trong bảng Users, và sau đó trả về giá trị UserID. Nếu không trùng khớp thì sẽ không có giá trị UserID nào được trả về, và thông tin người dùng nhập vào là không chính xác.
Tiếp theo, chúng ta hãy cùng tham khảo mẫu câu lệnh truy vấn xác nhận tài khoản có thể thay thế giá trị của người dùng nhập vào trên web.
SELECT UserID FROM Users WHERE UserName=’[user]‘ AND Password=’[pass]‘
Ngay từ cái nhìn đầu tiên, có thể nhiều người sẽ nghĩ rằng quy trình xác nhận tài khoản như vậy là hoàn toàn hợp lý và chuẩn xác. Tuy nhiên, chỉ cần một sự thay đổi nho nhỏ trong cấu trúc này thì đó có thể là dấu hiệu của đợt tấn công, xâm nhập của SQLI.
Ví dụ, “myuser’–” là giá trị nhập vào trường Username và “wrongpass” là mật khẩu, thì mẫu câu lệnh truy vấn thay thế sẽ có dạng như sau:
SELECT UserID FROM Users WHERE UserName='myuser'--' AND Password='wrongpass'
Điểm mấu chốt và đặc điểm nhận dạng ở đây chính là 2 dấu gạch ngang liền nhau (- -), đây là điểm bắt đầu của phần thông báo đối với câu lệnh SQL, bất cứ những gì ở sau 2 dấu gạch ngang này sẽ bị bỏ qua. Và do vậy, câu lệnh trên sẽ được cơ sở dữ liệu xác nhận thành:
SELECT UserID FROM Users WHERE UserName='myuser'
Phần thiếu sót lớn nhất ở đây chính là khâu kiểm tra mật khẩu, chỉ với 2 dấu gạch ngang như trên hacker đã hoàn toàn có thể vượt qua được quá trình kiểm tra, và “ngang nhiên” đăng nhập bằng tên tài khoản “myuser” mà không cần phải nhập mật khẩu tương ứng. Tiếp theo sau đó sẽ là các cuộc tấn công SQL injection tiếp theo.
Thực chất, nguồn gốc của quá trình tấn công SQL injection là sự cẩu thả trong quy trình mã hóa ứng dụng, mật khẩu nhưng vẫn có thể ngăn chặn được, tuy nhiên mức độ thiệt hại là không thể lường trước được và phụ thuộc vào quy mô của từng database. Trong quá trình một ứng dụng web bất kỳ có thể giao tiếp với backend database thì sẽ phải cung cấp thông tin đăng nhập tới 1 cơ sở dữ liệu (quy trình này khác hẳn so với lúc người dùng tiến hành đăng nhập vào website qua form login). Phụ thuộc vào mức phân quyền tương ứng mà ứng dụng web yêu cầu, tài khoản trong cơ sở dữ liệu có thể sử dụng được bất kỳ quyền chỉnh sửa nào, từ việc đơn giản như đọc, ghi đơn thuần trên những bảng có sẵn cho tới mức quyền đầy đủ.
Cũng dựa vào ví dụ trên, chúng ta thấy bằng việc nhập tên tài khoản (ví dụ "youruser'--", "admin'--" hoặc bất kỳ) thi hoàn toàn có thể đăng nhập trực tiếp vào database mà không cần biết password. Khi ở bên trong, hệ thống sẽ không thể biết được tài khoản đó là tài khoản bình thường hoặc có đầy đủ quyền tương ứng. Về mặt bản chất, việc phân quyền của database không cung cấp quyền chính xác tương ứng và an toàn trong quá trình này, bởi vì thông thường 1 website ít nhất phải có quyền đọc hoặc ghi tới cơ sử dữ liệu tương ứng.
Giả sử rằng hệ thống website của chúng ta có đầy đủ quyền truy cập, bao gồm việc xóa dữ liệu, thêm hoặc xóa bảng, tạo mới tài khoản... và trên thực tế, có khá nhiều chương trình nếu muốn cài đặt và sử dụng thì phải được phân quyền ở mức cao nhất, do vậy bạn phải cẩn thận khi thực hiện việc gán quyền.
Để minh họa thêm về mức độ thiệt hại có thể gây ra trong tình huống này, chúng ta sẽ dựa vào hình vẽ trên, và nhập phần thông tin sau vào trường Username:
"Robert'; DROP TABLE Users;--"
Chỉ với vài sự thay đổi nho nhỏ, câu lệnh query sẽ trở thành:
SELECT UserID FROM Users WHERE UserName='Robert'; DROP TABLE Users;--' AND Password='wrongpass'
Lưu ý rằng dấu phẩy trong MySQL được sử dụng để kết thúc mệnh đề cũ và bắt đầu 1 mệnh đề mới.
Dòng lệnh trên sẽ được database thực hiện thành:
SELECT UserID FROM Users WHERE UserName='Robert'
DROP TABLE Users
Chỉ đơn giản như vậy, chúng ta đã thực hiện thành công 1 pha tấn công SQLI nho nhỏ với mục đích chính là xóa toàn bộ bảng dữ liệu Users.
Như chúng ta đã đề cập tới tại phần trên của bài viết, SQL Injection hoàn toàn có thể ngăn chặn được. Và 1 trong những quy tắt không thể bỏ qua là không nên tin tưởng tuyệt đối vào bất kỳ thông tin nào mà người sử dụng nhập vào (tương tự như tình huống chúng tôi mô phỏng bên trên).
Và mô hình SQLI có thể dễ dàng bị ngăn chặn bởi 1 bước gọi là Sanitization – hiểu nôm na là việc chắt lọc thông tin đầu vào – input từ phía người dùng. Rất đơn giản, quy trình này sẽ xử lý bất kỳ ký tự ngoặc đơn nào xuất hiện trong câu lệnh truy vân SQL.
Ví dụ cụ thể, nếu muốn tìm bản ghi “O’neil” trong cơ sở dữ liệu, thì không thể dùng phương pháp đã mô phỏng bên trên vì dấu ' đằng sau chữ O sẽ khiến cho cú pháp bị ngắt giữa chừng. Thay vào đó, chúng ta có thể tách biệt ký tự đặc biệt này khỏi cơ sở dữ liệu bằng dấu \. Và như vậy, bản ghi “O’neal” sẽ biến thành “O\’neil”.
Để hiểu kỹ hơn về quá trình này, chúng ta hãy quay trở lại ví dụ trên:
myuser'-- / wrongpass:
SELECT UserID FROM Users WHERE UserName='myuser\'--' AND Password='wrongpass'
Bởi vì dấu phẩy đằng sau myuser đã được đảm bảo an toàn, nên cơ sở dữ liệu sẽ tiến hành tìm kiếm thông tin UserName của "myuser'--". Bên cạnh đó, các dấu gạch ngang (- -) đã được bao gồm với chuỗi dữ liệu, chúng sẽ trở thành 1 phần của chuỗi thông tin tìm kiếm và được biên dịch bởi cú pháp tương ứng của SQL.
Robert'; DROP TABLE Users;-- / wrongpass:
SELECT UserID FROM Users WHERE UserName='Robert\'; DROP TABLE Users;--' AND Password='wrongpass'
Chỉ với việc tách biệt dấu ngoặc đơn đằng sau Robert, dấu phẩy và gạch ngang bao gồm bên trong chuỗi tìm kiếm UserName, và do vậy cơ sở dữ liệu sẽ tìm kiếm toàn bộ các bản ghi theo thông tin: "Robert'; DROP TABLE Users;--" thay vì việc xóa bảng dữ liệu như cũ.
Chúc các bạn thành công!
[nguồn HowToGeek]