安卓抓包
BurpSuite代理抓包
- 导出burp证书 ==> 转为”hashValue.0”这个文件名 ==> 移动到安卓系统证书路径中(/system/etc/security/cacerts/)
- 安装代理转发插件:appproxy.apk
- 安装相关的bp插件:HaE、apiFinder等
自动转换证书格式并通过adb上传到/sdcard/download目录下
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#!/usr/bin/env python3
"""
Android 系统证书转换 & 上传工具
支持任意 X.509 证书(DER/PEM/PFX/PEM 内嵌)→ Android 7+ 格式 *.0
author : K0u
"""
import os
import sys
import subprocess
import tempfile
from pathlib import Path
class AndroidCertConverter:
def __init__(self):
self.adb_available = self._check_adb()
# -------------------- 工具 -------------------- #
def _check_adb(self) -> bool:
try:
subprocess.run(['adb', 'version'], capture_output=True, check=True)
return True
except (subprocess.CalledProcessError, FileNotFoundError):
return False
# -------------------- 格式统一 -------------------- #
def ensure_pem(self, cert_path: str) -> str:
"""DER->PEM(如需要)并返回 PEM 路径"""
try:
subprocess.run(['openssl', 'x509', '-in', cert_path, '-noout'],
check=True, capture_output=True)
return cert_path # 已是 PEM
except subprocess.CalledProcessError:
tmp = tempfile.NamedTemporaryFile(delete=False, suffix='.pem')
try:
subprocess.run(['openssl', 'x509', '-inform', 'DER',
'-in', cert_path, '-out', tmp.name], check=True)
print(f'[+] 自动 DER→PEM :{tmp.name}')
return tmp.name
except subprocess.CalledProcessError:
print('[-] 无法识别的证书格式')
sys.exit(1)
def _get_subject_hash_old(self, pem_path: str) -> str:
"""返回 8 位 subject_hash_old"""
r = subprocess.run(['openssl', 'x509', '-subject_hash_old',
'-in', pem_path], capture_output=True, text=True, check=True)
return r.stdout.strip().split('\n')[0]
# -------------------- 主转换 -------------------- #
def convert_to_android_format(self, cert_path: str, out_dir: str = '.') -> str:
pem_path = self.ensure_pem(cert_path)
hash_val = self._get_subject_hash_old(pem_path)
out_file = os.path.join(out_dir, f'{hash_val}.0')
with open(pem_path, 'rb') as f:
data = f.read()
with open(out_file, 'wb') as f:
f.write(data)
if not data.endswith(b'\n'):
f.write(b'\n')
if pem_path != cert_path: # 清理临时文件
os.remove(pem_path)
print(f'[+] Android 证书已生成 :{out_file}')
return out_file
# -------------------- ADB 上传 -------------------- #
def upload_via_adb(self, cert_path: str, device_path: str = "/sdcard/Download") -> bool:
if not self.adb_available:
print('[-] ADB 不可用')
return False
dev_list = subprocess.run(['adb', 'devices'], capture_output=True, text=True)
if 'device' not in dev_list.stdout:
print('[-] 未检测到连接设备')
return False
subprocess.run(['adb', 'shell', 'mkdir', '-p', device_path], capture_output=True)
target = f'{device_path}/{os.path.basename(cert_path)}'
try:
subprocess.run(['adb', 'push', cert_path, target], check=True)
print(f'[+] 上传完成 :{target}')
return True
except subprocess.CalledProcessError:
print('[-] ADB 上传失败')
return False
# -------------------- 提示 -------------------- #
def show_instructions(self, filename: str):
print('\n---- 后续操作(需 root) ----')
print(f'adb shell')
print(f'su')
print(f'mount -o remount,rw /system')
print(f'mv /sdcard/Download/{filename} /system/etc/security/cacerts/')
print(f'chmod 644 /system/etc/security/cacerts/{filename}')
print(f'mount -o remount,ro /system')
print(f'reboot')
print('----------------------------')
# -------------------- CLI -------------------- #
def main():
import argparse
parser = argparse.ArgumentParser(description='证书转换 & ADB 上传')
parser.add_argument('cert', help='原始证书文件(DER/PEM/PFX 均可)')
parser.add_argument('-o', '--output-dir', default='.', help='输出目录')
parser.add_argument('-d', '--device-path', default='/sdcard/Download', help='设备目录')
parser.add_argument('--no-upload', action='store_true', help='仅转换,不上传')
args = parser.parse_args()
converter = AndroidCertConverter()
cert_0 = converter.convert_to_android_format(args.cert, args.output_dir)
if not args.no_upload:
ok = converter.upload_via_adb(cert_0, args.device_path)
if ok:
converter.show_instructions(os.path.basename(cert_0))
else:
print(f'\n[-] 上传失败,证书已生成:{cert_0}')
else:
print(f'\n[+] 转换完成:{cert_0}')
if __name__ == '__main__':
banner = '''
__ __ ______ ________ ______
/ | / | / \\ / | / \\
_______ $$ |____ ______ ______ __ __ $$/ _______ /$$$$$$ |$$$$$$$$/ /$$$$$$ |
/ |$$ \\ / \\ / \\ / \\ / |/ |/ \\ $$ \\__$$/ $$ |__ $$ | $$/
/$$$$$$$/ $$$$$$$ | $$$$$$ |/$$$$$$ |$$ \\/$$/ $$ |$$$$$$$ |$$ \\ $$ | $$ |
$$ \\ $$ | $$ | / $$ |$$ | $$ | $$ $$< $$ |$$ | $$ | $$$$$$ |$$$$$/ $$ | __
$$$$$$ |$$ | $$ |/$$$$$$$ |$$ \\__$$ | /$$$$ \\ $$ |$$ | $$ |/ \\__$$ |$$ |_____ $$ \\__/ |
/ $$/ $$ | $$ |$$ $$ |$$ $$/ /$$/ $$ |$$ |$$ | $$ |$$ $$/ $$ |$$ $$/
$$$$$$$/ $$/ $$/ $$$$$$$/ $$$$$$/ $$/ $$/ $$/ $$/ $$/ $$$$$$/ $$$$$$$$/ $$$$$$/
support: .pem .crt .cer .key .der .cer .pfx .p12
'''
print(banner)
main()


