安卓逆向分析百世来取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来测试一下

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

View Code

测试结果,OK,登录接口完成。

接下来就是业务需要了,公司给的任务是获取出库接口,那么就用安卓模拟器模拟一下出库操作,抓包抓接口。

出库接口分析得出,用户认证是采用的jwt认证,请求体是billCode,里面填上单号即可。那么就可以编写python的demo来测试了

# 出库

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('出库失败')

View Code

测试结果发现出库并没有成功,然后经过一番排查,发现在用户登录的时候不只是用户登录这一个接口,还有一个登录站点的接口

那么接下来就是模拟站点登录接口

# 登录站点

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('登录站点失败')

View Code

然后测试出库接口,发现OK,出库成功。

End.