安卓抓包总结

1.大纲

主要是从几个点来了解安卓APP通用的解决办法:

  • wifi代理抓包
  • vpn抓包
  • 客户端ssl验证解决方案
  • 服务器ssl验证解决方案
  • 双向ssl验证
  • 非http协议抓包
  • 自有的ssl验证协议

1.wifi代理抓包

当我们准备抓一个app的时候,第一件事肯定是抓包。传统的抓包解决方案是电脑安装Fiddler/Charles,手机WIFI配置好代理。给手机流量代理到我们的抓包软件,这样我们就可以完成对app的抓包:


image.png

一般没有证书效验的app,或者抓包检测的app我们都可以通过这种办法进行抓包。但是这里我们并不推介这种抓包的办法。我个人的习惯一般是使用vpn抓包的方式。

因为网上很多对wifi配置代理抓包的文章,这里就不一一概述。主要就是wifi设置代理,app安装抓包软件的证书。

这里简单的说说我们通过抓包软件抓到的包的原理,方便后面理解为什么需要过ssl验证:


image.png

这里用猿人学一张图简单来说明,非常简单明了。就是客户端 -> 抓包软件 -> 服务端。

1.1 优点

wifi代理抓包的优点可能就是配置非常非常方便,导入抓包软件的证书后也可以抓https的包。

1.2 缺点

相对于vpn抓包方案,wifi代理抓包最容易被检测。

1.2.1 wifi代理检测

缺点就是很容易被检测是否使用了代理:

System.getProperty("http.proxyHost")
System.getProperty("http.proxyPort")

如何判断app进行了wifi代理检测?
配置好代理,打开抓包软件,可以抓到app的其它请求但是抓不到这个app的数据,app直接显示无网络。这时候可能就是wifi代理被检测,或者有ssl证书效验。

wifi代理检测用的app还是比较多,建议采用vpn抓包的方式规避。

1.2.2 强制代理

或者是某些APP直接强制使用代理:

OkHttpClient client = new OkHttpClient().newBuilder().proxy(Proxy.NO_PROXY).build();

和我们py的requests一样,安卓也可以设置代理。设置请求走默认代理而不走系统代理,防止被抓包。

如何判断app是进行了强制代理?
设置了wifi代理后,关闭抓包软件,app依旧可以正常请求网络。可能是app强制进行了代理转发,或者压根没走http协议。

强制代理的情况很少,目前没有遇见过,这时候可以通过tcpdump抓取网络报文可以发现App直接和服务器建立了连接而没有和代理建立连接

2 VPN抓包

vpn抓包个人习惯使用Postern+Charles的组合。这里非常推介,所以写一下安装和配置的过程

2.1 环境

简单的介绍一下我的环境:

  • Postern-3.1.2
  • charles-proxy-4.6.2-win64
  • win 10
  • 安卓8,面具root

注意电脑的防火墙要关闭,否则可能导致流量无法转发。之前出现过公司电脑不行,个人笔记本可以的情况。然后关闭公司电脑后charles才能连接到手机。害我折腾了半天

2.2 安装配置

先给我们的手机安装Postern,电脑安装charles。然后配置charles

2.2.1 Charles配置

打开charles设置proxy,点击proxy->proxy-settings,开启socks然后配置一个端口,我这里给的是8889,使用socks代理来转发流量。


image.png

保存后再点击proxy->ssl proxying后,配置抓https的包


image.png

规则,两个都填*就行了


image.png

2.2.2 charles导出证书

从charles导出证书,注意charles导出证书的时候会导出在你选择的路径上一级(有点坑)


image.png

推送到手机,并安装该证书

adb push xxx.pem /sdcard

安卓7以后不信用户目录的证书,所以需要把证书移至系统证书目录。利用面具的Move Certificates模块来移动证书。


image.png

重启自动迁移证书。


image.png

2.2.3 没有面具迁移证书的办法

有时候手机使用的su去进行的root,没有使用面具。所以这么好的插件就无法使用了,这时候我们可以用命令进行操作:

先安装charles证书,再获取root权限

su
mount -o rw,remount -t auto /system
image.png

执行后,通过 mount | grep /system 查看,很明显有了rw权限。还有就是mount的时候要加上-t auto,不然我手机提示设备繁忙。

再移动用户证书到系统证书:

