Burp Suite 行動應用測試

Burp Suite Mobile Application Security Testing

前言

行動應用程式的安全測試是現代滲透測試中不可或缺的一環。隨著行動裝置的普及,越來越多的敏感資料透過行動應用程式進行傳輸。Burp Suite 作為業界標準的 Web 應用程式安全測試工具,同樣可以有效地應用於行動應用程式的安全測試。本文將詳細介紹如何使用 Burp Suite 對 Android 和 iOS 應用程式進行安全測試。

1. 行動應用測試概述

1.1 測試範圍

行動應用程式安全測試主要涵蓋以下幾個面向:

  • 網路通訊安全:分析應用程式與後端伺服器之間的通訊
  • 資料儲存安全:檢查本地儲存的敏感資料
  • 認證與授權機制:驗證身份認證與權限控制的實作
  • 加密實作:評估加密演算法的使用是否正確
  • 商業邏輯漏洞:測試應用程式特定的業務流程

1.2 測試環境準備

進行行動應用測試前,需要準備以下環境:

1
2
3
4
5
6
# 測試環境清單
- Burp Suite Professional 或 Community Edition
- Android 模擬器(如 Genymotion)或實體裝置(建議 root)
- iOS 模擬器或實體裝置(建議 jailbreak)
- ADB (Android Debug Bridge)
- Frida 或 Objection(用於動態分析)

1.3 Burp Suite 基礎設定

首先,確保 Burp Suite 正確設定監聽介面:

1
2
3
4
# 開啟 Burp Suite 後,前往 Proxy > Options
# 設定監聽位址為所有介面
Bind to address: All interfaces
Bind to port: 8080

2. Android 代理設定

2.1 Wi-Fi 代理設定

對於 Android 裝置,可以透過 Wi-Fi 設定來配置代理:

  1. 進入 設定 > Wi-Fi
  2. 長按連接的網路,選擇「修改網路」
  3. 展開「進階選項」
  4. 設定代理為「手動」
  5. 輸入 Burp Suite 主機的 IP 位址和連接埠
1
2
3
4
5
6
# 確認主機 IP 位址
# Linux/macOS
ip addr show | grep "inet " | grep -v 127.0.0.1

# Windows
ipconfig | findstr /i "IPv4"

2.2 使用 ADB 設定代理

對於需要頻繁切換代理的情況,可以使用 ADB 命令:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
# 設定全域代理
adb shell settings put global http_proxy <burp_ip>:<port>

# 範例:設定代理為 192.168.1.100:8080
adb shell settings put global http_proxy 192.168.1.100:8080

# 移除代理設定
adb shell settings put global http_proxy :0

# 針對 Android 10+ 的替代方法
adb shell settings put global http_proxy $(your_ip):8080
adb shell settings put global global_http_proxy_host $(your_ip)
adb shell settings put global global_http_proxy_port 8080

2.3 ProxyDroid 應用程式

對於 root 過的裝置,可以使用 ProxyDroid 進行更靈活的代理設定:

1
2
3
4
5
6
7
8
# 透過 ADB 安裝 ProxyDroid
adb install proxydroid.apk

# ProxyDroid 設定
Host: <Burp Suite IP>
Port: 8080
Proxy Type: HTTP
Global Proxy: 啟用

3. iOS 代理設定

3.1 Wi-Fi 代理設定

iOS 裝置的代理設定步驟:

  1. 開啟 設定 > Wi-Fi
  2. 點選已連接網路旁的 (i) 圖示
  3. 捲動到底部,點選「設定代理伺服器」
  4. 選擇「手動」
  5. 輸入伺服器位址和連接埠

3.2 設定檔安裝

對於企業環境,可以透過 MDM 設定檔來配置代理:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>PayloadContent</key>
    <array>
        <dict>
            <key>PayloadType</key>
            <string>com.apple.proxy.http.global</string>
            <key>ProxyServer</key>
            <string>192.168.1.100</string>
            <key>ProxyServerPort</key>
            <integer>8080</integer>
            <key>ProxyType</key>
            <string>Manual</string>
        </dict>
    </array>
    <key>PayloadDisplayName</key>
    <string>Burp Proxy Profile</string>
    <key>PayloadIdentifier</key>
    <string>com.security.burpproxy</string>
    <key>PayloadType</key>
    <string>Configuration</string>
    <key>PayloadVersion</key>
    <integer>1</integer>
