NoSQL Injection
1. Giới thiệu
Trong bài viết này, chúng ta sẽ tìm hiểu về một kĩ thuật tấn công nhằm vào các ứng dụng web có sử dụng cơ sở dữ liệu NoSQL, đó là NoSQL Injection. Cụ thể, bài viết này sẽ đề cập đến việc khai thác lỗ hổng trên các website sử dụng MongoDB (Hệ quản trị CSDL thuộc họ NoSQL).
2. Khái quát về NoSQL
a. Định nghĩa:
NoSQL được viết tắt của “Non-Relational SQL” hay “Not-Only SQL”. Nó được giới thiệu lần đầu vào năm 1998, được sử dụng làm tên gọi chung của các hệ quản trị cơ sở dữ liệu không sử dụng mô hình dữ liệu quan hệ cũng như truy vấn SQL truyền thống trong việc lưu trữ và truy xuất dữ liệu.
NoSQL ra đời để thay thế các RDBMS(Relational DataBase Management System), vốn đã cho thấy sự hạn chế trong việc quản lý lượng dữ liệu lớn, khi hiệu năng xử lý khá thấp do đặc tính dữ liệu quan hệ . NoSQL vượt trội so với RDBMS ở khả năng mở rộng và hiệu năng xử lý
Trong họ NoSQL có khá nhiều những DB được sử dụng bởi các website lớn như Bigtable (Google), Cassandra (Facebook), MongoDB, Riak ...
b. MongoDB:
MongoDB là một đại diện trong dòng NoSQL được sử dụng khá phổ biến hiện nay. Nó thích hợp cho việc lưu trữ các dữ liệu ít được đọc nhưng được thay đổi thường xuyên.
Trong MongoDB, mỗi cơ sở dữ liệu là 1 collection (tương ứng với table trong RDBMS). Mỗi collection bao gồm các document (tương ứng với row trong RDBMS), các document này có thể có cấu trúc khác nhau.
MongoDB sử dụng cấu trúc JSON để lưu trữ dữ liệu theo các cặp (key, value) cho mỗi document.
Một document là một cặp key-value:
VD: Một collection bao gồm một hoặc nhiều document:
Một ví dụ khác của collection:
3. Khai thác lỗi NoSQL Injection với các website viết bằng PHP và sử dụng MongoDB:
Điểm khác biệt lớn của các DB NoSQL so với các DB RDBMS là việc lưu trữ, truy xuất dữ liệu không thông qua câu lệnh SQL, vốn ở dạng string và có thể “inject” các biến đầu vào không được kiểm soát kỹ để tạo ra 1 truy vấn khác với truy vấn ban đầu.
Với NoSQL, tư tưởng “inject” vẫn giống với SQL Injection truyền thống, nhưng thay vì “inject” vào một string, ta phải “inject” vào một cấu trúc khác. Cụ thể với MongoDB là JSON.
VD: Một lệnh lấy dữ liệu từ MongoDB trong PHP
Trong lệnh trên, PHP sẽ lấy trong colection user một tập những document có chứa 2 cặp key-value là (uname:$_POST[‘uname’]) và (passwd:$_POST[‘passwd’])
Để tấn công NoSQL dạng này, ta sẽ lợi dụng việc PHP cho phép các biến nhập vào thuộc kiểu array và sử dụng 1 số toán tử của MongoDB để thay đổi giá trị trả về. Sau khi inject, cấu trúc chuỗi JSON truy vấn sẽ khác với chuỗi JSON ban đầu.
Gửi Post data:
Chuỗi JSON truy vấn sẽ trở thành:
Toán tử $regex dùng để match 1 chuỗi regular expression với 1 string. Ở đây ta dùng “.*”, sẽ match với một string bất kì.
Như vậy chuỗi JSON sau khi “inject” sẽ trả về tất cả các document trong collection user mà không có việc lọc username và password.
Ngoài ra ta có thể sử dụng các toán tử khác của MongoDB để khai thác, như $or, $and, $in, $notin
4. Phòng tránh NoSQL Injection
Cách phòng tránh kinh điển và không thể thiếu đối với những ứng dụng dính lỗi Injection, đó là kiểm soát chặt chẽ đầu vào. Các cách phòng tránh NoSQL có thể là:
Tài liệu tham khảo:
http://www.tutorialspoint.com/mongodb/index.htm
http://arxiv.org/pdf/1506.04082.pdf
http://blogs.adobe.com/security/files/2011/04/NoSQL-But-Even-Less-Security.pdf
http://2012.zeronights.org/includes/docs/Firstov - Attacking MongoDB.pdf
Trong bài viết này, chúng ta sẽ tìm hiểu về một kĩ thuật tấn công nhằm vào các ứng dụng web có sử dụng cơ sở dữ liệu NoSQL, đó là NoSQL Injection. Cụ thể, bài viết này sẽ đề cập đến việc khai thác lỗ hổng trên các website sử dụng MongoDB (Hệ quản trị CSDL thuộc họ NoSQL).
2. Khái quát về NoSQL
a. Định nghĩa:
NoSQL được viết tắt của “Non-Relational SQL” hay “Not-Only SQL”. Nó được giới thiệu lần đầu vào năm 1998, được sử dụng làm tên gọi chung của các hệ quản trị cơ sở dữ liệu không sử dụng mô hình dữ liệu quan hệ cũng như truy vấn SQL truyền thống trong việc lưu trữ và truy xuất dữ liệu.
NoSQL ra đời để thay thế các RDBMS(Relational DataBase Management System), vốn đã cho thấy sự hạn chế trong việc quản lý lượng dữ liệu lớn, khi hiệu năng xử lý khá thấp do đặc tính dữ liệu quan hệ . NoSQL vượt trội so với RDBMS ở khả năng mở rộng và hiệu năng xử lý
Trong họ NoSQL có khá nhiều những DB được sử dụng bởi các website lớn như Bigtable (Google), Cassandra (Facebook), MongoDB, Riak ...
b. MongoDB:
MongoDB là một đại diện trong dòng NoSQL được sử dụng khá phổ biến hiện nay. Nó thích hợp cho việc lưu trữ các dữ liệu ít được đọc nhưng được thay đổi thường xuyên.
Trong MongoDB, mỗi cơ sở dữ liệu là 1 collection (tương ứng với table trong RDBMS). Mỗi collection bao gồm các document (tương ứng với row trong RDBMS), các document này có thể có cấu trúc khác nhau.
MongoDB sử dụng cấu trúc JSON để lưu trữ dữ liệu theo các cặp (key, value) cho mỗi document.
Một document là một cặp key-value:
PHP:
{“key1” : ”value1”}
{“key2” : ”value2”}
PHP:
{
“Name” : ”Stark”,
“Age” : ”15”,
“Address” : ”Winterfell”
}
PHP:
{
“Name” : ”Ned”,
“Age” : ”40”,
“Children” : [
{“Name” : “Robb”, “Age” : ”15” },
{“Name” : “Jon”, “Age” : ”14” },
{“Name” : “Bran”, “Age” : ”7” },
{“Name” : “Rickon”, “Age” : ”5” },
]
}
3. Khai thác lỗi NoSQL Injection với các website viết bằng PHP và sử dụng MongoDB:
Điểm khác biệt lớn của các DB NoSQL so với các DB RDBMS là việc lưu trữ, truy xuất dữ liệu không thông qua câu lệnh SQL, vốn ở dạng string và có thể “inject” các biến đầu vào không được kiểm soát kỹ để tạo ra 1 truy vấn khác với truy vấn ban đầu.
Với NoSQL, tư tưởng “inject” vẫn giống với SQL Injection truyền thống, nhưng thay vì “inject” vào một string, ta phải “inject” vào một cấu trúc khác. Cụ thể với MongoDB là JSON.
VD: Một lệnh lấy dữ liệu từ MongoDB trong PHP
PHP:
$db->user->find(array(“uname”=>$_POST[“uname”], “passwd”=>$_POST[“passwd”])
Để tấn công NoSQL dạng này, ta sẽ lợi dụng việc PHP cho phép các biến nhập vào thuộc kiểu array và sử dụng 1 số toán tử của MongoDB để thay đổi giá trị trả về. Sau khi inject, cấu trúc chuỗi JSON truy vấn sẽ khác với chuỗi JSON ban đầu.
Gửi Post data:
PHP:
uname[$regex]=.*&passwd[$regex]=.*
PHP:
{
“uname”: { “$regex” : “.*”},
“passwd”: { “$regex” : “.*”}
}
Như vậy chuỗi JSON sau khi “inject” sẽ trả về tất cả các document trong collection user mà không có việc lọc username và password.
Ngoài ra ta có thể sử dụng các toán tử khác của MongoDB để khai thác, như $or, $and, $in, $notin
4. Phòng tránh NoSQL Injection
Cách phòng tránh kinh điển và không thể thiếu đối với những ứng dụng dính lỗi Injection, đó là kiểm soát chặt chẽ đầu vào. Các cách phòng tránh NoSQL có thể là:
- Không cho phép biến đầu vào thuộc kiểu array
- Chặn 1 số kí tự, keyword: [, ], {, }, $or, $and, $regex, ...
Tài liệu tham khảo:
http://www.tutorialspoint.com/mongodb/index.htm
http://arxiv.org/pdf/1506.04082.pdf
http://blogs.adobe.com/security/files/2011/04/NoSQL-But-Even-Less-Security.pdf
http://2012.zeronights.org/includes/docs/Firstov - Attacking MongoDB.pdf
Chỉnh sửa lần cuối bởi người điều hành: