本文不构成任何技术操作指导或建议,仅供技术交流与学习参考。如发现本文内容存在可能违反法律规定的情况,请立即联系本人删除相关内容。(已对图片中出现的包名和应用名进行处理)

Charles使用

官网网址:https://www.charlesproxy.com
网上已经有很多相关的教程了,我这里写一遍有点浪费时间。这里给几个链接:

  • 激活工具:https://down.52pojie.cn/?query=chales

  • 教程:https://blog.csdn.net/weixin_43612602/article/details/135287720
    这个教程缺少手机端的操作:
    下载安装好证书之后,电脑和手机连接到同一个网络,手机 WIFI 设置中,长按连接的网络,选择修改网络,其中代理选择手动,代理主机名是电脑的 IP 地址(IP 并不是每次都不变的,路由器的 ARP 表会更新的,所以一段时间之后重新进行代理,一定要记得重新设置一下‘代理服务器主机名’这一项)

    Pastedimage20250524172222.png

端口往往是 8888:
可以在电脑端 Charles 中的 Help->SSL Proxying->install charles RootCertificate on a Mobile…

Pastedimage20250524172648.png


然后,当开始抓包时,

Pastedimage20250524173255.png


点击 Allow 即可。

应用抓包

这次的目标是一款心理治愈类 APP,它有个挖胶囊的功能,但是每个账号每天只能抓 5 个胶囊。
开始之前,可以先把本地抓包关闭了,只抓手机上的数据包:

Pastedimage20250524175146.png


关闭 Windows Proxy。
然后挖个胶囊看看怎么个事:

Pastedimage20250524194201.png


先发送一个 POST 请求,获取 Yaoyiyao 服务,服务器随机返回一个用户的 info,然后 APP 根据 info 再次发送 info 中相关资源的 GET 请求,获取诸如头像,图片,音乐之类的资源,最后再获取与该 info 相关的评论。
再看看 POST 请求的 param 怎么设计的,有哪些参数:

Pastedimage20250524194829.png


我们照着这个请求自己实现一下 POST:

import requests  
  
URL="https://服务器/services/v2/xxxx/yaoYiYao"  
myparams = {  
    "userId":100000,  
    "longitude":100,  
    "latitude":50,  
    "blindBox":0  
}  
myheader={  
    "Content-Length": "0",  
    "Host": "服务器",  
    "Connection": "Keep-Alive",  
    "Accept-Encoding": "gzip",  
    "User-Agent": "okhttp/4.10.0"  
}  
response=requests.post(url=URL,params=myparams,headers=myheader)  
print(response.text)
Pastedimage20250524200553.png


这样就能获得服务了,id 可以随意伪造,longitude 和 latitude 也是可以随意伪造的。这个功能有个机制就是每个账号每天只能挖五个胶囊,我们可以设计一下,每请求 5 次,更改一下账号和经纬度,就能继续获取。
我据此实现了一个漂流瓶功能:

import requests  
import random  
import time  
import json  
  
class Myhttp:  
    def __init__(self):  
        # 基础URL和默认参数  
        self.base_url = "https://服务器/services/v2/xxxx/yaoYiYao"  
        self.userId = 100000  
        self.longitude = 109  
        self.latitude = 35  
        self.blindBox = 0  
  
        # 通用请求头  
        self.headers = {  
            "Content-Length": "0",  
            "Host": "服务器",  
            "Connection": "Keep-Alive",  
            "Accept-Encoding": "gzip",  
            "User-Agent": "okhttp/4.10.0"  
        }  
  
    def update_params(self):  
        """更新请求参数(随机化)"""  
        random.seed(time.time())  
        temp = random.random()  
  
        # 更新参数(使用更合理的随机化逻辑)  
        self.userId += int(temp * 1000000)  # 随机增加用户ID  
        self.longitude += (temp - 0.5) * 20  # 经度随机浮动  
        self.latitude += (temp - 0.5) * 20  # 纬度随机浮动  
  
        # 打印当前参数(调试用)  
        print(f"当前参数: UserID={self.userId}, 经纬度=({self.longitude}, {self.latitude})")  
  
    def post(self):  
        """发送POST请求(无需参数)"""  
        try:  
            # 构建请求参数  
            params = {  
                "userId": self.userId,  
                "longitude": self.longitude,  
                "latitude": self.latitude,  
                "blindBox": self.blindBox  
            }  
  
            # 发送请求  
            response = requests.post(self.base_url, params=params, headers=self.headers)  
            response.raise_for_status()  # 若状态码不是2xx,抛出异常  
            response_text=json.loads(response.text)  
            #print(response.text)  
  
            return response_text  # 返回JSON格式的响应数据  
  
        except requests.RequestException as e:  
            print(f"请求出错: {e}")  
            exit()  
  
  
def Myprint(msg):  
    """安全地打印消息内容,处理可能的空数据情况"""  
    if msg is None or msg.get("datas") is None:  
        print("没有找到有效的漂流瓶数据,跳过打印")  
        return  
  
    xxxx_dto = msg["datas"].get("xxxxDTO")  
    if not xxxx_dto:  
        print("没有找到有效的漂流瓶信息,跳过打印")  
        return  
  
    # 安全获取各个字段的值  
    xxxx_info = xxxx_dto.get("xxxxInfo", "")  
    user = xxxx_dto.get("user", {})  
    nickname = user.get("nickName", "无名人")  
    city_name = xxxx_dto.get("cityName", "未知地")  
    create_date_short = xxxx_dto.get("createDateShort", "")  
    media_url_list = xxxx_dto.get("mediaUrlList", "")  
  
    # 打印获取到的信息  
    print(nickname, 'from', city_name, '\n', xxxx_info, '\n', create_date_short, '\n', media_url_list)  
# 使用示例  
if __name__ == "__main__":  
    http_client = Myhttp()  
  
    while True:  
        http_client.update_params()  
        for i in range(5):  
            msg=http_client.post()  # 发送请求  
            Myprint(msg)  
            time.sleep(2)  # 等待2秒  
            print("\n\n\n\n\n\n下一个漂流瓶来咯~~~~~~\n\n")  
        # 每5次请求后等待更长时间  
        print("===== 休息5秒 =====")  
        time.sleep(3)

再加上一点页面:

Pastedimage20250524201438.png