Xposed Framework使用方法以及SSL pinning绕过

0x00 上文

前一篇文章APK篡改以及SSL PINNING绕过介绍了使用APK篡改的方式绕过SSL pinning,本文则使用另一种思路,无需篡改APK,而是用hook绕过SSL pinning。

首先,测试一下SSLPinningExample在接入burp代理时是无法请求github的:在电脑上启动burp,在手机上启动ProxyDroid,然后打开SSLPinningExample,,点击test按钮,发现无法请求github。

为了能使SSLPinningExample在接入burp时也能请求github,我们需要用hook绕过SSL Pinning。

0x01 Xposed Framwork

先来学习一下如何使用Xposed Framework。

基本是按照这篇教学来的:
XposedBridge Development tutorial,但是这篇并不完整,要加上这篇:
Using the Xposed Framework API

特别要注意:

  1. dependencies要用provided而不是compile,否则会将XposedBridgeApi-54.jar编译到apk中,从而在运行中产生Class ref in pre-verified class resolved to unexpected implementation错误。
  2. XposedBridgeApi-54.jar要放在新建的lib目录下,不要放在默认的libs目录下,不然android studio仍然会把API编译到apk中,产生与上面相同的问题。

总结起来分为这么几步:

  1. 用Android Studio新建一个项目(假设命名为SSLHook),Minimum SDK选择API15,选择Add no Activity。
  2. 在app/src/main目录下新建assets文件夹,在该文件夹下新建xposed_init文件,在文件里添加如下语句

    com.example.xxx.sslhook.SSLHook

    (即包名和类名)

  3. 在app/src/main/下的AndroidManifest.xml配置成如下:

    <?xml version="1.0" encoding="utf-8"?>
    <manifest xmlns:android="http://schemas.android.com/apk/res/android"
        package="com.example.xxx.sslhook">
    
        <uses-sdk android:minSdkVersion="15"/>
    
        <application
            android:allowBackup="true"
            android:icon="@mipmap/ic_launcher"
            android:label="@string/app_name"
            android:supportsRtl="true"
            android:theme="@style/AppTheme">
    
            <meta-data
                android:name="xposedmodule"
                android:value="true" />
            <meta-data
                android:name="xposeddescription"
                android:value="Easy example which makes the status bar clock red and adds a smiley" />
            <meta-data
                android:name="xposedminversion"
                android:value="53" />
    
        </application>
    
    </manifest>
    

    主要注意三个meta-data的部分。

  4. 下载XposedBridgeApi,或者使用这个链接api-82.jar。在app/目录下新建lib目录,将XposedBridgeApi-54.jar拷贝到该目录下,sync gradle。

5. 在app/build.gradle里添加如下代码:

    repositories {
        jcenter();
    }

    dependencies {
        provided 'de.robv.android.xposed:api:82'
    }



dependencies可以和已有的合并。
  1. 在app/src/main/java/com.example.xxx.sslhook/下新建class,命名为SSLHook,添加如下代码:
    package com.example.xxx.sslhook;
    
    import java.io.InputStream;
    
    import de.robv.android.xposed.IXposedHookLoadPackage;
    import de.robv.android.xposed.XC_MethodHook;
    import de.robv.android.xposed.XC_MethodReplacement;
    import de.robv.android.xposed.XposedBridge;
    import de.robv.android.xposed.XposedHelpers;
    import de.robv.android.xposed.callbacks.XC_LoadPackage.LoadPackageParam;
    
    
    /**
     * Created by xxx on 2016/04/18.
     */
    public class SSLHook implements IXposedHookLoadPackage {
        public void handleLoadPackage(final LoadPackageParam lpparam) throws Throwable {
            /*
            if (!lpparam.packageName.equals("com.android.systemui"))
                return;
    
            findAndHookMethod("com.android.systemui.statusbar.policy.Clock", lpparam.classLoader, "updateClock", new XC_MethodHook() {
                @Override
                protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                    TextView tv = (TextView) param.thisObject;
                    String text = tv.getText().toString();
                    tv.setText(text + " :)");
                    tv.setTextColor(Color.RED);
                }
            });
            */
    
            /*
            if (!lpparam.packageName.equals("com.example.sslpinningexample"))
                return;
    
            XposedBridge.log("Loaded app: " + lpparam.packageName);
    
            try {
                XposedHelpers.findAndHookMethod("com.example.sslpinningexample.HttpClientBuilder.HttpClientBuilder", lpparam.classLoader, "pinCertificates", InputStream.class, char[].class, new XC_MethodHook() {
    
                    @Override
                    protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                        try {
                            XposedBridge.log("hooked");
                            param.setResult(param.thisObject);
                        } catch (Throwable v0) {
                            XposedBridge.log(v0);
                        }
                    }
                });
            } catch(Throwable e){
                XposedBridge.log("hook failed");
                XposedBridge.log(e);
            }
            */
    
    
    
            if (!lpparam.packageName.equals("com.example.sslpinningexample"))
                return;
    
            XposedBridge.log("Loaded app: " + lpparam.packageName);
    
            try {
                XposedHelpers.findAndHookMethod("com.example.sslpinningexample.HttpClientBuilder.HttpClientBuilder", lpparam.classLoader, "pinCertificates", InputStream.class, char[].class, new XC_MethodReplacement() {
                    @Override
                    protected Object replaceHookedMethod(XC_MethodHook.MethodHookParam methodHookParam) throws Throwable {
                        return methodHookParam.thisObject;
                    }
                });
            } catch (Throwable e){
                XposedBridge.log("hook failed");
                XposedBridge.log(e);
            }
    
    
        }
    }
    
  2. 编译生成apk,安装即可。

0x02 结果

最后来测试一下:在电脑上启动burp,在手机上打开XposedInstaller,把安装好的SSLHook模块勾选上,重启手机,打开ProxyDroid,打开SSLPinningExample,点击SSLPinningExample里的test按钮,发现能正常请求github了,成功!