ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

android逆向奇技淫巧二十五:x音另类抓包(十)

2022-03-26 22:33:57  阅读:520  来源: 互联网

标签:ssl RANDOM SSL client android CLIENT 抓包 奇技淫巧


  低版本x音client会验证server的证书,所以把抓包软件的证书安装在android系统后就可以冒充server欺骗client抓包了;但是后来的高版本libttboringssl.so中调用了SSL_CTX_set_custom_verify来设置server对client的验证,这下抓包软件就抓瞎了,因为不知道client的公钥,怎么在server面前冒充client了(当然也可以想办法在app中找到client的公钥,但肯定不轻松)?看雪有大佬通过hook或者直接硬编码把SSL_CTX_set_custom_verify第二个参数改为0,不让server验证client;同时把第三个参数回调函数的返回值也改成0来绕开验证的逻辑,这是非常好的一种思路!我这里根据tls原理、libssl.so或libttboringssl.so源码从其他角度抓包!

  1、(1)刚打开x音时,client和server要互相验明正身,由于抓包软件没有client的公钥,是没法在server面前冒充client的,这里只能罢了!client和server通信首要就是通过handshake协商出双方对称加密的key,后续一律通过对称加密通信!所以handshake阶段最重要的就是这个key了!有了这个key,后续一切通信的数据不就能解开了么?这个key怎么获取了?参考我上一篇文章https://www.cnblogs.com/theseventhson/p/16051195.html 介绍的frida脚本如下:

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')
)

  我hook的结果是抓了50多个key,部分key如下:

CLIENT_RANDOM 05c10ca9bfb225e24e5fc03fa6dfef05292ce52dab90edd39b20124fd9ce64db 8ea99a617f99e59e1676f26e7266725227d8305fbb48dd36fe91e0e9133b7de4efb28edeacd52d5a06a69d41c4c0d232
CLIENT_RANDOM 75c5363ef6dd0e8ed769bb61dd3b6440d01eb1aa61b52e57be780446281e7b5d c72ba6c9fe54f643d79e330fc83130cd24f88151ea5f2ca9462577cd2585d1a72edd3132010f0bcf675f1aaf9ac5bf94
CLIENT_RANDOM a67744ecb0afb61a70b41604e7e711f56042af51266e02d79d73f28563b2de84 1ab1a45ed5407307e545a47a88a39f2c533c3e5d4effcccdf4a72b12927442fe1b6feaa38063e7ada28a9ca2553e026c
CLIENT_RANDOM 64c75bc38d438669602690369f696df57349e66d5ee784a5e22b66b37f91bff6 f7008fac9daa766edcb636be5ebccc0c3dc3d73c119f39c38f9a7e89d54a508a9da9d96ea30d5b2745639ae275eb8d79
CLIENT_RANDOM b87890d1c9e17f6741985f7e42f96569df9a1153a19c215b107c19a088bec98d 4edec3ac50b381f67125da34014408b70b4c75973db6421fca3e0fde20c859187360e2c68b5efba493ea4efab78fe062
CLIENT_RANDOM bbebae8d1ec928eb785281d56baa50b38f41dd0e6848304af06f4227d1dd1f1c 33c9be07cfd31dbe6a77dfa2f89845f8cf72d1afa196d53bfc9c4bab3757b3b187f631d592e4ac7ec01fb29b87c2a1f5
CLIENT_RANDOM a0a78b7b2a4c100337cd6af637bf40af079ec6bd4f922a3bb1ffbf9f5f4e403b 5c9dd3e00dcac4838fefc498d29d445831e0b92af4480e0dc0815d85552c9f5452bef423a5481252d95066104ef597b1
CLIENT_RANDOM c4ec4ee28686ceb7d68c0c3c1262993848271f809ab3e0824043814e9fa49683 97f2510382981b51bdc3458bda2a0df1994039648ab5b6db9e3d131898952b0574d6772c90461161cc758453ab8e4e10
CLIENT_RANDOM 03572dfae7a9c42406b00d3a17443ed085b42f6094081b6ae951ae5f5a466019 84f2b4c3b08cb3b9335ba087e334fb92f01f0310a9547d220f18604e8e3b3d3780c62d1126ad586707f5fd5e3b6a03e2
CLIENT_RANDOM a190584887037a9deef70ee793ddc8876e379aa196d5c0298216370811c74824 91e661957726600703b2ac7580e0cdce16c135f8627fc1665fa436c4a2a7ea81a10ae55e9754fbc1896e90d4971ba050
CLIENT_RANDOM f379c78bd8efb66d6774cbafa7f7e4953c3d699c24a1cda0e2cfa72e122f9a67 22169928550d7daaf002eeb317de3aae816b2e1dc1b91839fe69f2385e367e39d8723548cfb1dada605c8e6a3d4f6fed
CLIENT_RANDOM 132fd7ae00fa066077d8d99306ee4f248391567fe0cb1edc8859308074361101 4017bee954c38afc02437b472e5c6a175043696cb9587f1680aff3a0c0d5d8d4ec178171e095d4f615a273a445020e0c

  key倒是有了,client和server之间通信的数据又怎么获取了?

  (2)前面提到了普通的抓包软件抓不了包,是因为client和server在应用层互相验证身份,导致charles、fiddler、burpsuit等应用层的抓包软件立马抓瞎!换个角度想:所有的数据肯定都是要通过网卡、wifi等硬件设备发送出去的,既然在应用层又验证无法抓包,为啥不通过“降维打击”的思路在更底层的传输层、ip等、链路层等抓包了?这里就要用到wireshark了!由于wireshark是底层抓包,所以完全不用给操作系统装任何证书,走的也不是“中间人攻击”的方式抓包,而是直接简单粗暴地从网卡拿frame数据!现在网络通信的数据确实拿到了,但应用层是加密的,这时就用到了上面的sslkey了!在wireshark的编辑->首选项->protocols->tls这里把上面hook得到的sslkey上传,如下:

    

   我这里的抓包结果(我用的是雷电模拟器):这个貌似是个图片

     

      这里不知道又从x音的cdn拿了啥:

    

   2、上述抓包需要先得到key,再用wireshark解析,各种操作较多,使用并不方便,还有另一种抓包方法:通信双方不是用tls协议通信么?既然数据是key加密的,在加密前hook总可以吧? 顺着这个思路去hook SSL_write(往外发送数据的)函数和SSL_read(接收外面数据)函数,还真能得到加密前的数据,我hook SSL_write部分结果如下:  

  (1) 这时get方法:

  

 

  (2)这是post方法:

        

 

   可以看出确实都是明文的!hook的脚本如下:

