写在前面

Python 课最后的大作业,跟大哥们一起写这个小玩意,因为学院好像很喜欢刷这些东西,总体来说挺简单的

分到我的模块刚刚好需要手机抓包,网页端易班登陆进去没有发动态的模块了,模块在维护

2022.11.30:不知道这篇文章里面的脚本还有没有用,如果有需要就自己试试脚本还能不能用吧

源码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
# -*- coding: utf-8 -*-
"""
@Time : 2021/5/5
@Author : C1everF0x
@File : dongtai
@Description :
"""
import re
import requests
import urllib.parse

def login():
'''
登录模块其实没有真正实现,网页端登录已经能通过逆向分析 login.js 文件来获取易班对密码在前端的加密算法,可以真正实现模拟登录
app端无法通过抓包或分析接口地址来找到加密方式
第一次输入密码登陆过后,app会将 loginToken 嵌入到 app 里,下次打开会提取拼接到 autologin 接口的 url中
目前能想到的 app 端实现真正模拟登录两种方法:
1、app 端在登录时候对密码的加密是嵌在 app 的源码里,真要做可以通过逆向分析 app 源码,找到加密代码逆向破解
2、使用类似于 seleium 的 appium 来实现模拟真正的人进行登录,再从中提取出 loginToken
目前实现只能够是抓包拿 loginToken 来给到 autologin 接口进行伪造登录
2021.05.07
:return:
'''
url = "https://mobile.yiban.cn/api/v3/passport/autologin?access_token=e3017321cf9cdae74e34061cf7adef4a"
header = {
'User-Agent': 'YiBan/4.9.9 Mozilla/5.0 (Linux; Android 5.1.1; MI 9 Build/NMF26X; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/74.0.3729.136 Mobile Safari/537.36',
'Authorization': 'Bearer e3017321cf9cdae74e34061cf7adef4a',
'loginToken': 'e3017321cf9cdae74e34061cf7adef4a',
'AppVersion': '4.9.9',
'Content-Type': 'application/json',
'Accept-Encoding': 'gzip, deflate'
}
try:
r = requests.get(url = url,headers = header)
r.raise_for_status() # 判断异常
r.encoding = r.apparent_encoding # 设置编码
return '登录成功'
except:
return '登录失败'

class DongTai:
def __init__(self,token,neirong_dongtai,neirong_pinglun): # 初始化类里面的私密属性
self.__token = token
self.neirong_dongtai = neirong_dongtai
self.__dongtai_hao = None
self.neirong_pinglun = neirong_pinglun
def release(self,neirong_dongtai):
'''
自动发布动态,动态内容需要进行一次 url 编码
动态发布成功后会返回一个 json ,里面有每个动态专属的一个九位数的号码
之后对动态进行的点赞、评论操作,需要通过该号码定位是哪条动态
:return:
'''
url = r'https://mobile.yiban.cn/api/v3/feeds/?access_token=' + self.__token + '&content=' + urllib.parse.quote(neirong_dongtai) + '&visibleScope=0&artwork=0&toUserIds=&address=&lat=&lng=&share=0&shareTitle=&shareUrl=&shareContent=&shareImage=&shareSource=&kind=1&hiddenAddress=0'
header = {
'User-Agent': 'YiBan/4.9.9 Mozilla/5.0 (Linux; Android 5.1.1; MI 9 Build/NMF26X; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/74.0.3729.136 Mobile Safari/537.36',
'Authorization': 'Bearer e3017321cf9cdae74e34061cf7adef4a',
'loginToken': 'e3017321cf9cdae74e34061cf7adef4a',
'AppVersion': '4.9.9',
'Content-Type': 'application/x-www-form-urlencoded',
'Accept-Encoding': 'gzip, deflate',
'Content-Length': '0',
}
try:
r = requests.post(url,headers = header)
r.raise_for_status()
r.encoding = r.apparent_encoding
response_json = r.text
re_response_json = re.findall(r'\d{9}',response_json) # 正则匹配提取动态号码
self.__dongtai_hao = ''.join(re_response_json) # 赋给私有变量
return '发布成功,该动态 id 为 {}'.format(self.__dongtai_hao)
except:
return '发布失败'

# 返回 json 样例,feedId 是动态号码
# {"response": 100, "message": "\u8bf7\u6c42\u6210\u529f",
# "data": {"feedId": 294594341, "feedCheckinReward": null}}

def give_good(self):
'''
自动给动态点赞
:return:
'''
url = r'https://mobile.yiban.cn/api/v3/feeds/' + self.__dongtai_hao + r'/ups?access_token=' + self.__token
header = {
'User-Agent': 'YiBan/4.9.9 Mozilla/5.0 (Linux; Android 5.1.1; MI 9 Build/NMF26X; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/74.0.3729.136 Mobile Safari/537.36',
'Authorization': 'Bearer e3017321cf9cdae74e34061cf7adef4a',
'loginToken': 'e3017321cf9cdae74e34061cf7adef4a',
'AppVersion': '4.9.9',
'Content-Type': 'application/x-www-form-urlencoded',
'Accept-Encoding': 'gzip, deflate',
'Content-Length': '0',
}
try:
r = requests.post(url, headers=header)
r.raise_for_status()
r.encoding = r.apparent_encoding
return '点赞成功'
except:
return '点赞失败'

