易语言服务端与客户端怎么传送_一个关于客户端与服务端传送密钥的测试

c027fc9865799281bb52a5496dc604b4.png

先看两段代码:

13ef4a20e32e7e6339ce9d1cdc842da1.png

54942d3ec7afabb1200d0357f8d22ecc.png

这两段代码大概意思就是本地随机生成一个AES的密钥a,然后使用硬编码在代码中的字符串来生成RSA公钥,最后再使用生成的公钥对这个AES密钥a进行加密,这样对称加密的密钥a就可以安全传输了。

当客户端和服务端进行通讯时,客户端使用这个密钥a对明文进行加密,同时再使用公钥加密密钥a进行安全传输,服务器收到密文和加密后的密钥a之后,先使用私钥解密得到密钥a,再使用密钥a解密密文,这样即可正确解密服务端传送的数据。

看似是这么回事,我们使用Frida来Hook一下这个随机产生AES密钥的方法,得到随机生成的密钥,之后抓包,把Hook出来的密文拿来解密,验证一下我们的方法~

Hook代码如下,这里依旧添加了SSL pinning绕过的脚本代码,免得抓包失败:

Java.perform(function () {    var SecurityKeys = Java.use("com.platform.usercenter.common.security.SecurityProtocolManager$SecurityKeys")    SecurityKeys.$init.implementation = function () {        this.$init();        console.log("=================")        console.log(this.mAES.value)        console.log("=================")    }    SecurityKeys.decrypt.implementation = function (str) {        console.log("-----------")        console.log(str)        console.log("-----------")    }    console.log('')    console.log('===')    console.log('* Injecting hooks into common certificate pinning methods *')    console.log('===')    var X509TrustManager = Java.use('javax.net.ssl.X509TrustManager');    var SSLContext = Java.use('javax.net.ssl.SSLContext');    // build fake trust manager    var TrustManager = Java.registerClass({        name: 'com.sensepost.test.TrustManager',        implements: [X509TrustManager],        methods: {            checkClientTrusted: function (chain, authType) {            },            checkServerTrusted: function (chain, authType) {            },            getAcceptedIssuers: function () {                return [];            }        }    });    // pass our own custom trust manager through when requested    var TrustManagers = [TrustManager.$new()];    var SSLContext_init = SSLContext.init.overload(        '[Ljavax.net.ssl.KeyManager;', '[Ljavax.net.ssl.TrustManager;', 'java.security.SecureRandom'    );    SSLContext_init.implementation = function (keyManager, trustManager, secureRandom) {        console.log('! Intercepted trustmanager request');        SSLContext_init.call(this, keyManager, TrustManagers, secureRandom);    };    console.log('* Setup custom trust manager');    // okhttp3    try {        var CertificatePinner = Java.use('okhttp3.CertificatePinner');        CertificatePinner.check.overload('java.lang.String', 'java.util.List').implementation = function (str) {            console.log('! Intercepted okhttp3: ' + str);            return;        };        console.log('* Setup okhttp3 pinning')    } catch(err) {        console.log('* Unable to hook into okhttp3 pinner')    }    // trustkit    try {        var Activity = Java.use("com.datatheorem.android.trustkit.pinning.OkHostnameVerifier");        Activity.verify.overload('java.lang.String', 'javax.net.ssl.SSLSession').implementation = function (str) {            console.log('! Intercepted trustkit{1}: ' + str);            return true;        };        Activity.verify.overload('java.lang.String', 'java.security.cert.X509Certificate').implementation = function (str) {            console.log('! Intercepted trustkit{2}: ' + str);            return true;        };        console.log('* Setup trustkit pinning')    } catch(err) {        console.log('* Unable to hook into trustkit pinner')    }    // TrustManagerImpl    try {        var TrustManagerImpl = Java.use('com.android.org.conscrypt.TrustManagerImpl');        TrustManagerImpl.verifyChain.implementation = function (untrustedChain, trustAnchorChain, host, clientAuth, ocspData, tlsSctData) {            console.log('! Intercepted TrustManagerImp: ' + host);            return untrustedChain;        }        console.log('* Setup TrustManagerImpl pinning')    } catch (err) {        console.log('* Unable to hook into TrustManagerImpl')    }    // Appcelerator    try {        var PinningTrustManager = Java.use('appcelerator.https.PinningTrustManager');        PinningTrustManager.checkServerTrusted.implementation = function () {            console.log('! Intercepted Appcelerator');        }        console.log('* Setup Appcelerator pinning')    } catch (err) {        console.log('* Unable to hook into Appcelerator pinning')    }});

Hook结果:

5d69922c10c0858d6d6b798e87d2e1b9.png

密钥如上图第一列,下面那一大坨就是Hook到的密文,接下来用代码解密试试看(解密方法是我直接从反编译的源码里面抠出来的~):

ebd4e0a4b09edbb48f05950d7f7119d3.png

成了......

值得一说的是上面Hook构造函数的地方,我想Hook的是AES密钥,这个密钥是类内静态类的成员变量,如下:

de39ab425ef40b6b9e0180ab4c2318cf.png

Java的内部类名字一般就是OuterClass$InnerClass,所以代码应该这样写:

var SecurityKeys = Java.use("com.platform.usercenter.common.security.SecurityProtocolManager$SecurityKeys")

如果是匿名内部类,那类名一般就是OuterClass$1、$2、$3一直往下走,而我选择在构造方法执行时Hook这个成员变量的值,这时候就需要注意一点,我们在编写Hook脚本的时候,一定要调用一下它本身的构造方法,我是这样写的:

SecurityKeys.$init.implementation = function () {    this.$init();    console.log("=================")    console.log(this.mAES.value)    console.log("=================")    }

如果构造方法有参数,我们想看传入参数是啥,那就先输出参数,最后return this.$init(参数),也就是说对于构造方法类的Hook行为,我们最终一定要执行原本的init方法,否则会导致原程序无法正常运行,这时候Frida不一定会报错,但是你的目标Apk肯定没法正常执行了,我的就会显示这个:

99510d944c22534d929358446c340cac.png

同时,Hook到的东西是null:

394cb1896b9c8e3b17aa069035283af1.png

觉得好看的铁铁们可以关注一哈:

d1687d3db3e62a5d76fb7910f9d07f2d.png

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值