APP HTTPS传输仍遭窃取|mitmproxy中间人攻击实战教学与防范技巧
iOS与MacOS环境下,利用mitmproxy实现中间人攻击,成功嗅探APP API资料传输,揭露HTTPS传输漏洞;并解析SSL Pinning与资料加密两大防护策略,提升APP资料安全,阻挡90%爬虫与攻击威胁。
Click here to view the English version of this article.
點擊這裡查看本文章正體中文版本。
基于 SEO 考量,本文标题与描述经 AI 调整,原始版本请参考内文。
APP有用HTTPS传输,但资料还是被偷了。
iOS+MacOS 使用 mitmproxy 进行中间人攻击(Man-in-the-middle attack) 嗅探API传输资料教学及如何防范?
前言
前阵子刚在公司办完一场内部的 CTF竞赛 ,在发想题目时回想起大学时候还在做后端(PHP)时经手的专案,一个集点的APP,大概就是有个任务列表,然后触发条件完成就Call API获得点数;老板认为Call API有经过HTTPS加密传输资料就很安全了 — 直到我向他展示中间人攻击,直接嗅探传输资料,伪造API呼叫获得点数….
再加上最近几年大数据崛起,网路爬虫满天飞;爬虫攻防战日渐白热化, 爬取与防爬之间花招百出 ,只能说道高一尺魔高一丈啊!
爬虫的另一条下手对象就是APP的API,如果没有任何防范几乎等于门户大开;不但好操作而且格式也干净,更不容易被识别阻挡;所以如果网页端已经费尽全力阻挡,资料还是不段被爬,不妨检查一下APP的API有无漏洞。
因为这个议题我不知道该如何出在 CTF比赛中 ,所以就单拉出一篇文章作为纪录 ;本篇只是粗浅给个概念 — HTTPS能透过凭证替换进行传输内容解密 、如何加强安全性防止;实际网路理论不是我的强项也都还给老师了,如果已经有这方面概念的朋友就不用花时间看这篇,或拉到底看APP该如果保护!
实际操作
环境: MacOS + iOS
Android 使用者可以直接下载 Packet Capture (免费)、iOS 用户可使用 Surge 4 这套软体( 付费) 解锁中间人攻击功能、MacOS也可以使用另一套付费软体Charles。
本文章主要讲解iOS使用 免费 的 mitmproxy 进行操作,如果您有上述的环境就不用这么麻烦啦,直接APP打开在手机上挂载VPN替换掉凭证就能进行中间人攻击!(ㄧ样请直接下拉到底看该如何保护!)
[2021/02/25 更新]: Mac 有新的免费图形化介面程式 ( Proxyman ) 可以用,可搭配 参考此篇文章 的第一部分。
安装 mitmproxy
直接使用 brew 安装 :
1
brew install mitmproxy
安装完成!
p.s 如果你出现 brew: command not found 请先安装 brew 套件管理工具 :
1
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
mitmproxy 使用
安装完成后,在 Terminal 输入以下指令启用:
1
mitmproxy
启动成功
让手机跟Mac在同个区域网路内&取得Mac的IP位址
方法(1) Mac 连接 WiFi、手机也使用同个 WiFi Mac的IP位址 = 「系统偏好设定」->「网路」->「Wi-Fi」->「IP Address」
方法(2) Mac 使用有线网路,开启网路分享;手机连上该热点网路:
「系统偏好设定」-> 「共享」->选择「乙太网路」->「Wi-Fi」打勾-> 「Internet 共享」启用
Mac的IP位址 = 192.168.2.1 (️️注意⚠️ 不是乙太网路网路的IP,是Mac用做网路分享基地台的IP)
手机网路设置WiFi — Proxy伺服器资讯
「设定」-> 「WiFi」-> 「HTTP 代理伺服器」-> 「手动」-> 「伺服器输入 Mac的IP位址 」-> 「连接埠输入 8080 」-> 「储存」
这时网页打不开、出现凭证错误是正常的;我们继续往下做…
安装 mitmproxy 自订 https 凭证
如同上述所说,中间人攻击的实现方式就是在通讯之中使用自己的凭证做抽换加解密资料;所以我们也要在手机上安装这个自订的凭证。
1.用手机safari打开 http://mitm.it
出现左边->Proxy设定✅/ 出现右边代表 Proxy设定有误🚫
「Apple」->「安装描述档」->「安装」
⚠️到这里还没结束,我们还要去关于里启用描述档
「一般」->「关于」->「凭证信任设定」->「mitmproxy」启用
完成!这时我们再回去浏览器就能正常浏览网页了。
回到Mac 上操作 mitmproxy
可以在mitmproxy Terminal上看到刚手机的资料传输纪录
找到想嗅探的纪录进入查看Request(送出哪些参数)/Response(回传了什么内容)
常用操作按键集:
1
2
3
4
5
6
7
8
9
10
11
12
13
「 ? 」= 查看按键操作集文档
「 k 」/「⬆」= 上
「 j 」/「⬇」= 下
「 h 」/「⬅」= 左
「 l 」/「➡️」️= 右
「 space 」= 下一页
「 enter 」= 进入查看详情
「 q 」= 返回上一页/退出
「 b 」= 汇出response body到指定path文字档
「 f 」= 筛选纪录条件
「 z 」= 清除所有纪录
「 e 」= 编辑Request(cookie、headers、params...)
「 r 」= 重新发送Request
不习惯CLI? 没关系,可以改用 Web GUI !
除了 mitmproxy 启用方式之外,我们可以改下:
1
mitmweb
就能使用新的 Web GUI 进行操作观察
mitmweb
重头戏,嗅探APP资料:
上述环境都建置完成也熟悉之后,就可以进入我们的重头戏;嗅探APP API的资料传输内容!
这边以某房屋APP作为范例,无恶意纯学术交流使用!
我们想知道物件列表的API是如何请求和回传什么内容!
首先先按「z」清除所有纪录(避免搞乱)
开启目标 APP
开启目标 APP 尝试「下拉重整」或触发「载入下一页」的动作。
🛑若你的目标APP打不开、连不上;那抱歉了,代表APP有做防范无法用这招嗅探,请直接下拉到如何保护的章节🛑
mitmproxy 纪录
回到 mitmproxy 查看纪录,发挥侦探的精神猜测哪个API请求纪录是我们想要的并进入查看详细!
Request
Request 部分可以看到 请求传递了哪些参数
搭配「e」编辑与「r」重新发送,并观察 Response 就可以猜到每个参数的用途啰!
Response
Response 也能直接获得原始回传内容。
🛑若Response内容是一堆编码;那也抱歉了,代表APP可能有自己再做一次加解密无法用这招嗅探,请直接下拉到如何保护的章节🛑
很难阅读?中文乱码?没关系,这边可以用「b」汇出成文字档到桌面,再将内容复制到 Json Editor Online 解析即可!
**或是直接使用 mitmweb 使用 web gui 直接浏览、操作*
mitmweb
经过嗅探、观察、过滤、测试之后就能知道APP API的运作方式,借此就能利用,用爬虫爬取资料。
*搜集完所需资讯记得关闭mitmproxy、手机网路Proxy代理伺服器改回自动,才能正常使用网路。
APP 该如何自保?
若挂上 mitmproxy 之后发现APP不能用、回传内容是编码,代表APP有做保护。
做法(1):
大略是将凭证资讯放一份到APP中,若当前HTTPS使用的凭证与APP中的资讯不符则拒绝访问,详细可以 看此 或找 SSL Pinning 相关资源。缺点可能就是要注意凭证有效期的问题吧!
https://medium.com/@dzungnguyen.hcm/ios-ssl-pinning-bffd2ee9efc
作法(2):
APP端在资料要传输前先进行编码加密,API后端收到后解密取得原始请求内容;API回传内容一样先进行编码加密,APP端收到资料后解密取得回传内容;步骤很烦琐也耗效能,但的确是个方法;据我所知好像某数字银行就是用这招进行保护!
不过….
作法1,依然有破解方法: 如何在iOS 12上绕过SSL Pinning
作法2,透过反编译工程也能获得编码加密用的密钥
⚠️没有100%的安全⚠️
或是干脆挖个洞让它爬,边搜集各种证据,再用法务解决(?
还是那句话:
「 NEVER TRUST THE CLIENT」
mitmproxy 的更多玩法:
1.使用mitmdump
除 mitmproxy
、 mitmweb
, mitmdump
可直接将所有纪录汇出到文字档中
1
mitmdump -w /log.txt
并且能使用 玩法(2) python程式,设定、筛选流量:
1
mitmdump -ns examples/filter.py -r /log.txt -w /result.txt
2.搭配python程式做请求参数设定、访问控制、转址:
1
2
3
4
5
6
7
8
9
10
11
12
13
from mitmproxy import http
def request(flow: http.HTTPFlow) -> None:
# pretty_host takes the "Host" header of the request into account,
# which is useful in transparent mode where we usually only have the IP
# otherwise.
# 请求参数设定 Example:
flow.request.headers['User-Agent'] = 'MitmProxy'
if flow.request.pretty_host == "123.com.tw":
flow.request.host = "456.com.tw"
# 将123.com.tw的访问全导到456.com.tw
转址范例
启用mitmproxy时加上参数:
1
2
3
4
5
mitmproxy -s /redirect.py
or
mitmweb -s /redirect.py
or
mitmdump -s /redirect.py
补个坑
在使用 mitmproxy 观察使用 HTTP 1.1 及 Accept-Ranges: bytes、 Content-Range 长连接片段持续拿取资源的请求时,会等到 response 全部回来才会显示,而不是显示分段、使用持久连接接续下载!
踩坑在这 。
延伸阅读
后记
因为我没有网域权限无法取得ssl凭证资讯,所以也无法实作;看程式码感觉并不困难,虽然没有100%安全的方法,但多一道防护至少能更安全一些,再继续攻需要花费很多时间研究,应该能劝退90%的爬虫了!
这篇文章可能有点含金量太低,medium荒废了一阵子(跑去玩单眼),主要为本周六日(2019/09/21–2019/09/22)的 iPlayground 2019 提前热热写文手感;期待今年的议程🤩,希望回来后能吸收产出更多精品文章!
[2019/02/22 更新文章] iPlayground 2019 是怎么样的体验?
有任何问题及指教欢迎 与我联络 。
本文首次发表于 Medium (点击查看原始版本),由 ZMediumToMarkdown 提供自动转换与同步技术。