Mac中使用Mitmproxy/Charles拦截移动设备网络请求(抓包)

背景

拦截http proxy的软件很多,如 FiddlerCharles等,能够实现对http通信的拦截,可以查验Request和Response参数,特别是移动设备快速普及,此类软件逐渐被用于移动设备APP的网络请求拦截。

Mitmproxy的使用

官网

安装方式

1
brew install mitmproxy

启动

1
mitmweb

清空请求

点击mitmproxy 点击new 可将所有的请求清空

拦截Https请求

如今很多APP都开始使用Https请求,以确保数据安全,默认无法拦截https的接口,这时我们就要配置证书。

需要电脑和手机端都安装证书

Mac安装证书

找到证书位置

1
2
3
cd ~
cd .mitmproxy
open ./

双击安装其中的mitmproxy-ca-cert.pem文件即可

Android安装证书

在你的移动设备上打开连接,或者扫描下面的二维码,下载相应证书,然后安装。

1554262074

Android 手机可以在“设置–>安全–>从SD卡安装证书”中安装刚才下载的证书。

不用的Android位置不一样,我们可以搜索从SD卡安装找到对应的配置,选择下载的证书安装即可。

下载的位置默认在Downloads文件夹中。

Charles的使用

下载地址百度云链接

密码:5v9y

Mac端安装证书

1) 安装证书

Help–>SSL Proxying–>Install Charles Root Certificate安装即可

2) 配置需要证书的域名

Proxy–>SSL Proxying Settings–>SSL Proxying

中添加域名 比如

  • Host:*.baidu.com
  • Port:443

Android安装证书

Help–>SSL Proxying–>Install Charles Root Certificate on a Mobile Device or Remote Browser

  • 设置手机代理 比如我的是192.168.2.1:8888

  • 在浏览器中打开 http://chls.pro/ssl 或者扫描如下二维码

    1554271067

  • 下载证书后安装 安装方式参见上文

代码中的配置

Retrofit/okhttp

客户端不对服务器证书做任何验证

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
public static SSLSocketFactory getSSLSocketFactory() throws Exception {
//创建一个不验证证书链的证书信任管理器。
final TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
@Override
public void checkClientTrusted(
java.security.cert.X509Certificate[] chain,
String authType) throws CertificateException {
}

@Override
public void checkServerTrusted(
java.security.cert.X509Certificate[] chain,
String authType) throws CertificateException {
}

@Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new java.security.cert.X509Certificate[0];
}
}};

// Install the all-trusting trust manager
final SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, trustAllCerts,new java.security.SecureRandom());
// Create an ssl socket factory with our all-trusting manager
return sslContext.getSocketFactory();
}

//使用自定义SSLSocketFactory
private void onHttps(OkHttpClient.Builder builder) {
try {
builder.sslSocketFactory(getSSLSocketFactory()).hostnameVerifier(org.apache.http.conn.ssl.SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);
} catch (Exception e) {
e.printStackTrace();
}
}

客户端验证证书

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
public static SSLSocketFactory getSSLSocketFactory() throws Exception {
// Create a trust manager that does not validate certificate chains
final TrustManager[] trustAllCerts = new TrustManager[]{new X509TrustManager() {
//证书中的公钥
public static final String PUB_KEY = "输入您的公钥";

@Override
public void checkClientTrusted(
java.security.cert.X509Certificate[] chain,
String authType) throws CertificateException {
}

//客户端并为对ssl证书的有效性进行校验
@Override
public void checkServerTrusted(
java.security.cert.X509Certificate[] chain,
String authType) throws CertificateException {
if (chain == null) {
throw new IllegalArgumentException("checkServerTrusted:x509Certificate array isnull");
}

if (!(chain.length > 0)) {
throw new IllegalArgumentException("checkServerTrusted: X509Certificate is empty");
}

if (!(null != authType && authType.equalsIgnoreCase("RSA"))) {
throw new CertificateException("checkServerTrusted: AuthType is not RSA");
}

// Perform customary SSL/TLS checks
try {
TrustManagerFactory tmf = TrustManagerFactory.getInstance("X509");
tmf.init((KeyStore) null);
for (TrustManager trustManager : tmf.getTrustManagers()) {
((X509TrustManager) trustManager).checkServerTrusted(chain, authType);
}
} catch (Exception e) {
throw new CertificateException(e);
}
// Hack ahead: BigInteger and toString(). We know a DER encoded Public Key begins
// with 0×30 (ASN.1 SEQUENCE and CONSTRUCTED), so there is no leading 0×00 to drop.
RSAPublicKey pubkey = (RSAPublicKey) chain[0].getPublicKey();

String encoded = new BigInteger(1 /* positive */, pubkey.getEncoded()).toString(16);
// Pin it!
final boolean expected = PUB_KEY.equalsIgnoreCase(encoded);

if (!expected) {
throw new CertificateException("checkServerTrusted: Expected public key: "
+ PUB_KEY + ", got public key:" + encoded);
}
}

@Override
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return new java.security.cert.X509Certificate[0];
}
}};

// Install the all-trusting trust manager
final SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, trustAllCerts,new java.security.SecureRandom());
// Create an ssl socket factory with our all-trusting manager
return sslContext.getSocketFactory();
}

OkGo

客户端不对服务器证书做任何验证

1
2
3
OkHttpClient.Builder builder = new OkHttpClient.Builder();
HttpsUtils.SSLParams sslParams1 = HttpsUtils.getSslSocketFactory();
builder.sslSocketFactory(sslParams1.sSLSocketFactory, sslParams1.trustManager);