# Lỗ hổng phía máy chủ: Phần 7: SQL injection
## 1. SQL injection (SQLi) là gì?
SQL injection (SQLi) là một lỗ hổng bảo mật web cho phép kẻ tấn công can thiệp vào các truy vấn mà ứng dụng thực hiện đối với cơ sở dữ liệu của ứng dụng. Điều này có thể cho phép kẻ tấn công xem dữ liệu mà thông thường chúng không thể truy xuất được. Dữ liệu này có thể bao gồm dữ liệu thuộc về người dùng khác hoặc bất kỳ dữ liệu nào khác mà ứng dụng có thể truy cập. Trong nhiều trường hợp, kẻ tấn công có thể sửa đổi hoặc xóa dữ liệu này, gây ra những thay đổi liên tục đối với nội dung hoặc hành vi của ứng dụng.
Trong một số trường hợp, kẻ tấn công có thể leo thang tấn công SQL injection để xâm phạm máy chủ cơ sở hoặc cơ sở hạ tầng phụ trợ khác. Nó cũng có thể cho phép chúng thực hiện các cuộc tấn công từ chối dịch vụ.
## 2. Cách phát hiện lỗ hổng SQL injection
Bạn có thể phát hiện SQL injection theo cách thủ công bằng cách sử dụng một tập hợp các bài kiểm tra có hệ thống đối với mọi điểm vào trong ứng dụng. Để thực hiện việc này, bạn thường sẽ gửi:
- Ký tự dấu nháy đơn `'` và tìm kiếm lỗi hoặc các bất thường khác.
- Một số cú pháp SQL cụ thể đánh giá theo giá trị cơ sở (gốc) của điểm vào và một giá trị khác, đồng thời tìm kiếm sự khác biệt có hệ thống trong phản hồi của ứng dụng.
- Các điều kiện Boolean như `OR 1=1` và `OR 1=2`, và tìm kiếm sự khác biệt trong phản hồi của ứng dụng.
- Tải trọng được thiết kế để kích hoạt độ trễ thời gian khi được thực hiện trong truy vấn SQL và tìm kiếm sự khác biệt về thời gian phản hồi.
- Tải trọng OAST được thiết kế để kích hoạt tương tác mạng ngoài băng tần khi được thực hiện trong truy vấn SQL và giám sát mọi tương tác phát sinh.
Ngoài ra, bạn có thể tìm thấy phần lớn các lỗ hổng SQL injection một cách nhanh chóng và đáng tin cậy bằng Burp Scanner.
## 3. Truy xuất dữ liệu ẩn
Hãy tưởng tượng một ứng dụng mua sắm hiển thị sản phẩm theo các danh mục khác nhau. Khi người dùng nhấp vào danh mục Quà tặng , trình duyệt của họ yêu cầu URL:
```
https://insecure-website.com/products?category=Gifts
```
Điều này khiến ứng dụng thực hiện truy vấn SQL để lấy thông tin chi tiết về các sản phẩm có liên quan từ cơ sở dữ liệu:
```
SELECT * FROM products WHERE category = 'Gifts' AND released = 1
```
Truy vấn SQL này yêu cầu cơ sở dữ liệu trả về:
- tất cả các chi tiết (`*`)
- từ bảng `products`
- nơi `category` là `Gifts`
- và `released` là `1`
Hạn chế `released = 1` được sử dụng để ẩn các sản phẩm chưa được phát hành. Chúng ta có thể cho rằng đối với các sản phẩm chưa được phát hành `released = 0`.
Ứng dụng không triển khai bất kỳ biện pháp phòng thủ nào chống lại các cuộc tấn công SQL injection. Điều này có nghĩa là kẻ tấn công có thể xây dựng các cuộc tấn công sau:
```
https://insecure-website.com/products?category=Gifts'--
```
Kết quả cho ra truy vấn SQL như sau:
```
SELECT * FROM products WHERE category = 'Gifts'--' AND released = 1
```
Quan trọng, lưu ý rằng -- là một chỉ báo chú thích trong SQL. Điều này có nghĩa là phần còn lại của truy vấn được hiểu là một chú thích, về cơ bản là xóa nó. Trong ví dụ này, điều này có nghĩa là truy vấn không còn bao gồm `AND released = 1`. Kết quả là, tất cả các sản phẩm đều được hiển thị, bao gồm cả những sản phẩm chưa được phát hành.
Có thể sử dụng một cuộc tấn công tương tự để 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, bao gồm cả những danh mục mà ứng dụng không biết:
```
https://insecure-website.com/products?category=Gifts'+OR+1=1--
```
Kết quả cho ra truy vấn SQL như sau:
```
SELECT * FROM products WHERE category = 'Gifts' OR 1=1--' AND released = 1
```
Truy vấn đã sửa đổi trả về tất cả các mục có giá trị là `category`, `Gifts` hoặc 1 bằng 1. Như `1=1` luôn đúng, truy vấn trả về tất cả các mục.
Cảnh báo
Hãy cẩn thận khi đưa điều kiện `OR 1=1` vào truy vấn SQL. Ngay cả khi điều kiện có vẻ vô hại trong ngữ cảnh bạn đưa vào, thì các ứng dụng vẫn thường sử dụng dữ liệu từ một yêu cầu duy nhất trong nhiều truy vấn khác nhau. Ví dụ, nếu điều kiện của bạn đạt đến câu lệnh `UPDATE` hoặc `DELETE`, điều đó có thể dẫn đến mất dữ liệu ngoài ý muốn.
## Lab: Lỗ hổng SQL injection trong mệnh đề WHERE cho phép truy xuất dữ liệu ẩn
https://0aec001c04df7f1e805bee9d00e10054.web-security-academy.net/
Bài lab này chứa lỗ hổng SQL injection trong bộ lọc danh mục sản phẩm. Khi người dùng chọn một danh mục, ứng dụng sẽ thực hiện truy vấn SQL như sau:
```
SELECT * FROM products WHERE category = 'Gifts' AND released = 1
```
Để giải quyết bài lab, hãy thực hiện một cuộc tấn công tiêm SQL khiến ứng dụng hiển thị một hoặc nhiều sản phẩm chưa phát hành.
https://0aec001c04df7f1e805bee9d00e10054.web-security-academy.net/filter?category=Gifts%27+OR+1=1--
## 4. Phá vỡ logic ứng dụng
Hãy tưởng tượng 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. Nếu người dùng gửi tên người dùng `wiener` và mật khẩu `bluecheese`, ứng dụng sẽ kiểm tra thông tin xác thực bằng cách thực hiện truy vấn SQL sau:
```
SELECT * FROM users WHERE username = 'wiener' AND password = 'bluecheese'
```
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. Nếu không, đăng nhập sẽ bị từ chối.
Trong trường hợp này, kẻ tấn công có thể đăng nhập với tư cách là bất kỳ người dùng nào mà không cần mật khẩu. Họ có thể thực hiện việc này bằng cách sử dụng chuỗi chú thích SQL -- để xóa kiểm tra mật khẩu khỏi mệnh đề WHERE của truy vấn. Ví dụ, gửi tên người dùng administrator'-- và mật khẩu trống sẽ dẫn đến truy vấn sau:
```
SELECT * FROM users WHERE username = 'administrator'--' AND password = ''
```
Truy vấn này trả về tên người dùng là `administrator` và ghi nhận thành công kẻ tấn công vào tài khoản người dùng đó.
## Lab: Lỗ hổng SQL injection cho phép bỏ qua đăng nhập
https://0a4200cb04a87f1180d1f36f004b0005.web-security-academy.net/
Bài lab này chứa lỗ hổng SQL injection trong chức năng đăng nhập.
Để giải quyết bài lab, hãy thực hiện một cuộc tấn công tiêm SQL để đăng nhập vào ứng dụng với tư cách là người dùng `administrator`
Tấn công vào Username trong My account
Username: administrator'--