</dict>
</plist>

3.3 使用 Surge 或 Shadowrocket

對於 Jailbreak 裝置或需要更進階控制的情況:

1
2
3
4
5
6
7
# Surge 設定範例
[General]
loglevel = notify
skip-proxy = 127.0.0.1, 192.168.0.0/16, 10.0.0.0/8, localhost

[Proxy]
BurpProxy = http, 192.168.1.100, 8080

4. SSL Pinning 繞過

4.1 什麼是 SSL Pinning

SSL Pinning(憑證綁定)是一種安全機制,應用程式會驗證伺服器憑證是否符合預期的憑證或公鑰。這可以防止中間人攻擊,但同時也會阻礙安全測試。

4.2 使用 Frida 繞過

Frida 是一個強大的動態分析框架,可以用來繞過 SSL Pinning:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 安裝 Frida
pip install frida-tools

# 下載 Frida Server(根據裝置架構選擇)
wget https://github.com/frida/frida/releases/download/16.1.4/frida-server-16.1.4-android-arm64.xz
unxz frida-server-16.1.4-android-arm64.xz

# 推送到 Android 裝置
adb push frida-server /data/local/tmp/
adb shell chmod 755 /data/local/tmp/frida-server
adb shell "/data/local/tmp/frida-server &"

使用 SSL Pinning 繞過腳本:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
// ssl_pinning_bypass.js
Java.perform(function() {
    // 繞過 OkHttp3 CertificatePinner
    var CertificatePinner = Java.use('okhttp3.CertificatePinner');
    CertificatePinner.check.overload('java.lang.String', 'java.util.List').implementation = function(hostname, peerCertificates) {
        console.log('[+] Bypassing OkHttp3 CertificatePinner for: ' + hostname);
        return;
    };

    // 繞過 TrustManagerImpl
    var TrustManagerImpl = Java.use('com.android.org.conscrypt.TrustManagerImpl');
    TrustManagerImpl.verifyChain.implementation = function(untrustedChain, trustAnchorChain, host, clientAuth, ocspData, tlsSctData) {
        console.log('[+] Bypassing TrustManagerImpl for: ' + host);
        return untrustedChain;
    };

    // 繞過自訂 X509TrustManager
    var X509TrustManager = Java.use('javax.net.ssl.X509TrustManager');
    var SSLContext = Java.use('javax.net.ssl.SSLContext');

    var TrustManager = Java.registerClass({
        name: 'com.bypass.TrustManager',
        implements: [X509TrustManager],
        methods: {
            checkClientTrusted: function(chain, authType) {},
            checkServerTrusted: function(chain, authType) {},
            getAcceptedIssuers: function() { return []; }
        }
    });

    console.log('[*] SSL Pinning bypass loaded');
});

執行繞過腳本:

1
2
3
4
5
# 執行 Frida 腳本
frida -U -f com.target.app -l ssl_pinning_bypass.js --no-pause

# 或者附加到執行中的程序
frida -U com.target.app -l ssl_pinning_bypass.js

4.3 使用 Objection 繞過

Objection 提供了更簡便的繞過方式:

1
2
3
4
5
6
7
8
9
# 安裝 Objection
pip install objection

# 使用 Objection 繞過 SSL Pinning
objection -g com.target.app explore

# 在 Objection 互動式 shell 中
android sslpinning disable
ios sslpinning disable

4.4 使用 apktool 修改 APK

對於靜態修改的方式:

1
2
3
4
5
# 反編譯 APK
apktool d target.apk -o target_decompiled

# 修改 network_security_config.xml
# 路徑: res/xml/network_security_config.xml

修改 network_security_config.xml:

1
2
3
4
5
6
7
8
9
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
    <base-config cleartextTrafficPermitted="true">
        <trust-anchors>
            <certificates src="system" />
            <certificates src="user" />
        </trust-anchors>
    </base-config>
</network-security-config>

重新打包並簽署:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 重新打包
apktool b target_decompiled -o target_modified.apk

