Python与crontab实现自动化每日健康上报

持续了快两年的疫情,改变了很多事也打乱了很多人生活的节奏(对我这个死宅来说几乎没啥影响),就是每天的健康上报经常会忘,所以为了偷懒,就突发奇想利用脚本实现每日自动化上报。

实现过程分析

电脑上对模拟器里的企业微信进行抓包分析

因为健康打卡的url链接在首届和电脑的浏览器上不能直接打开,所以我想只能通过模拟器里装企业微信进行抓包分析,我用了网上比较推荐的夜神模拟器,用Bp抓包,首先设置模拟器wifi代理,然后安装CA证书,就可以将流量代理到bp上,这些基操就不多写了(网上文章很多),直接上图

一共抓到三个包

第一个包是一个302跳转,跳转到第二个包,这个包不知道是什么意思,感觉有点多余

image-20211106181215379

第二个包才是真正的提交页面

image-20211106181306381

第三个是表单提交的包

image-20211106181408269

分析请求的url里,前面都是固定的,只有两个参数是变化的,一个是_time/后面的时间戳,另一个就是code/后面的一串编码,不知道是什么编码,我尝试用cyberchef的magic模块来进行检测

image-20211106182907524

image-20211106183308291

看起来好像是Base64编码,然而解密出来的内容是加密的,不知道算法就很难搞,不知道这个code参数是什么意思,这里就不管它了,因为我经过测试发现,即使只用这个单一不变的code来发包也同样能够健康上报成功。

然后分析POST包的提交内容,显然是url编码,由于我Bp字体乱码问题用不了decode模块,直接去在线url解码平台,解码之后的数据如下

image-20211106184420185

其实就是健康上报页面的form表单内的内容,这里我把学号和手机号进行了马赛克的脱敏操作防止信息泄露,举个例子其中的dkjtdz参数就是健康上报页面的打卡具体地址(必填),这里我一直写的是杭商院,其他的一些参数(如地区、绿码等等)对每个人来说都是通用的不用改,只需要改姓名、学号、手机号就行了。

分析好之后就可以用Python进行POST发包实现健康上报了

利用Python的requests模块模拟POST请求发包来实现健康上报

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
import requests
import smtplib
import time
from email.mime.text import MIMEText
from email.utils import formataddr

# name=input("请输入姓名:")
# xh=input("请输入学号:")
# sj=input("请输入手机号:")
# email=input("请输入邮箱:")

name="朱文豪"
xh="xxxxxxxx34"
sj="xxxxxxxxxxx"
email="1252448508@qq.com"
time=time.strftime("%Y/%m/%d", time.localtime())

def healthsubmit(name,xh,sj,time,email):
url="http://qy.zjhzcc.edu.cn/ami/ihs.php/Index/icon_yqtb/id/27/_sign/5E29795015AFD5127A14DFA86A579F7140B159F3/wtype/student/_time/1635955731/code/qJP0xu9Cgiu9QUvpypw9gAJyBktl8jFiBQ37YZ90Q-A.html"
headers={
"Host": "qy.zjhzcc.edu.cn",
"Content-Length":"565",
"Cache-Control": "max-age=0",
"Origin": "http://qy.zjhzcc.edu.cn",
"Upgrade-Insecure-Requests": "1",
"Content-Type": "application/x-www-form-urlencoded",
"User-Agent": "Mozilla/5.0 (Linux; Android 7.1.2; SM-G955N Build/NRD90M.G955NKSU1AQDC; wv) AppleWebKit/537.36 (KHTML, like Gecko) Version/4.0 Chrome/75.0.3770.143 Mobile Safari/537.36 wxwork/3.1.19 ColorScheme/Light MicroMessenger/7.0.1 NetType/WIFI Language/zh Lang/zh",
"Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3",
"Referer": "http://qy.zjhzcc.edu.cn/ami/ihs.php/Index/icon_yqtb/id/27/_sign/5E29795015AFD5127A14DFA86A579F7140B159F3/wtype/student/_time/1635955731/code/qJP0xu9Cgiu9QUvpypw9gAJyBktl8jFiBQ37YZ90Q-A.html",
"Accept-Encoding": "gzip, deflate",
"Accept-Language": "zh-CN,zh;q=0.9,en-US;q=0.8,en;q=0.7",
"Cookie": "PHPSESSID=ph5pv47p86i2kk54es8kk8nm67",
"X-Requested-With": "com.tencent.wework",
"Connection": "close"
}
data={
"tbrq":time,
"txr":name,
"lx":"Xs",
"gh":xh,
"bm":"人工智能与电子商务学院",
"bj":"计科1901",
"sj":sj,
"jtzz":"低风险区(大杭州内)",
"jtdz":"",
"addr":"浙江省杭州市",
"ip":"36.22.152.16",
"area":"浙江省",
"dkjtdz":"杭商院",
"yqfk":"健康",
"jkm":"已申领,绿码",
"xmfl":"否",
"hxrq":""
}
res=requests.post(url,headers=headers,data=data)
#print(res.text)
my_sender = '1252448508@qq.com' # 发件人邮箱账号
my_pass = 'xxxxxxxxx' # 发件人邮箱密码
my_user = email # 收件人邮箱账号,我这边发送给自己
ret = True
try:
msg = MIMEText(res.text, 'plain', 'utf-8')
msg['From'] = my_sender # 括号里的对应发件人邮箱昵称、发件人邮箱账号
msg['To'] = my_user # 括号里的对应收件人邮箱昵称、收件人邮箱账号
msg['Subject'] = "每日疫情签到情况:" # 邮件的主题,也可以说是标题

server = smtplib.SMTP_SSL("smtp.qq.com", 465) # 发件人邮箱中的SMTP服务器,端口是25
server.login(my_sender, my_pass) # 括号中对应的是发件人邮箱账号、邮箱密码
server.sendmail(my_sender, my_user, msg.as_string()) # 括号中对应的是发件人邮箱账号、收件人邮箱账号、发送邮件
server.quit() # 关闭连接
except Exception: # 如果 try 中的语句没有执行,则会执行下面的 ret=False
ret = False
if ret:
print("邮件发送成功")
print("健康上报完成")
else:
print("邮件发送失败")
print("健康上报失败")

if __name__=="__main__":
# print("---------------")
# print("[*]杭商院健康上报脚本启动")
healthsubmit(name,xh,sj,time,email)
healthsubmit("金正阳","xxxxxxxx31","xxxxxxxxxxx",time,"xxxxxxx@qq.com")
healthsubmit("卢雨诚","xxxxxxxx36","xxxxxxxxxxx",time,"xxxxxxx@qq.com")
healthsubmit("黄晔莹","xxxxxxxx26","xxxxxxxxxxx",time,"xxxxxxx@qq.com")

代码分为两个部分,第一部分是用requests模块进行POST请求,第二部分是用smtplib库将POST请求返回的上报完成情况发送到个人邮箱进行提醒,两部分都在healthsubmit函数中完成,出于安全的考虑我将代码中我和我室友的个人信息(学号、手机号)以及smtp的授权码进行了脱敏,本地测试成功,然后就将文件放到服务器上设置crontab定时任务,实现每日自动上报。

crontab定时任务设置

基本思路就是先将写好的python脚本上传到服务器,然后写一个.sh文件作为入口,然后在.sh文件中执行该py脚本(不用sh入口直接在crontab里运行py脚本也可以),然后设置crontab定时任务,让服务器在每天的0时1分的时候自动执行健康上报的脚本。

1.在ssh客户端上安装lrzsz,然后就可以将本地文件直接传到服务器上

1
apt install lrzsz

2.sh文件内容如下

1
2
cd /home/ubuntu
python3 healthsubmit.py >> hist

c

3.设置crontab定时任务

使用crontab -e命令来编辑cron任务,由于我之前用新的ssh客户端,用该命令进去是nano编辑器不是vim导致我不会退出,所以用了另一种方式来创建cron任务,先将要运行的命令放到rootcron文件,然后执行crontab rootcron就可以将该文件提交给cron进程。

截屏2021-11-06 下午7.18.00

