0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

APP抓不到包?

哆啦安全 来源:哆啦安全 2023-08-03 16:45 次阅读
了解了HTTPS的传输流程,再来了解一下抓包相关知识。

一、前置知识

  • 默认你了解了HTTPS中间人攻击的流程,再来回顾一下这个图:

49095d80-3190-11ee-9e74-dac502259ad0.png

  • 网络在传输过程中一般不会被监控解密,但是通过中间人进行攻击(也就是抓包)可以解密这个传输流程。

    • 其实如果不进行客户端安装证书,也是可以抓包的,但是没有信任的证书相当于就是在路由上走一次,并没有加解密过程,实际上还是客户端与服务器端进行加解密通信

  • 这个中间人自己生成的证书在中间进行加解密与双方进行通信。

二、核心知识点

2.1 证书安装

  • 了解了中间人的攻击流程,也就知道了关键是这个证书,证书被校验成功即可以进行双向的传输解密

  • 安卓7以后安装的证书是放在用户目录的,并不能被系统信任,所以无法加解密流量。

      • 大多数抓不到包的原因就是证书安装了,但是在用户目录

      • 解决方法:

      • 1使用MT管理器把用户目录的证书移动到系统证书目录(据说可以支持到安卓10)

        • 用户证书文件目录/data/misc/user/0/cacerts-added/

        • 系统证书目录/etc/security/cacerts/

      • 2 由于 Android 10 采用了某些安全策略,将系统分区/system挂载为只读,就算你 root 了也没用,无法写入系统分区也就无法导入系统证书

        • 解决:使用Move Certificates模块

        • https://github.com/Magisk-Modules-Repo/movecert

      • 3 修改源码默认信任用户证书(提供几个检测的源码定位代码)

        • /frameworks/base/core/java/android/security/net/config/NetworkSecurityConfig.java

        • /frameworks/base/core/java/android/security/net/config/XmlConfigSource.java

        • libcore/ojluni/src/main/java/java/net/NetworkInterface.java

        • libcore/ojluni/src/main/java/java/lang/System.java

  • 到此安装完证书 使用抓包工具(charles、fidder、Burpsuit等)就可以进行抓包了

  • 但是我们使用的证书是中间人的证书 不是服务器直接下发的证书所以只能解决80%的HTTPS抓包问题。

三、SSLPinning环境下如何抓包

3.1 证书校验——SSL证书绑定

上文可以了解到从 HTTP 到 HTTPS 数据在传输过程中添加了一层 加密(SSL/TLS),让我们数据流量处于加密状态,不再是明文可见。一旦 app 校验了证书的指纹信息。我们的证书不再受信任了。自然而然就无法建立连接,所以必须想办法让 app 信任,才能继续抓包。当然这个分为两种情况:

3.1.1客户端校验服务器端的证书

上篇文件提到了一个证书包含了很多信息,那么客户端校验的原理就是:在APP中预先设置好证书的信息,在证书校验阶段时与服务器返回的证书信息进行比较。

  • 一般会有以下整数的信息会被校验,每种校验的方式这里就不展开了,下一篇文件在详细研究。

    • 公钥校验

    • 证书校验

    • Host校验

  • 如何绕过?(未混淆的情况)

    • 因为本质上校验是在客户端中完成的,所以客户端中肯定会有相关的校验代码,我们找到校验的地方进行HOOK,使得校验的地方直接PASS。这里方法列举,暂时不展开,下一篇文件在详细研究。加好友hackctf55进交流群。

    • frida hook(见下面)

    • JustTrustMe(xposed的Hook脚本)

      • https://github.com/LSPosed/LSPosed/releases

      • https://github.com/Fuzion24/JustTrustMe/releases/tag/v.2

      • 安装后无图标

      • 手机/data/adb/lspd/目录下找apk包,然后再点击安装即可。

探索开发逻辑

1 公钥校验

  • 这里我把52pj的证书公钥写进app进行校验实验

