某图网站新版加密分析
1. 前言
网站:aHR0cHMlM0EvL21tenp0dC5jb20
关于该网站的js加密方式,我在之前分享过。最近发现网站图片链接的获取方式又有所改变,于是再次分析图片的获取方法。
2. 解密过程
网站有无限debugger,可以选择本地替换或者js注入。
2.1 图片链接来源
在之前的分析中,我们找出图片链接的来源是在当前界面的源代码中(comment中),现在网站改变了获取方式,通过开发者工具可以发现,链接实际来源改由ajax获取。 从上面的请求中可以得知,网站通过当前界面的id请求加密的图片链接资源,推测网站接下来将会通过js解密得到图片链接。在这里需要注意,网站在获取到data后会储存,因此可能会出现刷新后获取不到数据包的情况。
2.2 寻找解密代码
经过打断点、查看堆栈后,发现数据解密入口函数 可以看到,_0x1ecabc函数获取两个参数:id和data,通过解密后得到一个包含图片链接关键信息的列表,由于web端的限制,该列表只有20条数据。接下来,我们进入这个函数分析。 发现实际上是这个函数,我们把它扣下来,放入vscode中运行试试。 提示_0x1708未定义,在源代码中搜索 找到这个函数后同样扣下来,再次运行,发现又缺少_0x32ea这个函数,再去源代码中找 将_0x32ea扣下来,并将代码进行一定优化后再次运行,可以看到已经不缺其他的自定义方法了。
2.3 代码优化
接下来对代码进行优化并复现解密方法。 在简化代码的过程中,可以发现这个地方非常奇怪,尤其是在后面的代码优化中更是如此,于是中途试运行代码打印出运行中使用到的变量,发现完全不符合预期。经过一段时间的寻找,终于发现原来在开头的地方对fun1中的字符串列表的顺序进行了改变,但是我们不必关心它的方法,只需要在最后把正确顺序的列表抓出来即可
得到正确的列表后再次对代码进行优化。 代码的大致思路是:在fun1中存了一个字符串列表,fun2中使用一个参数,将它减去一个值后作为索引取到fun1中的字符串,而在最终的fun3中则大量使用了其中的字符串,此外代码中有大量的16进制数字和字符串,看起来十分混乱,简化后的最终代码,只需要最后一个函数即可。
3. 解密方法复现
现在我们使用python代码复现数据的解密方法,此处我选择使用chatgpt将上面的最终代码改写为python代码,以下是chatgpt给我的并经过我优化改写后的代码。
from Crypto.Cipher import AES
from Crypto.Hash import MD5
from Crypto.Util.Padding import unpad
import base64
import json
from loguru import logger
def decrypt(pid: int, data: str) ->str :
rel_data = data.split('固定字符')[1]
iv = ''
for i in range(2, 18):
iv += str(pid % i % 9)
logger.info(f'IV:{iv}')
data_bytes = bytes.fromhex(rel_data)
data_base = base64.b64encode(data_bytes).decode()
key = MD5.new((str(pid) + '固定字符' + iv).encode()).hexdigest()[8:24]
logger.info(f'Key:{key}')
result = AES.new(key.encode(), AES.MODE_CBC, iv=iv.encode()).decrypt(base64.b64decode(data_base))
return json.loads(unpad(result, AES.block_size).decode())
通过以上代码即可成功解密ajax传回的data数据。
4. 总结
总体而言,这个网站的加密不算复杂,要说麻烦主要来源于大量的16进制数据与混淆的变量和方法名,细心一点还是比较容易。
完整的文件代码:https://lanzout.com/idLC10qj7rdi
分享:经过分析,这个网站的app确实使用了ssl证书双向验证,使用r0ysue的项目r0capture可以导出p12证书,将证书导入charles中可以实现对app的抓包,不过返回的依然是加密数据。此外,app使用了数据加固,并能够检测模拟器和xposed,难以分析。
本文由 mdnice 多平台发布