当前位置:   article > 正文

xposed+justTrustme使用与分析

xposed+justtrustme

xposed+justTrustme使用与分析

有时候在测试APP抓取数据包,配置正常,网络也是正常的,但就是抓取不到数据包;这可能是APP做了证书验证,APP通过进行证书验证,判断当前手机是否开启了代理端口,判断当前网络环境是否是证书所允许;如果开启了代理,APP中的数据流量就不会通过代理端口,我们就抓取不到数据包了。这时我们可以使用一个框架组合来解决此问题:Xposed框架+justTrustme。

安装xposed和justTrustme

Xposed框架https://xposed.appkg.com/是一款可以在不修改APK的情况下影响程序运行(修改系统)的框架服务,可以基于它可以制作出许多功能强大的模块,且在功能不冲突的情况下同时运作。我们现在官网中下载xposed应用(也可以在github上面下载https://github.com/Fuzion24/JustTrustMe/releases/latest),直接安装到手机中,但有一个前提手机必须root,当然模拟器也是可以的,建议还是使用真机吧,有些APP对运行环境做了判断,在模拟器环境可能会直接闪退。

         在安装好xposed框架后,打开xposed应用,他会提示“xposed框架未安装”,就如他提示所言,这里安装需要重启。

         点击“确定”,开始安装。

         点击“install”,他会自动下载安装,下载速度根据网速而定。

         当你看到这个的时候,就是安装好了,接着就是重启手机了。

接下来就是安装可以禁止证书验证的模块,安好后就可以愉快的进行抓包了,比如说:justTrustmehttps://github.com/Fuzion24/JustTrustMe/releases),这个app下载之后,直接安装就行了;这个justTrustme是没有界面的,但手机会提示xposed模块没有激活;

      打开xposed中的模块,就可以按到安装好的justTrustme,只需要勾选上,然后重启手机就行了。

      接下来直接使用burpsuite或者其他抓包工具正常抓包就行了,justTrustMe会将APP中所有进行证书验证的方法都Hook,绕过所有证书验证达到可以正常抓包的效果。

 

分析justTrustme代码执行过程及原理:

      githubhttps://github.com/Fuzion24/JustTrustMe/releases/latest)上面下载justTrustme的源码,解压之后来分析一下源码写的什么。

先来看看justTrustme工程的主要结构,工程不大,主要的Hook代码将近500行,但是却导入了很多个包。

      先说说android逆向中有一个很重要的技术,xposedhook技术,现在我也是菜鸟;我就先从我所知道的来分析一下;所谓hook技术,hook即“钩子”,主要的作用就是在不修改目标程序的情况下融入到程序中,再找到程序中的某个函数,再将这个函数勾住,并对函数的参数进行修改,从而让程序得出我们要想要的结果。

在编写hook程序时,主要的文件有:

  1. HookFileName.java,这个文件中编写需要hook的主要方法,找到目标的包名,路径,函数,参数,并对参数进行操作;

2build.gradle,这个文件是对导入的lib依赖包进行导入声明;

3xposed_init,这个文件里面主要声明HookFileName.java的路径,让系统能够找到HookFileName.java在哪里,xposed_init文件必须在新建assests文件夹,并放在assests文件夹下面

4AndroidManifest.xml,这个xml文件是应用清单,主要配置当前程序是一个xposed模块,最低支持的lib版本,xposed模块描述;

5、最后就是libs文件夹里面导入第三方库的lib包“XposedBridgeApi”;

经过上面的描述我们可以从工程中的xposed_init文件中我们可以得知主要的hook代码是just.trust.me路径下面的Main.java

那先来看看导入的包,总共导入了45个包,我对导入的所有的包进行了查询,分别有androidjavaapache-httpclient,xposed;大家查看代码时可以根据以下导入包的描述来分析代码。

android

描述

android.content.Context;

有关应用程序环境的全局信息

android.net.http.SslError;

该类表示一组一个或多个SSL错误和关联的SSL证书。

android.util.Log;

用于发送日志输出的API。

android.webkit.SslErrorHandler;

表示处理SSL错误的请求。

android.webkit.WebView;

显示web页面的视图。

java

描述

java.io.IOException;

表示发生了某种类型的I/O异常。

java.net.Socket;

实现客户端套接字(也称为“套接字”)

java.net.UnknownHostException;

指示无法确定主机的IP地址。

java.util.ArrayList;

List 接口的大小可变数组的实现

java.util.List;

提供了一个可滚动的文本项列表。

java.security.SecureRandom;

加密的强随机数生成器

