Charles抓取HttpClient的包

前因

这几天在尝试写另一个xposed模块,本以为是很简单的一个项目,可经过一天的研究后发现,是自己太天真了,还是要通过抓取数据包才能彻底完成这个功能。所以又又又玩起了抓包操作。

抓包工具当然还是我最喜欢的Charles,说实话我都没考虑过其他的抓包工具。

本以为这项工作很简单,毕竟我在这方面都是老手了,也抓过不少APP的包,甚至是一些需要验证证书的APP的数据都能够抓到,这个APP应该也蛮简单才对。

可当我设置好一切后,却发现怎么也抓不到,当时我都懵逼了,再三下拉刷新数据,数据是正常加载的,只是Charles上怎么都没有数据请求的信息出现,wtf?

我寻思自己也没配置错误啊,而且其他的数据倒是可以正常抓取,HTTPS的也不例外,哪怕是酷安这个需要验证证书的APP也都抓到了,怎么这货还抓不到包呢?

难不成用了其他的通讯协议,比如socket?

没道理,这种小型APP在选择网络通讯框架的时候,几乎只有HTTP这条路可以走,顶多来个HTTPS增加一下安全性,不至于大费周章用其他的方式进行通讯。

解包看的时候,发现这个APP用了cz.msebera.android.httpclient 这个网络库,一看有点陌生,毕竟我是OKhttp的忠实用户,这个网络库应该是很老的吧。

然后去查了下自己想要hook的APP,发现这个APP居然从3.0开始支持,果然这个网络框架很老了,可能好几年都没有更换或是更新过了。又去Google了下这个类库,发现版本少得可怜,最新的更新似乎在2016年。

后来无意间找到这篇文章,里面提到flutter的httpclient似乎默认不走系统的代理,所以只能通过内置代码设置代理或是通过PC共享热点然后用wireshark来抓包才能抓到数据。

后者我试过了,发现一样抓不到,无奈之下只能尝试前者,给它手动设置代理。

可要怎么设置呢?

解决方案

修改APP代理

上面我也说了,似乎只能手动在代码里设置代理,才能成功通过Charles抓到包的样子。所以一切的重点都放在了如何设置代理上。

虽然这些看上去很扯,但xposed是可以做到的,只是要在哪里做才好。

毕竟代码都被混淆了,面对全部被改成abcd的class和method,我是真的认输也认怂。

于是我改变主意,从这个网络框架入手,如果不能在使用的地方改,那我就直接改这个网络框架,在它实例化的时候,找到设置代理的那个class,对它的构造方法进行更改。但是APP内的网络框架包是被混淆过的,我就找了个网络上的版本进行查看,发现在cz.msebera.android.httpclient 下有个HttpHost类,它就是负责设置代理的class,查看源码得知它的构造方法里就需要传入代理域名以及代理端口,所以我对这个构造方法进行了hook,代码如下。

XposedHelpers.findAndHookConstructor(CLASS, lpparam.classLoader, String.class, int.class, String.class, new XC_MethodHook() {
            @Override
            protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
                super.beforeHookedMethod(param);

//                String h= (String) param.args[0];
//                int p= (int) param.args[1];

                param.args[0]="192.168.0.6";
                param.args[1]=9001;

//                XposedBridge.log("host---->>>"+h);
//                XposedBridge.log("port---->>>"+p);


            }
        });

由此我得知这个APP的代理域名以及代理端口。因为这是个在构造方法之前就hook的操作,所以还可以直接对传入构造方法的两个参数进行修改,于是将其改为我电脑的IP以及Charles反向代理的本地端口,至于这个本地端口,下面的Charles配置会提到,稍安勿躁。

hook完成后,APP修改完成。

PC端Charles配置

虽然APP修改好了,但主角还是Charles。一如既往的,Charles需要安装证书,毕竟是要抓取HTTPS数据,如果之前已经安装过了,则可以跳过这步。

然后在Charles菜单里点击proxy,Reverse Proxies

alt

点击后看到如下图

alt

点击上面的Enable Reverse Proxies,再点击下面的Add,添加一个新的反向代理,如下所示

alt

其中,最上面的是local port,表示本地APP访问的端口,这个跟我修改的APP代理端口保持一致,我修改里填的是9001,所以这里也要填9001。

第二个Remote Host是远程服务器域名,这个就是APP没被我修改之前获取的域名,我这里不方便透露,如果你遇到了跟我类似的情况,就填写你自己获得的域名。

最后一个是远程端口,这个也是要填写没被修改过的端口,没被修改过的端口之前是443,所以我这里填写443,如果你获取到的是其他的端口,请按实际情况填写。不过我认为一般都是443。

填写完成后点击OK,再点OK即可。

如果你发现提示出错,则应该是端口被占用,那就换一个别的本地端口,比如我之前填写的是8888,也就是代理监听的端口,所以报错了,赶紧改了个9001,这才恢复。

填写好以后,要保证这个Reverse Proxies在菜单里是被勾选上的。

alt

之后把macOS Proxy这个选项的勾给去掉,不然将无法获取数据。另外手机也不用再设置代理,因为代码里设置上了代理。

现在,打开需要抓包的APP,看看有没有自己想要的数据吧!

为什么

我将此事与一好友提及后,他一直在询问我为什么APP里设置了代理,就不走系统代理了呢?

我刚刚的思绪也很混乱,一时间没能整理好,但现在我整理好了,容我上张图。

alt

这是一般APP的访问网络数据操作,在手机系统没设置代理的情况下是这样的,如果手机系统有设置代理,那么将会是这样的

alt

这个大概是一般使用Charles的状态,通过系统代理将数据传给Charles了。

而现在我遇到的情况是这样的

alt

由于这个APP自己设置了一个代理,自己从代理服务器上获取数据,系统就不会再给这个APP走代理通道,而是直连远程代理了,相当于系统检测到APP有了代理后,不愿再给这个APP配置代理。

这种情况下,我没能抓到包也就可以解释清楚了。

所以我干了一件事,修改这个APP的代理,如图

alt

如此一来,便解决了这个APP无法抓包的问题。

当然有人会问我为什么不用手机的抓包工具操作,比如HttpCanary,为什么要那么麻烦。

我说我喜欢你会信吗?

开玩笑,最主要还是,这个APP还真是挑起了我抓包的欲望,仅此而已。

暂无评论
发表新评论