安卓逆向分析百世来取app接口及其实现
安卓逆向分析百世来取app接口及其实现
1.解压缩apk文件,得到三个dex文件
2.反编译出3个jar包
3.fiddler抓包相关的接口
以这个登录接口为例。
登录url为https://laiqu.800best.com/lqapi/Security/UserLogin
请求体为json格式的字符串
{ "password":"Ps6q3ZDX4YGEI8A/Xp2FscYZ/+DPDDluMSjqiVZ1klFpcbwjZObQdrc3v7Slp/hXAc196IRa/z+Kp5CiuXHRtxlxfnq9ioKV+/1yz3VoZ5zMILDdkL3rdXu78m35sQ5aq6XOPvVeex5tL1ZBv08aDM7cdE3udkl+kgrMheRs6Ug=", "userName":"130****2887" # 账号就不公开了 }
发现密码是加密后的,所以要找到密码是怎么加密的,一眼看上去,能大概得出是rsa加密,然后转base64编码(其实是抓包里面看出来的)
既然知道了是rsa加密,那就用python写个demo来测试一下
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 # 获取Rsa公钥 2 def getRsaPublicKey(): 3 url = 'https://laiqu.800best.com/lqapi/Security/GetRsaPublicKey' 4 try: 5 r = requests.post(url, timeout=5) 6 res_data = r.json() 7 except Exception as e: 8 res_data = {} 9 rsaPublicKey = res_data['result']['publicKey'] 10 return rsaPublicKey 11 12 13 def rsa_password(password, public_key): 14 key = '''-----BEGIN PUBLIC KEY----- 15 {} 16 -----END PUBLIC KEY----- 17 ''' 18 rsakey = RSA.importKey(key.format(public_key)) 19 cipher = Cipher_pkcsl_v1_5.new(rsakey) 20 cipher_text = base64.b64encode(cipher.encrypt(password.encode())) 21 res = cipher_text.decode() 22 return res 23 24 25 # 用户登录 26 def login(public_key, userName, password): 27 # 用户登录 28 url = 'https://laiqu.800best.com/lqapi/Security/UserLogin' 29 encrypt_password = rsa_password(password, public_key) 30 login_data = { 31 "password": encrypt_password, 32 "userName": userName 33 } 34 res_data = post_json_headers_verify(url, login_data) 35 if res_data['status'] != 1: 36 raise Exception('登录出错') 37 else: 38 jwt_token = res_data['result']['token'] 39 serviceSiteCode = res_data['result']['serviceSites'][0]['serviceSiteCode'] 40 return jwt_token, serviceSiteCode
测试结果,OK,登录接口完成。
接下来就是业务需要了,公司给的任务是获取出库接口,那么就用安卓模拟器模拟一下出库操作,抓包抓接口。
出库接口分析得出,用户认证是采用的jwt认证,请求体是billCode,里面填上单号即可。那么就可以编写python的demo来测试了
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
# 出库 def optionalPickup(billCode): url = 'https://splaiquapp.800best.com/lq/api/optionalPickup' reqData = {"billCode": billCode} res_dict = post_json_headers_verify(url, reqData, headers) print(res_dict) if res_dict['status'] == 1: print('出库成功') else: raise Exception('出库失败')
测试结果发现出库并没有成功,然后经过一番排查,发现在用户登录的时候不只是用户登录这一个接口,还有一个登录站点的接口
那么接下来就是模拟站点登录接口
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
# 登录站点 def LoginServiceSite(serviceSiteCode): url = 'https://laiqu.800best.com/lqapi/Security/LoginServiceSite' login_data = {"serviceProvideCode": "laiqu", "serviceSiteCode": serviceSiteCode} res_dict = post_json_headers_verify(url, login_data, headers) if res_dict['status'] == 1: print('登录站点成功') else: raise Exception('登录站点失败')
然后测试出库接口,发现OK,出库成功。
End.