java.security.KeyStore;

密钥和证书的存储设施

java.security.KeyStoreException;

KeyStore 异常处理

java.security.cert.CertificateException;

各种证书问题处理

java.security.cert.X509Certificate;

此类提供了一种访问 X.509 证书所有属性的标准方式

java.security.KeyManagementException;

处理密钥管理的操作的通用密钥管理异常

java.security.NoSuchAlgorithmException;

当请求特定的加密算法而它在该环境中不可用时抛出此异常

java.security.UnrecoverableKeyException;

如果 keystore 中的密钥无法恢复,则抛出此异常

javax.net.ssl.HostnameVerifier;

主机名验证的基接口

javax.net.ssl.KeyManager;

JSSE 密钥管理器的基接口

javax.net.ssl.SSLContext;

表示安全套接字协议的实现,它充当用于安全套接字工厂或 SSLEngine 的工厂

javax.net.ssl.TrustManager;

JSSE 信任管理器的基接口

javax.net.ssl.X509TrustManager;

管理使用哪一个 X509 证书来验证远端的安全套接字

Apache httpclient

描述

org.apache.http.conn.ClientConnectionManager;

客户端连接的管理接口

org.apache.http.conn.scheme.HostNameResolver;

主机名到IP地址解析器

org.apache.http.conn.scheme.PlainSocketFactory;

用于创建未加密套接字的默认类。

org.apache.http.conn.scheme.SchemeRegistry;

一组受支持的协议方案

org.apache.http.conn.scheme.Scheme;

封装协议,如“http”或“https”

org.apache.http.conn.ssl.SSLSocketFactory;

用于TLS/SSL连接的分层套接字工厂

org.apache.http.impl.client.DefaultHttpClient;

为大多数常见的使用场景预先配置HttpClient的默认实现。

org.apache.http.impl.conn.SingleClientConnManager;

用于单个连接的连接管理器

org.apache.http.impl.conn.tsccm.ThreadSafeClientConnManager;

管理一个OperatedClientConnection池,并能够为来自多个执行线程的连接请求提供服务

org.apache.http.params.HttpParams;

这个接口表示HTTP协议参数的集合

xposed

描述

de.robv.android.xposed.IXposedHookLoadPackage;

当应用程序(“Android包”)加载时得到通知。

de.robv.android.xposed.XC_MethodHook;

钩子方法的回调类。

de.robv.android.xposed.XC_MethodReplacement;

XC_MethodHook的一个特殊情况,它完全替换了原来的方法。

de.robv.android.xposed.callbacks.XC_LoadPackage.LoadPackageParam;

包装正在加载的应用程序的信息。

de.robv.android.xposed.XposedHelpers.callMethod;

调用给定对象的实例或静态方法。

de.robv.android.xposed.XposedHelpers.callStaticMethod;

调用给定类的静态方法。

de.robv.android.xposed.XposedHelpers.findAndHookConstructor;

查找构造函数并将其挂钩。

de.robv.android.xposed.XposedHelpers.findAndHookMethod;

查找一个方法并将其挂钩。

de.robv.android.xposed.XposedHelpers.getObjectField;

返回给定对象实例中对象字段的值

de.robv.android.xposed.XposedHelpers.newInstance;

创建给定类的新实例。

de.robv.android.xposed.XposedHelpers.setObjectField;

设置给定对象实例中的对象字段的值。

de.robv.android.xposed.XposedHelpers.findClass;

使用指定的类装入器查找类。

 

现在我们看看这个Main.java中几个有代表性的代码。

