某猫超市茅台抢购脚本python
仅供学习研究。请勿⽤于⾮法⽤途,本⼈将不承担任何法律责任。
前⾔
最近听到同事在讨论茅台,就打算买⼏瓶。
53 度飞天茅台官⽅指导出⼿价是 1499 元,但是正常情况下,1499 根本买不到,线下的专卖店可以买到 2000-3000 元左右,⽽
且还容易买到假货。
就打算写个脚本去⾃动化抢购,前⾯研究了⼀段时间京东之后,直接放弃了,太⿇烦了,没有可以测试的商品,主要是预约抢购的商品下单接⼝跟普通的商品不⼀样,这个就⽐较蛋疼了,于是就把⽬标放到了天猫超市上
环境
本次使⽤的环境是 python frida jeb jadx-gui charles,天猫版本是 8.11.0 这个版本的加密⽐较容易。
整个抢购流程分三步:
1、添加购物车
2、点击购买
2、提交订单
也就是需要请求三个 api,这⾥我们只分析 购买跟下单接⼝
分析请求包
这是点击购买接⼝,⼤家都知道淘宝系的接⼝请求头都会包含 x-sign x-mini-wua 这两个参数,其他的都不是很重要,但是推荐还是带上⽐较好,可以⾃⾏测试
这个是下单的接⼝请求头都是⼀样的,请求体多了两个加密参数 wua params,两个接⼝现在需要破解四个加密参数,下⾯来分析
分析加密参数
⾸先来看 x-sign,具体的分析过程就不说了,没经验的话是⾮常掉头发的,知道应该都清楚这个参数
最终是调⽤ so 层
python转java代码
JNICLibrary.doCommandNative 函数加密的,⼩弟不才没有能⼒去分析 so ⽂件,只能祭出强⼤的 hook 框架 frida 了,本次也是使⽤这个⼯具来主动调⽤函数获取加密结果的。
反编译之后到 libsgmain.so ⽂件,把后缀改成 zip 在解压,使⽤ jadx-gui 或者其他⼯具打开解压后的 dex ⽂件就能看到JNICLibrary.doCommandNative 函数的代码逻辑了
function getMapData(mapSet){
try{
var result ={};
var key_set = mapSet.keySet();
var it = key_set.iterator();
while(it.hasNext()){
var key_str = it.next().toString();
result[key_str]= (key_str).toString();
}
return result
}catch(error){
return mapSet
}
}
function searchClassLoader(className){
onMatch:function(loader){
try{
if(loader.findClass(className)){
console.log(loader);
Java.classFactory.loader = loader;
}
}catch(error){
}
},
onComplete:function(){
}
})
}
function hookDoCommandNative(){
var JNICLibrary = Java.use('com.taobao.wireless.security.adapter.JNICLibrary');
JNICLibrary.doCommandNative.implementation=function(a, b){
console.log('JNICLibrary.doCommandNative.a: ', a);
console.log('JNICLibrary.doCommandNative.b: ', b);
console.log('JNICLibrary.doCommandNative.b: ', b.length);
console.log('JNICLibrary.doCommandNative.b: ',JSON.stringify(b));
for(var i =0; i < b.length; i++){
try{
console.log('JNICLibrary.doCommandNative.b.i: ', i,' data: ', b[i].toString())
}catch(error){
console.log('JNICLibrary.doCommandNative.b.i: ', i,' data: ','空')
}
}
var res =this.doCommandNative(a, b);
console.log('s: ', res);
try{
var result =getMapData(Java.cast(res, Java.use('java.util.HashMap')));
console.log('result: ',JSON.stringify(result));
}catch(error){
}finally{
console.log('-------------------start stack-------------------');
console.log(Java.use("android.util.Log").getStackTraceString(Java.use("java.lang.Throwable").$new()));            console.log('-------------------end stack-------------------');
}
return res;
}
}
function main(){
function main(){
var className1 ='com.taobao.wireless.security.adapter.JNICLibrary';
Java.perform(function(){
searchClassLoader(className1);
hookDoCommandNative();
})
}
setImmediate(main);
这⾥放⼀段 frida hook 代码,想要查看那个接⼝ x-sign x-mini-wua 加密参数的明⽂,直接运⾏这段代码就OK了
这张图⽚是运⾏后的log⽇志,可以看到 JNICLibrary.doCommandNative 函数的输⼊输出全部打印出来了,包括 object array 类型的数据也打印出来了。
根据log⽇志打印的明⽂信息,就可以⾃⼰去构建 frida hook 主动调⽤的代码了
function getXSign8110(signData){
var result ='';
Java.perform(function(){
onMatch:function(loader){
try{
if(loader.findClass('com.taobao.wireless.security.adapter.JNICLibrary')){                        Java.classFactory.loader = loader;
}
}catch(error){
}
},onComplete:function(){
}
});
var hashMap = Java.use('java.util.HashMap').$new();
var JNICLibrary = Java.use('com.taobao.wireless.security.adapter.JNICLibrary');        hashMap.put('INPUT', signData['input']);
var params =[
hashMap,
Java.use('java.lang.String').$new(signData['app_key']),
Java.use('java.lang.Integer').$new(7),
Java.use('java.lang.String').$new(''),
Java.use('java.lang.Boolean').$new(true),
];
var ps = Java.array('Ljava.lang.Object;', params);
result = JNICLibrary.doCommandNative(10401, ps).toString();
});
return result
}
function getMiniWua8110(wuaData){
var result ='';
Java.perform(function(){
onMatch:function(loader){
try{
if(loader.findClass('com.taobao.wireless.security.adapter.JNICLibrary')){                        Java.classFactory.loader = loader;
}
}catch(error){
}
},onComplete:function(){
}
});
var JNICLibrary = Java.use('com.taobao.wireless.security.adapter.JNICLibrary');
var params =[
Java.use('java.lang.String').$new(wuaData['time_str']),
Java.use('java.lang.String').$new(wuaData['app_key']),
Java.use('java.lang.Integer').$new(8),
Java.use('java.lang.String').$new(''),
Java.use('java.lang.String').$new(wuaData['input']),
Java.use('java.lang.Integer').$new(0),
];
var ps = Java.array('Ljava.lang.Object;', params);
result = JNICLibrary.doCommandNative(20102, ps).toString();
});
return result
}

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。