关于抓包的碎碎念--https抓包总结的很全面

0x01

抓包是作为apk分析的首要切入点,获取apk的通信协议的必要手段。常见的抓包手段是基于中间人攻击来进行的,还有另外一种抓包手段是基于手机VPN进行的。这里将罗列常见的抓包手段,以及SSL Pinning手段的对抗。

正文

基于中间人攻击的抓包

比较常规的抓包手段,常用的抓包工具有Burpsuite、Charles、Fiddler、Mitmproxy等等。通常在手机端安装工具的证书,如若抓取的手机客户端未做SSL pinning便可直接进行抓包。

手机APP不走代理

通常有些APP为了防止被抓包,会设置APP默认不走代理,在分析的时候你会发现即使你设置了APP代理,也不影响APP的正常通信。通过tcpdump抓取网络报文可以发现app直接和服务器建立了连接而没有和代理建立连接。对应Java代码如下。

1

OkHttpClient client = new OkHttpClient().newBuilder().proxy(Proxy.NO_PROXY).build();

这种情况下可以通过建立VPN服务,直接将流量导向我们的抓包工具。当然也有现成的工具,如SocksDroid直接将流量导向抓包工具,Burpsuite是不支持socks5代理的,可以使用Charles设置Socks5代理,然后设置Charles的上游代理到Burpsuite。
还有的检测手段就是检测代理状态,如果设置代理了就拒绝通信,这种情况下也可以使用SocksDroid工具直接转发流量,这种情况下检测不到代理,另外的方法就是将检测的代码Bypass掉。
之前遇到过用Flutter写的应用,这种应用默认不走系统代理,所以也使用SocksDroid进行流量转发,然后需要注意的是需要将抓包证书安装在System Level而不是User Level。因为在User level的证书,应用是不信任的。

 

[安装系统证书] https://blog.ropnop.com/configuring-burp-suite-with-android-nougat/

证书绑定(单向绑定)

证书绑定的安全策略在目前的APP开发中是越来越常见了,其根本策略就是检测客户端发来的证书是否合法,一般在APP中会硬编码合法的服务端证书信息,然后进行对比,笔者见的比较多的是OkHttp3中的一些SSL Pinning策略,而且很多APP也是使用的OKHttp3框架进行流量通信,比较常见的就是实现 HostnameVerifier接口中的verify函数,其verify函数中实现检测逻辑,返回值是boolean类型,常见的bypass策略就是Hook verify函数使其返回true。那么如何找到verify函数呢?下面将列举常见的方法:

  1. frida-trace

    1

    2

    3

    4

    5

    frida-trace

     -U \

     -F \

     --runtime=v8 \

     -'*!verify/iu'

    关于抓包的碎碎念--https抓包总结的很全面_第1张图片
    可以看到的确调用了verify函数,上图是我在没有设置代理的情况下返回的是true。

  2. frida Java.enumerateMethods
    前不久frida提供了枚举Methods的接口,这样就比以前更易于操作了,不然之前得枚举类然后得到方法。使用以下脚本便可

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    const groups = Java.enumerateMethods('*!verify/u')

    // console.log(JSON.stringify(groups, null, 2));

    var classes = null;

    for(var i in groups){

     var classes = groups[i]['classes']

     

     for(var i in classes){

         Java.use(classes[i]['name'])

         .verify

         .overload('java.lang.String''javax.net.ssl.SSLSession')

         .implementation = function(){

             console.log("[+] invoke verify");

             return true

         }

     }

    }

  3. 找到verify函数,直接Hook
    此方法不能实现通用脚本

  4. 上述情况是针对okhttp3的情况说明的,如遇到其他框架请采用网上集成的bypass脚本。

https://raw.githubusercontent.com/WooyunDota/DroidSSLUnpinning/master/ObjectionUnpinningPlus/hooks.js

证书绑定(双向绑定)

双向绑定即客户端验证服务端证书,服务端验证客户端证书。要实现抓包需要绕过客户端对服务端的校验,以及服务端对客户端的证书校验,首先绕过客户端对服务端的校验一般采用以上方法即可。绕过服务端的校验一般需要提取嵌入在客户端中的证书,有的开发者将此加密了,有的可以在assets目录中找到,以及raw目录中。对于加密的证书提取,可以Hook Keystore的load方法