private void doRequest(){
     new Thread(){
         @Override
         public void run() {
              final  String CA_PUBLIC_KEY = "sha256/kO7OP94daK9P8+X52s00RvJLU0SiCXA9KAg9PelfwIw=";
              final  String CA_DOMAIN = "www.52pojie.cn";
              //校验公钥
             CertificatePinner buildPinner = new CertificatePinner.Builder()
                                                 .add(CA_DOMAIN, CA_PUBLIC_KEY)
                                                 .build();
             OkHttpClient client = new OkHttpClient.Builder().certificatePinner(buildPinner).build();


             Request req = new Request.Builder().url("https://www.52pojie.cn/forum.php")
                     .build();
             Call call = client.newCall(req);
             try {
                 Response res = call.execute();
                 Log.e("请求成功", "状态码:" + res.code());
             } catch (IOException e) {
                 e.printStackTrace();
                 Log.e("请求失败", "异常" + e);
             }


         }
     }.start();
  }
  • 安装好charles的证书后发现抓包就不好使了

4962334c-3190-11ee-9e74-dac502259ad0.png

  • 证书公钥校验的代码 一般来说是使用同的网络请求框架,大多都是Okhttp3

CertificatePinner buildPinner = new CertificatePinner.Builder()
                                                   .add(CA_DOMAIN, CA_PUBLIC_KEY)
                                                   .build();
//将buildPinner 传给OkHttpclient
OkHttpClient client = new OkHttpClient.Builder()
                                                .certificatePinner(buildPinner)
                                                .build();
  • 查看certificatePinner(buildPinner)的代码逻辑,使用frida hook把返回值空即可

498b5c18-3190-11ee-9e74-dac502259ad0.png

49cfb534-3190-11ee-9e74-dac502259ad0.png

49e8646c-3190-11ee-9e74-dac502259ad0.png

