第一章 · 起源

某日,想做个爬虫工具,爬某个网站上的数据已做实验之用。大家都知道爬pc网页上的数据有几个常见的问题:首先是数据不规范需要自己解析html,第二现在很多网站是前端动态渲染的,直接爬取的html可能就是个静态页面什么也没有,还需要执行js才能生成最终的页面。因此就考虑,能否用它App的接口去爬数据,因为一般App调用的接口返回的都是json格式,解析起来比较方便。

第二章 · 尝试

既然要抓取App的接口,肯定需要抓包,现在接口一般都用的https通信,直接抓二进制的tcp包是无法解密的。想到用Fiddler,它的原理很简单,就是启动一个https代理服务器,手机上设置Fidder启动的代理服务ip和端口。这是第一步,第二步就是证书,Fiddler会自己生成一个证书,把这个证书作为根证书导入的手机中,这时手机对Fiddler返回的证书就是可信任的。通信的时候,Fiddler作为客户端它会和服务端建立https连接,得到解密后的数据,然后自己启动一个https的服务,把数据返回给手机端。手机端这个时候实际访问的是Fillder启动的https服务,验证的证书也是Fillder自己颁发的。至于https如何验证签名如何加密通讯的这里就不做展开了,有兴趣的可以自己查阅。

但是,必须要说的是这样配置代理用Fiddler抓包的确可以抓到用手机浏览器访问的内容,现在App为了防止代理模式抓https的包,一般都会把证书放到自己的App中,验证https server返回的证书和App中的证书是否一致,这个时候server返回的证书是Fiddler自己颁发的,肯定和App本地的不一样所以App这时是无法访问接口的。

为什么Fiddler要自己颁发一个证书呢?这是由于Fiddler需要把和服务端通信的内容解密,所以它作为一个正常的client端先和服务端建立连接,验证服务端的证书,用服务端的证书上的公钥加密自己生成的对称秘钥,服务端拿到对称秘钥后用私钥解密,双方都知道对称秘钥,之后的通信用对称秘钥加解密。同理Fiddler作为App的代理服务器,也是要和app建立https连接的,这时如果直接返回服务端上的证书,App用服务端上证书的公钥加密App生成的对称秘钥。但是Fiddler没有证书的私钥,所以Fiddler需要自己颁发一个证书,有公私钥,才能和App正常的用https通信。

尝试用Fiddler代理抓App的包失败了

第三章 · 脱狱

遇到了问题,肯定要解决问题。现在问题的关键就是App验证本地证书和Fiddler返回的证书不一致,要做的就是绕开这验证,或者让App验证这个证书永远通过。不得不说,道高一尺魔高一丈,还真有这样的东西,根据维基百科的解释Xposed框架(Xposed framework)是一套开放源代码的、在Android高权限模式下运行的框架服务,可以在不修改APK文件的情况下修改程序的运行(修改系统),基于它可以制作出许多功能强大的模块,且在功能不冲突的情况下同时运作。

安装Xposed是有风险的,弄不好手机会变成砖,这里我就用模拟器替代手机安装了,下载MuMu模拟器,安装Xposed框架



同时还需要安装一个Xposed的一个插件Just Trust Me



安装好之后,我们再打开这个App,同时配置模拟器网络的代理,再用Fiddler抓包可以看到内容

第四章 · 柳暗花明

看到上面的截图,的确是找打了请求的地址,但是发现发出的请求内容是

{
"pagesize": 10,
"page": 1,
"platid": "0",
"langid": "0",
"typeid": "0",
"saletime": "全部",
"time": 1595672934792,
"sign": "c2522179dd87522f0d2997e28d48289e"
}

没错,有一个签名,这个签名一看就知道是md5做的,但是我不知道规则,而且生成的签名肯定是这些请求的参数加上一个字符串,最后md5一下,服务端还要验证签名,才能正常返回结果。这时仿佛又回到了原点,不解决这个签名,我们是无法正常请求服务的。要解决这个签名唯一的办法就是反编译包,从代码中发现蛛丝马迹。

apktool是一个开源的用于反编译apk包的工具,用它试试看能不能找到对应的md5加密的源码。用它反编译apk后,代码非常庞大,在里面搜索接口的名称djscreen竟然找到代码了

    invoke-static {}, Ljava/lang/System;->currentTimeMillis()J