启动appproxy,选择需要抓包的程序以及配置相应的代理




小黄鸟vpn抓包(通杀)
| 特性 | Reqable | BurpSuite |
|---|---|---|
| 抓包原理 | 利用系统VPN服务,在网卡层面拦截app发出的流量,属于原生抓包 | 通过配置代理,在上层将流量抓发到指定主机,属于代理抓包 |
| 是否需手动设代理 | 否 | 是 |
| 代码层面是否可规避抓包 | 实现较难 | OkHttpClient client = new OkHttpClient.Builder() .proxy(Proxy.NO_PROXY) // 禁用所有代理 .build(); |
| 是否支持透明代理 | 是 | 否 |
| 支持非HTTP协议 | TCP/UDP 等 | HTTP/HTTPS |
| 适合场景 | web安全 + 移动端抓包 | Web安全 |
安装移动端app以及桌面端程序(桌面端可省略):GitHub · reqable
数据线将手机和电脑相连,确保可以使用adb
启动桌面端Reqable,安装证书到Android/iOS的系统目录


确保手机和电脑处于同一局域网,桌面端点击
手机协同配置,移动端Reqable点击扫一扫进行连接

连接成功之后,移动端添加目标APP,启动抓包(启动之后,手机端小窗口可以关闭)



启动目标APP,桌面端成功接收到流量

如果不习惯小黄鸟的改包或者其他操作,可以在桌面端设置二级代理,将流量代理到BurpSuite/Yakit/……(这些都不需要安装证书,小黄鸟不验证)


本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来源 少欣安全!