# 產生金鑰
keytool -genkey -v -keystore test.keystore -alias test -keyalg RSA -keysize 2048 -validity 10000

# 簽署 APK
jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore test.keystore target_modified.apk test

# 對齊 APK
zipalign -v 4 target_modified.apk target_final.apk

5. 憑證安裝與信任

5.1 匯出 Burp Suite CA 憑證

1
2
3
4
5
6
# 方法一:透過瀏覽器
# 訪問 http://burp 並下載 CA 憑證

# 方法二:透過 Burp Suite 介面
# Proxy > Options > Import / export CA certificate
# 選擇 "Certificate in DER format"

5.2 Android 憑證安裝

Android 7.0 以上版本需要將憑證安裝為系統憑證:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
# 將 DER 格式轉換為 PEM 格式
openssl x509 -inform DER -in cacert.der -out cacert.pem

# 取得憑證雜湊值
openssl x509 -inform PEM -subject_hash_old -in cacert.pem | head -1
# 假設輸出為 9a5ba575

# 重新命名憑證檔案
mv cacert.pem 9a5ba575.0

# 推送到系統憑證目錄(需要 root)
adb root
adb remount
adb push 9a5ba575.0 /system/etc/security/cacerts/
adb shell chmod 644 /system/etc/security/cacerts/9a5ba575.0
adb reboot

對於 Android 14+ 系統:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
# 使用 Magisk 模組或 APEX 方式安裝
# 建立 Magisk 模組結構
mkdir -p module/system/etc/security/cacerts
cp 9a5ba575.0 module/system/etc/security/cacerts/

# 建立 module.prop
cat > module/module.prop << EOF
id=burp-cert
name=Burp Suite CA Certificate
version=1.0
versionCode=1
author=Security Tester
description=Install Burp Suite CA as system certificate
EOF

# 打包並安裝模組
cd module && zip -r ../burp-cert.zip .
adb push burp-cert.zip /sdcard/
# 在 Magisk 中安裝模組

5.3 iOS 憑證安裝

iOS 憑證安裝步驟:

1
2
3
4
5
# 1. 透過 Safari 訪問 http://burp 下載憑證
# 2. 進入 設定 > 一般 > VPN 與裝置管理
# 3. 點選下載的描述檔並安裝
# 4. 進入 設定 > 一般 > 關於本機 > 憑證信任設定
# 5. 啟用 PortSwigger CA 的完全信任

對於 Jailbreak 裝置:

1
2
3
4
5
# 使用 SSL Kill Switch 2
# 透過 Cydia 安裝 SSL Kill Switch 2
# 或手動安裝 deb 套件
dpkg -i com.nablac0d3.sslkillswitch2_0.14.deb
killall -HUP SpringBoard

6. 攔截 HTTPS 流量

6.1 基本攔截設定

在 Burp Suite 中設定攔截規則:

1
2
3
4
5
6
7
8
9
# Proxy > Options > Intercept Client Requests
# 新增規則攔截特定網域

Rule: URL → Matches → *.target.com
Rule: URL → Matches → api.example.com

# 排除不需要的請求
Rule: File extension → Matches → (css|png|jpg|gif|woff|woff2)
Action: Don't intercept

6.2 設定 TLS Pass Through

對於某些需要保持原始連線的情況:

1
2
3
4
5
6
7
# Proxy > Options > TLS Pass Through
# 新增不需要攔截的主機

*.googleapis.com
*.firebase.com
*.crashlytics.com
*.google-analytics.com

6.3 處理非 HTTP 流量

使用 Burp Suite 的 Invisible Proxying:

1
2
3
4
5
# Proxy > Options > Proxy Listeners
# 編輯監聽器,啟用 "Support invisible proxying"

# 在 Android 上使用 iptables 重定向流量
adb shell su -c "iptables -t nat -A OUTPUT -p tcp --dport 443 -j DNAT --to-destination <burp_ip>:8080"

6.4 監控 WebSocket 流量

1
2
3
4
5
6
# 在 Burp Suite 中
# Proxy > WebSockets history
# 可以查看所有 WebSocket 訊息

# 使用 Extender 安裝 WebSocket 相關外掛
# 如 "WebSocket Turbo Intruder"

