# 【教學手冊】OWASP ZAP開源弱掃軟體使用教學,與介紹如何結合Rapi、Selenium、Cypress、Playwright進行深度弱掃
蔡承翰 施宣迪 李信杰
## 一、簡介
OWASP ZAP 是一個知名的 Web 安全測試的工具,免費且開源,此手冊將說明如何安裝與使用ZAP,並介紹如何結合一些網頁自動化測試工具來進行深度弱掃。
## 二、安裝步驟
該工具透過 Java 執行,在執行前需先安裝好相關環境,以下示範需要的步驟
### a. Java Development Kit(JDK)
1. 前往 [Oracle Java](https://www.oracle.com/tw/java/technologies/downloads/#jdk22-windows) 下載對應系統的 Java
2. 設定 `JAVA_HOME` 環境變數:
* 複製 jdk 的**儲存位置** (ex. C:\Program Files\Java\jdk-19)
* 至**設定環境變數**將 `JAVA_HOME` 設定為上述路徑
### b. 安裝 ZAP
* 前往 [ZAP](https://zaproxy.org/download/) 下載對應系統的安裝檔
### c. 靶機設定
此手冊涵蓋攻擊網站的教學內容,請注意此類行為可能觸犯法律。為了避免不必要的法律問題,以靶機 DVWA 示範,此虛擬 IP 位址為 http://192.168.56.105/dvwa 。
## 三、ZAP 使用說明
### a. 開啟 ZAP
1. 根據需求選擇是否儲存紀錄
![image](https://hackmd.io/_uploads/ryFLaQIz0.png)
### b. Proxy 設定
1. 啟動 ZAP 後,點擊 **Tools -> Options**
![image](https://hackmd.io/_uploads/B187RmUMR.png)
2. 選擇 **Network -> Local Servers/Proxies**,並設定 Proxy 的埠號
![image](https://hackmd.io/_uploads/SJbaRmIMC.png)
網路請求透過瀏覽器傳遞,需要設定瀏覽器的 Proxy,每個瀏覽器設定不太一樣,以下使用 Chrome 示範:
3. 進入 Chrome 的 settings
![image](https://hackmd.io/_uploads/ryc2vZCWC.png)
4. Chrome 使用本機預設,直接在本機設定
![image](https://hackmd.io/_uploads/Hk8S7mC-C.png)
5. 點擊手動 proxy 設定,開啟 server 開關,將上述 ZAP IP address設定在欄位裡(說明: 127.0.0.1 與 localhost相同的意思),最後按下儲存
![image](https://hackmd.io/_uploads/SyfagmRbR.png)
6. 設定完成後,即可在 Sites 看到 ZAP 監聽的請求
![image](https://hackmd.io/_uploads/r1ORx4IzR.png)
### c. CA 憑證
監看 HTTP 請求時,瀏覽器確保資料不被中間人所攻擊,會出現"你的連線不是私人連線"
![image](https://hackmd.io/_uploads/rkr8rm0b0.png)
解決此問題需匯入瀏覽器 ZAP 的憑證,操作流程如下
1. 點擊 **Tools -> Options -> Network -> SeverCertificates**,按 Generate 產生 SSL 憑證並按下 Save,儲存在本機
![image](https://hackmd.io/_uploads/B14aHE8zC.png)
![image](https://hackmd.io/_uploads/HJ_lI4UfR.png)
2. 接著將憑證匯入瀏覽器,在chrome settings搜尋certificate
![image](https://hackmd.io/_uploads/SJBTtMRZ0.png)
![image](https://hackmd.io/_uploads/HJWjYMRbR.png)
![image](https://hackmd.io/_uploads/H1vfTMAZ0.png)
![image](https://hackmd.io/_uploads/SywiTG0WA.png)
![image](https://hackmd.io/_uploads/Hyk8_VLzR.png)
![image](https://hackmd.io/_uploads/SkLmRG0WA.png)
![image](https://hackmd.io/_uploads/Sy8DYVUG0.png)
完成以上步驟,網站即可正常連線
### d. ZAP 攻擊方式簡介
ZAP 的攻擊行為大致上可分為以下兩種方式:
- Passive Scan:檢查 ZAP 攔截到的所有 HTTP/HTTPS 請求,不會針對請求內容作修改。
- Active Scan:透過實際的攻擊行為 (例如:修改部分請求內容) 攻擊 Web APP,以尋找網站潛在的弱點。
透過 ZAP 的掃描,我們可以在下方 Alerts 欄位中看到已偵測出來的弱點。
![image](https://hackmd.io/_uploads/HkiK2NUfA.png)
### e. ZAP 模式設定
根據使用者的不同需求,ZAP 擁有以下四種掃描模式:
- Safe Mode:使用者不允許進行任何潛在的攻擊行為。
- Protected Mode:使用者僅允許在指定的 Scope 中進行攻擊。
- Standard Mode:使用者可進行所有的攻擊行為。
- ATTACK Mode:當使用者指定的 Scope 中出現新的網站節點時,ZAP 會自動對其進行 Active Scan。
我們推薦使用 Protected Mode,透過預先設定攻擊範圍 (Scope),以避免攻擊到未擁有攻擊權限的網站。
### f. Scope 設定
1. 開啟一個新的 Context。
![image](https://hackmd.io/_uploads/Hy4i94LGR.png)
![image](https://hackmd.io/_uploads/rkUaqNUzC.png)
![image](https://hackmd.io/_uploads/HJCyo4IGC.png)
2. 點擊新建立的 Context 進入設定,選擇 **Include in Context** 頁面。
![image](https://hackmd.io/_uploads/Byozs4LG0.png)
3. 新增正規表達式以設定允許攻擊的範圍 (Scope)。
例如:此 Context 設定攻擊範圍有且僅有 http://192.168.56.105/dvwa 以下的目錄。
![image](https://hackmd.io/_uploads/Bknl2NIzC.png)
### g. 產生弱點報告
1. 選擇**工具列 -> Report -> Generate Report**
![image](https://hackmd.io/_uploads/SyzfpEIMR.png)
2. 在 template 頁面可選擇報告格式
![image](https://hackmd.io/_uploads/ry5maVLGR.png)
3. 點擊 Generate Report 產生弱點報告
![image](https://hackmd.io/_uploads/BJ9U64LM0.png)
## 四、ZAP 結合自動化測試工具
除了手動測試網站外,也可以透過自動化測試工具撰寫、錄製網站測試腳本,再透過 ZAP 的 proxy 功能將網路請求攔截,以達到深度弱點掃描的目的。
### a. Rapi Recorder
#### a-1. 錄製 Rapi 腳本 (DVWA login)
此章節將透過 Rapi 錄製手動瀏覽過程,以結合後續的測試操作,以下使用上述靶機的登入畫面示範
1. 開啟 Rapi 並點擊 Record 進行錄製,可依錄製需求調整 Rapi 功能
![image](https://hackmd.io/_uploads/ryCJPcym0.png)
2. 進行錄製,在 Rapi 中可以看到瀏覽的過程,依照個人需求可儲存錄製腳本
![image](https://hackmd.io/_uploads/rkqKv5J7C.png)
#### a-2. Rapi Recorder 結合 ZAP 進行深度弱掃
1. 根據以下指令在 `http://127.0.0.1:4444` 啟動 Selenium server,並設定讓 chrome webdriver 自動將瀏覽器網路請求送至 proxy (`http://127.0.0.1:8080`)
```shell!
$ java -jar selenium-server-<version>.jar standalone --host 127.0.0.1 --port 4444 --detect-drivers false --driver-configuration display-name="Chrome" max-sessions=1 stereotype='{"browserName": "chrome","proxy":{"proxyType":"manual","httpProxy":"http://127.0.0.1:8080","sslProxy":"http://127.0.0.1:8080"},"acceptInsecureCerts": true}'
```
![image](https://hackmd.io/_uploads/rJkDRqyX0.png)
2. 啟用 Rapi 的 Webdriver 功能
![image](https://hackmd.io/_uploads/BybQMiJQ0.png)
3. 播放 Rapi 腳本,此時 Rapi 會透過 webdriver 驅動瀏覽器,並將腳本中所有的 HTTP/HTTPS 請求全部送到 ZAP 中
![image](https://hackmd.io/_uploads/Hk-m7okXR.png)
4. 在 sites 中可以看到 Rapi 腳本經過的網路請求,可以再向這些請求做 active scan 等操作達到深度弱掃的目標
![image](https://hackmd.io/_uploads/Hk3V7sk7A.png)
### b. Selenium
此章節介紹 Selenium,該工具模擬一般使用者瀏覽網頁的操作,以下透過兩種方式設定 webdriver 與 proxy,使用 python 示範:
#### b-1. 撰寫 Selenium 腳本
##### 在腳本中設定 webdriver 的行為
第一種方式是在程式碼中設定 proxy 和 webdriver 下載,即可模擬網頁操作
```python!
from selenium import webdriver
from selenium.webdriver.common.by import By
from webdriver_manager.chrome import ChromeDriverManager
# Create a new Proxy object
proxy_server_url = "127.0.0.1:8080"
# Options for Webdriver
options = webdriver.ChromeOptions()
options.add_argument(f"--proxy-server={proxy_server_url}")
# Create a new Chrome session
service = webdriver.ChromeService(executable_path=ChromeDriverManager().install())
driver = webdriver.Chrome(service=service, options=options)
# Take some actions on the DVWA login page below
driver.get("http://192.168.56.105/login.php")
driver.find_element(By.NAME, "username").send_keys("admin")
driver.find_element(By.NAME, "password").send_keys("password")
driver.find_element(By.NAME, "Login").click()
driver.quit()
```
##### 預先在 Selenium server 設定 webdriver 的行為
第二種方式則是事先啟動 Selenium server (`http://127.0.0.1:4444`),並設定讓 chrome webdriver 自動將瀏覽器網路請求送至 proxy (`http://127.0.0.1:8080`),再透過 API 使用已設定完成的 webdriver 撰寫腳本。
啟動 Selenium server 與設定 Webdriver:
```shell!
$ java -jar selenium-server-<version>.jar standalone --host 127.0.0.1 --port 4444 --detect-drivers false --driver-configuration display-name="Chrome" max-sessions=1 stereotype='{"browserName": "chrome","proxy":{"proxyType":"manual","httpProxy":"http://127.0.0.1:8080","sslProxy":"http://127.0.0.1:8080"},"acceptInsecureCerts": true}'
```
腳本中設定指定 Webdriver URL:
```python!
# Options for Webdriver
options = webdriver.ChromeOptions()
driver = webdriver.Remote(command_executor="http://127.0.0.1:4444/wd/hub", options=options)
```
#### b-2. 結合 ZAP 進行深度弱掃
執行 Selenium 腳本後,啟動 webdriver 模擬相關操作,將腳本中所有的 HTTP/HTTPS 請求全部送到 ZAP 中,再向這些請求做 active scan 等操作以達到深度弱掃的目標。
![image](https://hackmd.io/_uploads/HJx9xpKXA.png)
### c. Cypress
Cypress 是一個開源的 E2E 測試軟體,可以在網頁上進行自動化測試,可自行前往[官網](https://www.cypress.io/install) 安裝,以下使用 npm 示範
#### 1. 設定 Proxy 環境變數
欲紀錄 cypress 測試網頁的請求,需在執行前設定環境變數
```
set HTTP_PROXY=http://127.0.0.1:8080/
```
由 Cypress 設定中查看是否成功設定
![image](https://hackmd.io/_uploads/HylyHfc7C.png)
#### 2. 設定錄製環境
實現即時錄製腳本的功能,需於 `cypress.config.js` 新增 `experimaentalStudio: true` ,如下
```javascript!
const { defineConfig } = require("cypress");
module.exports = defineConfig({
e2e: {
setupNodeEvents(on, config) {
// implement node event listeners here
},
experimentalStudio: true,
},
});
```
#### 3. 執行及錄製環境
執行 `npm run cypress:open` 後,即可在 cypress 操作,並按照以下步驟即可進入錄製環境
![image](https://hackmd.io/_uploads/rySvQGcQC.png)
![image](https://hackmd.io/_uploads/S1cAQGc7A.png)
![image](https://hackmd.io/_uploads/HJrgNG57C.png)
![image](https://hackmd.io/_uploads/rJFPBfcXR.png)
![image](https://hackmd.io/_uploads/S1EgLM5QR.png)
#### 4. 錄製腳本
進行登入測試後,點擊右上角儲存
![image](https://hackmd.io/_uploads/ryKWPf5XC.png)
播放 Cypress 錄製腳本即可在 ZAP 上查看監控的請求
![image](https://hackmd.io/_uploads/HJVzdG9XA.png)
### d. Playwright
Playwright 是一個由 Microsoft 開發的自動化網頁測試腳本開源套件,以下使用 Python 套件示範:
#### 1. 設定錄製環境
- 安裝具有 pytest plugin 的 playwright 套件
```shell!
$ pip install pytest-playwright
```
- 安裝所需瀏覽器
```shell!
$ playwright install
```
#### 2. 設定 HTTP Proxy
在程式碼中設定 proxy 為 http://127.0.0.1:8080,並啟動套用此 proxy 的 browser (以 chromium 為例):
```python!
proxy = {"server": "http://127.0.0.1:8080"}
browser = chromium.launch(proxy=proxy)
```
#### 3. 撰寫 Playwright 腳本
透過 `page.goto()` 訪問待測網站,並使用定位器 (如:XPath、CSS locator) 及各種行為 (如:點擊指定元素、填入指定值) 來撰寫腳本。
```python!
page.goto("http://192.168.56.105/login.php")
page.locator("css=input[name='username']").fill("admin")
page.locator("css=input[name='password']").fill("password")
page.locator("css=input[name='Login']").click()
```
#### 4. 結合 ZAP 進行深度弱掃
以下為 dvwa_login 功能的測試腳本 (test_dvwa.py):
```python!
from playwright.sync_api import sync_playwright
# Use "test_" prefix to design function name
def test_dvwa_login():
with sync_playwright() as playwright:
proxy = {"server": "http://127.0.0.1:8080"}
chromium = playwright.chromium
browser = chromium.launch(proxy=proxy)
page = browser.new_page()
page.goto("http://192.168.56.105/login.php")
page.locator("css=input[name='username']").fill("admin")
page.locator("css=input[name='password']").fill("password")
page.locator("css=input[name='Login']").click()
browser.close()
```
並使用 pytest 執行此腳本:
```shell!
$ pytest test_dvwa.py
```
即可透過 ZAP 攔截執行測試腳本時經過的所有 HTTP/HTTPS請求。
![image](https://hackmd.io/_uploads/HJx9xpKXA.png)