在“i茅台”App中可以预约茅台酒,每天早上9:00-10:00可以在线预约茅台酒,每天手动预约过于繁琐,且容易忘记,中奖概率低,为了提高中奖概率无非就是用大量的手机号去登录APP每天定时预约,为了降低成本就需要上柯基了。
实现步骤:
1.通过手机号收取验证码登录i茅台app拿到用户token。
2.查询所预约门店投放数量
3.提交申购单
具体实现:
第一步:抓包分析i茅台app的登录接口
发送验证码接口:
1. 请求内容 Request:
POST /xhr/front/user/register/vcode HTTP/1.1
Host: app.moutai519.com.cn
MT-Device-ID: 2F2075D0-B66C-4287-A903-DBFF6358342C
MT-User-Tag: 0
Accept: */*
MT-Network-Type: WIFI
MT-Token: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJtdCIsImV4cCI6MTY3NzAzMDk4OSwidXNlcklkIjoxMDU0NDI3MzYxLCJkZXZpY2VJZCI6IjJGMjA3NUQwLUI2NkMtNDI4Ny1BOTAzLURCRkY2MzU4MzQyQyIsImlhdCI6MTY3NDQzODk4OX0.jMzprM-mO6yBTG3pjEcmq2fUgAjKwyuWHREmY6vynv0
MT-Team-ID:
MT-Bundle-ID: com.moutai.mall
Accept-Language: en-CN;q=1, zh-Hans-CN;q=0.9
MT-Request-ID: 167560018873318465
MT-APP-Version: 1.3.6
User-Agent: iOS;16.3;Apple;?unrecognized?
MT-R: clips_OlU6TmFRag5rCXwbNAQ/Tz1SKlN8THcecBp/HGhHdw==
Content-Length: 93
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Content-Type: application/json
{"md5":"66ca82023ea11ebca976db4506d34997","mobile":"199********","timestamp":"1675600188717"}
2. 响应内容 Response:
HTTP/1.1 200
Content-Type: application/json
Transfer-Encoding: chunked
Connection: keep-alive
Date: Sun, 05 Feb 2023 12:29:49 GMT
Server: yanxuan-ianus/0.9.7
{"code":2000}
发现请求body中有一个md5字段和时间戳字段,应该是进行了接口签名,修改手机号重放请求,不出所料返回{ "message" : "获取验证码失败","code" : 4010}对i茅台app进行hook分析,和逆向分析得到签名算法为:固定值+手机号+时间戳 进行md5
改写算法实现:
public static String getSignature(long timestamp, Map<String, String> data) {
Map<String, String> sortedMap = new TreeMap<>(data);
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(SALT);
for (Map.Entry<String, String> entry : sortedMap.entrySet()) {
stringBuilder.append(entry.getValue());
}
stringBuilder.append(timestamp);
return DigestUtils.md5Hex(stringBuilder.toString());
}
代入上面抓包结果进行验证得到相同的结果,验证成功!
验证码登录接口分析:
POST /xhr/front/user/register/login HTTP/1.1
Host: app.moutai519.com.cn
Connection: keep-alive
Content-Type: application/json
MT-Device-ID: 2F2075D0-B66C-4287-A903-DBFF6358342C
MT-User-Tag: 0
Accept: */*
MT-Network-Type: WIFI
MT-Token: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJtdCIsImV4cCI6MTY3NzAzMDk4OSwidXNlcklkIjoxMDU0NDI3MzYxLCJkZXZpY2VJZCI6IjJGMjA3NUQwLUI2NkMtNDI4Ny1BOTAzLURCRkY2MzU4MzQyQyIsImlhdCI6MTY3NDQzODk4OX0.jMzprM-mO6yBTG3pjEcmq2fUgAjKwyuWHREmY6vynv0
MT-K: 1675600193742
MT-Team-ID:
MT-Bundle-ID: com.moutai.mall
MT-V: adc8d8d93d0a7aa61bc1df89ad5
User-Agent: iOS;16.3;Apple;?unrecognized?
Accept-Language: en-CN;q=1, zh-Hans-CN;q=0.9
MT-Request-ID: 167560019374225511
MT-R: clips_OlU6TmFRag5rCXwbNAQ/Tz1SKlN8THcecBp/HGhHdw==
MT-APP-Version: 1.3.6
Content-Length: 65
Accept-Encoding: gzip, deflate, br
{"ydToken":"","mobile":"199********","vCode":"9884","ydLogId":""}
直接post提交收到的验证码过去,后端返回登录的token和用户信息:
成功实现登录(MT-Device-ID这个参数必须在请求头中,且每次请求需一致,获取验证码的时候生成一个随机UUID并在后续保持一致)
第二步:查询所预约的地区门店投放的产品类型和数量
抓包分析:
1.获取当天的sessionId
https://static.moutai519.com.cn/mt-backend/xhr/front/mall/index/session/get/1675267200000
1675267200000为当日00:00的时间戳,每天的sessionId是不一样的。
2.查询所在省市的投放产品和数量
https://static.moutai519.com.cn/mt-backend/xhr/front/mall/shop/list/slim/v3/512/重庆市/10213/1675526400000
链接后面四个参数分别为sessionId、省份名称、茅台的itemId、当日00:00的时间戳,可以根据自己所需来更改,接口所返回的数据为:
{
"code": 2000,
"data": {
"shops": [
{
"shopId": "150500101001",
"items": [
{
"count": 1,
"itemId": "10056",
"inventory": 3,
"ownerName": "重庆市垫江县辉高酒业有限公司"
},
{
"count": 1,
"itemId": "10213",
"inventory": 4,
"ownerName": "重庆市垫江县辉高酒业有限公司"
}
]
},
{
"shopId": "150500101002",
"items": [
{
"count": 1,
"itemId": "10056",
"inventory": 3,
"ownerName": "重庆市万州区醉仁川商贸有限公司"
},
{
"count": 1,
"itemId": "10213",
"inventory": 10,
"ownerName": "重庆市万州区醉仁川商贸有限公司"
}
]
},
{
"shopId": "150500101003",
"items": [
{
"count": 1,
"itemId": "10056",
"inventory": 3,
"ownerName": "重庆市涪陵区涛沭商贸有限公司"
},
{
"count": 1,
"itemId": "10213",
"inventory": 6,
"ownerName": "重庆市涪陵区涛沭商贸有限公司"
}
]
},
{
"shopId": "150500102001",
"items": [
{
"count": 1,
"itemId": "10056",
"inventory": 3,
"ownerName": "重庆茅美香商贸有限公司"
},
{
"count": 1,
"itemId": "10213",
"inventory": 6,
"ownerName": "重庆茅美香商贸有限公司"
}
]
},
{
"shopId": "150500103003",
"items": [
{
"count": 1,
"itemId": "10056",
"inventory": 9,
"ownerName": "重庆市綦江区储备粮有限公司"
},
{
"count": 1,
"itemId": "10213",
"inventory": 10,
"ownerName": "重庆市綦江区储备粮有限公司"
}
]
},
{
"shopId": "150500103005",
"items": [
{
"count": 1,
"itemId": "10056",
"inventory": 30,
"ownerName": "重庆茅台酒销售有限公司"
},
{
"count": 1,
"itemId": "10213",
"inventory": 6,
"ownerName": "重庆茅台酒销售有限公司"
},
{
"count": 1,
"itemId": "10214",
"inventory": 2,
"ownerName": "重庆茅台酒销售有限公司"
},
{
"count": 1,
"itemId": "2478",
"inventory": 2,
"ownerName": "重庆茅台酒销售有限公司"
}
]
},
{
"shopId": "150500106001",
"items": [
{
"count": 1,
"itemId": "10056",
"inventory": 3,
"ownerName": "重庆江岸酒类销售有限公司"
},
{
"count": 1,
"itemId": "10213",
"inventory": 12,
"ownerName": "重庆江岸酒类销售有限公司"
}
]
},
{
"shopId": "150500106003",
"items": [
{
"count": 1,
"itemId": "10213",
"inventory": 12,
"ownerName": "重庆国誉商贸有限公司"
}
]
},
{
"shopId": "150500107003",
"items": [
{
"count": 1,
"itemId": "10056",
"inventory": 6,
"ownerName": "重庆灏达伟业贸易有限公司"
},
{
"count": 1,
"itemId": "10213",
"inventory": 4,
"ownerName": "重庆灏达伟业贸易有限公司"
}
]
},
{
"shopId": "150500108002",
"items": [
{
"count": 1,
"itemId": "10056",
"inventory": 3,
"ownerName": "重庆崇贵酒类销售有限公司"
},
{
"count": 1,
"itemId": "10213",
"inventory": 8,
"ownerName": "重庆崇贵酒类销售有限公司"
}
]
},
{
"shopId": "150500109002",
"items": [
{
"count": 1,
"itemId": "10056",
"inventory": 3,
"ownerName": "重庆市德樽贸易有限公司"
},
{
"count": 1,
"itemId": "10213",
"inventory": 8,
"ownerName": "重庆市德樽贸易有限公司"
}
]
},
{
"shopId": "150500112001",
"items": [
{
"count": 1,
"itemId": "10056",
"inventory": 3,
"ownerName": "重庆市润鑫酒业有限公司"
},
{
"count": 1,
"itemId": "10213",
"inventory": 14,
"ownerName": "重庆市润鑫酒业有限公司"
}
]
},
{
"shopId": "150500112002",
"items": [
{
"count": 1,
"itemId": "10056",
"inventory": 3,
"ownerName": "重庆熙晋酒业有限公司"
},
{
"count": 1,
"itemId": "10213",
"inventory": 8,
"ownerName": "重庆熙晋酒业有限公司"
}
]
},
{
"shopId": "150500112006",
"items": [
{
"count": 1,
"itemId": "10056",
"inventory": 30,
"ownerName": "重庆国酒茅台销售有限公司"
},
{
"count": 1,
"itemId": "10213",
"inventory": 10,
"ownerName": "重庆国酒茅台销售有限公司"
},
{
"count": 1,
"itemId": "10214",
"inventory": 2,
"ownerName": "重庆国酒茅台销售有限公司"
},
{
"count": 1,
"itemId": "2478",
"inventory": 2,
"ownerName": "重庆国酒茅台销售有限公司"
}
]
},
{
"shopId": "150500113002",
"items": [
{
"count": 1,
"itemId": "10056",
"inventory": 3,
"ownerName": "重庆海惠酒类销售有限公司"
},
{
"count": 1,
"itemId": "10213",
"inventory": 10,
"ownerName": "重庆海惠酒类销售有限公司"
}
]
},
{
"shopId": "150500223001",
"items": [
{
"count": 1,
"itemId": "10056",
"inventory": 9,
"ownerName": "重庆乾恒来商贸有限公司潼南分公司"
},
{
"count": 1,
"itemId": "10213",
"inventory": 8,
"ownerName": "重庆乾恒来商贸有限公司潼南分公司"
}
]
},
{
"shopId": "150500224001",
"items": [
{
"count": 1,
"itemId": "10056",
"inventory": 3,
"ownerName": "重庆市铜梁区榕润酒类销售有限公司"
},
{
"count": 1,
"itemId": "10213",
"inventory": 14,
"ownerName": "重庆市铜梁区榕润酒类销售有限公司"
}
]
},
{
"shopId": "150500227001",
"items": [
{
"count": 1,
"itemId": "10056",
"inventory": 3,
"ownerName": "重庆市羽杨酒业有限公司"
},
{
"count": 1,
"itemId": "10213",
"inventory": 6,
"ownerName": "重庆市羽杨酒业有限公司"
}
]
},
{
"shopId": "150500228001",
"items": [
{
"count": 1,
"itemId": "10056",
"inventory": 6,
"ownerName": "重庆国荣酒店用品有限公司"
},
{
"count": 1,
"itemId": "10213",
"inventory": 8,
"ownerName": "重庆国荣酒店用品有限公司"
}
]
},
{
"shopId": "150500237001",
"items": [
{
"count": 1,
"itemId": "10213",
"inventory": 8,
"ownerName": "重庆宜满商贸有限公司"
}
]
},
{
"shopId": "150500383002",
"items": [
{
"count": 1,
"itemId": "10056",
"inventory": 3,
"ownerName": "重庆蓥浆商贸有限公司"
},
{
"count": 1,
"itemId": "10213",
"inventory": 10,
"ownerName": "重庆蓥浆商贸有限公司"
}
]
},
{
"shopId": "150500383003",
"items": [
{
"count": 1,
"itemId": "10056",
"inventory": 3,
"ownerName": "重庆市沛泉酒类有限公司"
},
{
"count": 1,
"itemId": "10213",
"inventory": 10,
"ownerName": "重庆市沛泉酒类有限公司"
}
]
},
{
"shopId": "150500700002",
"items": [
{
"count": 1,
"itemId": "10056",
"inventory": 3,
"ownerName": "重庆明培成商贸有限公司"
},
{
"count": 1,
"itemId": "10213",
"inventory": 14,
"ownerName": "重庆明培成商贸有限公司"
},
{
"count": 1,
"itemId": "10214",
"inventory": 4,
"ownerName": "重庆明培成商贸有限公司"
}
]
},
{
"shopId": "250500103001",
"items": [
{
"count": 1,
"itemId": "10213",
"inventory": 4,
"ownerName": "重庆糖酒有限责任公司"
}
]
},
{
"shopId": "250500105003",
"items": [
{
"count": 1,
"itemId": "10213",
"inventory": 4,
"ownerName": "重庆乾虹酒类销售有限公司"
}
]
},
{
"shopId": "250500105007",
"items": [
{
"count": 1,
"itemId": "10213",
"inventory": 14,
"ownerName": "重庆聪易商贸有限公司"
}
]
},
{
"shopId": "250500107004",
"items": [
{
"count": 1,
"itemId": "10213",
"inventory": 4,
"ownerName": "重庆贵可丰酒业有限责任公司"
},
{
"count": 1,
"itemId": "2478",
"inventory": 2,
"ownerName": "重庆贵可丰酒业有限责任公司"
}
]
},
{
"shopId": "250500112005",
"items": [
{
"count": 1,
"itemId": "10213",
"inventory": 14,
"ownerName": "重庆瑞干商贸有限公司"
}
]
},
{
"shopId": "250500381001",
"items": [
{
"count": 1,
"itemId": "10213",
"inventory": 4,
"ownerName": "重庆银怀祥贸易有限公司"
},
{
"count": 1,
"itemId": "2478",
"inventory": 2,
"ownerName": "重庆银怀祥贸易有限公司"
}
]
},
{
"shopId": "250500700001",
"items": [
{
"count": 1,
"itemId": "10213",
"inventory": 14,
"ownerName": "重庆崇晟商贸有限公司"
},
{
"count": 1,
"itemId": "10214",
"inventory": 4,
"ownerName": "重庆崇晟商贸有限公司"
}
]
}
],
"validTime": 1675577461135,
"items": [
{
"picUrl": "https://resource.moutai519.com.cn/mt-resource/static-union/1647438760fef3c7.png",
"title": "53%vol 500mL茅台1935",
"price": "1188",
"count": 0,
"itemId": "10056",
"inventory": 0,
"areaLimitTag": false,
"areaLimit": 0
},
{
"picUrl": "https://resource.moutai519.com.cn/mt-resource/static-union/16727494184eeb12.png",
"title": "53%vol 500ml贵州茅台酒(癸卯兔年)",
"price": "2499",
"count": 0,
"itemId": "10213",
"inventory": 0,
"areaLimitTag": false,
"areaLimit": 0
},
{
"picUrl": "https://resource.moutai519.com.cn/mt-resource/static-union/16727492927991ce.png",
"title": "53%vol 375ml×2贵州茅台酒(癸卯兔年)",
"price": "3599",
"count": 0,
"itemId": "10214",
"inventory": 0,
"areaLimitTag": false,
"areaLimit": 0
},
{
"picUrl": "https://resource.moutai519.com.cn/mt-resource/static-union/16474387600e74c1.png",
"title": "53%vol 500mL贵州茅台酒(珍品)",
"price": "4599",
"count": 0,
"itemId": "2478",
"inventory": 0,
"areaLimitTag": false,
"areaLimit": 0
}
]
}
}
第三步:提交预约信息
手动进行一次申购,抓包分析:
1. 请求内容 Request:
POST /xhr/front/mall/reservation/add HTTP/1.1
Host: app.moutai519.com.cn
User-Agent: iOS;16.3;Apple;?unrecognized?
MT-Token: eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJtdCIsImV4cCI6MTY3NzAzMDk4OSwidXNlcklkIjoxMDU0NDI3MzYxLCJkZXZpY2VJZCI6IjJGMjA3NUQwLUI2NkMtNDI4Ny1BOTAzLURCRkY2MzU4MzQyQyIsImlhdCI6MTY3NDQzODk4OX0.jMzprM-mO6yBTG3pjEcmq2fUgAjKwyuWHREmY6vynv0
MT-Network-Type:
MT-User-Tag: 0
MT-R: clips_OlU6TmFRag5rCXwbNAQ/Tz1SKlN8THcecBp/HGhHdw==
MT-Lat: 28.499562
MT-K: 1675213490331
MT-Lng: 102.182324
Content-Length: 255
MT-Info: 028e7f96f6369cafe1d105579c5b9377
Connection: keep-alive
MT-Team-ID:
MT-APP-Version: 1.3.6
MT-Request-ID: 16752134903311510
Accept-Language: en-CN;q=1, zh-Hans-CN;q=0.9
MT-Device-ID: 2F2075D0-B66C-4287-A903-DBFF6358342C
Accept: */*
Content-Type: application/json
Accept-Encoding: gzip, deflate, br
MT-V: 854487cbb9b9aac538e0ce894by
MT-Bundle-ID: com.moutai.mall
{"actParam":"IdiwwdtRdEBhdeHkaJbq1J59r8j5hLj3e34vWmtgR3uF1TYR/v0XjWK/NmSFHV3v9z8jPw27gwdkpCHFaUU8/g1GgyhkiAlOo9qJfCv778NWPRnZDTVPsRyGBzRAxasuTpH+ZyaSlKKZViJHuh8tLw==","itemInfoList":[{"count":1,"itemId":"2478"}],"shopId":"151510100019","sessionId":508}
2. 响应内容 Response:
HTTP/1.1 200
Content-Type: application/json;charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
Date: Wed, 01 Feb 2023 01:04:50 GMT
Server: yanxuan-ianus/0.9.7
{"code":2000,"data":{"successDesc":"申购完成,请于2月1日18:00查看预约申购结果","reservationList":[{"reservationId":15675400124,"sessionId":508,"shopId":"151510100019","reservationTime":1675213491048,"itemId":"2478"}],"reservationDetail":{"desc":"申购成功后将以短信形式通知您,请您在申购成功次日18:00前确认支付方式,并在3天内完成提货。","lotteryTime":1675245600000,"cacheValidTime":1675245600000}}}
分析请求的body有一个加密参数actParam,对茅台app进行hook分析得到加密算法为AES CBC PKCS7 改写加密算法:
public static final String AES_KEY="qbhajinld***************gypwuvcjaa";
public static final String AES_IV="2018********63515";
public static String AesEncrypt(String params){
AES aes = new AES(Mode.CBC, Padding.PKCS5Padding, AES_KEY.getBytes(), AES_IV.getBytes());
return aes.encryptBase64(params);
}
public static String AesDecrypt(String params){
AES aes = new AES(Mode.CBC, Padding.PKCS5Padding, AES_KEY.getBytes(), AES_IV.getBytes());
return aes.decryptStr(params);
}
用刚刚抓到得到的加密文本进行解密验证:
验证成功!!
最后就是提交预约信息了,经过我反复测试发现,reservation/add接口的请求头中有一个MT-Info参数需要带上才能成功提交预约信息,且该参数为固定值:028e7f96f6369cafe1d105579c5b9377
综合以上步骤进行实现一个添加账号的前端界面实现上号功能:
后台设置定时任务每天早上9:00-10:00之间进行预约:
至此,所有功能大功告成!!
仅供学习参考!!!技术交流:c2tpZG9vZGl1ZGl1(base64)