蔡承翰 施宣迪 李信杰
OWASP ZAP 是一個知名的 Web 安全測試的工具,免費且開源,此手冊將說明如何安裝與使用ZAP,並介紹如何結合一些網頁自動化測試工具來進行深度弱掃。
該工具透過 Java 執行,在執行前需先安裝好相關環境,以下示範需要的步驟
JAVA_HOME
環境變數:
JAVA_HOME
設定為上述路徑此手冊涵蓋攻擊網站的教學內容,請注意此類行為可能觸犯法律。為了避免不必要的法律問題,以靶機 DVWA 示範,此虛擬 IP 位址為 http://192.168.56.105/dvwa 。
啟動 ZAP 後,點擊 Tools -> Options
選擇 Network -> Local Servers/Proxies,並設定 Proxy 的埠號
網路請求透過瀏覽器傳遞,需要設定瀏覽器的 Proxy,每個瀏覽器設定不太一樣,以下使用 Chrome 示範:
進入 Chrome 的 settings
Chrome 使用本機預設,直接在本機設定
點擊手動 proxy 設定,開啟 server 開關,將上述 ZAP IP address設定在欄位裡(說明: 127.0.0.1 與 localhost相同的意思),最後按下儲存
設定完成後,即可在 Sites 看到 ZAP 監聽的請求
監看 HTTP 請求時,瀏覽器確保資料不被中間人所攻擊,會出現"你的連線不是私人連線"
解決此問題需匯入瀏覽器 ZAP 的憑證,操作流程如下
完成以上步驟,網站即可正常連線
ZAP 的攻擊行為大致上可分為以下兩種方式:
透過 ZAP 的掃描,我們可以在下方 Alerts 欄位中看到已偵測出來的弱點。
根據使用者的不同需求,ZAP 擁有以下四種掃描模式:
我們推薦使用 Protected Mode,透過預先設定攻擊範圍 (Scope),以避免攻擊到未擁有攻擊權限的網站。
例如:此 Context 設定攻擊範圍有且僅有 http://192.168.56.105/dvwa 以下的目錄。
選擇工具列 -> Report -> Generate Report
在 template 頁面可選擇報告格式
點擊 Generate Report 產生弱點報告
除了手動測試網站外,也可以透過自動化測試工具撰寫、錄製網站測試腳本,再透過 ZAP 的 proxy 功能將網路請求攔截,以達到深度弱點掃描的目的。
此章節將透過 Rapi 錄製手動瀏覽過程,以結合後續的測試操作,以下使用上述靶機的登入畫面示範
開啟 Rapi 並點擊 Record 進行錄製,可依錄製需求調整 Rapi 功能
進行錄製,在 Rapi 中可以看到瀏覽的過程,依照個人需求可儲存錄製腳本
http://127.0.0.1:4444
啟動 Selenium server,並設定讓 chrome webdriver 自動將瀏覽器網路請求送至 proxy (http://127.0.0.1:8080
)$ 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}'
啟用 Rapi 的 Webdriver 功能
播放 Rapi 腳本,此時 Rapi 會透過 webdriver 驅動瀏覽器,並將腳本中所有的 HTTP/HTTPS 請求全部送到 ZAP 中
在 sites 中可以看到 Rapi 腳本經過的網路請求,可以再向這些請求做 active scan 等操作達到深度弱掃的目標
此章節介紹 Selenium,該工具模擬一般使用者瀏覽網頁的操作,以下透過兩種方式設定 webdriver 與 proxy,使用 python 示範:
第一種方式是在程式碼中設定 proxy 和 webdriver 下載,即可模擬網頁操作
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 (http://127.0.0.1:4444
),並設定讓 chrome webdriver 自動將瀏覽器網路請求送至 proxy (http://127.0.0.1:8080
),再透過 API 使用已設定完成的 webdriver 撰寫腳本。
啟動 Selenium server 與設定 Webdriver:
$ 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:
# Options for Webdriver
options = webdriver.ChromeOptions()
driver = webdriver.Remote(command_executor="http://127.0.0.1:4444/wd/hub", options=options)
執行 Selenium 腳本後,啟動 webdriver 模擬相關操作,將腳本中所有的 HTTP/HTTPS 請求全部送到 ZAP 中,再向這些請求做 active scan 等操作以達到深度弱掃的目標。
Cypress 是一個開源的 E2E 測試軟體,可以在網頁上進行自動化測試,可自行前往官網 安裝,以下使用 npm 示範
欲紀錄 cypress 測試網頁的請求,需在執行前設定環境變數
set HTTP_PROXY=http://127.0.0.1:8080/
由 Cypress 設定中查看是否成功設定
實現即時錄製腳本的功能,需於 cypress.config.js
新增 experimaentalStudio: true
,如下
const { defineConfig } = require("cypress");
module.exports = defineConfig({
e2e: {
setupNodeEvents(on, config) {
// implement node event listeners here
},
experimentalStudio: true,
},
});
執行 npm run cypress:open
後,即可在 cypress 操作,並按照以下步驟即可進入錄製環境
進行登入測試後,點擊右上角儲存
播放 Cypress 錄製腳本即可在 ZAP 上查看監控的請求
Playwright 是一個由 Microsoft 開發的自動化網頁測試腳本開源套件,以下使用 Python 套件示範:
$ pip install pytest-playwright
$ playwright install
在程式碼中設定 proxy 為 http://127.0.0.1:8080,並啟動套用此 proxy 的 browser (以 chromium 為例):
proxy = {"server": "http://127.0.0.1:8080"}
browser = chromium.launch(proxy=proxy)
透過 page.goto()
訪問待測網站,並使用定位器 (如:XPath、CSS locator) 及各種行為 (如:點擊指定元素、填入指定值) 來撰寫腳本。
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()
以下為 dvwa_login 功能的測試腳本 (test_dvwa.py):
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 執行此腳本:
$ pytest test_dvwa.py
即可透過 ZAP 攔截執行測試腳本時經過的所有 HTTP/HTTPS請求。