7. 常見漏洞測試

7.1 不安全的資料儲存

測試本地儲存的敏感資料:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
# Android - 檢查 SharedPreferences
adb shell su -c "cat /data/data/com.target.app/shared_prefs/*.xml"

# 檢查 SQLite 資料庫
adb shell su -c "sqlite3 /data/data/com.target.app/databases/app.db '.dump'"

# 檢查檔案權限
adb shell su -c "ls -la /data/data/com.target.app/"

# iOS - 檢查 NSUserDefaults
find /var/mobile/Containers/Data/Application/ -name "*.plist" -exec plutil -p {} \;

# 檢查 Keychain
# 使用 Keychain-Dumper
./keychain_dumper

7.2 認證繞過測試

使用 Burp Suite Intruder 測試:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# 攔截登入請求
POST /api/login HTTP/1.1
Host: api.target.com
Content-Type: application/json

{"username":"admin","password":"§password§"}

# 使用 Intruder 進行暴力破解
# Intruder > Payloads
# 載入密碼字典

測試 JWT Token 漏洞:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
# 使用 Burp Suite 擴充套件 "JWT Editor"
# 或手動測試

import jwt
import base64

# 取得原始 token
token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."

# 嘗試 None 演算法攻擊
header = {"alg": "none", "typ": "JWT"}
payload = {"user_id": 1, "role": "admin"}

# 偽造 token
forged_token = base64.b64encode(json.dumps(header).encode()).decode().rstrip('=') + '.' + \
               base64.b64encode(json.dumps(payload).encode()).decode().rstrip('=') + '.'

7.3 API 安全測試

測試常見 API 漏洞:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# IDOR (Insecure Direct Object Reference)
# 原始請求
GET /api/users/123/profile HTTP/1.1

# 修改為其他使用者 ID
GET /api/users/124/profile HTTP/1.1

# 使用 Burp Intruder 批量測試
# 設定 payload 位置
GET /api/users/§id§/profile HTTP/1.1
# Payload: 1-1000

SQL Injection 測試:

1
2
3
4
5
6
7
8
9
# 使用 sqlmap 整合 Burp Suite
# 1. 在 Burp Suite 中右鍵點選請求
# 2. 選擇 "Copy to file"
# 3. 使用 sqlmap

sqlmap -r request.txt --level=5 --risk=3 --batch

# 或使用 Burp Suite 的 Active Scan
# 右鍵請求 > "Actively scan this host"

7.4 商業邏輯漏洞

測試價格篡改:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
# 原始請求
POST /api/checkout HTTP/1.1
Host: api.target.com
Content-Type: application/json

{
    "product_id": "12345",
    "quantity": 1,
    "price": 99.99
}

# 修改價格
{
    "product_id": "12345",
    "quantity": 1,
    "price": 0.01
}

測試數量限制繞過:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# 測試負數值
{
    "product_id": "coupon",
    "quantity": -1
}

# 測試極大值
{
    "product_id": "item",
    "quantity": 999999999
}

8. 自動化測試整合

8.1 Burp Suite REST API

使用 Burp Suite Professional 的 REST API 進行自動化:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
import requests

# Burp Suite API 設定
BURP_API = "http://127.0.0.1:1337"
API_KEY = "your-api-key"

headers = {
    "Authorization": API_KEY
}

# 取得掃描狀態
def get_scan_status(scan_id):
    response = requests.get(
        f"{BURP_API}/v0.1/scan/{scan_id}",
        headers=headers
    )
    return response.json()

# 啟動新掃描
def start_scan(target_url):
    data = {
        "urls": [target_url],
        "scan_configurations": [
            {"name": "Audit coverage - maximum", "type": "NamedConfiguration"}
        ]
    }
    response = requests.post(
        f"{BURP_API}/v0.1/scan",
        headers=headers,
        json=data
    )
    return response.json()

# 匯出掃描結果
def export_issues(scan_id):
    response = requests.get(
        f"{BURP_API}/v0.1/scan/{scan_id}/issues",
        headers=headers
    )
    return response.json()

8.2 整合 CI/CD Pipeline

GitHub Actions 範例:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
name: Mobile Security Scan

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]

