首页
社区
课程
招聘
2
[原创]实现frida版的JustTrustMe(二)用frida实现JustTrustMe
发表于: 2021-5-7 10:53 13541

[原创]实现frida版的JustTrustMe(二)用frida实现JustTrustMe

2021-5-7 10:53
13541

前言

有了上一篇JustTrustMe源码解读作铺垫,下面我讲解用frida实现JustTrustMe就很容易了。但是还是有些难点,比如JustTrustMe中有一些自定义的类和方法。那到底如何用frida的方式来实现自定义的类和方法?

怎么实现JustTrustMe自定义类和方法问题

自定义类虽然在frida语法中可以用registerClass的方式实现,但是由于类太复杂。我们可以把实现好的java代码打包成dex然后inject到目标进程中再跑hook脚本。

 

梳理JustTrustMe Main.java中内部类有如下3个:

1. ImSureItsLegitTrustManager

2. ImSureItsLegitHostnameVerifier

3. TrustAllSSLSocketFactory

直接用java实现上面三个类

同学们要对技术要有自己的判断力,虽然frida有registerClass让你用js语法定义一个类这样的功能。但是,这只是frida的附属价值。你看到这样的技术,了解一下就得了。不用学它,浪费精力!frida的openClassFile摆在那里让你可以注入dex,你居然还用registerClass。那你跟放弃用计算器,手动算数有什么区别?有什么本质的提高吗?并没有,还JB浪费时间。别人在进步,你在原地踏步!
IDA和GDB都说自己反汇编,哪个更好你没点B数吗?
Java和C++都说自己是面向对象,面向对象封装性哪个更好你没点B数吗?

1. ImSureItsLegitTrustManager实现

2. ImSureItsLegitHostnameVerifier实现

3. TrustAllSSLSocketFactory实现

Helper类实现

除了以上3个类,JustTrustMe还有几个静态方法需要我们实现。可以说上面几个类,最终都是通过这几个方法使用的。比如getSCCM()、getEmptySSLFactory()、getCCM()等
我们还是用Java直接实现,那么这些方法。

打包dex

关于怎么打包涉及到一些技术细节,暂时不便透露。感兴趣的朋友可以去https://github.com/CreditTone/hooker看我的radar.dex里面有所有打包好的代码。

 

 

现在JustTrustMe除hook逻辑之外的所有自定义类和方法我们现在全部搞定了。我们可以正式开始用frida来实现JustTrustMe所有hook点了。

用frida实现JustTrustMe的hook点

我们还是按上一篇《实现frida版的JustTrustMe(一)JustTrustMe官方源码学习》的源码解读顺序来逐一实现。为了让大家更容易理解,我不贴JustTrustMe的代码了。我贴每个hook点的伪代码,然后跟上frida的实现。这样大家会理解的清晰一点。

1、DefaultHttpClient的3个构造方法hook

上节分析:三个构造方法的目的都是在new DefaultHttpClient之后替换connManager参数。而getSCCM()方法就是返回一个不安全的ClientConnectionManager。

JustTrustMe实现的伪代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
public DefaultHttpClient(final ClientConnectionManager conman, final HttpParams params) {
    super(getCCM(conman, params), params);
}
 
 
public DefaultHttpClient(final HttpParams params) {
    super(getSCCM(), params);
}
 
 
public DefaultHttpClient() {
    super(getSCCM(), null);
}