前面的五个参数分别代表:分钟、小时、日、月、星期,第六个参数就是要运行的命令

所以我这里的意思是,在每天的0时1分自动运行写好的健康上报脚本,由于crontab运行完会有输出信息,日积月累,日志信息会非常大可能影响系统正常运行,所以就需要重定向,命令中的> /dev/null 2>&1的意思就是将输出信息重定向到/dev/null,因为/dev/null代表空设备文件,它会丢弃一切写入的数据。

经过今天(11月6日)的测试,我和我室友都成功在0时1分的时候完成了健康上报,成功解放了双手

image-20211106193853117

image-20211106193908993

需要思考的问题

code参数的具体含义

这个问题虽然影响不大,但是如果能成功解码,获取其内容的话,就可以根据它的含义来让代码自动生成并编码进行拼接请求

cookie的时间问题

image-20211106195546706

image-20211106200259415

这是我在手机端抓的包,可以看到Set-Cookie的expire过期时间为1969-12-31T23:59:59.000Z,经过查询在Set-Cookie时,如果没有设置expire过期时间的话,chrome就会显示为1969-12-31T23:59:59.000Z,这个过期时间代表这个cookie是session cookie(会话cookie),浏览器关闭之后就失效了

但是奇怪的是,这个脚本我测试了两天,即使企业微信的cookie由于我在手机端和电脑端的切换导致cookie已经发生了变化,但是我用前两天的cookie进行请求也成功完成了健康上报,所以不知道这个cookie我能用到什么时候

代码的可用性有待提高

我写的Python代码太low了,需要事先在代码中写好需要上报的人的个人信息,我想如果之后有更多的人需要我帮忙挂的话,我又要改代码然后再重新传到服务器上,这显然是麻烦且没必要的。所以如果要改的话,我想应该再加上数据库的联动,有了数据库就可以通过对数据库的增删改来控制需要挂脚本的人,或者可以做个GUI的图形化工具,发给别人来提交个人信息到数据库。另外,还有一个思路就是创建一个excel表格,只要增删表格内容,然后让python自动获取表中的内容进行健康上报就行了。这两个方法本质上都是对一个可变数据集的读取然后循环进行健康上报。

这些仅仅是我的个人想法,如果以后有时间和需求的话,我可能会改进一下代码。

越权操作带来的安全问题

因为将请求包中的学号等个人信息修改成别人的,就可以实现替别人进行健康上报,这个越权的带来的安全问题就是因为,健康上报涉及到打卡居住地(可恶意将别人改为高风险区)、打卡具体地址(也可恶意修改)、当日身体健康状况(恶意改成发烧咳嗽等等)、健康码状况(可改为红码)、有无接触过确诊/疑似病例(可改成有)。

试想如果将别人的健康上报内容恶意修改为不安全的内容之后,可能入校通行码会变红甚至会被学校拉去隔离,虽然可能后续的危害不大,但是会给受害人造成很多不必要的麻烦。因为我不知道学校的这个健康上报系统若收到有风险的上报后会如何处理,所以也不确定具体的风险

造成该越权的原因大概是后端对健康上报表单的提交没有进行身份验证(authentication)

参考资料

http://testingpai.com/article/1612340448369

https://www.cnblogs.com/wjrblogs/p/13683812.html

https://tianzeee.github.io/2021/03/31/python-requests-learning/

https://www.cnblogs.com/netsa/p/7992280.html

https://www.136.la/shida/show-108833.html

https://www.petefreitag.com/item/854.cfm

https://dengxj.blog.csdn.net/article/details/104853830

https://blog.csdn.net/Deep_Rayne/article/details/109599171

https://www.cnblogs.com/kerrycode/p/3238346.html

https://linuxtools-rst.readthedocs.io/zh_CN/latest/tool/crontab.html

  • Copyright: Copyright is owned by the author. For commercial reprints, please contact the author for authorization. For non-commercial reprints, please indicate the source.

扫一扫,分享到微信

微信分享二维码
  • Copyrights © 2020-2021 Blog of Tianze

请我喝杯咖啡吧~

支付宝
微信