jobs:
  security-scan:
    runs-on: ubuntu-latest

    steps:
    - uses: actions/checkout@v4

    - name: Setup Java
      uses: actions/setup-java@v4
      with:
        java-version: '17'
        distribution: 'temurin'

    - name: Download Burp Suite
      run: |
        wget -q "https://portswigger.net/burp/releases/download?product=pro&version=2024.1.1&type=Jar" -O burp.jar        

    - name: Start Burp Suite Headless
      run: |
        java -jar burp.jar --config-file=burp-config.json &
        sleep 30        

    - name: Run Mobile API Scan
      run: |
        python scripts/run_mobile_scan.py --target ${{ secrets.API_ENDPOINT }}        

    - name: Upload Scan Results
      uses: actions/upload-artifact@v4
      with:
        name: security-report
        path: reports/

8.3 使用 Burp Suite Extensions

安裝與使用常用擴充套件:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# 自訂 Burp Extension 範例
# mobile_scanner.py

from burp import IBurpExtender, IHttpListener
import re

class BurpExtender(IBurpExtender, IHttpListener):

    def registerExtenderCallbacks(self, callbacks):
        self._callbacks = callbacks
        self._helpers = callbacks.getHelpers()
        callbacks.setExtensionName("Mobile App Scanner")
        callbacks.registerHttpListener(self)
        print("[*] Mobile App Scanner loaded")

    def processHttpMessage(self, toolFlag, messageIsRequest, messageInfo):
        if not messageIsRequest:
            response = messageInfo.getResponse()
            analyzed = self._helpers.analyzeResponse(response)
            body = response[analyzed.getBodyOffset():].tostring()

            # 檢查敏感資料洩露
            patterns = {
                'API Key': r'["\']?api[_-]?key["\']?\s*[:=]\s*["\']([^"\']+)["\']',
                'Password': r'["\']?password["\']?\s*[:=]\s*["\']([^"\']+)["\']',
                'Token': r'["\']?token["\']?\s*[:=]\s*["\']([A-Za-z0-9_-]{20,})["\']',
                'Private Key': r'-----BEGIN (?:RSA )?PRIVATE KEY-----',
            }

            for name, pattern in patterns.items():
                if re.search(pattern, body, re.IGNORECASE):
                    print(f"[!] Potential {name} found in response")
                    # 新增 Issue
                    self._callbacks.addIssue(
                        self.createIssue(messageInfo, name, body)
                    )

8.4 自動化測試腳本

完整的自動化測試腳本:

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
#!/usr/bin/env python3
"""
Mobile Application Security Testing Automation Script
"""

import subprocess
import requests
import json
import time
import sys
from pathlib import Path

