逆向-爬虫-抓包

搬砖

ebpf in android

1.osi七层协议(ssl/tls 所在位置)

1
2
3
4
5
6
7
应用层tcp     (第7层)        <-- 应用数据(HTTP、FTP、IMAP等)
表示层tcp (第6层)
会话层tcp (第5层) <-- SSL/TLS 握手,密钥交换,记录协议
传输层tcp (第4层) <-- SSL/TLS 记录协议(安全的传输)
网络层 (第3层) <-- IP协议等,进行路由选择
数据链路层 (第2层) <-- 在物理网络中传输数据帧
物理层 (第1层) <-- 物理传输介质

ssl/tls

tcp 是网络编程的抽象,ssl/tls 对tcp加密,同时处理握手,密钥交换

https

  1. TCP 三次握手:
    TCP 连接开始时,客户端发出一个 SYN(同步序列编号) 数据包。
    服务器回应一个带有 SYN/ACK 标志的数据包。
    客户端发送一个 ACK(确认)数据包,完成三次握手。

  2. TLS 握手 —— 客户端发送 “Client Hello”:
    握手开始后,客户端发送 “Client Hello” 消息,包含其支持的 TLS 版本、加密套件、压缩方法和一个客户端随机数。

  3. TLS 握手 —— 服务器响应 “Server Hello”:
    服务器选择双方共同支持的协议和密码套件,并发送 “Server Hello” 消息给客户端。它也包含一个服务器随机数。

  4. 服务器发送证书链:
    这包括服务器的公共证书及任何必需的中间CA证书。根CA证书通常不会发送,因为它应该已经预先安装在客户端系统中。

  5. 客户端验证证书,并使用CA的公钥进行加密的密钥交换:
    客户端验证服务器证书和证书链的有效性。如果验证通过,客户端使用服务器证书中包含的公钥来加密生成的预备主秘钥(pre-master secret)并发送给服务器。

  6. 密钥交换和加密套件的确定:
    服务器利用其私钥解密并得到预备主秘钥,并基于这个秘钥以及双方共享的随机数生成主秘钥。双方会使用主秘钥派生出会话秘钥,用于此后的会话加密。
    双方会各自发送“Change Cipher Spec”消息,之后即使用选定的对称加密算法(如 AES)、特定模式(如 GCM)和会话秘钥来加密通信。

  7. 握手完成,开始加密通信:
    双方分别发送包含握手消息哈希的”Finished”消息。一旦 “Finished” 消息被验证,加密会话开始,传输的数据使用会话秘钥加密。

3.2. https单向认证和双向认证

  1. 单向认证 sslping

    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
    单向认证信任所有证书
    public class HttpsUtils {

    private MyTrustManager mMyTrustManager;

    private SSLSocketFactory createSSLSocketFactory() {
    SSLSocketFactory ssfFactory = null;
    try {
    mMyTrustManager = new MyTrustManager();
    SSLContext sc = SSLContext.getInstance("TLS");
    sc.init(null, new TrustManager[]{mMyTrustManager}, new SecureRandom());
    ssfFactory = sc.getSocketFactory();
    } catch (Exception ignored) {
    ignored.printStackTrace();
    }

    return ssfFactory;
    }

    //实现X509TrustManager接口
    public class MyTrustManager implements X509TrustManager {
    @Override
    public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {
    }

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

    @Override
    public X509Certificate[] getAcceptedIssuers() {
    return new X509Certificate[0];
    }
    }

    //实现HostnameVerifier接口
    private class TrustAllHostnameVerifier implements HostnameVerifier {
    @Override
    public boolean verify(String hostname, SSLSession session) {
    return true;
    }
    }

    public OkHttpClient getTrustAllClient() {
    OkHttpClient.Builder mBuilder = new OkHttpClient.Builder();
    mBuilder.sslSocketFactory(createSSLSocketFactory(), mMyTrustManager)
    .hostnameVerifier(new TrustAllHostnameVerifier());
    return mBuilder.build();
    }
    }
  2. 单向认证 验证服务器端证书

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    public static SSLSocketFactory getSSLSocketFactory_Certificate(Context context, String str) {
    try {
    CertificateFactory instance = CertificateFactory.getInstance("X.509");
    KeyStore instance2 = KeyStore.getInstance(KeyStore.getDefaultType());
    instance2.load((KeyStore.LoadStoreParameter) null);
    int i = 0;
    for (Certificate certificateEntry : instance.generateCertificates(context.getAssets().open(str))) {
    instance2.setCertificateEntry(Integer.toString(i), certificateEntry);
    i++;
    }
    TrustManagerFactory instance3 = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
    instance3.init(instance2);
    SSLContext instance4 = SSLContext.getInstance("TLS");
    instance4.init((KeyManager[]) null, instance3.getTrustManagers(), new SecureRandom());
    return instance4.getSocketFactory();
    } catch (Exception e) {
    throw new RuntimeException(e);
    }
    }
  3. 双向认证

    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
    public static SSLSocketFactory getSSLSocketFactory_Certificate(Context context, String str) {
    try {
    CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
    //通过证书工厂得到自签证书对象集合
    Collection<? extends Certificate> certificates = certificateFactory.generateCertificates(in);
    if (certificates.isEmpty()) {
    throw new IllegalArgumentException("expected non-empty set of trusted certificates");
    }
    //为证书设置一个keyStore
    char[] password = "password".toCharArray(); // Any password will work.
    KeyStore keyStore = newEmptyKeyStore(password);
    int index = 0;
    //将证书放入keystore中
    for (Certificate certificate : certificates) {
    String certificateAlias = Integer.toString(index++);
    keyStore.setCertificateEntry(certificateAlias, certificate);
    }
    // Use it to build an X509 trust manager.
    //使用包含自签证书信息的keyStore去构建一个X509TrustManager
    KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(
    KeyManagerFactory.getDefaultAlgorithm());
    keyManagerFactory.init(keyStore, password);
    TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(
    TrustManagerFactory.getDefaultAlgorithm());
    trustManagerFactory.init(keyStore);
    SSLContext instance4 = SSLContext.getInstance("TLS");
    instance4.init(keyManagerFactory.getKeyManagers(), trustManagerFactory.getTrustManagers(), new SecureRandom());
    return instance4.getSocketFactory();
    } catch (Exception e) {
    throw new RuntimeException(e);
    }
    }

2.常用抓包工具及原理

中间人劫持

旁观者观察

3.抓包脚步及原理

4.工作中的抓包方案

  • 要阻止来自特定IP地址的所有入站流量:
    iptables -A INPUT -s -j DROP
  • iptables -L INPUT -v -n
  • iptables -D INPUT 3