从Android视角看数据爬虫

从Android视角看数据爬虫

简介

从Android客户端视角看数据爬虫,主要分为以下几个步骤
1、通过反编译等手段,hook住对应app的网络请求库,得到对应的URL
2、根据hook的点打印出当时的header和参数
3、模拟APP请求,发起对应的数据请求

如何实现

通过反编译和Hook获取url

这个爬虫的重点步骤,通过此步骤才能的到对应的URL,难易程度取决于APP对自己的保护程度。主要从以下几种情况来说明:


1、使用了OkHttp,但未自己进行封装或修改的:

直接通过hook OkHttp的addInterceptoer方法即可随意往里添加自己定义的interceptoer方法,由于此方法会将整个chain(请求链)作为参数,因此我们添加到最后即可获取所有的请求信息并打印出来。

现在大部分的私人app或者小公司app通过此方法即可轻松获取url、header和参数等信息。



2、使用了OkHttp,但对其中的实现进行了修改:

此情况如果没有混淆,可以找到修改后添加Interrupter的方法,并进行hook方法插入。其余同方案1。

如果混淆了,可以先找到添加Interrupter的方法,但过程比较麻烦,需要好很多经历。或同方案3.



3、对于自己封装或者对OkHttp修改比较大的,Android可以直接HOOK网络底层,直接hook到请求和数据返回的地方,获取对应的url和参数。

此方法比较麻烦,不同的Android版本,对于请求的封装并不相同。

使用XPosed来hook请求,获取URL和参数

hook到OkHttp的buid方法,然后将自定义的interceptor添加到interceptors中。

    XposedHelpers.findAndHookMethod(instanceClazz, "build", new XC_MethodHook() {
            @Override
            protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                super.beforeHookedMethod(param);
                synchronized (OkHttpHook.class){
                    if (hasHooked){
                        return;
                    }
                    hasHooked = true;
                    LOGGER.d("正在运行build方法,开始hook");
                    List interceptors = (List) XposedHelpers.getObjectField(param.thisObject, "interceptors");

                    if (interceptors != null){
                        //如果获取到了interceptors
                        LOGGER.d("interceptors = "+interceptors.size());
                        Object logInterceptor = getLoggingInterceptor();
                        if (logInterceptor != null){
                            //获取到了interceptor
                            LOGGER.d("获取到Log的interceptor");
                            interceptors.add(logInterceptor);
                        }
                        LOGGER.d("interceptors = "+interceptors.size());
                        LOGGER.e("has been hooked succeed!");
                    }
                }
            }

            @Override
            protected void afterHookedMethod(MethodHookParam param) throws Throwable {
                super.afterHookedMethod(param);
            }
        });

    /**
     * 获取jar包中的interceptor
     * @return
     */
    private Object getLoggingInterceptor() {
        String jarPath = FileUtils.PATH_FILE_DIR + File.separator + FileUtils.FILE_NAME_INTERCEPTOR;
        LOGGER.d("当前jarPath="+jarPath);
        File file = new File(jarPath);
        if (file.exists()){
            LOGGER.d("存在interceptor的jar文件");
        }
        DexClassLoader dexClassLoader = new DexClassLoader(jarPath, FileUtils.PATH_OUT_DIR, null, mClassLoader);
        try {
            mHttpLoggingInterceptor = dexClassLoader.loadClass("com.alzzz.interceptor.AlzInterceptor");
            mLoggerClass = dexClassLoader.loadClass("com.alzzz.interceptor.AlzInterceptor$Logger");
            if (mLoggerClass != null && mHttpLoggingInterceptor != null) {
                LOGGER.e("获取到jar包中的拦截器");
                return InitInterceptor();
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return null;
    }

具体的interceptor随自己心愿,想写什么写什么,类需要实现Interceptor接口,方法中可以获取chain对象,这个能做的事情就有很多了。拿到url和参数很轻松。

模拟请求,获取数据

使用第二步获取到的url和header及params,进行模拟数据请求。如果此时的request鉴权通过,即可绕过获取数据。

https证书问题

以上方案,除了模拟请求都可以完全绕过证书,不受证书控制。Android手机在root后使用XPose可以绕过证书鉴权,获取请求数据。

怎么防御

从客户端出发

1、监听进程,判断是否有Xpose的运行进程,如果有则直接弹出提示,不让对方使用。

现在市面上很多APP都做了这项处理,但是,不能完全防御,因为XPosed可以hook自己把自己进程也变了

2、加壳
使用第三代的加密方式,对自己的apk进行加密,大大加强反编译和hook难度。

XPosed可以hook到Android系统然后将转成的SO库从系统中导出出来,加大反编译成本,而且会替换掉部分代码,是的可读性更差。

3、使用更加恶心的混淆方式0o0o00这样的加密方式,大大降低可读性。

从Server出发

1、除了信安的鉴权方式外,为每个接口都增加业务鉴权。

对比与闲鱼,每次请求闲鱼会不断修改

wua=HHnB_xFKMPecU%2BxPA%2FNwVHVrwPQq7O83RzZawsAN%2FgEb2fGizfJ%2FWZU6SC%2BxxVPx4VI1K0noc2g8gpji27DUg9uleZNA169x2z8zyYSc8RaeBRaXSAszUK90P%2FI%2BkH5mVXD%2F%2B<br>
x-sign=ab23180010e22f50c705640041863ba451bb884b3cd0aad85f<br>

每次请求都会进行修改,这里就可以推断出,每次鉴权都会根据一个双方协定好的加密方式,对每次请求的唯一标示进行了加密。例如:


时间戳+用户id+关键某几个过程中不可修改的参数+私钥(或对称加密方式的随机串)



进行了一次加密。Server根据这次请求唯一的加密鉴权,确定是否返回数据。

成本:每次请求都需要进行加密串的生成,确认是对哪些参数进行加密。



2、如果请求就是从客户端发起的,直接是模拟的客户端真实的点击

该情况,很难避免,只能加大其成本,如果间隔频率太小的请求,划入到异常请求,如果达到某个量级则对deviceId进行封禁。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值