https://blog.csdn.net/song_lee/article/details/128847729
https://evilpan.com/2023/01/30/android-iptables/
https://blog.seeflower.dev/archives/296/
总结来说,有两个难点:
- 如何拦截到这个包:这对应了把数据从网线中拿出来的能力,对应透明代理
- 如何看懂这个包:这就要绕过网络应用层的加密方案,对应证书绕过
拦截包
这里我们有两种方法:显式代理和透明代理。本质上都是放一个传话的人在中间,我们通过中间人就能知道包的内容了,问题就是怎么让应用去和这个中间人说话而不是不管他。
普通代理
- 手动配置代理:你需要在手机设置中填写代理服务器的 IP 和端口(例如 192.168.1.200:8888)。
- 手机发送 HTTP 请求时,目标地址改为代理服务器(192.168.1.200:8888),而不是原始服务器。代理服务器收到请求后,解析出真正的目标地址(www.example.com),代替你向服务器发送请求。
- 代理服务器将服务器的响应返回给手机。
本质:你主动告诉手机:“所有流量都先发给代理,让它帮我转发”。那这个就很简单,但也很容易检测到
透明代理(无感知代理)
ARP 欺骗(透明代理常见手段)
ARP 协议的作用:将 IP 地址映射为 MAC 地址(局域网内通信依赖 MAC 地址)。
ARP 欺骗原理: 代理服务器发送虚假 ARP 响应,告诉路由器:“IP 93.184.216.34 的 MAC 地址是我的(代理服务器的 MAC)”。路由器误将本应发往外部服务器的数据包,发送给代理服务器。
NAT 重定向(iptables 实现)
在 Linux 系统中,可以通过 iptables 命令强制将流量转发到代理端口:将所有 80 端口的流量重定向到代理的 8888 端口
iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8888
https://evilpan.com/2023/01/30/android-iptables/ 这篇文章就很详细的介绍了实践方法
到现在为止,我们算是弄懂了在网线中飞的数据是什么了,但是因为现代通信协议的加密,我们还是看不懂内容的,因此我们还需要第二步:
解密包
https 协议中,C(Client 客户端) 需要确保 C 发送包的目标就是 C 想要发送给的 ip 地址下的那个 S(Server 服务器端),不然就会导致我们正要干的事情——提前假扮成那个 ip 地址下的服务器,从而和我交换密钥开始加密流量传输了。这要借助 数字证书
有一个大家都能找得到的机构,它的公钥大家都能权威的唯一确定,那么经过它签名后的东西也相当可信。于是真正的 S 们就把自己的公钥上传给它让它签名(当然这里权威机构也得看着,不可能允许两个 S 同样 ip 的事情发生),然后 S 再给 C 发送权威机构签过名的公钥,C 就相信了这就是我要找的 ip 对应的那个 S,于是双方就这么交换通信密钥了。
但是我们在这里做猫腻。
这里的代理工具需要生成一个自签名证书(需要手动安装到设备的信任证书列表中)
有的同学就要问了,你说装了我就要信任啊,我应用里面自己固定了就那几个我才信任怎么办?别急,这 SSL Pinning 我们直接 hook 绕过嘛,或者之类的东西直接暴力让它不工作就行了嘛,这就是 JustTrustMe 之类的工具的原理
如果客户端信任了这个证书,那么就认为代理伪装好的 S 就是那个 ip 对应的真正的 S,从而和它建立加密链接,这样一来,我们的代理就知道包里面的内容了。
todo:如何系统化的找到应用那个位置发的哪个包?自定义协议的破解工作该怎么规范化展开?(被面试问到了,这我确实感觉是一个非常好的点需要我后面去研究)