阅读本篇文章请先具备python爬虫、java、js逆向基础
下载油联合伙人:
https://www.wandoujia.com/apps/8051276
在模拟器中登录并抓包,发现被加密过
同时X-sign字段也一直在不断变化,所以我们需要逆向出X-sign和password的算法并用python去实现
1.安装jadx,将其编译出来:
2.通过搜索关键字定位到password
3.接着查找用例,定位到谁使用了它:
4.紧接着继续查找用例loginWithToken,分析定位到第二条:
ps:如果查找用例搜索不到,可以通过搜索功能搜索关键字定位:
5.最后定位到该位置,进行跳到声明,查看具体的算法:
6.最后跳转到的加密算法如下,分析得就是一个普通的MD5加密
7.使用python的MD5算法调用即可
from hashlib import md5
# 网上找一段md5加密的代码
def encrypt_md5(s):
# 创建md5对象
new_md5 = md5()
# 这里必须用encode()函数对字符串进行编码,不然会报 TypeError: Unicode-objects must be encoded before hashing
new_md5.update(s.encode(encoding='utf-8'))
# 加密
return new_md5.hexdigest()
print(encrypt_md5("123456"))
1.通过搜索X-sign定位
2.再通过搜索X-sign定位出的值进行查找用例
3.查找用例定位到如下代码,发现该代码和Header请求体中的请求一样,所以就能大概确定是这个位置
4.分析this.sign的值为sb.toString()
4.而sb的值为从formBody,append了一个name和value
6.而这个name和value也就是我们请求包中对应的名字和值
7.所以分析出,sb.toString的值就是:phone=13333333333&password=5c2687a62a342e51e4a45ed62aaa714c
8.最后再定位到sign()这个函数的实现方法:
9.通过分析实现方法可以直接构造出python代码
from hashlib import md5
# 网上找一段md5加密的代码
def encrypt_md5(s):
# 创建md5对象
new_md5 = md5()
# 这里必须用encode()函数对字符串进行编码,不然会报 TypeError: Unicode-objects must be encoded before hashing
new_md5.update(s.encode(encoding='utf-8'))
# 加密
return new_md5.hexdigest()
# 定义sign所需要的值
token = "" # 在包中可以看到token的值为空
reqTime = "1661661320955" # 这里是时间戳,可以用代码自己生成,我这里图方便直接赋值
noncestr = "123456" # 这里noncestr的值是代码中定义好的
noncestr_2 = noncestr[:2] # 实现切片substring(2)
str = "phone=13333333333&password=5c2687a62a342e51e4a45ed62aaa714c"
def sign():
res = f"{token}{reqTime}{noncestr_2}{str}" # 这里的f类似于.formate
return res
print(encrypt_md5(f"{sign()}"))
import requests
from hashlib import md5
phone="13333333333"
pwd="123456"
#逆向算法实现部分:
# 网上找一段md5加密的代码
def encrypt_md5(s):
# 创建md5对象
new_md5 = md5()
# 这里必须用encode()函数对字符串进行编码,不然会报 TypeError: Unicode-objects must be encoded before hashing
new_md5.update(s.encode(encoding='utf-8'))
# 加密
return new_md5.hexdigest()
# 定义sign所需要的值
token = "" # 在包中可以看到token的值为空
reqTime = "1661669606606" # 这里是时间戳,可以用代码自己生成,我这里图方便直接赋值
noncestr = "123456" # 这里noncestr的值是代码中定义好的
noncestr_2 = noncestr[2:] # 实现切片substring(2)
str = "phone=13333333333&password={pwd}".format(pwd=encrypt_md5(pwd))
def sign():
res = f"{token}{reqTime}{noncestr_2}{str}" # 这里的f类似于.formate
return res
#爬虫部分:
url="http://chinayltx.com/app/api/v1/partnerLogin/login"
md5_pwd=encrypt_md5(pwd)
sign=encrypt_md5(f"{sign()}")
headers={
"X-App": "native",
"X-Noncestr": "123456",
"X-Os": "partnerApp_android",
"X-Req-Time": "1661669606606",
"X-Sign": f"{sign}",
"Content-Type": "application/x-www-form-urlencoded"
}
data={
"phone":f"{phone}",
"password":md5_pwd
}
res=requests.post(url,headers=headers,data=data)
print(res.text)