mv /data/misc/user/0/cacerts-added/* /system/etc/security/cacerts/

执行完后考虑到系统安全,最好改回ro权限:

mount -o ro,remount -t auto /system

验证一下证书是否在系统目录:


image.png

2.2.4 Postern配置

charles配置好后,打开手机的Postern添加一个代理


image.png

名字随便取,地址是电脑的局域网ip,端口是之前设置的socket端口,然后协议选择socks5,保存。


image.png

配置代理规则,添加一个规则。匹配类型是匹配所有地址,动作是通过代理连接,代理组选择刚配置好的代理即可。


de5fc79c353ff91d9a86245bdb29b42.jpg

app设置vpn为charles的代理后,正常情况下会弹出这个提示:


image.png

这样就配置就可以通过vpn抓包的办法去抓包了。

2.3 优点

相较于wifi代理抓包的办法,vpn检测相对较少。而且一次配置终生受益。

2.4 缺点

虽然vpn抓包的方式非常棒,但是也并不是全能的,它也是可以被检测的。

    public void isDeviceInVPN() {
        try {
            List<NetworkInterface> all = Collections.list(NetworkInterface.getNetworkInterfaces());
            for (NetworkInterface nif : all) {
                if (name.equals("tun0") || name.equals("ppp0")) {
                    Log.i("TAG", "isDeviceInVPN  current device is in VPN.");
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

可以通过判断网络接口名字包含 ppp0 或 tun0是否有vpn代理,当然也有很多其它的办法进行检测。但是对app进行vpn检测的还是很少,除非是安全性要求较高的app。

并且现在的许多app都开始增加了app抓包的防范,比如说ssl 单向/双向验证,socket协议,某些有实力的大厂自己实现一套协议。

3 客户端ssl验证

在抓https的包的时候我们经常涉及到一个证书的问题,再说这个之前简单的说说http和https:
http是明文传播,易被拦截和修改。
https在HTTP的基础上加了一安全层(SSL或TSL)

这也就引出了我们抓https包的时候,容易遇见的ssl证书问题。

https实际上就是http+ssl。由于http发送的数据直接就是明文。安全性非常差。https会在数据发送前,先用ssl进行加密

客户端ssl验证简单来说就是客户端验证服务端返回的证书,从刚才第一点说的wifi代理抓包的原来来说,如果我们使用了中间人软件来抓包,其实真正请求服务端和响应客户端的是我们抓包软件。这时候客户端验证的是抓包软件的证书,所以肯定验证会失败!

刚好这里有hatch的一个案例,我们通过这个案例来学习如何bypass 客户端的ssl验证。

3.1 案例

该app是波兰某电商app,刚好app客户端验证了服务端的证书。

3.1.1 vpn抓包

先看看我们vpn抓包的表现效果,打开我们的charles和postern。然后打开app进行抓包:

app显示:


image.png

虽然看不懂波兰语,但是大概的意思应该是没有网络连接了

charles显示:


image.png

抓包都是连接失败,请求里面也提示了证书问题:SSL handshake with client failed: An unknown issue occurred processing the certificate (certificate_unknown)

3.1.2 bypass ssl pinning

一般这种情况都是app验证了服务端的证书,服务端验证app证书的app非常少,因为太消耗服务器资源。除了soul之前是双向验证之外(后面新版本好像也取消了双向验证)

这里推介使用frida 的一个bypass 脚本,就是hook掉验证的代码即可:

https://github.com/WooyunDota/DroidSSLUnpinning/blob/master/ObjectionUnpinningPlus/hooks.js

下载这段通用的hook脚本,先启动我们的frida server:

ail@aildeMacBook-Pro ~ % adb shell
hammerhead:/ $ su
hammerhead:/ # cd /data/local/tmp/                                             
hammerhead:/data/local/tmp # ./frs14  

使用spwan的方式hook:

ail@aildeMacBook-Pro ObjectionUnpinningPlus % workon firda14
ERROR: Environment 'firda14' does not exist. Create it with 'mkvirtualenv firda14'.
ail@aildeMacBook-Pro ObjectionUnpinningPlus % workon frida14
(frida14) ail@aildeMacBook-Pro ObjectionUnpinningPlus % frida -U -f pl.allegro -l hooks.js --no-pause
     ____
    / _  |   Frida 14.2.18 - A world-class dynamic instrumentation toolkit
   | (_| |
    > _  |   Commands:
   /_/ |_|       help      -> Displays the help system
   . . . .       object?   -> Display information about 'object'
   . . . .       exit/quit -> Exit
   . . . .
   . . . .   More info at https://frida.re/docs/home/
Spawned `pl.allegro`. Resuming main thread!                             
[Nexus 5::pl.allegro]-> message: {'type': 'send', 'payload': 'Custom, Empty TrustManager ready'} data: None
message: {'type': 'send', 'payload': 'com.squareup.okhttp not found'} data: None
message: {'type': 'send', 'payload': 'registerClass from hostnameVerifier >>>>>>>> Missing implementation for: boolean verify(java.lang.String, javax.net.ssl.SSLSession)'} data: None
message: {'type': 'send', 'payload': 'Xutils hooks not Found'} data: None
message: {'type': 'send', 'payload': 'httpclientandroidlib Hooks not found'} data: None
message: {'type': 'send', 'payload': 'OpenSSLSocketImpl pinning'} data: None
message: {'type': 'send', 'payload': 'Trustkit pinner not found'} data: None
[-] Cronet pinner not found
message: {'type': 'send', 'payload': 'OpenSSLSocketImpl.verifyCertificateChain'} data: None
message: {'type': 'send', 'payload': 'Overriding SSLContext.init() with the custom TrustManager'} data: None
message: {'type': 'send', 'payload': 'Overriding SSLContext.init() with the custom TrustManager'} data: None
message: {'type': 'send', 'payload': 'Overriding SSLContext.init() with the custom TrustManager'} data: None
message: {'type': 'send', 'payload': 'Overriding SSLContext.init() with the custom TrustManager'} data: None
message: {'type': 'send', 'payload': 'Overriding SSLContext.init() with the custom TrustManager'} data: None
message: {'type': 'send', 'payload': 'Overriding SSLContext.init() with the custom TrustManager'} data: None
message: {'type': 'send', 'payload': 'Overriding SSLContext.init() with the custom TrustManager'} data: None
message: {'type': 'send', 'payload': 'OpenSSLSocketImpl.verifyCertificateChain'} data: None
message: {'type': 'send', 'payload': 'OpenSSLSocketImpl.verifyCertificateChain'} data: None
message: {'type': 'send', 'payload': 'OpenSSLSocketImpl.verifyCertificateChain'} data: None
message: {'type': 'send', 'payload': 'OpenSSLSocketImpl.verifyCertificateChain'} data: None
message: {'type': 'send', 'payload': 'OpenSSLSocketImpl.verifyCertificateChain'} data: None

抓包成功:


image.png

当然解决方案不止这一种,我们还可以hook掉加载证书的地方,给证书替换成我们抓包软件的证书就行

4 服务端ssl验证

服务端ssl验证就是服务端验证ssl证书,这时候就需要我们找到app的证书和密码。然后将app中内置的证书导入到Charles中去。

一般通用的找证书的办法就是反编译apk后,直接通过grep搜索p12后缀的文件名。但是一些app会将证书改成jpg或者gif等其它后缀名。这时候我们可以hook app加载证书的地方,输出证书路径和密码。

这时候我们可以使用肉丝巨巨的r0capture,github地址是:

https://github.com/r0ysue/r0capture

r0capture不止提供了证书导出的功能,还提供了非常强大的功能,这里因为我用的比较少后面有机会进行补充。

找到证书后,再charles的Proxy→SSL Proxy Settings→Client Certificates→Add添加新的证书即可。

5 双向验证

双向验证的app太少了,这里没有案例。参考单向的客户端验证和服务端验证的解决方案。只是需要同时解决客户端验证和服务端验证证书的问题。

6 非http协议抓包

现在一些app不走http协议,而选择一些开源的非http协议。比如某手的quic协议和某宝的Spdy协议,默认并不采用传统的http或者https协议。

这种情况下我们如何进行抓包呢?

6.1 某宝抓包

我们以某宝为例,淘宝采用的是Spdy协议,如果要直接去抓这个协议的数据估计要去研究该协议了或者直接hook app构造参数的地方,输出参数内容,避免直接抓包需要研究一个协议带来的时间成本。

但是索性的是不论是某宝还是某手,某团都提供了一个降级成http协议方案,当他们协议使用的服务器无法连接时会采用http协议去连接其他服务器。所以这里就提出来了两个解决方案:

  • iptables 直接干掉所有tcp或者udp这种可疑的协议,使他们被迫降级成http协议
  • hook掉开关,直接让app采用http协议

这里只说hook的方案:


image.png

这里就是它的开关,我们hook后直接返回false就行:

Java.perform(
        function(){
                
                var SwitchConfig_2 = Java.use('mtopsdk.mtop.global.e')
                SwitchConfig_2.d.implementation = function(){
                    return  false
                }
                
                SwitchConfig_2.e.implementation = function(){
                    return  false
                }
                
        }
)

hook后app就会采用http协议了

7 自集成的SSL库

除了使用tcp协议外,现在还有一些有实力的大厂APP基于开源的SSL库,自己集成了一套SSL库。这样我们传统的单向/双向证书解决的方案又行不通了。因为它是自己实现的一套SSL库,和安卓默认的SSL效验的地方肯定不一样。

这里我们就以最新版本的抖音为例。

7.1 最新版的抖音

定位过程参考:https://bbs.pediy.com/thread-269028.htm

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 194,761评论 5 460
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 81,953评论 2 371
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 141,998评论 0 320
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 52,248评论 1 263
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 61,130评论 4 356
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 46,145评论 1 272
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 36,550评论 3 381
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,236评论 0 253
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 39,510评论 1 291
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 34,601评论 2 310
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 36,376评论 1 326
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,247评论 3 313
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 37,613评论 3 299
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 28,911评论 0 17
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,191评论 1 250
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 41,532评论 2 342
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 40,739评论 2 335

推荐阅读更多精彩内容