https://github.com/ZJ595/AndroidReverse/blob/main/Article/20%E7%AC%AC%E4%BA%8C%E5%8D%81%E8%AF%BE%E3%80%81%E6%8A%93%E5%8C%85%E5%AD%A6%E5%BE%97%E5%A5%BD%EF%BC%8C%E7%89%A2%E9%A5%AD%E5%90%83%E5%BE%97%E9%A5%B1(%E4%B8%8A).md

https://blog.csdn.net/song_lee/article/details/128847729

https://evilpan.com/2023/01/30/android-iptables/

https://blog.seeflower.dev/archives/296/


总结来说,有两个难点:

  1. 如何拦截到这个包:这对应了把数据从网线中拿出来的能力,对应透明代理
  2. 如何看懂这个包:这就要绕过网络应用层的加密方案,对应证书绕过

拦截包

这里我们有两种方法:显式代理和透明代理。本质上都是放一个传话的人在中间,我们通过中间人就能知道包的内容了,问题就是怎么让应用去和这个中间人说话而不是不管他。

普通代理

  • 手动配置代理:你需要在手机设置中填写代理服务器的 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:如何系统化的找到应用那个位置发的哪个包?自定义协议的破解工作该怎么规范化展开?(被面试问到了,这我确实感觉是一个非常好的点需要我后面去研究)