class MobileSecurityTester:
    def __init__(self, burp_api_url, api_key):
        self.burp_api = burp_api_url
        self.api_key = api_key
        self.headers = {"Authorization": api_key}

    def setup_proxy(self, device_type, device_ip, proxy_ip, proxy_port):
        """設定裝置代理"""
        if device_type == "android":
            cmd = f"adb shell settings put global http_proxy {proxy_ip}:{proxy_port}"
            subprocess.run(cmd, shell=True, check=True)
        elif device_type == "ios":
            print(f"[*] Please manually configure iOS proxy: {proxy_ip}:{proxy_port}")

    def install_certificate(self, device_type, cert_path):
        """安裝 CA 憑證"""
        if device_type == "android":
            # 轉換憑證格式
            subprocess.run([
                "openssl", "x509", "-inform", "DER",
                "-in", cert_path, "-out", "/tmp/cacert.pem"
            ], check=True)

            # 取得雜湊值
            result = subprocess.run([
                "openssl", "x509", "-inform", "PEM",
                "-subject_hash_old", "-in", "/tmp/cacert.pem"
            ], capture_output=True, text=True)
            hash_name = result.stdout.split('\n')[0]

            # 安裝憑證
            subprocess.run([
                "adb", "push", "/tmp/cacert.pem",
                f"/system/etc/security/cacerts/{hash_name}.0"
            ], check=True)

    def bypass_ssl_pinning(self, package_name):
        """使用 Frida 繞過 SSL Pinning"""
        script = """
        Java.perform(function() {
            var TrustManager = Java.use('javax.net.ssl.X509TrustManager');
            var SSLContext = Java.use('javax.net.ssl.SSLContext');

            var TM = Java.registerClass({
                name: 'bypass.TrustManager',
                implements: [TrustManager],
                methods: {
                    checkClientTrusted: function(chain, authType) {},
                    checkServerTrusted: function(chain, authType) {},
                    getAcceptedIssuers: function() { return []; }
                }
            });

            console.log('[+] SSL Pinning bypassed');
        });
        """

        with open('/tmp/bypass.js', 'w') as f:
            f.write(script)

        subprocess.Popen([
            "frida", "-U", "-f", package_name,
            "-l", "/tmp/bypass.js", "--no-pause"
        ])

    def start_scan(self, target_urls):
        """啟動 Burp Suite 掃描"""
        data = {
            "urls": target_urls,
            "scan_configurations": [
                {"name": "Audit coverage - maximum", "type": "NamedConfiguration"}
            ]
        }

        response = requests.post(
            f"{self.burp_api}/v0.1/scan",
            headers=self.headers,
            json=data
        )

        return response.json().get("task_id")

    def wait_for_scan(self, task_id, timeout=3600):
        """等待掃描完成"""
        start_time = time.time()

        while time.time() - start_time < timeout:
            response = requests.get(
                f"{self.burp_api}/v0.1/scan/{task_id}",
                headers=self.headers
            )
            status = response.json()

            if status.get("scan_status") == "succeeded":
                return True
            elif status.get("scan_status") == "failed":
                return False

            print(f"[*] Scan progress: {status.get('scan_metrics', {}).get('crawl_and_audit_progress', 0)}%")
            time.sleep(30)

        return False

    def export_report(self, task_id, output_path, report_type="HTML"):
        """匯出掃描報告"""
        response = requests.get(
            f"{self.burp_api}/v0.1/scan/{task_id}/report",
            headers=self.headers,
            params={"report_type": report_type}
        )

        with open(output_path, 'wb') as f:
            f.write(response.content)

        print(f"[+] Report saved to: {output_path}")

def main():
    tester = MobileSecurityTester(
        burp_api_url="http://127.0.0.1:1337",
        api_key="your-api-key"
    )

    # 設定測試
    print("[*] Setting up proxy...")
    tester.setup_proxy("android", "192.168.1.50", "192.168.1.100", 8080)

    # 安裝憑證
    print("[*] Installing certificate...")
    tester.install_certificate("android", "cacert.der")

    # 繞過 SSL Pinning
    print("[*] Bypassing SSL Pinning...")
    tester.bypass_ssl_pinning("com.target.app")

    # 等待流量收集
    print("[*] Collecting traffic for 5 minutes...")
    time.sleep(300)

    # 啟動掃描
    print("[*] Starting security scan...")
    task_id = tester.start_scan(["https://api.target.com"])

    # 等待完成
    if tester.wait_for_scan(task_id):
        tester.export_report(task_id, "security_report.html")
        print("[+] Scan completed successfully")
    else:
        print("[-] Scan failed")
        sys.exit(1)

if __name__ == "__main__":
    main()

總結

本文詳細介紹了如何使用 Burp Suite 進行行動應用程式安全測試,涵蓋了從環境設定、代理配置、SSL Pinning 繞過到自動化測試整合的完整流程。以下是關鍵要點的摘要:

  1. 環境準備:確保 Burp Suite、模擬器或實體裝置、以及相關工具都正確安裝配置
  2. 代理設定:根據不同平台(Android/iOS)選擇合適的代理配置方式
  3. SSL Pinning 繞過:使用 Frida、Objection 或修改 APK 等方式繞過憑證驗證
  4. 憑證管理:正確安裝和信任 Burp Suite CA 憑證
  5. 漏洞測試:系統性地測試常見的行動應用安全漏洞
  6. 自動化整合:將測試流程整合到 CI/CD pipeline 中,實現持續安全測試

行動應用安全測試是一個持續演進的領域,建議定期關注最新的測試技術和工具更新,以確保測試的有效性和完整性。

參考資源

comments powered by Disqus
Built with Hugo
Theme Stack designed by Jimmy