某单位组织员工开展健步走活动,由于策略限制,必须使用传统计步器或者手机APP的方式记录行走步数,且APP必须始终处于运行状态方能计步,这种不合理的方式严重影响了客户体验,但是这一切的一切都没法改变,所以想着能不能通过修改数据包的方式完成步数的刷新上传。
使用Charles对上传的数据进行分析
由于是通过手机APP的记录并上传行走步数,因此采用比较易用和好用的Charles抓包工具对APP上传的数据包进行分析
为了避免被某APP发现,此处隐藏掉APP的网站链接和目录
通过不断的下拉刷新该APP的步数可以看出,发生变动的有三个网站链接,继续寻找与步数记录相关的数据包可以发现,它存在于IHttpServletDataService下
进一步查看数据包
通过查看数据包内容发现,整个步数的刷新是通过ReqMessageBody以及commond两个字段组成的Form提交完成的
Form表单内容分析
展开ReqMessageBody的内容(使用json数据格式方便进行查看)
{
"clientvison": "4.3.2",
"commond": "UploadData",
"dayPackage": "0",
"deviceType": "DS101",
"deviceserial": "06800000010130ffc4162b9fc",
"hourPackage": "0",
"listday": [
{
"calorieConsumed": 78.0,
"exerciseAmount": 1.2,
"fatConsumed": 11.1,
"goalStepNum": 10000,
"stepNumber": 2247,
"stepWidth": 70,
"walkDistance": 157290,
"walkTime": 18,
"walkdate": "20180910",
"weight": 60,
"zmrule": "6,7,8,9#3000;18,19,20,21,22#4000",
"zmstatus": "0,0"
},
{
"calorieConsumed": 1.0,
"exerciseAmount": 0.0,
"fatConsumed": 0.1,
"goalStepNum": 10000,
"stepNumber": 35,
"stepWidth": 70,
"walkDistance": 2450,
"walkTime": 0,
"walkdate": "20180909",
"weight": 60,
"zmrule": "6,7,8,9#3000;18,19,20,21,22#4000",
"zmstatus": "0,0"
}
],
"listhour": [
{
"hour0": "0,0,0,0,0,0",
"hour1": "0,0,0,0,0,0",
"hour10": "668,46760,668,46760,0,0",
"hour11": "228,15960,228,15960,0,0",
"hour12": "0,0,0,0,0,0",
"hour13": "0,0,0,0,0,0",
"hour14": "0,0,0,0,0,0",
"hour15": "0,0,0,0,0,0",
"hour16": "0,0,0,0,0,0",
"hour17": "0,0,0,0,0,0",
"hour18": "0,0,0,0,0,0",
"hour19": "0,0,0,0,0,0",
"hour2": "0,0,0,0,0,0",
"hour20": "0,0,0,0,0,0",
"hour21": "0,0,0,0,0,0",
"hour22": "0,0,0,0,0,0",
"hour23": "0,0,0,0,0,0",
"hour24": "0,0,0,0,0,0",
"hour25": "0,0,0,0,0,0",
"hour3": "0,0,0,0,0,0",
"hour4": "0,0,0,0,0,0",
"hour5": "0,0,0,0,0,0",
"hour6": "508,35560,508,35560,0,0",
"hour7": "184,12880,184,12880,0,0",
"hour8": "659,46130,659,46130,0,0",
"hour9": "0,0,0,0,0,0",
"walkdate": "20180910"
},
{
"hour0": "0,0,0,0,0,0",
"hour1": "0,0,0,0,0,0",
"hour10": "0,0,0,0,0,0",
"hour11": "0,0,0,0,0,0",
"hour12": "0,0,0,0,0,0",
"hour13": "0,0,0,0,0,0",
"hour14": "0,0,0,0,0,0",
"hour15": "0,0,0,0,0,0",
"hour16": "0,0,0,0,0,0",
"hour17": "0,0,0,0,0,0",
"hour18": "0,0,0,0,0,0",
"hour19": "0,0,0,0,0,0",
"hour2": "0,0,0,0,0,0",
"hour20": "0,0,0,0,0,0",
"hour21": "16,1120,16,1120,0,0",
"hour22": "19,1330,19,1330,0,0",
"hour23": "0,0,0,0,0,0",
"hour24": "0,0,0,0,0,0",
"hour25": "0,0,0,0,0,0",
"hour3": "0,0,0,0,0,0",
"hour4": "0,0,0,0,0,0",
"hour5": "0,0,0,0,0,0",
"hour6": "0,0,0,0,0,0",
"hour7": "0,0,0,0,0,0",
"hour8": "0,0,0,0,0,0",
"hour9": "0,0,0,0,0,0",
"walkdate": "20180909"
}
],
"reqservicetype": 1,
"sequenceID": "1536550643973"
}
大致判断步数主要由stepNumber字段控制,walkdate为计步日期,同时listhour列表中包含了每个计步小时周期内的具体步数,虽然不知道具体的含义,但是已经不影响数据的修改和上传了
使用requests模拟POST表单提交
到现在我们就找到了影响数据步数的数据字段,下面使用python模拟数据交互过程
导入需要的类和库文件
import requests
import urllib
import json
import datetime
import time
import random
通过分析可以得出,真正标识一个用户或者设备的是deviceserial,这个可以通过ReqMessageBody看出,同时为了真实伪装POST报文信息,对headers进行相应设置
url = '网站链接'
headers = {
'User-Agent' : 'Dalvik/2.1.0 (Linux; U; Android 8.0.0; MHA-TL00 Build/HUAWEIMHA-TL00)',
'Content-Type' : 'application/x-www-form-urlencoded; charset=UTF-8',
'Content-Length' : '2000',
'Connection' : 'keep-alive'}
today = (datetime.datetime.now() - datetime.timedelta(days = 0))
yesterday = (datetime.datetime.now() - datetime.timedelta(days = 1))
str_today = today.strftime("%Y%m%d")
str_yesterday = yesterday.strftime("%Y%m%d")
表头中设置了User-Agent和Content-Type等关键信息,同时使用datetime函数以及strftime函数获取格式化为20180910格式的当前日期
为了模拟步数的真实性,使用random.randint函数获取每个小时时段内的随机步数
hour6_1number = random.randint(500,1500)
hour6_2number = random.randint(500,1500)
hour7_1number = random.randint(500,1500)
hour7_2number = random.randint(500,1500)
hour8_1number = random.randint(500,1500)
hour8_2number = random.randint(500,1500)
hour10_1number = random.randint(500,1500)
hour10_2number = random.randint(500,1500)
hour12_1number = random.randint(500,1500)
hour12_2number = random.randint(500,1500)
hour13_1number = random.randint(500,1500)
hour13_2number = random.randint(500,1500)
hour18_1number = random.randint(500,1500)
hour18_2number = random.randint(500,1500)
hour19_1number = random.randint(500,1500)
hour19_2number = random.randint(500,1500)
hour20_1number = random.randint(500,1500)
hour20_2number = random.randint(500,1500)
hour21_1number = random.randint(500,1500)
hour21_2number = random.randint(500,1500)
组装新的Message报文信息
message = {
"clientvison": "4.3.2",
"commond": "UploadData",
"dayPackage": "0",
"deviceType": "DS101",
#"deviceserial": "06800000010130ffc4162b9fc",
"deviceserial": "0680000001000ecb75cdf611c542",
"deviceserial":device,
"hourPackage": "0",
"listday": [
{
"calorieConsumed": 78.0,
"exerciseAmount": 1.2,
"fatConsumed": 11.1,
"goalStepNum": 10000,
#"stepNumber": 18222,
"stepNumber": today_stepNumber,
"stepWidth": 70,
"walkDistance": 157290,
"walkTime": 18,
#"walkdate": "20180910",
"walkdate": str_today,
"weight": 60,
"zmrule": "6,7,8,9#3000;18,19,20,21,22#4000",
"zmstatus": "0,0"
},
{
"calorieConsumed": 1.0,
"exerciseAmount": 0.0,
"fatConsumed": 0.1,
"goalStepNum": 10000,
#"stepNumber": 35,
"stepNumber": yesterday_stepNumber,
"stepWidth": 70,
"walkDistance": 2450,
"walkTime": 0,
#"walkdate": "20180909",
"walkdate": str_yesterday,
"weight": 60,
"zmrule": "6,7,8,9#3000;18,19,20,21,22#4000",
"zmstatus": "0,0"
}
],
"listhour": [
{
"hour0": "0,0,0,0,0,0",
"hour1": "0,0,0,0,0,0",
#"hour10": "668,46760,668,46760,0,0",
"hour10":"{step1},{cal1},{step2},{cal2},0,0".format(step1 = hour10_1number,cal1 = hour10_1number * 70,step2 = hour10_2number,cal2 = hour10_2number * 70,),
"hour11": "228,15960,228,15960,0,0",
#"hour12": "0,0,0,0,0,0",
"hour12":"{step1},{cal1},{step2},{cal2},0,0".format(step1 = hour12_1number,cal1 = hour12_1number * 70,step2 = hour12_2number,cal2 = hour12_2number * 70,),
#"hour13": "0,0,0,0,0,0",
"hour13":"{step1},{cal1},{step2},{cal2},0,0".format(step1 = hour13_1number,cal1 = hour13_1number * 70,step2 = hour13_2number,cal2 = hour13_2number * 70,),
"hour14": "0,0,0,0,0,0",
"hour15": "0,0,0,0,0,0",
"hour16": "0,0,0,0,0,0",
"hour17": "0,0,0,0,0,0",
#"hour18": "0,0,0,0,0,0",
"hour18":"{step1},{cal1},{step2},{cal2},0,0".format(step1 = hour18_1number,cal1 = hour18_1number * 70,step2 = hour18_2number,cal2 = hour18_2number * 70,),
#"hour19": "0,0,0,0,0,0",
"hour19":"{step1},{cal1},{step2},{cal2},0,0".format(step1 = hour19_1number,cal1 = hour19_1number * 70,step2 = hour19_2number,cal2 = hour19_2number * 70,),
#"hour20": "0,0,0,0,0,0",
"hour20":"{step1},{cal1},{step2},{cal2},0,0".format(step1 = hour20_1number,cal1 = hour20_1number * 70,step2 = hour20_2number,cal2 = hour20_2number * 70,),
#"hour21": "0,0,0,0,0,0",
"hour21":"{step1},{cal1},{step2},{cal2},0,0".format(step1 = hour21_1number,cal1 = hour21_1number * 70,step2 = hour21_2number,cal2 = hour21_2number * 70,),
"hour22": "0,0,0,0,0,0",
"hour23": "0,0,0,0,0,0",
"hour24": "0,0,0,0,0,0",
"hour25": "0,0,0,0,0,0",
"hour3": "0,0,0,0,0,0",
"hour4": "0,0,0,0,0,0",
"hour5": "0,0,0,0,0,0",
#"hour6": "508,35560,508,35560,0,0",
"hour6":"{step1},{cal1},{step2},{cal2},0,0".format(step1 = hour6_1number,cal1 = hour6_1number * 70,step2 = hour6_2number,cal2 = hour6_2number * 70,),
#"hour7": "184,12880,184,12880,0,0",
"hour7":"{step1},{cal1},{step2},{cal2},0,0".format(step1 = hour7_1number,cal1 = hour7_1number * 70,step2 = hour7_2number,cal2 = hour7_2number * 70,),
#"hour8": "659,46130,659,46130,0,0",
"hour8":"{step1},{cal1},{step2},{cal2},0,0".format(step1 = hour8_1number,cal1 = hour8_1number * 70,step2 = hour8_2number,cal2 = hour8_2number * 70,),
"hour9": "0,0,0,0,0,0",
"walkdate": str_today,
#"walkdate": "20180910"
},
{
"hour0": "0,0,0,0,0,0",
"hour1": "0,0,0,0,0,0",
"hour10": "0,0,0,0,0,0",
"hour11": "0,0,0,0,0,0",
"hour12": "0,0,0,0,0,0",
"hour13": "0,0,0,0,0,0",
"hour14": "0,0,0,0,0,0",
"hour15": "0,0,0,0,0,0",
"hour16": "0,0,0,0,0,0",
"hour17": "0,0,0,0,0,0",
"hour18": "0,0,0,0,0,0",
"hour19": "0,0,0,0,0,0",
"hour2": "0,0,0,0,0,0",
"hour20": "0,0,0,0,0,0",
"hour21": "16,1120,16,1120,0,0",
"hour22": "19,1330,19,1330,0,0",
"hour23": "0,0,0,0,0,0",
"hour24": "0,0,0,0,0,0",
"hour25": "0,0,0,0,0,0",
"hour3": "0,0,0,0,0,0",
"hour4": "0,0,0,0,0,0",
"hour5": "0,0,0,0,0,0",
"hour6": "0,0,0,0,0,0",
"hour7": "0,0,0,0,0,0",
"hour8": "0,0,0,0,0,0",
"hour9": "0,0,0,0,0,0",
#"walkdate": "20180909"
"walkdate": str_yesterday,
}
],
"reqservicetype": 1,
"sequenceID": "1536550643973"
}
使用requests函数提交表单信息并打印返回信息
req_message = {
#'ReqMessageBody' : '{"clientvison":"4.3.2","commond":"UploadData","dayPackage":"0","deviceType":"DS101","deviceserial":"06800000010130ffc4162b9fc","hourPackage":"0","listday":[{"calorieConsumed":522.0,"exerciseAmount":8.3,"fatConsumed":74.5,"goalStepNum":10000,"stepNumber":18111,"stepWidth":70,"walkDistance":1045730,"walkTime":124,"walkdate":"20180910","weight":60,"zmrule":"6,7,8,9#3000;18,19,20,21,22#4000","zmstatus":"0,0"}],"listhour":[{"hour0":"0,0,0,0,0,0","hour1":"0,0,0,0,0,0","hour10":"0,0,0,0,0,0","hour11":"171,11970,171,11970,0,0","hour12":"690,48300,690,48300,0,0","hour13":"12,840,12,840,0,0","hour14":"1819,127330,1819,127330,0,0","hour15":"0,0,0,0,0,0","hour16":"0,0,0,0,0,0","hour17":"0,0,0,0,0,0","hour18":"0,0,0,0,0,0","hour19":"0,0,0,0,0,0","hour2":"0,0,0,0,0,0","hour20":"0,0,0,0,0,0","hour21":"0,0,0,0,0,0","hour22":"0,0,0,0,0,0","hour23":"0,0,0,0,0,0","hour24":"0,0,0,0,0,0","hour25":"0,0,0,0,0,0","hour3":"0,0,0,0,0,0","hour4":"0,0,0,0,0,0","hour5":"0,0,0,0,0,0","hour6":"0,0,0,0,0,0","hour7":"0,0,0,0,0,0","hour8":"0,0,0,0,0,0","hour9":"0,0,0,0,0,0","walkdate":"20180910"}],"reqservicetype":1,"sequenceID":"1536561269248"}',
'ReqMessageBody' : json.dumps(message),
'commond' : 'UploadData'
}
r = requests.post(url,headers = headers,data = req_message)
r.raise_for_status()
print(r.text)
time.sleep(10)
至此,所有的代码编写完毕,最重要的还是对数据包的分析,代码相对比较基础,目前来看,这个程序能够有效修改步数(希望不要被某APP发现并进行策略限制)
将Python程序添加到windows例行任务里面能够每天定时执行代码并修改步数,当然啦,这个只是单纯的玩一玩,为了自己的身体健康还是应该运动起来,真正修改自己的Body,让它充满活力。