function SSL_hook() {
    if (!Java.available) {
        console.error('Java API not available');
        return;
    }
 
    Java.perform(function () {
        console.log('hooked');
        var SSL_write, SSL_read;
        //可查找当前已加载的共享库的导入与导出方法
        const apiResolver = new ApiResolver('module');
        apiResolver.enumerateMatches('exports:*lib*ssl*!SSL_*').forEach(function (v) {
            if (v.name.indexOf('SSL_write') > 0) {
                SSL_write = v.address;
                console.log('SSL_write:',SSL_write);
            } else if (v.name.indexOf('SSL_read') > 0) {
                SSL_read = v.address;
                console.log('SSL_read:',SSL_read);
            }
        });
 
        if (SSL_write) {
            Interceptor.attach(SSL_write, {
                onEnter: function (args) {
                    this.ssl = args[0].toString();
                    this.buf = ptr(args[1]);
                },
                onLeave: function (retval) {
                    const len = retval.toInt32();
                    if (len > 0) {
                        console.log('SSL_write\n', this.buf.readByteArray(len), '\n', '*'.repeat(120));
                        //send({code: 100,ssl: this.ssl}, this.buf.readByteArray(len));
                        // send({
                            // code: 100,
                            // ssl: this.ssl
                        // }, Memory.readByteArray(this.buf, len));
                    }
                }
            });
        }
 
        if (SSL_read) {
            Interceptor.attach(SSL_read, {
                onEnter: function (args) {
                    this.ssl = args[0].toString();
                    this.buf = ptr(args[1]);
                },
                onLeave: function (retval) {
                    const len = retval.toInt32();
                    if (len > 0) {
                        //console.log('SSL_read\n', this.buf.readByteArray(len), '\n', '*'.repeat(120));
                        //send({code: 200,ssl: this.ssl}, this.buf.readByteArray(len));
                        // send({
                            // code: 200,
                            // ssl: this.ssl
                        // }, Memory.readByteArray(this.buf, len));
                    }
                }
            });
        }
    });
}
 
function main() {
    SSL_hook();
}

setImmediate(main);

   注意:x音不同的版本貌似调用了libssl.so和libttboringssl.so,建议这两个不同的so都hook一下,看看都发了啥数据!

   

 

参考:

1、http://www.zhuoyue360.com/crack/73.html  android硬核抓包

2、https://bbs.pediy.com/thread-268014.htm 非标准sslpinning抓包

标签:ssl,RANDOM,SSL,client,android,CLIENT,抓包,奇技淫巧
来源: https://www.cnblogs.com/theseventhson/p/16059276.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有