move-result-wide v8
.line 493
.local v8, "time":J
new-instance v10, Ljava/lang/StringBuilder;
invoke-direct {v10}, Ljava/lang/StringBuilder;-><init>()V
const-string v11, "10"
invoke-virtual {v10, v11}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
move-result-object v10
iget v11, p0, Lcom/ws3dm/app/activity/GameCategoryActivity;->mPage:I
invoke-virtual {v10, v11}, Ljava/lang/StringBuilder;->append(I)Ljava/lang/StringBuilder;
move-result-object v10
iget-object v11, p0, Lcom/ws3dm/app/activity/GameCategoryActivity;->platid:Ljava/lang/String;
invoke-virtual {v10, v11}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
move-result-object v10
iget-object v11, p0, Lcom/ws3dm/app/activity/GameCategoryActivity;->langid:Ljava/lang/String;
invoke-virtual {v10, v11}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
move-result-object v10
iget-object v11, p0, Lcom/ws3dm/app/activity/GameCategoryActivity;->typeid:Ljava/lang/String;
invoke-virtual {v10, v11}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
move-result-object v10
iget-object v11, p0, Lcom/ws3dm/app/activity/GameCategoryActivity;->saletime:Ljava/lang/String;
invoke-virtual {v10, v11}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
move-result-object v10
invoke-virtual {v10, v8, v9}, Ljava/lang/StringBuilder;->append(J)Ljava/lang/StringBuilder;
move-result-object v10
invoke-virtual {v10}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
move-result-object v7
.line 494
.local v7, "validate":Ljava/lang/String;
invoke-static {v7}, Lcom/ws3dm/app/util/StringUtil;->MD5(Ljava/lang/String;)Ljava/lang/String;

根据代码可以看到MD5的规则就是10+mPage+platid+langid+typeid+saletime+time然后送达工具com.ws3dm.app.util.StringUtil执行MD5方法,进入这个类看看怎么MD5的

    .method public static MD5(Ljava/lang/String;)Ljava/lang/String;
.locals 9
.param p0, "string" # Ljava/lang/String;
.prologue
.line 77
const-string v4, "e8S8Ho0N25z78u6qn4kHyN"
.line 78
.local v4, "key":Ljava/lang/String;
new-instance v5, Ljava/lang/StringBuilder;
invoke-direct {v5}, Ljava/lang/StringBuilder;-><init>()V
invoke-virtual {v5, p0}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
move-result-object v5
invoke-virtual {v5, v4}, Ljava/lang/StringBuilder;->append(Ljava/lang/String;)Ljava/lang/StringBuilder;
move-result-object v5
invoke-virtual {v5}, Ljava/lang/StringBuilder;->toString()Ljava/lang/String;
move-result-object p0

惊喜的发现传入的字符串+e8S8Ho0N25z78u6qn4kHyN然后再MD5就是结果

试试101000全部1595672934792e8S8Ho0N25z78u6qn4kHyN正好是c2522179dd87522f0d2997e28d48289e和抓包中的参数一致,搞定,到此基本上是破解结束了。后续还发现基本上所有的接口都是采取这种模式进行md5然后请求的。

第五章 · 终结

至此整个的抓包加破解的流程就结束了,整个过程其实是做二件事情,解决https验证证书,找到md5签名的规则。整个App相对而且是比较好破解的,整个MD5的过程都是Java写的,比较好反编译。这也是和后端通信,常见的一种处理方式。但是这种方式,的确不是很安全,没有很好的保护Api不被外部破解,比较安全的做法是把签名方法放到so中,或者对数据进行加密解密,同时也不要忘记混淆代码。