程序首先实现了一个接口类IXposedHookLoadPackage,这个是编写xposed模块必须的,接下来程序定义一个“currentPackageName”获取当前APP包名的变量,以此获取目标APP包名;使用handleLoadPackage方法获取APP的包名,并将APP包名赋值给currentPackageName变量,输出运行日志,findAndHookConstructor获取当前运行的APP的结构,并勾住它,得到HTTP默认的请求方法,并对APP中默认的HTTP请求参数进行修改。

      在上面的方法中的72行调用了一个方法setObjectField(param.thisObject, "connManager", getSCCM());其中getSCCM()方法替换了APP原来的HTTP默认的请求方法;自定一个getSCCM方法来获取证书和秘钥,初始化拉一个trustStore,使用这个trustStore进一步生成TrustManager来验证,先关闭主机验证,默认允许所有主机连接,重新设置连接协议,端口,最后返回一个自定义的连接管理器。

      Main.java91行直接获取了APP的默认请求方式,连接管理,接着获取http连接的第一个参数,赋值给params,依次设置对象域替换了原来的证书。

      在上面的99行调用了一个getCCM()方法,此方法用于判断连接对象中是否有SingleClientConnManagerThreadSafeClientConnManager这两个方法,如果有则依次返回相应的方法运行结果,如果都没有则返回null

 

      Main.java105行是hook了一个SSLSocketFactory方法;获取这个方法的参数,证书,安全随机数,主机IP;接下来创建相对应的参数并赋值,判断方法里面的证书是否存在,将证书和秘钥赋值给keymanagers,自定义重新创建信任管理,并重新设置了对象域,简单的说就是它自定义了SSLSocketFactory 方法绕过校验。

      Main.javahook SSLSocketFactory方法时调用了431行的ImSureItsLegitTrustManager,这里自定义一个接受任意证书的信任管器,可以接受所有的任意客户端和服务器的证书,以此来替换了原来的TrustManager,就达到了绕过校验。

      Main.java中的158行,hook一个TrustManagerFactory,修改APP中存在的信任管理器;先找到一个TrustManagerFactory的类,获取加载类,获取里面的一个getTrustManagers方法名,判断TrustManagerImpl是否存在,如果存在,将TrustManagerImpl和类加载器赋值一个class对象,接着创建一个信任管理器接口对象,又判断如果managers大于0并且cls中的信任管理不为空就直接返回,跳出这个方法,最后设置一个自定义的信任管理器。

      158行的方法中调用了一个hasTrustManagerImpl,这里的方法就是在判断目标APP中是否有TrustManagerImpl类存在,存在返回true,不存在返回false

      Main.java216行,hook了一个android.webkit.WebViewClient方法类,先获取方法类android.webkit.WebViewClient,找到onReceivedSslError函数,获取webview参数,SslErrorHandlerSslError,再使用替换方法,让onReceivedSslError忽略ssl错误,继续加载页面就可以绕过ssl校验了。

 

Main.java237行,代码hook一个android.app.Application类,findAndHookMethod找到这个类,获取里面的attach方法名,和一个Context参数,接着获取第一个参数赋值给自定义的context,在将第一个参数加载类方法传递到processOkHttp函数中进行执行。

      processOkHttp函数在347行开始,在使用第三方库OkHttp 中进行 SSL 证书校验情况下,根据不同的情况分4中情况依次进行了try-catch,第一个try-catch过程为加载类com.squareup.okhttp.CertificatePinner,然后找到方法com.squareup.okhttp.CertificatePinner,获取里面的check方法,及参数,接着替换check的结果返回true;这里是因为通过 CertificatePinner 进行连接的 okhttp,在连接之前,会调用其 check 方法进行证书校验,那就直接返回true就绕过了校验。

第二个try-catch中是okhttp3,思路是一样的只不过这里调用的是CertificatePinner,连接前会调用check 方法进行证书校验,索性直接返回true就可以绕过。

      接着是第三个try-catch,这里先依次找到okhttp3.internal.tls.OkHostnameVerifier类,再获取类中的verify方法,返回true;这是因为Okhttp3 中如果不指定 HostnameVerifier,会直接调用的OkHostnameVerifier 里面的verify方法进行服务器主机名校验,可以直接返回true绕过校验;

      最后是第四个try-catch,这里也是先依次找到okhttp3.internal.tls.OkHostnameVerifier类,再获取类中的verify方法,这里校验的是证书,也可以直接返回true,然后就绕过校验了;

      Main.java的最后一个hook方法先判断TrustManagerImpl信任管理是否存在,接着找到类com.android.org.conscrypt.TrustManagerImpl进行hook,找到里面的checkServerTrusted方法,获取证书参数,接着使用hook的替换方法,新建一个X509CertificateArrayList表并赋值给list,最后返回这个list。这里通过直接获取X509Certificate证书绕过证书认证,这也是通过替换了TrustManager绕过了校验。

      经过分析以上几个绕过证书校验的函数,可以知道JustTrustMe 是将 APP 中所有用于校验SSL证书的方法类进行Hook,有的是替换,有的是忽略证书错误,有的是直接返回true绕过证书校验。在xposed中可不仅仅只有justTrustme可以绕过证书验证,还有SSLkillersslunpinning也可以绕过证书验证,有机会的话都可以下载安装使用。

      最后,需要保证APP的数据传输安全,需要对APP进行加固,传输过程中对传递的数据进行加密,使用https协议进行传输。

 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/440504
推荐阅读
相关标签
  

闽ICP备14008679号