public void check(String hostname, List peerCertificates)
    throws SSLPeerUnverifiedException {
  List pins = findMatchingPins(hostname);
  if (pins.isEmpty()) return;


  if (certificateChainCleaner != null) {
    peerCertificates = certificateChainCleaner.clean(peerCertificates, hostname);
  }


  for (int c = 0, certsSize = peerCertificates.size(); c < certsSize; c++) {
    X509Certificate x509Certificate = (X509Certificate) peerCertificates.get(c);


    // Lazily compute the hashes for each certificate.
    ByteString sha1 = null;
    ByteString sha256 = null;


    for (int p = 0, pinsSize = pins.size(); p < pinsSize; p++) {
      Pin pin = pins.get(p);
      if (pin.hashAlgorithm.equals("sha256/")) {
        if (sha256 == null) sha256 = sha256(x509Certificate);
        if (pin.hash.equals(sha256)) return; // Success!
      } else if (pin.hashAlgorithm.equals("sha1/")) {
        if (sha1 == null) sha1 = sha1(x509Certificate);
        if (pin.hash.equals(sha1)) return; // Success!
      } else {
        throw new AssertionError("unsupported hashAlgorithm: " + pin.hashAlgorithm);
      }
    }
  }
  • frida 脚本片段

// Bypass OkHTTPv3 {1}
var okhttp3_Activity_1 = Java.use('okhttp3.CertificatePinner');    
okhttp3_Activity_1.check.overload('java.lang.String', 'java.util.List').implementation = function(a, b) {                              
console.log('[+] Bypassing OkHTTPv3 {1}: ' + a);
return;

2 证书校验

4a319f4c-3190-11ee-9e74-dac502259ad0.png

private void doRequest2(){
      X509TrustManager trustManager = new X509TrustManager() {
          @Override
          public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {


          }


          @Override
          public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {
              //服务器返回的证书
              X509Certificate cf = chain[0];
              //转换为RSA的公钥
              RSAPublicKey rsaPublicKey = (RSAPublicKey) cf.getPublicKey();
              //Base64 encode
              String ServerPubkey = Base64.encodeToString(rsaPublicKey.getEncoded(), 0);
              Log.e("服务器端返回的证书",ServerPubkey);


              //读取客户端资源目录中的证书
              InputStream client_input = getResources().openRawResource(R.raw.pojie);
              CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
              X509Certificate realCertificate = (X509Certificate) certificateFactory.generateCertificate(client_input);
              String realPubkey = Base64.encodeToString(realCertificate.getPublicKey().getEncoded(), 0);
              Log.e("客户端资源目录中的证书",realPubkey);


              cf.checkValidity();


              final  boolean expected = realPubkey.equalsIgnoreCase(ServerPubkey);
              Log.e("eq = ",String.valueOf(expected));


              if (!expected){
                  throw new CertificateException("证书不一致");
              }


          }


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


          SSLSocketFactory factory = null;


      try {
          SSLContext sslContext = SSLContext.getInstance("SSL");


          sslContext.init(null,new TrustManager[]{trustManager},new SecureRandom());


          factory = sslContext.getSocketFactory();
      } catch (Exception e) {
          e.printStackTrace();
      }


      SSLSocketFactory finalFactory = factory;


      new Thread(){
          @Override
          public void run() {


              try {
                  OkHttpClient client = new OkHttpClient.Builder().sslSocketFactory(finalFactory, trustManager).build();
                  Request req = new Request.Builder().url("https://www.52pojie.cn/forum.php").build();


                  Call call = client.newCall(req);


                  Response res = call.execute();


                  Log.e("请求发送成功","状态码:" + res.code());
              } catch (IOException e) {
                  Log.e("请求发送失败","网络异常" + e);
              }


          }
      }.start();


  }

4a3e31ee-3190-11ee-9e74-dac502259ad0.png

4a73ede8-3190-11ee-9e74-dac502259ad0.png

X509TrustManager trustManager = new X509TrustManager() {
...
      @Override
      public void checkServerTrusted(X509Certificate[] chain, String authType) {
        ... 
        }
....
}
var X509TrustManager = Java.use('javax.net.ssl.X509TrustManager');
        var SSLContext = Java.use('javax.net.ssl.SSLContext');


        // TrustManager (Android < 7) //
        ////////////////////////////////
        var TrustManager = Java.registerClass({
            // Implement a custom TrustManager
            name: 'dev.asd.test.TrustManager',
            implements: [X509TrustManager],
            methods: {
                checkClientTrusted: function(chain, authType) {},
                checkServerTrusted: function(chain, authType) {},
                getAcceptedIssuers: function() {return []; }
            }
        });
        // Prepare the TrustManager array to pass to SSLContext.init()
        var TrustManagers = [TrustManager.$new()];
        // Get a handle on the init() on the SSLContext class
        var SSLContext_init = SSLContext.init.overload(
            '[Ljavax.net.ssl.KeyManager;', '[Ljavax.net.ssl.TrustManager;', 'java.security.SecureRandom');
        try {
            // Override the init method, specifying the custom TrustManager
            SSLContext_init.implementation = function(keyManager, trustManager, secureRandom) {
                console.log('[+] Bypassing Trustmanager (Android < 7) pinner');
                SSLContext_init.call(this, keyManager, TrustManagers, secureRandom);
            };
        } catch (err) {
            console.log('[-] TrustManager (Android < 7) pinner not found');
            //console.log(err);
}
      • 不用的请求框架 代码不一样需要看情况编写

    • 内置证书到资源文件目录

    • 抓包测试

    • 校验的核心逻辑:自定义的trustManager类实现的checkServerTrusted接口

    • 绕过:

    • 这个一般是自定义的类然后实现了这个trustManager的接口 ,所以不确定这个类在哪,不容易hook

    • 但是定义好trustManager会传入以下俩地方

      4ad89b3a-3190-11ee-9e74-dac502259ad0.png

    • 思路是这样:实例化一个trustManager类,然后里面什么都不写,当上面两处调用到这个类时hook这两个地方,把自己定义的空trustManager类放进去,这样就可以绕过,参考下面的frida脚本

3host(域名)校验

  • 背景:一个证书可能对应有很多域名都可以使用,但是开发者只想让当前的应用证书校验通过后只能往指定的域名发送请求,而不想证书校验通过后往其他可以校验证书通过的域名发送请求。(证书允许往很多域名发送请求,但是app限制只能往特定域名发送请求)

private void doRequest3(){


       HostnameVerifier verifier =  new HostnameVerifier() {
            @Override
            public boolean verify(String hostname, SSLSession session) {


                if ("www.52pojie.cn".equalsIgnoreCase(hostname)){
                    return true;
                }
                return false;
            }
        };


        new Thread() {
            @Override
            public void run() {
                try {
                    OkHttpClient client = new OkHttpClient.Builder().hostnameVerifier(verifier).build();
                    Request req = new Request.Builder().url("https://www.52pojie.cn/forum.php").build();
                    Call call = client.newCall(req);


                    Response res = call.execute();
                    Log.e("请求发送成功", "状态码:" + res.code());


                } catch (IOException ex) {
                    Log.e("Main", "网络请求异常" + ex);
                }
            }
        }.start();


    }
    • 绕过方式和证书校验思路一样 自己创建一个HostnameVerifier类实现的接口直接返回true,哪里调用传给哪里即可。加好友hackctf55进交流群。

3.1.2 服务器端证书校验

在客户端放入证书(p12/bks),客户端向服务端发送请求时,携带证书信息,在服务端会校验客户端携带过来的证书合法性

private void doRequest4(){
      X509TrustManager trustManager = new 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 verify = new HostnameVerifier() {
          @Override
          public boolean verify(String hostname, SSLSession session) {
              return true;
          }
      };


      new Thread(){
          @Override
          public void run() {
              try {
                  InputStream client_input = getResources().openRawResource(R.raw.client);
                  Log.e("x",client_input.getClass().toString());
                  SSLContext sslContext = SSLContext.getInstance("TLS");
                  KeyStore keyStore = KeyStore.getInstance("PKCS12");
                  keyStore.load(client_input, "demoli666".toCharArray());


                  KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
                  keyManagerFactory.init(keyStore, "demoli666".toCharArray());
                  sslContext.init(keyManagerFactory.getKeyManagers(), new TrustManager[]{trustManager}, new SecureRandom());
                  SSLSocketFactory factory = sslContext.getSocketFactory();


                  OkHttpClient client = new OkHttpClient.Builder().sslSocketFactory(factory, trustManager).hostnameVerifier(verify).build();
                  Request req = new Request.Builder().url("https://xxx.xxx.xxx.xxx:443/index").build();
                  Call call = client.newCall(req);


                  Response res = call.execute();


                  Log.e("请求发送成功","状态码:" + res.code());
              } catch (Exception e) {
                  Log.e("请求发送失败","网络异常" + e);
              }


          }
      }.start();


  }
  • 开发逻辑

    • 在APK打包时,将证书放入assets或raw目录

    • 在开发代码时,发送请求读取证书文件内容+证书密码 携带发送到服务器端

  • 标志

4b1cac94-3190-11ee-9e74-dac502259ad0.png

解决方法
  • 找到证书文件(bsk/p12)

  • 通过hook获取证书相关密码

Java.perform(function () {
  function uuid(len, radix) {
      var chars = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz'.split('');
      var uuid = [], i;
      radix = radix || chars.length;


      if (len) {
          // Compact form
          for (i = 0; i < len; i++) uuid[i] = chars[0 | Math.random() * radix];
      } else {
          // rfc4122, version 4 form
          var r;


          // rfc4122 requires these characters
          uuid[8] = uuid[13] = uuid[18] = uuid[23] = '-';
          uuid[14] = '4';


          // Fill in random data. At i==19 set the high bits of clock sequence as
          // per rfc4122, sec. 4.1.5
          for (i = 0; i < 36; i++) {
              if (!uuid[i]) {
                  r = 0 | Math.random() * 16;
                  uuid[i] = chars[(i == 19) ? (r & 0x3) | 0x8 : r];
              }
          }
      }


      return uuid.join('');
  }


  function storeP12(pri, p7, p12Path, p12Password) {
      var X509Certificate = Java.use("java.security.cert.X509Certificate")
      var p7X509 = Java.cast(p7, X509Certificate);
      var chain = Java.array("java.security.cert.X509Certificate", [p7X509])
      var ks = Java.use("java.security.KeyStore").getInstance("PKCS12", "BC");
      ks.load(null, null);
      ks.setKeyEntry("client", pri, Java.use('java.lang.String').$new(p12Password).toCharArray(), chain);
      try {
          var out = Java.use("java.io.FileOutputStream").$new(p12Path);
          ks.store(out, Java.use('java.lang.String').$new(p12Password).toCharArray())
      } catch (exp) {
          console.log(exp)
      }
  }


  //在服务器校验客户端的情形下,帮助dump客户端证书,并保存为p12的格式,证书密码为r0ysue
  Java.use("java.security.KeyStore$PrivateKeyEntry").getPrivateKey.implementation = function () {
      var result = this.getPrivateKey()
      var packageName = Java.use("android.app.ActivityThread").currentApplication().getApplicationContext().getPackageName();
      storeP12(this.getPrivateKey(), this.getCertificate(), '/sdcard/Download/' + packageName + uuid(10, 16) + '.p12', 'r0ysue');
      return result;
  }


  Java.use("java.security.KeyStore$PrivateKeyEntry").getCertificateChain.implementation = function () {
      var result = this.getCertificateChain()
      var packageName = Java.use("android.app.ActivityThread").currentApplication().getApplicationContext().getPackageName();
      storeP12(this.getPrivateKey(), this.getCertificate(), '/sdcard/Download/' + packageName + uuid(10, 16) + '.p12', 'r0ysue');
      return result;
  }
});

4b3ea88a-3190-11ee-9e74-dac502259ad0.png

4b5c0470-3190-11ee-9e74-dac502259ad0.png

    • 将证书导入charles即可正常抓包

    • charles只支持p12证书,若是在app中获取了bks证书 需要 转换p12

    • 可以使用https://keystore-explorer.org/downloads.html来做证书的转换。

    • 在使用py构造请求时也需要携带这个证书和密码

四、混淆代码

1 关于混淆

  • 只需要了解到安卓开发中,系统包是无法混淆的,例如java.security.KeyStore不会被混淆,但是第三方的包都会被混淆为a.b.c.v类似的形式

  • 所以在这样的情况下之前的hook第三方包的脚本都是不通用的

  • 客户端证书校验的frida脚本【不通用】

Java.use('okhttp3.CertificatePinner');
Java.use('com.square.okhttp.internal.tls.OkHostnamaVerifier');
  • 服务端证书校验的frida脚本【通用】

Java.use("java.security.KeyStore");
  • 遇到混淆的情况下,这些hook代码或多或少会失效一些,所以我们要寻找一个像服务端证书校验的系统函数来绕过客户端证书校验。

2 解决方法

  • 服务端的证书校验对于我们来说已经不是问题,混淆对于java.security.KeyStore没有作用。

  • 客户端的证书校验,我们先来捋一下开发时的逻辑

    • 1 调用证书校验

       X509TrustManager trustManager = new X509TrustManager() {
                   @Override
              public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {}
      }
    • 2 主机校验

        HostnameVerifier verify = new HostnameVerifier() {
                  @Override
                  public boolean verify(String hostname, SSLSession session) {
                      return true;
                  }
              };
    • 3 pinner 公钥校验这个校验主要是调用了CertificatePinner类中check方法

      CertificatePinner buildPinner = new CertificatePinner.Builder()
                                                         .add(CA_DOMAIN, CA_PUBLIC_KEY)
                                                         .build();
      OkHttpClient client = new OkHttpClient.Builder().certificatePinner(buildPinner).build();
  • 可以打调用栈或者hook查看这三个方法走的调用逻辑,结论就是都走了:okhttp3.internal.connection.RealConnection类中的connectTls方法:

4b64c7ea-3190-11ee-9e74-dac502259ad0.png

4bb2ae7e-3190-11ee-9e74-dac502259ad0.png

Java.perform(function () {
    var NativeSsl = Java.use('com.android.org.conscrypt.NativeSsl');
    NativeSsl.doHandshake.overload('java.io.FileDescriptor', 'int').implementation = function (a, b) {
        console.log("参数:", a, b);
        console.log(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Throwable").$new()));
        return this.doHandshake(a, b);
    };
});


// frida -UF -l 1.hook_check.js
  • 找到第三方调用栈 注意客户端的证书校验顺序

    • 1 证书校验

      Java.perform(function () {
        var Platform = Java.use('com.android.org.conscrypt.Platform');
        Platform.checkServerTrusted.overload('javax.net.ssl.X509TrustManager', '[Ljava.security.cert.X509Certificate;', 'java.lang.String', 'com.android.org.conscrypt.AbstractConscryptSocket').implementation = function (x509tm, chain, authType, socket) {
            console.log('
      [+] checkServer  ',x509tm,JSON.stringify(x509tm) );
            // 这里会去调用客户端证书校验的方法,不执行,就是不去校验(直接通过)。
            //return this.checkServerTrusted(x509tm, chain, authType, socket);
        };
      });
    • 2 hostname校验

      很少遇到 不写了
      Java.perform(function () {
      
      
          function getFieldValue(obj, fieldName) {
              var cls = obj.getClass();
              var field = cls.getDeclaredField(fieldName);
              field.setAccessible(true);
              var name = field.getName();
              var value = field.get(obj);
              return value;
          }
      
      
          function getMethodValue(obj, methodName) {
              var res;
              var cls = obj.getClass();
              var methods = cls.getDeclaredMethods();
      
      
              methods.forEach(function (method) {
                  var method_name = method.getName();
                  console.log(method_name, method);
                  if (method_name === methodName) {
                      method.setAccessible(true);
                      res = method;
                      return;
                  }
              })
              return res;
          }
      
      
          var RealConnection = Java.use('uk.c');
          RealConnection.f.implementation = function (a, b, c, d) {
              try {
                  console.log("===============");
                  var route = getFieldValue(this, "c");
                  console.log('route=', route);
                  var address = getFieldValue(route, 'a');
                  console.log('address=', address);
                  var hostnameVerifier = getFieldValue(address, 'hostnameVerifier');
                  console.log('hostnameVerifier=', hostnameVerifier);
                  console.log('
      [+] hostnameVerifier', hostnameVerifier);
              } catch (e) {
                  console.log(e);
              }
              return this.f(a, b, c, d);
          };
      });
    • 3 公钥pinner校验

      connectTls中就能找到他的类和方法被混淆后的名称,可以直接Hook

五、禁用代理的场景

4bf94bd6-3190-11ee-9e74-dac502259ad0.png

  • 现在的很多的app都是用禁止网络代理来防止抓包。在请求的时候都使用了Proxy.NO_PROXY

  • 解决方法:

    • 传输层的vpn进行流量转发

    • 使用charles + Postern

    • postern是在传输层久把流量转发指定的中间人(代理/抓包软件)

    • 不理解传输层什么意思?稍后来填坑

六、特殊框架 flutter 环境下如何抓包

4c40943c-3190-11ee-9e74-dac502259ad0.png

4c722470-3190-11ee-9e74-dac502259ad0.png

4c9fd3b6-3190-11ee-9e74-dac502259ad0.png

  • 框架特点:自实现SSL库 + 单向证书绑定 + 禁用代理

  • https://bbs.kanxue.com/thread-261941.htm

  • 注意自己的系统是32位还是64位

    4c1d6c28-3190-11ee-9e74-dac502259ad0.png

    4c342b84-3190-11ee-9e74-dac502259ad0.png

  • 拖到IDA中 ---> shift + f12 搜索ssl_server

    • 找到这个地方后 往上找函数开始的地方

    • 然后你需要这样操作才能把字节显示出来

    • 菜单栏->Options->General->Disassembly->Display disassambly line parts->number ofo opcode bytes(non-graph)->填入每行显示的字节数即可

  • 也可以直接找该函数的函数地址

    function hook_ssl_verify_result(address)
    {
     Interceptor.attach(address, {
      onEnter: function(args) {
       console.log("Disabling SSL validation")
      },
      onLeave: function(retval)
    {
       console.log("Retval: " + retval)
       retval.replace(0x1);
      }
     });
    }
    function disablePinning(){
      // Change the offset on the line below with the binwalk result
      // If you are on 32 bit, add 1 to the offset to indicate it is a THUMB function: .add(0x1)
      // Otherwise, you will get 'Error: unable to intercept function at ......; please file a bug'
      // 0x393DA4 换成你找到的函数地址
      var address = Module.findBaseAddress('libflutter.so').add(0x393DA4)
      hook_ssl_verify_result(address);
    }
    setTimeout(disablePinning, 1000)

七、非root环境如何抓包

  • 场景:应用对root环境进行校验

  • 暂时不展开

八、自实现SSL/TLS框架

九、其他抓包技巧

  • https://www.52pojie.cn/thread-1405917-1-1.html

  • hook得到 sslkey,可以解释原理

  • https://bbs.kanxue.com/thread-277996.htm


声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 服务器
    +关注

    关注

    12

    文章

    8120

    浏览量

    82524
  • APP
    APP
    +关注

    关注

    33

    文章

    1530

    浏览量

    71631
  • SSL
    SSL
    +关注

    关注

    0

    文章

    119

    浏览量

    25497

原文标题:APP抓不到包?

文章出处:【微信号:哆啦安全,微信公众号:哆啦安全】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    CC2530 packet sniffer 为什么不到,?

    我用packet sniffer 软件,芯片用的是CC2530,想协调器给终端设备发送的信道和pandid值,但是抓取不到,不知道为什么?只有MAXC层有数据,NWK层和应用层都
    发表于 03-14 10:53

    终端节点为什么无法

    终端节点为什么无法?终端节点收不到协调器无线发送的数据包打断点调试协调器无线发送成功,终端节点开启低功耗模式,并且轮询设置为5s,每5s向协调器发送data request请求
    发表于 03-16 10:27

    CC2640 使用BTool怎么用?

    sniffer识别不到芯片。开发板和连线如下:,[url=http://www.deyisupport.com/cfs-file.ashx/__key/communityserver-discussions-components-files/103/5633.yzy.jpg]请问我应该怎么进行
    发表于 03-16 11:27

    zigbee用zcl库做开发,为什么不到数据

    zigbee用zcl库做开发,为什么不到数据?zigbee用zcl库做开发,在ZStack-2.5.1a协议栈基础上,对协议栈自带的Light-switch的例子是跑通的,也明白流程,但是用
    发表于 04-01 10:23

    Zigbee网路协调器发送的超长数据帧在网络中不到

    Zigbee网路协调器发送的超长数据帧在网络中不到?有一个Zigbee网路,协调器-->路由-->终端节点。协调器有一个超过128byte的数据帧发送给终端节点。发现如果终端节点直接
    发表于 04-06 16:49

    CC2541和手机连接后不到

    我用SmartRF Packet Sniffer+u***dongleCC2541模块发送的数据,广播数据可以抓到,但是一旦用一个手机和CC2541模块建立连接后,sniffer就不能抓到数据包了。请问要怎样才能抓到连接后
    发表于 04-19 16:15

    WIZnet芯片通讯时怎么?

    `Q:WIZnet芯片进行公网通讯或者芯片间通讯的话怎么?A:芯片和PC通讯的话可以直接通过Wireshark,如果芯片和公网直接通讯或者通讯是发生在芯片之间,则没有办法直接
    发表于 03-13 11:32

    加密后分析的问题?

    请问一下,我的zigbee设备全部都开启了加密, 使用软件的时候,数据都是加密的,我应该怎么解密分析这些数据呢,谢谢了
    发表于 06-01 14:22

    Packet Sniffer 异常,有时能抓到有时不到,有时协调器会回应有时不会回应,请问是怎么回事?

    本帖最后由 一只耳朵怪 于 2018-6-1 16:49 编辑 USB Dongle总发序列号为0x(x)cLQI为0 的beacon request,有时能抓到有时不到,有时协调器会回应
    发表于 06-01 07:41

    cc2640的simpleblebroadcaster例程不到

    我把simpleblebroadcaster例程改成5*5封装的配置编译烧写到cc2640上但是我用包工具u*** dongle,不到,为什么?
    发表于 03-09 09:36

    wireshark数据分析问题

    用网络调试助手作为Tcp Server给STM32F429发送数据,每次传输完21845bytes后,就出现问题。用WireShark的数据有些不太理解。上图为用串口调试助手调试后的信息,每次传输到21846bytes就接收不到
    发表于 04-08 04:35

    请问BLE-Dongle是否支持协议分析?请问怎么进行协议分析?

    如题,请问贵司的BLE-Dongle是否支持协议分析?请问怎么进行协议分析?
    发表于 09-07 07:12

    九寨沟瀑布垮塌之后:九寨沟捐款刘强东说京东仓存任意使用 提前71秒的地震预警系统详解

    从2013年起,ICL已经连续预警了38次造成了破坏的地震,且无漏报、误报。而几乎在九寨沟地震发生的同时,地震预警(ICL)app不到20秒的时间内连续发布了5条推送,提前71秒为成都市的用户提供预警信息.
    发表于 08-12 12:44 2w次阅读

    山东高速与赛维安讯推出第一代物联网实时可视路况App路网

    2017年,山东高速与赛维安讯推出的第一代物联网实时可视路况App路网,不到一年时间,就已经获得近十万用户的认可。在山东省物联网协会的2017年度评选中,实时可视路况系统获得了“山东省十佳物联网产品
    的头像 发表于 01-26 11:35 6360次阅读

    不ROOT的安卓不是完整的安卓 SuperSU开发者不再更新ROOT软件

    ROOT对于不少安卓手机的用户来说应该是非常熟悉的,尤其是比较早期或者稍微高阶一点的玩家,ROOT几乎是家常必备,甚至曾经有“不ROOT的安卓不是完整的安卓”的说法,毕竟ROOT之后用户可以获得高级权限,可以做很多常规APP不到的高级修改。
    的头像 发表于 05-07 14:35 1.1w次阅读