记一次抓包和破解App接口的更多相关文章

  1. 小迪安全 Web安全 基础入门 - 第三天 - 抓包&封包&协议&APP&小程序&PC应用&WEB应用

    一.抓包工具 1.Fiddler.Fiddler是一个用于HTTP调试的代理服务器应用程序,能捕获HTTP和HTTPS流量,并将其记录下来供用户查看.它通过使用自签名证书实现中间人攻击来进行日志记录. ...

  2. charles 抓包工具破解方法

    在线破解地址: https://www.zzzmode.com/mytools/charles/ 之后将下载的jar包替换  charles.app ->右键显示包内容 ->content ...

  3. 猫眼电影App抓包获取评论数据接口

     之前在CSDN程序人生公众号上看到了这篇文章<邪不压正>评分持续走低,上万条网友评论揭秘,是救救姜文还是救救观众?,文中提到了通过抓包猫眼App发现了评论的数据接口:http://m.m ...

  4. fiddler抓包,搞定接口

    上篇介绍的世纪佳缘登录是由已有cookie保持登录状态的.世纪佳缘登陆不需要填入验证码,可以很方便直接请求登录接口来达到登录状态的目的. 这篇介绍直接从登录接口进行登录,那么这就要求要找到登录接口ur ...

  5. mac 下使用Charles抓包华为手机app

    安装Charles:https://www.cnblogs.com/sea-stream/p/11577418.html 需要保证手机与电脑连接同一个Wi-Fi设置mac charles,打开代理 2 ...

  6. [转载]Fiddler 解析!抓包抓得好真的可以为所欲为 [一]

    说起抓包,很多人以为就是用个工具,简简单单地抓一下就可以了.昨天在面试一个安卓逆向,直接告诉我[抓包没有技术含量].在这里,我必须发一个教程,解析一下抓包神器——Fiddler.Fiddler仅仅是一 ...

  7. Fiddler和app抓包

    1:请在“运行”,即下面这个地方输入certmgr.msc并回车,打开证书管理. 打开后,请点击操作--查找证书,如下所示: 然后输入“fiddler”查找所有相关证书,如下所示: 可以看到,我们找到 ...

  8. 转:APP开发浅谈-Fiddler抓包详解

    原文地址:http://www.luoxudong.com/?p=306 Fiddler抓包工具在APP开发过程中使用非常频繁,对开发者理解HTTP网络传输原理以及分析定位网络方面的问题非常有帮助.今 ...

  9. Airmon-ng抓包&破解wifi

    安装  aircrack获取(aircrack源) sudo apt-get install aircrack-ng 配置 安装组件 sudo apt-get install build-essent ...

随机推荐

  1. SQL注入之MySQL常用的查询语句

    MySQL是一种使用很广的数据库,大部分网站都是用MySQL,所以熟悉对MySQL数据库的注入很重要. 首先来说下MySQL注入的相关知识点 在MySQL5.0版本之后,MySQL默认在数据库存放一个 ...

  2. JDK8--03:lambda表达式语法

    对于lambda表达式的基础语法,一个是要了解lambda表达式的基础语法,另外一个是需要了解函数式接口 一.lambda表达式基础语法描述 java8中引入了新的操作符  ->  ,可以称为l ...

  3. Riccati方程迭代法求解

    根据上述迭代法求解P,P为Riccati方程的解,然而用LQR需要计算K,再将K算出. (迭代过程中 ,我们可以将此算法和dlqr函数求解的参数进行对比,当误差小于我们设置的允许误差我们就可以把此算法 ...

  4. Python实用笔记 (10)高级特性——生成器

    通过列表生成式,我们可以直接创建一个列表.但是,受到内存限制,列表容量肯定是有限的.而且,创建一个包含100万个元素的列表,不仅占用很大的存储空间,如果我们仅仅需要访问前面几个元素,那后面绝大多数元素 ...

  5. DOM-BOM-EVENT(2)

    2.获取DOM元素的方法 2.1.getElement系列 documentElementById 通过id获取元素 <div id="box"></div> ...

  6. 关于阿里云服务器Linux安装Tomcat后,外网不能访问解决方案

    这里需要提及三个方面的问题   第一个方面:Linux上启动防火墙的问题 当下比较流行的Linux镜像是CentOS,所以防火墙也随之变成了firewall,那么怎么操作这个防火墙呢?   #停止fi ...

  7. CSS布局之盒子模型[一]

    每个HTML标签都会生成一个盒模型,盒模型是正常流布局非常重要的概念.盒模型由内边距(padding)+长度(width)+高度(height)+边框(border)+外边距(margin)组成. 1 ...

  8. jquery 获取页面和滚动条的高度

    1.获取浏览器显示区域的高度 : $(window).height(); 2.获取浏览器显示区域的宽度 : $(window).width(); 3.获取页面的文档高度 : $(document).h ...

  9. 一.2.序列化使用之用户资源功能app

    1.环境准备:(1).新建功能app: (python36env) [vagrant@CentOS7 devops]$ python manage.py startapp users ---建议以后用 ...

  10. MySQL调优 优化需要考虑哪些方面

    MySQL调优 优化需要考虑哪些方面   优化目标与方向定位 总体目标:使得响应时间更快,吞吐量更大. (throughout --- 吞吐量:单位时间内处理事务的数量) 如何找到需要优化的地方 使用 ...