frida的实现如下:

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
Java.perform(function() {
    var Helper = Java.use("gz.justtrustme.Helper");
    var DefaultHttpClientClass = Java.use("org.apache.http.impl.client.DefaultHttpClient");
    //被强奸的构造方法
    var DefaultHttpClientClassRapeConstructor = DefaultHttpClientClass.$init.overload('org.apache.http.conn.ClientConnectionManager', 'org.apache.http.params.HttpParams');
    DefaultHttpClientClassRapeConstructor.implementation = function(v0, v1) {
        //被强奸的构造方法被调用的话,我们替换调ClientConnectionManager参数为我们的
        var returnObj = DefaultHttpClientClassRapeConstructor.call(this, Helper.getCCM(v0, v1), v1);
        console.log("org.apache.http.impl.client.DefaultHttpClient.$init('org.apache.http.conn.ClientConnectionManager', 'org.apache.http.params.HttpParams') was hooked!");
        return returnObj;
    };
    var DefaultHttpClientClassInit_1602 = DefaultHttpClientClass.$init.overload();
    DefaultHttpClientClassInit_1602.implementation = function() {
        //使用DefaultHttpClientClassRapeConstructor强奸它
        var returnObj = DefaultHttpClientClassRapeConstructor.call(this, Helper.getSCCM(), null);
        console.log("org.apache.http.impl.client.DefaultHttpClient.$init() was hooked!");
        return returnObj;
    };
    var DefaultHttpClientClassInit_1603 = DefaultHttpClientClass.$init.overload('org.apache.http.params.HttpParams');
    DefaultHttpClientClassInit_1603.implementation = function(v0) {
        //使用DefaultHttpClientClassRapeConstructor强奸它
        var returnObj = DefaultHttpClientClassRapeConstructor.call(this, Helper.getSCCM(), v0);
        console.log("org.apache.http.impl.client.DefaultHttpClient.$init('org.apache.http.params.HttpParams') was hooked!");
        return returnObj;
    };
    //以上DefaultHttpClient的三个构造方法逻辑全部被我们用frida的方式替换了
}

2、X509TrustManagerExtensions的checkServerTrusted方法hook

上节分析:X509TrustManagerExtensions原方法会进行一系列的效应证书和服务器是否可信。这里xposed用了XC_MethodReplacement直接替换方法的执行体。

JustTrustMe实现的伪代码:

1
2
3
public List checkServerTrusted(X509Certificate[] chain, String authType, String host) throws CertificateException {
        return chain;
}

frida的实现如下:

1
2
3
4
5
6
7
8
Java.perform(function() {
    var X509TrustManagerExtensionsClass = Java.use('android.net.http.X509TrustManagerExtensions');
    var X509TrustManagerExtensionsClassCheckServerTrusted = X509TrustManagerExtensionsClass.checkServerTrusted.overload('[Ljava.security.cert.X509Certificate;', 'java.lang.String', 'java.lang.String');
    X509TrustManagerExtensionsClassCheckServerTrusted.implementation = function(certsArr, v1, v2) {
        console.log("android.net.http.X509TrustManagerExtensions.checkServerTrusted('[Ljava.security.cert.X509Certificate;', 'java.lang.String', 'java.lang.String') was hooked!");
        return certsArr;
    };
}

3、NetworkSecurityTrustManager的checkPins方法hook

上节分析:原NetworkSecurityTrustManager类的checkPins方法List参数原型是List。校验X509Certificate集合是否合法,如果不合法就会抛CertificateException。这里xposed用了XC_MethodReplacement直接替换方法的执行体,并且什么都没做。

JustTrustMe实现的伪代码:

1
2
3
private void checkPins(List chain) throws CertificateException {
    //什么都不做
}

frida的实现如下:

1
2
3
4
5
6
7
8
Java.perform(function() {
    var NetworkSecurityTrustManagerClass = Java.use('android.security.net.config.NetworkSecurityTrustManager');
    var NetworkSecurityTrustManagerClassCheckPins = NetworkSecurityTrustManagerClass.checkPins.overload('java.util.List');
    NetworkSecurityTrustManagerClassCheckPins.implementation = function(v0) {
        //什么都不做
        console.log("android.security.net.config.NetworkSecurityTrustManager.checkPins('java.util.List') was hooked!");
    };
}

4. SSLSocketFactory的6参构造方法

上节分析:这个稍微有点复杂,但目的很简单。就是为了替换TrustManager,而TrustManager不可以直接传进来,是内部创建一个sslcontext来包装一个TrustManager[]。所以要new一个自定义的sslcontext然后把ImSureItsLegitTrustManager传进去。sslcontext对象要进行init()所以整个代码看起来比较多。

JustTrustMe实现的伪代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
public SSLSocketFactory(
        String algorithm,
        final KeyStore keystore,
        final String keystorePassword,
        final KeyStore truststore,
        final SecureRandom random,
        final HostNameResolver nameResolver)
        throws NoSuchAlgorithmException, KeyManagementException, KeyStoreException, UnrecoverableKeyException
    {
        super();
        if (algorithm == null) {
            algorithm = TLS;
        }
        KeyManager[] keymanagers = null;
        if (keystore != null) {
            keymanagers = createKeyManagers(keystore, keystorePassword);
        }
        TrustManager[] trustmanagers = new TrustManager[]{new ImSureItsLegitTrustManager()};;//这里被替换了,就这么简单
        this.sslcontext = SSLContext.getInstance(algorithm);
        this.sslcontext.init(keymanagers, trustmanagers, random);
        this.socketfactory = this.sslcontext.getSocketFactory();
        this.nameResolver = nameResolver;
    }

frida的实现如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
Java.perform(function() {
    var Helper = Java.use("gz.justtrustme.Helper");
    //替换trustmanagers参数
    var SSLSocketFactory = Java.use('org.apache.http.conn.ssl.SSLSocketFactory');
    var SSLSocketFactoryRapeConstructor = SSLSocketFactory.$init.overload('java.lang.String', 'java.security.KeyStore', 'java.lang.String', 'java.security.KeyStore', 'java.security.SecureRandom', 'org.apache.http.conn.scheme.HostNameResolver');
    SSLSocketFactoryRapeConstructor.implementation = function(v0, v1, v2, v3, v4, v5) {
        var returnObj = SSLSocketFactoryRapeConstructor.call(this, v0, v1, v2, v3, v4, v5);
        console.log("org.apache.http.conn.ssl.SSLSocketFactory.$init('java.lang.String', 'java.security.KeyStore', 'java.lang.String', 'java.security.KeyStore', 'java.security.SecureRandom', 'org.apache.http.conn.scheme.HostNameResolver') was hooked!");
        if (Helper.reInitSSLSocketFactory(returnObj, v0, v1, v2, v3, v4, v5)) {
            console.log("替换trustmanagers参数成功!");
        }else{
            console.log("替换trustmanagers参数失败!");
        }
        return returnObj;
    };
}

5. SSLSocketFactory的getSocketFactory方法

分析:逻辑过于简单,不解释了

JustTrustMe实现的伪代码:

1
2
3
4
public static SSLSocketFactory getSocketFactory() {
    //return NoPreloadHolder.DEFAULT_FACTORY;
    return new SSLSocketFactory();
}

frida的实现如下:


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

最后于 2021-5-7 10:54 被爬虫不看学历编辑 ,原因:
收藏
免费 2
支持
分享
赞赏记录
参与人
雪币
留言
时间
PLEBFE
为你点赞~
2023-1-13 11:39
ericyudatou
为你点赞~
2021-5-7 13:00
最新回复 (12)
雪    币: 142
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
2
期待大佬新作,逆向武功打穿看雪。
2021-5-7 11:01
1
雪    币: 268
活跃值: (1066)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
期待大佬新作,逆向武功打穿看雪。
2021-5-7 11:09
0
雪    币: 831
活跃值: (2830)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
4

************

最后于 2021-5-7 11:54 被kanxue编辑 ,原因: 就事论事,勿人身攻击!
2021-5-7 11:25
0
雪    币: 657
活跃值: (1882)
能力值: ( LV2,RANK:15 )
在线值:
发帖
回帖
粉丝
5


有威胁、恐吓行为的,尚未构成犯罪的,会被公安机关处五日以下拘留或者五百元以下罚款;情节较重的,处五日以上十日以下拘留,可以并处五百元以下罚款。

最后于 2021-5-7 11:35 被ogli324编辑 ,原因:
2021-5-7 11:29
0
雪    币: 2097
活跃值: (1727)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
https://blog.csdn.net/tl3shi/article/details/112001225 这个自述就是大佬吗?
2021-5-7 11:31
0
雪    币: 1228
活跃值: (503)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
期待大佬新作,逆向武功打穿看雪。
2021-5-7 11:40
0
雪    币: 3110
活跃值: (4257)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8

2021-5-7 11:47
0
雪    币: 831
活跃值: (2830)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
9
丶咖啡猫丶 https://blog.csdn.net/tl3shi/article/details/112001225 这个自述就是大佬吗?
@咖啡猫 不是
2021-5-7 11:48
0
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
10
爬虫不看学历 有一天我看见他,我一定会卸他几个手指头
届时务必直播
2021-5-7 11:53
0
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
11
2021-5-7 12:11
0
雪    币: 13
活跃值: (16)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12

恭喜大佬炒作成功

最后于 2021-5-7 13:31 被网络小男孩编辑 ,原因:
2021-5-7 13:30
0
雪    币: 1122
活跃值: (1938)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
13
郭钟哥哥yyds
2021-5-7 16:12
0
游客
登录 | 注册 方可回帖
返回

账号登录
验证码登录

忘记密码?
没有账号?立即免费注册