def comments(self,neirong_pinglun):
'''
自动给动态评论,内容需要进行一次 url 编码,通过之前发布存入私有变量的动态号码来确定需要评论哪条动态
:return:
'''
url = r'https://mobile.yiban.cn/api/v3/feeds/' + self.__dongtai_hao + '/comments?access_token=' + self.__token + r'&content=' + urllib.parse.quote(neirong_pinglun) + r'&toUserId=&toCommentId='
header = {
'User-Agent': 'YiBan/4.9.9 Mozilla/5.0 (Linux; Android 5.1.1; MI 9 Build/NMF26X; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/74.0.3729.136 Mobile Safari/537.36',
'Authorization': 'Bearer e3017321cf9cdae74e34061cf7adef4a',
'loginToken': 'e3017321cf9cdae74e34061cf7adef4a',
'AppVersion': '4.9.9',
'Content-Type': 'application/x-www-form-urlencoded',
'Accept-Encoding': 'gzip, deflate',
'Content-Length': '0',
}
try:
r = requests.post(url, headers=header)
r.raise_for_status()
r.encoding = r.apparent_encoding
return '评论成功,评论内容为 {}'.format(neirong_pinglun)
except:
return '评论失败'

if __name__ == "__main__":
print(login())
token = 'e6262d37a192f6be11c159f4080326d9'
neirong_dongtai = input('请输入动态内容:')
neirong_pinglun = input('请输入评论内容:')
dongtai = DongTai(token,neirong_dongtai,neirong_pinglun) # 实例化动态类,需要提供 loginToken,发布动态内容和评论内容
print(dongtai.release(neirong_dongtai))
print(dongtai.comments(neirong_pinglun))
print(dongtai.give_good())

最后结果如图:

整体流程

  • 流程图如下

知识点

  • 使用 requests 库编写爬虫程序,实现模拟真实用户进行发布动态、评论动态和点赞动态的功能

  • 使用 re 库对发布动态成功后的返回包进行解析,提取发布成功的动态的动态号码

  • 搭建安卓虚拟机 + xposed 框架 + justTrustMe 模块,因为 app 可以自己检验 SSL 握手时服务器返回的证书是否合法,“SSL pinning” 技术指在 app 中只信任固定的证书和公钥,安卓 7.0 以上把证书分为系统证书和用户证书,有些 app 只信任系统证书,真实手机抓包会提示手机没网,所以需要使用 xposed 框架 + justTrustMe 模块,来 hook 掉本地证书强校验的逻辑,同时导入 burp 的证书,使其流量通过 burp,实现手机抓包

    Xposed 框架是一款开源框架,其功能是可以在不修改 APK 的情况下影响程序运行(修改系统)的框架服务,基于它可以制作出许多功能强大的模块,且在功能不冲突的情况下同时运作

    JustTrustMe 一个用来禁用、绕过 SSL 证书检查的基于 Xposed 模块。简单来说,JustTrustMe 是将 APK 中所有用于校验 SSL 证书的 API 都进行了 Hook,从而绕过证书检查的

  • 抓包分析各个功能对 api 请求的 url 构造格式和 http 请求头的伪造方法

  • 使用面向对象编程,将三个功能封装成类,方便团队进行最后的代码拼接

模拟登录

​ 模拟登录模块其实没有真正实现,网页端登录已经能通过逆向分析 login.js 文件来获取易班对密码在前端的加密算法,可以真正实现模拟登录
​ app 端无法通过抓包或分析接口地址来找到加密方式
在 app 里第一次输入密码成功登陆后,app 会将 loginToken 嵌入到 app 里,下次打开会提取拼接到请求 autologin api 接口的 url 中
​ 目前能想到的 app 端实现真正模拟登录两种方法:
​ 1、app 端在登录时候对密码的加密是嵌在 app 的源码里,真要做可以通过逆向分析 app 源码,找到加密代码逆向破解
​ 2、使用类似于 seleium 的 appium 来实现模拟真正的人进行登录,再从中提取出 loginToken
​ 目前实现只能够是抓包拿 loginToken 来给到 autologin 接口进行伪造登录

抓取 loginToken

  • 假设已经配置好了安卓虚拟机环境,在安卓虚拟机上打开易班,同时用 burp 抓包

  • 保存下来复制到代码里面,替换掉所有需要用到的地方

自动发布动态

自动发布动态,动态内容需要进行一次 url 编码
动态发布成功后会返回一个 json ,里面有每个动态专属的一个九位数的号码
之后对动态进行的点赞、评论操作,需要通过该号码定位是哪条动态

抓包分析

  • 发布动态时需要在 url 中添加 access_token 参数,内容为之前抓取到的 loginToken,在 http 请求头里面还存在两个需要用到 loginToken 的头

自动评论动态

自动给动态评论,评论内容需要进行一次 url 编码,通过之前发布存入私有变量的动态号码来确定需要评论哪条动态

自动点赞动态

拼接需要点赞的动态号进入请求点赞 api 的 url 中,请求即可完成点赞