1

2

3

4

5

6

7

8

9

10

11

12

13

Java.perform(function () {

    var StringClass = Java.use("java.lang.String");

    var KeyStore = Java.use("java.security.KeyStore");

    KeyStore.load.overload('java.security.KeyStore$LoadStoreParameter').implementation = function (arg0) {

        console.log("KeyStore.load1:", arg0);

        this.load(arg0);

    };

    KeyStore.load.overload('java.io.InputStream''[C').implementation = function (arg0, arg1) {

        send(arg0)

        console.log("KeyStore.load2:", arg0, arg1 ? StringClass.$new(arg1) : null);

        this.load(arg0, arg1);

    };

});

关于抓包的碎碎念--https抓包总结的很全面_第2张图片
比如上述策略,证书是经过加密保存在apk中的,取出来先进行解密,然后使用Keystore进行加载,这时候可以通过Hook load方法得到证书以及证书的密钥,然后将证书导入到Burpsuite中,便可抓取报文。

奇淫技巧抓包

0x01 Hook SSL_write SSL_read

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

var ssl_write = Module.getExportByName(null,"SSL_write");

var ssl_read = Module.getExportByName(null,"SSL_read");

Interceptor.attach(ssl_write,

{

    onEnter: function (args)

    {

      send(,Memory.readByteArray(args[1], parseInt(args[2])));

    },

    onLeave: function (retval){

}

Interceptor.attach(ssl_read,

{

    onEnter: function (args)

    {

      send(,Memory.readByteArray(args[1], parseInt(args[2])));

    },

    onLeave: function (retval){

 }

https://sec.mrfan.xyz/2019/12/16/%E5%AE%89%E5%8D%93%E6%B5%8B%E8%AF%95%E4%B9%8BHook%20SSL_read%E5%92%8CSSL_write/
https://github.com/fanxs-t/Android-SSL_read-write-Hook/blob/master/frida-hook.py
这种方式抓取的是未经加密的报文,经测试,有的场景下无效。

0x02 SSL key logger

这种技巧相当于PC上运行chrome设置SSLLOGFILE环境变量记录SSL协商的密钥,在android上,默认未设置需要通过Hook进行设置

frida -U -f com.realcloud.loochadroid.college -l hook.js --no-pause -o key

 

抓出来是这样的格式
关于抓包的碎碎念--https抓包总结的很全面_第3张图片

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

function startTLSKeyLogger(SSL_CTX_new, SSL_CTX_set_keylog_callback) {

    function keyLogger(ssl, line) {

        console.log(new NativePointer(line).readCString());

    }

    const keyLogCallback = new NativeCallback(keyLogger, 'void', ['pointer''pointer']);

 

    Interceptor.attach(SSL_CTX_new, {

        onLeave: function(retval) {

            const ssl = new NativePointer(retval);

            const SSL_CTX_set_keylog_callbackFn = new NativeFunction(SSL_CTX_set_keylog_callback, 'void', ['pointer''pointer']);

            SSL_CTX_set_keylog_callbackFn(ssl, keyLogCallback);

        }

    });

}

startTLSKeyLogger(

    Module.findExportByName('libssl.so''SSL_CTX_new'),

    Module.findExportByName('libssl.so''SSL_CTX_set_keylog_callback')

)

使用方法,在程序spwan前使用tcpdump dump流量。然后wireshark设置TLS Logfile的位置
关于抓包的碎碎念--https抓包总结的很全面_第4张图片
关于抓包的碎碎念--https抓包总结的很全面_第5张图片
参考链接:https://codeshare.frida.re/@k0nserv/tls-keylogger/

0x03 CE扫描内存

这种方式是实在没有办法采用的方法,通过扫描关键字如HTTP、接口信息搜出http报文。

总结

获取HTTPS报文的方式多种多样,下面是此篇文章参考的文章
https://hackmag.com/security/ssl-sniffing/ 这是一篇讲通用SSL Pinning Bypass的方法
http://www.moserware.com/2009/06/first-few-milliseconds-of-https.html SSL建立流程

你可能感兴趣的:(看雪转载笔记)