前言
上两篇文章分析了两个app的md5算法,今天准备逆向分析sha1加密的app。
下图是唯品会app搜索关键词的Headers参数api_sign:
值为:233b31e1fa70070e4f56f0b02ff6a4d1817e340f
这次的长度不再是32位了,是40位
sha1的加密结果是40个16进制,而我们的结果恰好是40位长度
frida-trace跟踪“CC_SHA1”函数
frida-trace -H 192.168.31.188 -F -i "CC_SHA1"
-F 意思是前台使用的app
"CC_SHA1"是官方提供的函数
输入关键词并重新搜索,终端中的确显示了CC_SHA1,说明我们的猜想没错但是这样只能说明是sha1加密,但是看不到具体的入参和出参
所以要对js文件进行修改下,CC_SHA1.js代码如下:
onEnter(log, args, state) {
log('CC_SHA1() onEnter: ' + args[0].readCString(args[1].toInt32()));
this.args2 = args[2];
},
onLeave(log, retval, state) {
log('CC_SHA1() onLeave: ' + hexdump(this.args2, {length: 20}));
}
修改后终端显示结果
Charles抓包的结果
新的值:b3f80e7b7c141cdfacd1002ea1fac70bf20d465c,因为修改的js文件是16进制结果显示,所以搜索得是b3 f8 0e 7b 7c 14...这种方式 进行搜索,在终端中查找到了对应的值。
加密过程分析
onEnter参数进行sha1加密后的结果->603aaceb52f17a934203f2613f9592fbc3f07336
再次搜索sha1后的结果"603aaceb52f17a934203f2613f9592fbc3f07336",且找到了一条对应的结果。
发现在结果的前面出现重复的b93af00b1270239d67bafdf9cbb2523b,拼接后再次进行了sha1加密后得到了b3f80e7b7c141cdfacd1002ea1fac70bf20d465c
分析结果:
(b93af00b1270239d67bafdf9cbb2523b + 请求参数键值对 )进行sha1加密
(b93af00b1270239d67bafdf9cbb2523b + sha1结果)再次进行sha1加密
salt = "b93af00b1270239d67bafdf9cbb2523b"
和猜想的结果一致,说明预测的sha1加密算法正确,那么话不多说直接上代码
代码
import hashlib
# 生成api_sign参数
def api_sign():
sorted_data = {k: v for k, v in sorted(data.items())}
sorted_data = urllib.parse.urlencode(sorted_data)
sorted_data = urllib.parse.unquote(sorted_data)
headers['authorization'] = 'OAuth api_sign=' + sha1(sha1(sorted_data))
response = requests.post('https://gd16-cm.vip.com/vips-mobile/rest/shopping/search/product/list/v1',headers = headers, data = sorted_data)
print(response.text)
# sha1算法
def sha1(string):
salt = 'b93af00b1270239d67bafdf9cbb2523b'
# 创建 SHA-1 哈希对象
sha1_hash = hashlib.sha1()
# 更新哈希对象,传入字节类型的数据
sha1_hash.update((salt + string).encode('utf-8'))
# 获取哈希结果,返回十六进制表示
hash_result = sha1_hash.hexdigest()
return hash_result
上图代码中data中的params参数进行了a-z字母的排序操作
只展示了部分核心代码,params、headers参数需要自行补充