「如要转发或提 ISSUES,请联系作者!」
「Author:857-小数据神学工作者」
E-Mail:FreeOnePlus128@gmail.com
CreateTime:2021 年 12 月 15 日
通过 Mitmproxy 作为中间人拦截请求和响应包,然后通过 Python 解析响应包的 Data 数据,或是修改请求参数,模拟用户请求,完成爬虫操作。
「PS:本教程不涉及手机 ROOT,如有需要,请自行百度|GOOGLE~」
「Mitmproxy」 :拦截数据和模拟发送,无论是 Mac、Windows 还是 linux 都可以安装部署
「Python」:脚本编写和脚本环境搭建,用于解析拦截数据或者生成模拟发送数据参数
「Openssl」:生成系统级的证书
「ROOT 后的安卓手机|Android 模拟器」(二选一):安卓系统环境,安装目标 APP,用代理进行转发数据流
由于安卓手机的版本不同,不同版本的安全策略也不一样,高版本的安全策略程度高,无法通过直接 root 和安装证书即完成对 APP 的安全验证的规避操作,绝大部分 APP 都已不认可用户自己安装的证书,因为可能具有欺诈性,所以需要安装系统级的证书,并且绕开 Android 的证书安全策略。
所以以下分两种情况:
Android 5 及以下:
Android 5 以上:
「注意:安装 Magisk Manager 以及 Magisk 组件需要访问国外网站
Version:3.10
安装方式:https://www.python.org/downloads/
下载安装,可无脑安装器安装,也可二进制文件自主编译,看技术力
PS:安装器安装时可勾选添加 Python 路径到 PATH 中,选了就不用再去搞 PATH,手动二进制的话,需要去修改环境变量文件:
.bush_profile
文件(MAC)/etc/profile.d/mitmproxy.sh
(Linux)添加环境变量$PYTHON_HOME
,该source
就source
直接使用 pip 安装即可
pip install mitmproxy
pip 本质上会一是安装 mitmproxy 库的相关代码,二是安装 mitmproxy/mitmdump/mitmdump 三个可执行程序,可执行程序被安装在$PYTHON_HOME/Scripts 文件夹下。
PS:由于该教程是用 MAC 写的,没有相应 Windows 截图,只能凭记忆给大家描述了
直接安装可能会报错,提示 pip 版本过低,需要更高版本21.3.1
解决方案:先更新 PIP 版本
python -m pip install --upgrade pip
继续执行,还是可能会报错 —— 提示当前机器没有 C++ 14 相关环境
解决方案:别偷懒,直接下载 VS 最新版(虽然安装起来有点费空间,大概几个 G,提前做好准备工作),然后安装 C++相关环境(这一步很恶心人~需要有耐心)
https://visualstudio.microsoft.com/zh-hans/downloads/
继续执行,可能会报新错误 —— 提示没有 Windows SDK
解决方案:打开 VS 安装器(也可以理解为 VS Manager 软件),找到你下载的 VS 的版本(一台机器随便你安装多少个 VS 版本),选择修改,查找添加新的组件 Windows SDK
至此,安装 mitmproxy 的 Windows 环境都 OK 了,然后执行 PIP 命令
pip install mitmproxy
安装好以后,执行命令:mitmdump
(命令行式 mitmproxy),如果成功则大功告成,如果不成功那再看看教程步骤,哪一步出了纰漏,最大概率是 VS 环境没有安装好。
证书生成只需要在安装好以后,在命令终端(Mac 和 Linux 有 GUI 版打开终端,Windows 打开 CMD,Linux 无 GUI 版直接搞)执行mitmdump
,当出现以下界面,即代表运行成功
image-20211124131837630
规则服务器监听了所有通过 http 协议和 8080 端口进行传输数据的数据流,端口可以修改,只需要在启动的时候添加参数 -p xxxx
其中,xxxx 代表自定义端口号。
这个端口是用来监听的,也就是说不是用来拦截 APP 指定端口的,是用来监听代理端口的,不要设置一些敏感端口,比如 80,443 之类的。
执行成功该命令以后,证书会自动生成到用户文件夹下:
「注意:两个系统下的文件夹都是隐藏文件夹,Windows 的需要设置显示隐藏文件方可看到,Mac 建议在终端下使用 cp 命令复制到指定文件夹下!」
文件夹下会有好几个证书
具体证书的命名含义我也就不讲了,有兴趣的可以百度了解一下,然后我们使用 mitmproxy-ca-cert.pem
这个证书,将其复制至指定目标文件夹【个人建议新建一个文件夹来存放需要后期使用到的各种文件】。
cp /User/用户名/.mitmproxy/mitmproxy-ca-cert.pem /User/用户名/Document/AndroidCrawler/
mitmproxy-ca-cert.pem
这个整数就是我们中间代理 mitmproxy 的证书,把它安装到我们需要爬取的系统上,就可以实现证书认证,从而让 APP 放心的把数据交给我们、放心的接收我们修改以后的数据~
如果直接发送到 Android 或者模拟器安装,高版本 Android 下安装成功以后也没啥作用,因为是用户级的证书,不被系统认可,那么解决问题的办法就是,让该证书变成系统级的证书。
首先,安装 Openssl 工具(Mac 自带,直接开搞)。
先查看安装好的 Openssl 工具版本 openssl version
#openssl版本在1.0以上的版本的执行这一句
openssl x509 -inform PEM -subject_hash_old -in 你的证书路径
#openssl版本在1.0以下的版本的执行这一句
openssl x509 -inform PEM -subject_hash -in 你的证书路径
执行结束后会有这样的加密串
image-20211124134224272
在 BEGIN CERTIFICATE 之前会有「类似于」 c8750f0d
这样的串,然后复制它。
用这个串重命名你的证书文件mitmproxy-ca-cert.pem
,改为「类似于」 c8750f0d.0
的名字。
在 Mac 的 Finder 下重命名似乎后缀名无法更改,需要在终端进行mv
命令修改。
mv 你的证书路径/mitmproxy-ca-cert.pem 你的目标路径/c8750f0d.0
至此,证书也成功生成了,前期准备工作都已完成,接下来就是搞事情了。
ADB 是用于开发平台(Mac|Windows|Linux 等)模拟操作安卓手机端的工具,它可以完成模拟操作手机、获取手机信息、传输文件、安装 APK 等需求,后续我们会使用到。
brew install android-platform-tools
cd ~
open .bash_profile
在文末加入(内有路径需要改为自己的,别蒙头复制粘贴)export ANDROID_HOME=/Users/你的用户名/Library/Android/sdk
export PATH=$PATH:$ANDROID_HOME/tools
export PATH=$PATH:$ANDROID_HOME/platform-tools
source .bash_profile
adb
或者adb -version
,验证是否安装成功,成功如下Android Debug Bridge version 1.0.41
Version 29.0.6-6198805
Installed as /Users/freeoneplus/Documents/android-sdk-macosx/platform-tools/adb
//下面是各种参数详解,就不贴了
下载地址:https://dl.google.com/android/repository/platform-tools-latest-windows.zip
下载后的压缩包解压缩到你想放的目录下
打开此电脑
——>属性
——>系统高级设置
——>环境变量
然后把ADB存放路径
添加到Path
里(这太简单了,不赘述了)
然后各种保存以后,打开CMD
输入adb
或者adb -version
Android Debug Bridge version 1.0.41
Version 31.0.3-7562133
Installed as D:\AndroidSDK2.2\platform-tools\adb.exe
//下面是各种参数详解,就不贴了
Version:17.0+
下载地址:https://github.com/topjohnwu/Magisk/releases
通过数据线或其他方式传给手机,安装即可。
打开 Magisk Manager,安装 Magisk
Version:22.1 +
安装后重启手机。
Version:10 +
(不要太高,建议 25.4.4,太高下一模块没法依赖上,安装不了)
下载地址:https://github.com/RikkaApps/Riru/releases
一样,传给手机,打开 Magisk Manager,选择模块,选择本地安装,找到下载好的 ZIP 压缩包,进行安装。
安装后重启手机。
Version:0.5.2.2+
(低版本没测试,但是低版本依赖不了 Riru 的高版本,如果要降,要连同 Riru 模块一起降级,否则安装不通过,一直提示请先安装 Riru)
下载地址:https://github.com/RikkaApps/Riru/releases
一样,传给手机,打开 Magisk Manager,选择模块,选择本地安装,找到下载好的 ZIP 压缩包,进行安装。
安装后重启手机。
Version:4.6.2+
下载地址:https://github.com/ElderDrivers/EdXposedManager/releases
下载,传输,安装。
Version:0.2
下载地址:链接: https://pan.baidu.com/s/1YllByaVOnt3lL4RE17X0jg 密码: 6n5g
下载,传输,安装,重启。
然后打开 EdXposed Manager,看模块栏目,是否已提示成功运行 JustTrust,如果成功,至此,安全策略组已完整搞定。
通过数据线连到 Android 手机,把我们刚刚弄好的证书c8750f0d.0
(「你的证书名字不应该和我写的一样,格式类似即可」)传过去。
安装 RE 文件管理器(给这个文件管理器 ROOT 权限,可以访问系统级文件夹)。
复制证书到该目录下:
/system/etc/security/cacerts
重启手机。
打开手机的无线,将你的电脑和手机连到同一个无线上(要同一个路由器)
打开找到你本机的 IPv4 地址:
ifconfig
image-20211124171503579找到你的 en0 网卡,查看地址
image-20211124171636853
点击 Wi-Fi,查看右边的 IP 地址
两种方法都行
ipconfig
找到对应网卡的 IP 地址(我用 Mac,截不了 Windows 的图)在手机上进行下一步操作:
设置----无线和网络 WLAN----长按 wifi 名----修改网络----显示高级选项----代理----手动---服务器主机名输入 xxx.xxx.xxx.xxx(根据自己电脑 ip 修改)服务器端口输入 8080(如果想自定义端口也行,只要和 mitmproxy 启动监听时的端口一致即可)----保存
至此,代理配置完毕。
在终端执行mitmdump
,可加参数-p 作为自定义端口号
mitmdump -p 9998
如果出现下图,则表明没问题
image-20211124172612004
再往后,就是写 python 脚本进行数据接收和处理了,下回分解。
模拟器:推荐夜神模拟器(雷电也行)
模拟器内核版本:Android 7+
image-20211215130830887
image-20211215130912635
image-20211215130954703
image-20211215131032227
image-20211215131100561
image-20211215131248411
image-20211215131852892
image-20211215131203399
至此,模拟器的环境配置结束
模拟器安装证书的过程容易出错,出错以后证书无法生效,导致一直处于证书不信任状态,进而会导致我们请求无法成功(TimeOut)或者反复认证(弹窗警告)或者信息获取短缺(部分链拿取不到),给我们研究自动化造成很多困扰,这一步务必认真~
查看电脑是否成功连接到手机
adb devices -l #显示所有已连接的设备详细信息:127.0.0.1:62001
若未连接,则连接 ADB
adb connect 127.0.0.1:62001 #默认端口
进入我们已经重命名以后的证书所在位置
#Mac
cd /User/你的用户名/你存放的具体路径/
#Windows
#可能需要先切换盘符
D: #切换到D盘
cd 你的路径
传入手机
adb push c8750f0d.0 /sdcard
「注意!这里的c8750f0d.0
是你之前生成证书时改的名字,别直接无脑复制粘贴了哈」
安装 mitm 证书到手机的 ADB SHELL 操作
#获取手机的root权限
adb shell
su
#挂载系统目录为可写
mount -o rw,remount /
mv /sdcard/c8750f0d.0 /system/etc/security/cacerts
#修改证书权限
chmod 644 /system/etc/security/cacerts/c8750f0d.0
「还是注意!这里的c8750f0d.0
是你之前生成证书时改的名字,别直接无脑复制粘贴了哈」
最后,我们可以看一下我们用的模拟器内核是发行版还是其他版本
adb shell
cat /system/build.prop | grep build.type
如果返回ro.build.type=user
则代表没啥毛病,如果是其他版本可能需要做操作(后面补充一个)
打开模拟器,查看是否已成功安装 CA 系统级证书Mitmproxy
image-20211215140010157
image-20211215140058743
image-20211215140143300
上面提到如果不是发行版,假设是开发版的,可能有报错
错误信息:'/dev/block/dm-0' is read-only
对于开发调试的版本,用户必须先disable-verity
,然后再执行后续的操作
adb root
adb disable-verity
adb reboot
adb remount
adb shell
mount -o rw,remount /system
至此,证书安装结束
与真机一样,如果需要捕获数据,就得把网络代理配置给中间人去进行信息的抓取,所以直接来干~
1.打开设置,点击 WLAN
2.长按你看到的那个虚拟 WIFI
3.选择修改网络
4.点击高级选项,选择手动配置
5.输入你的本地 IP 和 mitmproxy 监听的端口号
6.本地 IP 去这里找
系统设置——>网络和 Internet
点击你正在使用的网络的「属性」(不建议无线与有线齐飞~)
左上角——>系统偏好设置——>网络
左边列表里找到你正在使用的网络,右边复制你的内网 IP 地址(因为现在基本没可能 IPV4 个人用公网 IP 了~)
7.然后保存你手机的网络配置
至此,配置代理网络结束
打开命令终端,输入
mitmweb -p 你刚刚写的代理接口的端口号
在模拟器上打开任意你想要抓取的 App,测试使用,比如我们打开浏览器
1.从拦截到的请求链中,找到百度发送搜索请求的链接
2.可以点击一个串,然后右边看它的请求头或者响应内容,希望找到的是一个完整的 H5 页面
3.查找的时候,可以尽量看接口,大部分搜索接口,都会以 search 或者 s 这样的命名方式命名,所以我们很快定位到了请求连接
4.点开响应,发现是一个挺大的文件,309.8kb,那大概率就是它
点击右边的Display anyway
按钮
5.的确是熟悉和喜闻见乐的 H5 页面
想看全部内容的话,还可以点击右下角的show full content
按钮进行查看
6.确认是该连接串以后,那么我们就可以用这个链接串的固定头进行筛选过滤了
# 原链接
https://m.baidu.com/from=844b/s?word=857%E6%98%AF%E4%BB%80%E4%B9%88%E6%84%8F%E6%80%9D&ts=0&t_kt=0&ie=utf-8&fm_kl=021394be2f&rsv_iqid=2591761736-2&rsv_t=791bVD%252BdGHAbMlNIs1MqSfhJO1q03VBqZqI2tvFyPXnESa0sjwdAhXFD8g&sa=is_1&ms=1&rsv_pq=2591761736&rsv_sug4=1639549768086&tj=1&inputT=1639549770482&sugid=13987157572640490342&ss=100&rq=857
# 过滤固定头的规则
https://m.baidu.com/from=844b/s
7.拿着https://m.baidu.com/from=844b/s进行过滤
Start
Tab
8.继续搜索857李奇峰是什么人
9.查看过滤出来的链接,是不是多了一条,如果是,则说明我们前置所有工作都是成功的
至此,我们 DEMO-1 的 mitmproxy 使用结束
❝无论是真机还是模拟器,作用都只是为了发起对 APP 的请求 Mitmproxy 则是在请求过程中充当一个中间人的角色,经手所有信任了它的请求连接 经手过后,还仅仅只是经手了,截止现在还是没有把数据持久化下来,进行进一步的操作 ❞
其实 Mitmproxy 是 Python 的一个三方库,既然是和 Python 完美嵌在一起的,那么一定就可以使用 Python 程序对中间人经手的数据进行处理,绝大多数需求,都是想将网络资源固化至服务器/本地/数据库,然后进行进一步的操作分析,那么本教程的范围截止到将数据固化即结束,后续再行讨论~
编写思路
1. 拦截连接串
2. 根据拦截规则进行匹配(比如我们刚刚设置的固定头)
3. 将拦截到的数据进行持久化(持久化至磁盘或者数据库)
编写代码如下(非常简单的 DEMO)
# coding=utf-8
import codecs
def response(flow):
# 过滤列表
rule_url = "https://m.baidu.com/from=844b/s"
url = flow.request.url
if flow.request.url.startswith(rule_url):
text = flow.response.text
f = codecs.open("request.html", 'a', 'utf-8')
f.write(str(text) + '\r\n-----------------------------------\r\n')
else :
f = codecs.open("pass.txt", 'a', 'utf-8')
f.write(str("非过滤列表URL\r\n" ))
程序作用很简单,就是将符合条件的链接过滤出来,并将返回的响应值持久化到 txt 文本文件中
保存 Python 程序,命名为857test.py
使用 Mitmproxy+Python 的启动方式启动我们整套项目
mitmweb -p 你的代理端口 -s 你的Python脚本路径
#eg:
mitmweb -p 9922 -s 857test.py
#如果你不想要WebUI窗口监听,只想命令行监听,那么吧mitmweb改为mitmdump就行
#eg:
mitmdump -p 9922 -s 857test.py
开始测试
打开执行命令文件夹
至此,APP 爬虫的请求过滤持久化教程告一段落,后续我再写一些在实际开发过程中的应用心得
首先,爬虫项目,要摆正态度,以搜索引擎的思想和用途是可以的,如果其他,要考虑一些风险因素,工作成果是给公司或者其他人提供的,但是风险和最终风险承受人还是开发者,切要小心。
项目实施过程中,能调用和捕获只是第一步,还有各种反爬和校验机制在内,所以此教程只是适合入门使用,距离落地稳定可靠的项目只能起一个启蒙作用,后续还需要大量的研发工作,简单罗列一下后续应该关注到的点:
技术无罪,研究技术和分享技术都应该是本着纯粹和开源的态度进行交流讨论的,而本人能力有限,若在教程过程中有谬误之处,还望各位同学多多指正,后续若时间充裕,会写一份企业级的爬虫项目构思和简述供大家参考,感谢各位